检查代码是否存在整数操作安全漏洞

时间:2023年09月22日

/

来源:三明

/

编辑:本站小编

收藏本文

下载本文

这里小编给大家分享一些检查代码是否存在整数操作安全漏洞,本文共2篇,方便大家学习。本文原稿由网友“三明”提供。

篇1:检查代码是否存在整数操作安全漏洞

来自:微软中国

Michael Howard

Secure Windows Initiative

摘要: Michael Howard 提出关于整数操作安全漏洞的问题,并且阐述可以用来保护自己应用程序的安全性计划,

很多年以前,很少有人听说过整数溢出攻击,但现在好像每隔几天它就会出现一种新的形式。下面的简短列表就是在最近几个月内发现的一些整数溢出的安全性错误:

? Sun RPC xdr_array

? OpenSSH authentication

? Apache Chunked Encoding

? Microsoft JScript

? FreeBSD socket and system calls

? Snort TCP Packet Reassembly

在本月的专栏中,我将阐述这些错误是如何出现的,如何在代码中搜寻它们以及如何修复它们。

在进入到本文的正题之前,我非常高兴的宣布“Writing Secure Code”接收到了在 年 4 月于 San Francisco 召开的 RSA Security Conference 的“Conference Award for Industry Innovation”。

现在,回到整数攻击问题吧!

我不想解释什么是整数,我假设您知道它们是什么,并且知道有两种类型(有符号和无符号),其中当值是负数时,有符号整数的高位设置为 1,这是对 2 求补算法的结果。您也知道整数大小各有不同,最常见的长度为 64 位、32 位、16 位和 8 位的整数。这就是我所说的关于整数的全部内容,对于本文而言,如果您知道这些知识就足够了。

有三种主要整数操作可以导致安全性漏洞:

? 上溢和下溢

? 有符号与无符号的错误

? 截断

取决于它们自己的情况,这些问题可能不会产生安全性错误。但是,如果您的代码显示有一个或多个这样的问题,并且您的代码会操作内存,那么产生缓冲区溢出错误或应用程序故障的可能性就会增加。让我们仔细查看一下每一项。

上溢和下溢

快速看一下这段代码有什么问题?

bool func(size_t cbSize) {

if (cbSize < 1024) {

// we never deal with a string trailing null

char *buf = new char[cbSize-1];

memset(buf,0,cbSize-1);

// do stuff

delete [] buf;

return true;

} else {

return false;

}

}

代码是正确的,对吗?它验证 cbSize 不大于 1 KB,并且 new 或 malloc 应该始终正确地分配 1 KB,对吗?让我们忽略以下事实,new 或 malloc 的返回值应该在此时进行检查。同样,cbSize 不能为负数,因为它是 size_t。但是,如果 cbSize 是零,又会如何呢?查看一下分配缓冲区的代码,它从缓冲区大小请求中减去一。从零减去一会产生 size_t 变量,这是一个无符号的整数,其限制为 0xFFFFFFFF(假设为 32 位的值)或者 4 GB。您的应用程序只有结束了,或者更糟!

请看下面相似的问题:

bool func(char *s1, size_t len1,

char *s2, size_t len2) {

if (1 + len1 + len2 >64)

return false;

// accommodate for the trailing null in the addition

char *buf = (char*)malloc(len1+len2+1);

if (buf) {

StringCchCopy(buf,len1+len2,s1);

StringCchCat(buf,len1+len2,s2);

}

// do other stuff with buf

if (buf) free(buf);

return true;

}

同样,代码看起来编写得很好;它检查数据大小,验证 malloc 是否成功,并且使用 safe 字符串处理函数 StringCchCopy 和 StringCchCat(您可以从 msdn.microsoft.com/library/en-us/dnsecure/html/strsafe.asp 阅读更多关于这些字符串处理函数的内容)。但是,这段代码可能会受到整数上溢的危害。如果 len1 是 64,len2 是 0xFFFFFFFF,又会如何呢?确定缓冲区大小的代码合法地将 1、64 和 0xFFFFFFFF 加在一起,由于加操作的限制,会产生 64。接下来,代码仅分配了 64 个字节,然后代码生成了一个长度为 64 个字节的新字符串,然后将 0xFFFFFFFFF 字节与该字符串相连。同样,应用程序将会结束,在某些情况下,如果利用精心设计的大小进行攻击,代码可能会受到可用缓冲区溢出攻击。

此处的另外一个教训就是,如果缓冲区大小计算不正确,_safe 字符串处理函数就不安全,

返回页首

JScript. 溢出攻击

当使用乘法时也会出现相同类型的上溢错误,这发生在 Microsoft JScript. 错误中。该错误仅表明它自己在使用 JScript. 稀疏数组支持时会出现:

var arr = new Array;

arr[1] = 1;

arr[2] = 2;

arr[0x40000001] = 3;

在这个示例中,数组具有三个元素,且长度为 0x40000001(十进制为 1073741825)。但是,由于该示例使用稀疏数组,它只占用内存的三个元素的数组。

实现 JScript. 自定义排序例程的 C++ 代码在堆上分配临时的缓冲区、将三个元素复制到临时缓冲区中、使用自定义函数排序临时缓冲区,然后将临时缓冲区的内容移动回数组中。下面是分配临时缓冲区的代码:

TemporaryBuffer = (Element *)malloc(ElementCount * sizeof(Element));

Element 是一个 20 字节的数据结构,用于保存数组项。看起来程序将尝试为临时缓冲区分配大约 20 GB。您可能认为由于大多数人的计算机上不会有 20 GB 的内存,分配尝试将会失败。那么,JScript. 常规内存不足处理例程将会处理该问题。遗憾的是,并没有发生这样的情况。

当使用 32 位的整数算法时,由于结果 (0x0000000500000014) 太大无法保存在 32 位的值中,我们会受到一个整数上溢攻击:

0x40000001 * 0x00000014 =  0x0000000500000014

C++ 会丢弃所有不符合的位,因此我们会得到 0x00000014。这就是分配并未失败的原因 - 分配没有尝试去分配 20 GB,而是仅仅尝试分配了 20 个字节。然后,排序例程会假设缓冲区对于保存稀疏数组中的三个元素来说足够大,因此它将组成这三个元素的 60 个字节复制到了 20 个字节的缓冲区中,这样就溢出缓冲区 40 个字节。实在太冒险了!

返回页首

有符号与无符号错误

快速查看下面的代码。它类似于第一个示例。看看您是否能够发现错误,如果您发现了错误,请试着确定该错误会产生什么结果。

bool func(char *s1, int len1,

char *s2, int len2) {

char buf[128];

if (1 + len1 + len2 >128)

return false;

if (buf) {

strncpy(buf,s1,len1);

strncat(buf,s2,len2);

}

return true;

}

此处的问题在于字符串的大小存储为有符号的整数,因此只要 len2 是负值,len1 就可以大于 128,从而和就小于 128 个字节。但是,到 strncpy 的调用将会溢出 buf 缓冲区。

返回页首

截断错误

让我们查看最后一种攻击类型,通过代码示例,您来猜猜看。

bool func(byte *name, DWORD cbBuf) {

unsigned short cbCalculatedBufSize = cbBuf;

byte *buf = (byte*)malloc(cbCalculatedBufSize);

if (buf) {

memcpy(buf, name, cbBuf);

// do stuff with buf

if (buf) free(buf);

return true;

}

return false;

}

这种攻击,至少这种结果,与前面阐述的 JScript. 错误有一点类似。如果 cbBuf 是 0x00010020,又会如何呢?cbCalculatedBufSize 只有 0x20,因为只从 0x00010020 复制了低 16 位。因此,仅分配了 0x20 个字节,并且 0x00010020 字节复制到新分配的目标缓冲区中。请注意,使用 Microsoft Visual C++?/W4 选项编译这段代码会生成:

warning C4244: initializing : conversion from DWORD to unsigned

short, possible loss of data

请注意类似下面的操作不要标记为一个警告:

int len = 16;

memcpy(buf, szData, len);

memcpy 的最后一个参数是 size_t,而参数 len 是有符号的。不会发出警告是因为 memcpy 始终假设第三个参数是无符号的,转换成无符号不会改变函数的输出。

注意,如果您尝试为 DWORD 分配一个 size_t,您将会收到一个警告,并不是因为在 32 位平台上可能会出现数据丢失,而是因为在 64 位平台上将会出现数据丢失。

warning C4267: = : conversion from size_t to DWORD, possible loss

of data

您将收到这个警告,因为所有默认 C++ 项目都使用 -Wp64 选项进行编译,该选项会通知编译器监视 64 位可移植性问题。

返回页首

托管代码中的整数操作问题

整数操作错误可能会发生在托管语言中,例如 C# 和 Visual Basic?.NET,

篇2:检查你的简历是否存在这些病症

第一,简历内容太过简单或夸夸其谈,内容不简称、描述的不切主题,很容易影响了整体效果;简历内容太过于简单了,对于应聘者的实力与资历就会缺乏证明与评论,让应聘者的信息不完整,用人单位就不能明确客观认识,从而让面试的机率降低。

第二,目标不明确,条理不清晰。简历的分布不合理,整体框架比较乱、内容重复、逻辑不清晰,很难让用人单位获得信息及理确;一份简历找不到一个方向,如应聘者的爱好,所具备的能力,应聘职位,职位要求等。

第三,个人简历用邮件的方式发过去,却大多是石沉大海,

一定要确认用人单位在招聘信息上有要求这样做,你就可以用这种方式。在提交前,你得再确认下格式是否正规,内容是否有误及易读性,如果用人单位有要求哪些形式,要尽量满足。

同时,你必须要备份好你的履历表到你的电脑硬盘中,以便在用人单位没有接收到你的邮件时,你可以继续发送。

第四,简历的内容有虚假或夸大成份。简历的内容是别人吹嘘或夸大出来的,或是自己在写简历过程中,用一些虚拟信息,把内容夸大了,变的不真实了,而且现在造假技术手段也越来越多,越来越狡猾,以为可以瞒得过,要知道一旦对方发觉到有虚假成份,经过调查后,你就只有后悔的机会了。

对此,要对那些心存一丝造假的求职者,奉劝你们不要这么做,因为躲的了初一,躲不过十五,总有被调查清楚的时候。

Windows和Office存在五个安全漏洞

童话般的爱情是否存在心情日记

对党是否忠诚老实检查材料

十八个是否检查对照材料

简历邮件的附件是否有必要存在?

下载检查代码是否存在整数操作安全漏洞(精选2篇)
检查代码是否存在整数操作安全漏洞.doc
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档
热门文章
    猜你喜欢
    点击下载本文文档