安全漏洞--整数溢出漏洞(IOV)分析

来源:互联网 发布:qq炫舞ktv网络连接失败 编辑:程序博客网 时间:2024/05/14 09:44

漏洞简介


        整数溢出漏洞(integer overflow):在计算机中,整数分为无符号整数以及有符号整数两种。其中有符号整数会在最高位用0表示正数,用1表示负数,而无符号整数则没有这种限制。另外,我们常见的整数类型有8位(单字节字符、布尔类型)、16位(短整型)、32位(长整型)等。关于整数溢出,其实它与其它类型的溢出一样,都是将数据放入了比它本身小的存储空间中,从而出现了溢出。由此引发的一切程序漏洞都可以成为整数溢出漏洞。



原理分析


2.1 整数表示:


最高位表示符号

0表示正数

1表示负数



+41-41的符号绝对值表示

 

2.2 标准常见的类型如下:


 

signed charshort intintlong intlong long inttypedef unsigned long       DWORDtypedef int                BOOLtypedef unsigned char       BYTEtypedef unsigned short      WORD__int8, __int16, __int32, __int64ATOMBOOLEAN, BOOLBYTECHARDWORD, DWORDLONG, DWORD32, DWORD64WORDINT, INT32, INT64LONG, LONGLONG, LONG32, LONG64




2.3 类型转化

 

符号引起的溢出


int iNumber= -3;unsigned short uNumber;uNumber = iNumber;printf("u = %hu\n", uNumber); 


运算引起的溢出


char cResult, cNum1, cNum2, cNum3;//默认都是有符号cNum1= 100;cNum2= 50;cNum3= 50;cResult= cNum1+ cNum2+ cNum3;


漏洞测试


3.1 符号位引起溢出


//漏洞验证代码



#define BUFF_SIZE 10int main(int argc, _TCHAR* argv[]){int iLength;char buf[BUFF_SIZE];iLength= atoi(argv[1]);//注意atoi这个函数//_int __cdecl atoi(_In_z_ const char *_Str);if (iLength< BUFF_SIZE){unsigned int num=iLength;memcpy(buf, argv[2], iLength);//memcpy((_Size) void * _Dst,(_Size) const void * _Src, size_t _Size);//typedef _W64 unsigned int   size_t;}return 1;}



3.2 运算超出范围引起的溢出

//漏洞验证代码

#include <Windows.h>int _tmain(int argc, _TCHAR* argv[]){unsigned short int total;total = strlen(argv[1])+strlen(argv[2]) + 1;char *buff = (char *) malloc(total);strcpy(buff, argv[1]);strcat(buff, argv[2]);        return 1;}





大家看看上面的两个示例,是不是溢出发生得很隐蔽,有的是隐式转化引起的,

有的是符号位出现变化引起的,有的是原酸范文超出边界引起的。上面的只是

进行的charshort类型示例,同样的只要是涉及符号位,运算,隐式转化等

可能出现数字溢出。所以大家在编写代码或者审计代码时候特别留意这些基本

数据类型的转化和运算。


漏洞利用


下面我们来做个例题吧,来熟悉练习一下这个漏洞原理吧。

题目只有一个inter程序。先检查一下:



LINUX程序随便输入一下,测试发现命令运行程序怎么输入都显示参数不对。



先暂时用IDA载入测试一下。

找到输出位置F5转换一下



注意到输出位置特殊,只有参数大于等于4才不会输出参数错误,

于是乎得知参数是4个以上。往下看貌似后面还有输出。参数v3就是argv首地址。





参数1(v4),参数2(v6),参数3(nptr),参数4(v8),这几个数有符号位和长度差异,

因此不同类型转化可能出现溢出。






往下继续查看isComment函数。果真如此,那么必须实现进入这个函数逻辑,

那么就可以实现获取flag.txt文件了。于是回溯继续研究上面的参数输入比较逻辑。






那么来研究每个参数

参数1(v4)

注意v4v5之间关系v4>79v5还要小于等于79只能发生溢出,v4整数,v5无符号短整数

可以实现溢出满足条件比如65536

 

参数2(v6)

参数2主要出现在v6位置,参数2进行了整数类型转化成v6同时v6还要满足是个无符号短整数

满足条件比如65541




参数3(nptr)

 

也就是转化后的nptr是个指针类型,要求长度大于3而且转化成整数值后必须等于1

利用atoi函数特性构造1ABC即可满足条件





参数4(v8)

参数4经过转化为v8(v8是个整数)转化成了char*字符串。

满足等于1其实就是十六进制0x01






测试以下,成功可以自己提交一下flag

65536 65541 1ABC 1



FLAG{(:welldone!2016-5t4rk-winners-:)}



0 0