整数溢出
基础知识
数据类型以及所取的范围(环境为64位下使用gcc-5.4)
类型 | 字节 | 范围 |
---|---|---|
short int | 2byte(word) | 0~32767(0~0x7fff) -32768~-1(0x8000~0xffff) |
unsigned short int | 2byte(word) | 0~65535(0~0xffff) |
int | 4byte(dword) | 0~2147483647(0~0x7fffffff) -2147483648~-1(0x80000000~0xffffffff) |
unsigned int | 4byte(dword) | 0~4294967295(0~0xffffffff) |
long int | 8byte(qword) | 正: 0~0x7fffffffffffffff 负:0x8000000000000000~0xffffffffffffffff |
unsigned long int | 8byte(qword) | 0~0xffffffffffffffff |
那么,所谓的整数溢出,就是指程序中变量所取数据超过了其数据类型的范围而造成的溢出现象。
整数溢出一共分为三种类型:
- 有符号数溢出
- 无符号数溢出
- 高位数传低位数的截断
# 伪代码
short int a;
a = a + 1;
# 对应的汇编
movzx eax, word ptr [rbp - 0x1c]
add eax, 1
mov word ptr [rbp - 0x1c], ax
unsigned short int b;
b = b + 1;
# assembly code
add word ptr [rbp - 0x1a], 1
以上为无符号数和有符号数进行+1操作的汇编指令,可以看出,有符号数的运算是在寄存器中进行运算的,而无符号数是直接在内存中进行运算的
有符号数溢出
以下均假设 short int a;
上界溢出
short的范围在0~0x7fff和负数0x8000~0xffff
假设取最大值0x7fff(32767)把它进行加1的运算,变为0x8000,就会发现:0x8000在有符号数中是-32768,实现了从一个正数变为了负数,用十进制来表示就是32767+1==-32768
下界溢出
假设取最小值0x8000进行减1运算,得到结果为0x7fff,这在有符号数中是正数32767。
即:-32768-1==32767
无符号数溢出
以下均假设 unsigned short int
上界溢出
unsigned short的范围是在0~0xffff
假设取最大值0xffff进行加1运算,虽然结果本应该是0x10000,但是由于只能存储两个字节的原因,会进行截断,只能取到0x0000。这个过程用十进制来表示就是65535+1==0
下界溢出
假设取最小值0x0000进行减1运算,因为无符号数不存在负数,那么得到的结果0xffff不会进行负数的补码还原得到-1,而是按照整数得到65535,即0-1==65535
以上,两种的上下界溢出的道理是一致的,都是因为计算机底层指令是不区分有符号和无符号的,数据都是以二进制形式存在而在编译器的层面才对有符号和无符号进行区分,产生不同的汇编指令。正前后的不一致,造成了漏洞的出现
高位数传低位数的截断
这种其实最好理解,就是因为数据类型的位数不够,而不能取得完全值,只能取到与自身位数相等的数值,而造成数据的截断
- 加法截断:
0xffffffff + 0x00000001
= 0x0000000100000000 (long int)
= 0x00000000 (int)
- 乘法截断
0x00123456 * 0x00654321
= 0x000007336BF94116 (long int)
= 0x6BF94116 (int)
整数溢出就大致到此了,但是如何利用它造成危害呢?一般都是利用整数溢出和其他的漏洞进行搭配而造成危害。
以下有两个函数,常被误用而产生整数溢出,接着就可能导致缓冲区溢出漏洞。
- memcpy()函数原型为void *memcpy(void *dest, const void *src, size_t n); 功能是将 src 所指向的字符串的前 n 个字符复制到 dest 所指的数组中,并返回 dest。
- strncpy()函数原型为char *strncpy(char *dest, const char *src, size_t n);功能是从源 src 所指的内存地址的起始位置开始复制 n 个字节到目标 dest 所指的内存地址的起始位置中。并不会自动添加’\0’字符。
这两个函数的n都是无符号数,如果用一个负数去填充,就可能变成一个很大的数。从而复制大量内容到缓冲区中,造成溢出
其他的就靠做题与实战去提升巩固了