安全漏洞--整数溢出漏洞(IOV)分析 港控/mmm° 2022-06-17 06:29 320阅读 0赞 # **一 漏洞简介** # 整数溢出漏洞(integer overflow):在计算机中,整数分为无符号整数以及有符号整数两种。其中有符号整数会在最高位用0表示正数,用1表示负数,而无符号整数则没有这种限制。另外,我们常见的整数类型有8位(单字节字符、布尔类型)、16位(短整型)、32位(长整型)等。关于整数溢出,其实它与其它类型的溢出一样,都是将数据放入了比它本身小的存储空间中,从而出现了溢出。由此引发的一切程序漏洞都可以成为整数溢出漏洞。 # **二 原理分析** # **2.1 整数表示:** 最高位表示符号 0表示正数 1表示负数 ![Center][] \+41和\-41的符号绝对值表示 **2.2 标准常见的类型如下:** signed char short int int long int long long int typedef unsigned long DWORD typedef int BOOL typedef unsigned char BYTE typedef unsigned short WORD __int8, __int16, __int32, __int64 ATOM BOOLEAN, BOOL BYTE CHAR DWORD, DWORDLONG, DWORD32, DWORD64 WORD INT, INT32, INT64 LONG, LONGLONG, LONG32, LONG64 ![Center 1][] ![Center 2][] **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 10 int 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; } ![Center 3][] 大家看看上面的两个示例,是不是溢出发生得很隐蔽,有的是隐式转化引起的, 有的是符号位出现变化引起的,有的是原酸范文超出边界引起的。上面的只是 进行的char和short类型示例,同样的只要是涉及符号位,运算,隐式转化等均 可能出现数字溢出。所以大家在编写代码或者审计代码时候特别留意这些基本 数据类型的转化和运算。 # **四 漏洞利用** # 下面我们来做个例题吧,来熟悉练习一下这个漏洞原理吧。 题目只有一个inter程序。先检查一下: ![Center 4][] LINUX程序随便输入一下,测试发现命令运行程序怎么输入都显示参数不对。 ![Center 5][] 先暂时用IDA载入测试一下。 找到输出位置F5转换一下 ![Center 6][] 注意到输出位置特殊,只有参数大于等于4才不会输出参数错误, 于是乎得知参数是4个以上。往下看貌似后面还有输出。参数v3就是argv首地址。 ![Center 7][] ![Center 8][] ![Center 9][] 参数1(v4),参数2(v6),参数3(nptr),参数4(v8),这几个数有符号位和长度差异, 因此不同类型转化可能出现溢出。 ![Center 10][] ![Center 11][] 往下继续查看isComment函数。果真如此,那么必须实现进入这个函数逻辑, 那么就可以实现获取flag.txt文件了。于是回溯继续研究上面的参数输入比较逻辑。 ![Center 12][] ![Center 13][] 那么来研究每个参数 参数1(v4) 注意v4和v5之间关系v4>79且v5还要小于等于79只能发生溢出,v4整数,v5无符号短整数 可以实现溢出满足条件比如65536 参数2(v6) 参数2主要出现在v6位置,参数2进行了整数类型转化成v6同时v6还要满足是个无符号短整数 满足条件比如65541 ![Center 14][] 参数3(nptr) 也就是转化后的nptr是个指针类型,要求长度大于3而且转化成整数值后必须等于1 利用atoi函数特性构造1ABC即可满足条件 ![Center 15][] ![Center 16][] 参数4(v8) 参数4经过转化为v8(v8是个整数)转化成了char\*字符串。 满足等于1其实就是十六进制0x01 ![Center 17][] ![Center 18][] 测试以下,成功可以自己提交一下flag 65536 65541 1ABC 1 ![Center 19][] **FLAG\{(:welldone!2016-5t4rk-winners-:)\}** [Center]: /images/20220617/66a85843bfe343afa7de6c518c0d60b1.png [Center 1]: /images/20220617/1b640396946249d7b7c065ef109495f4.png [Center 2]: /images/20220617/e2e42d475a984820936a1628e9dc50c0.png [Center 3]: /images/20220617/fba6e342f5ad4528a3887c90b0188e6c.png [Center 4]: /images/20220617/5508dde1aa374f6ba74cb0996be9714e.png [Center 5]: /images/20220617/21ebb721e2874d96a031d8a7b9e7cbad.png [Center 6]: /images/20220617/6e990ee551ca420a87f5a3648bd4ba40.png [Center 7]: /images/20220617/23b230206b0747788cd52746d221f3c2.png [Center 8]: /images/20220617/485abc7c5b6e4ca1aae0f7cfe9349924.png [Center 9]: /images/20220617/7879fefa49b843c68429b17b3a43360f.png [Center 10]: /images/20220617/5dec30f6853c4ef7b35de9302f8a84b5.png [Center 11]: /images/20220617/c647475817834235871a1c5912a892ab.png [Center 12]: /images/20220617/b629f4046ba242049118501004153d81.png [Center 13]: /images/20220617/9eaf642c68be48a2836b347c05bd88ea.png [Center 14]: /images/20220617/5ea051cac45444278a37a8d608363a49.png [Center 15]: /images/20220617/554c05df72e54e5182462ce54a7620e7.png [Center 16]: /images/20220617/58be2097fb0742baa33aad850f20f47e.png [Center 17]: /images/20220617/d6d9b4628e784093af80845a51ba44b9.png [Center 18]: /images/20220617/4b082ca8139e4116a381a04303b54d1b.png [Center 19]: /images/20220617/b55eecd26b464aa29667ddc7d9230154.png
还没有评论,来说两句吧...