前言
我们之前所研究的漏洞,都是非常经典的栈溢出漏洞,也是最为常见的漏洞形态。但是我们对于缓冲区溢出的学习,是不能够仅仅局限在这类的漏洞里面的,其实还有一些比较少见,但却值得我们注意的漏洞形式,,是需要我们进行研究的。在接下来的几次课程中,就对这些漏洞逐一进行分析。而我这次所讲的,是整数溢出的漏洞。
什么是整数溢出
#include <stdio.h>int main(){int InputTest;unsigned short OutputTest;printf("InputTest:");scanf("%d", &InputTest);OutputTest = InputTest;printf("OutputTest:%d\n", OutputTest);getchar();return 0;}
以上只是一个简单的例子,归根到底,出现整数溢出漏洞的根本原因依旧是由于编程人员自身的疏忽造成的,没能重视整数的相关操作,于是埋下了隐患。
动态调试溢出程序
可导致安全漏洞的整数溢出
无符号整数的下溢问题是由于无符号整数不能识别负数所导致的,代码如下:
BOOL fun(size_t cbSize){if( cbSize > 1024 ){return FALSE;}char *pBuf = new char[cbSize-1];// 存在溢出隐患memset(pBuf, 0x90, cbSize-1);…return TRUE;}
在上述代码中,在使用
1111 11111111 1111
无符号整数的上溢示例代码如下:
BOOL fun(char *s1, size_t len1, char *s2, size_t len2){if(len1 + len2 + 1 > 1024){return FALSE;}char pBuf = new char[len1 + len2 + 1];if(pBuf == NULL){return FALSE;}memcpy(pBuf, s1, len1);// 存在溢出隐患memcpy(pBuf + len1, s2, len2);…return TRUE;}
符号的问题有以下三点是需要注意的。
代码示例如下:
int copy_something(char *buf, int len){char szBuf[800];if(len > sizeof(szBuf)){return -1;}// 存在溢出隐患return memcpy(szBuf, buf, len);}
BOOL fun(byte *name, DWORD cbBuf){unsigned short cbCalculatedBufSize = cbBuf;byte *buf = new byte(cbCalculatedBufSize);if(buf == NULL){return FALSE;}// 存在溢出隐患memcpy(buf, name, cbBuf);…return TRUE;}
如果出现了整数溢出的情况,那么之后所有的相关操作的结果都会发生变化。与缓冲区溢出不同的是,整数溢出发生时并不会马上出现异常,即使程序执行结果与预期的不同,也很不容易发现问题所在。
由整数溢出引发的栈溢出的简单例子
#include "string.h"#include "stdlib.h"char overflow[] ="\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50""\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60""\x61\x62\x63\x64\x65\x66\x67\x68";int fun(int i){unsigned short s;char szBuf[8];s = i;if(s > 8){return 0;}if(i > sizeof(overflow)){memcpy(szBuf, overflow, sizeof(overflow));}else{memcpy(szBuf, overflow, i);}return 1;}int main(int argc, char *argv[]){int i, ret;if(argc != 2){return -1;}i = atoi(argv[1]);ret = fun(i);return 0;}
上述程序需要利用
C:\&;OverflowTest.exe 65536
然后就出现了错误提示对话框:
在旅途中,我遇见了你,你我相识是缘分!看着你手中的戒指,