目录
整数漏洞
1.1、简介:
如果应用程序在执行某种缓冲区操作前对一个长度值运用某种算法,但却没有考虑到编译器与处理器整数计算方面的一些特点,往往就会出现与整数有关的漏洞。有两种类型的漏洞最值得关注:整数溢出与符号错误
1.2、整数溢出
简述:
当对一个整数值进行操作时,如果整数大于它的最大可能值或小于它的最小可能值, 就会造成整数溢出漏洞。这时,数字就会"回绕",使一个非常大的数字变得非常小, 或者与之相反。
示例:
例如,应用程序求出用户提交的用户名的长度,增加一个长度安置字符串最后的空字节, 再给它分配一个相应长度的缓冲区,然后将用户名复制到这个缓冲区内。如果使用正常长度的输入, 这段代码就能够正常运行。但如果用户提交一个65535个字符的用户名,就会造成整数溢出。一个长度较短的整数包含16位,它足以保存0-65 535之间的值。如果堤交一个长度为65535的字符串, 程序会在这个字符串后面培加一个长度,使得这个值"回绕"而变为0。于是应用程序为它分配一个长度为0的缓冲区,把用户名复制到它里面,因而造成堆溢出。这样即使程序员试图确保目标缓冲区足够大,攻击者仍然能够制造溢出
1.3、符号错误
简述:
如果应用程序使用有符号和无符号的整数来表示缓冲区的长度,并且在某个地方混淆这两个整数, 或将一个有符号的值与无符号的值进行直接比较,或向一个仅接受无符号的值的函数参数提交有符号的值,都会出现符号错误。在上述两种情况下,有符号的值都会被当做其对应的无符号的伉处理, 也就是说,一个负数变成一个大正数。
示例:
1、函数以用户提交的用户名和一个表示其长度的有符号整数为参数。程序员在栈上建立一个固定大小的缓冲区,检查用户名的长度是否小于缓冲区的大小,如果是这样, 就执行计数缓冲区复制,确保缓冲区不会溢出
2、如果len参数为负数,这段代码就能够正常运行。但如果攻击者能够向函数提交一个负值,那么程序员的保护性检查就会失效,仍然可以成功将它与32进行比较,因为编译器会把这两个数字当做有符号的整数处理。因此这个负值被提交给strncpy函数,成为它的计数函数。因为strncpy仅接受无符号的整数为参数,所以编译器将len值隐含地转换成这种类型,因而负值被当做一个大的正数处理。如果用户提交的用户名字符串长度大于328,那么缓冲区就会溢出,这种情况和标准栈溢出类似
3、通常实施这种攻击必须满足一个前提,即长度参数由攻击者直接控制。如它由客户端JavaScript计算并在请求中将它所属的字符串一起提交。但如果整数变量足够小(非常短),且程序在服务器端计算它的长度,那么攻击者仍然可以通过向应用程序提交一个超长的字符串,借由整数溢出引入一个负值。
1.4、查找整数漏洞
简述:
任何时候只要客户端向服务器提交整数值,就可以在这些位置探查整数漏洞。
通常这种行为发生在以下两种不同的情况下:
A、应用程序通过查询字符串参数、cookie或消息主体,以正常形式提交整数值。这些数字一般使用标准的ASCII字符,以十进制表示。这时表示一个同样被提交的字符串长度的字段是我们测试的主要目标。
B、应用程序可能提交嵌入到二进制数据对象中的整数值。这些数据可能源自一个客户端组件,如ActiveX控件,或通过客户端在隐藏表单字段或cookie中传送,在这种情况下,与长度有关的整数漏洞更难以发现。它们一般以十六进制的形式表示,通常出现在与其关联的字符串或缓冲区之前。上述二进制数据可能会通过Base64或类似的方案编码,以便于通过HTTP传送
过程:
1、确定测试目标后,需要提交适当的有效载荷,以触发任何漏洞。轮流向每一个目标数据发送一系列不同的值,分别表示不同有符号与无符号整数值的边界情况
2、如果被修改的数据以十六进制表示,应该发送每个测试字符串的little-endian与big-endian版本。如果十六进制数字以ASCII形式提交,应该使用应用程序自身使用的字母字符,确保这些字符被正确编码
3、与查找缓冲区溢出漏洞时一样, 应该监控应用程序响应中出现的反常事件