-
-
[原创]HEVD学习笔记之整数溢出漏洞
-
发表于: 2021-11-9 20:35 17301
-
HEVD及实验环境请看:HEVD学习笔记之概述
整数有有符号整数与符号整数。有符号整数将最高位作为符号位,如果最高位是1则该数为负数,如果最高位为0,则该数为正数。而对于无符号数来说,它没有符号位,最高位也用来做运算,所以它只有正数且整数范围比有符号数要大的多。在C语言中,这些类型和取值范围如下
但是,对于计算机而言对于有符号数与无符号数并没有区别,比如-1对应的4294967295对应的都是0xFFFFFFFF,只是在对这两个数据具体操作的时候,编译器会根据不同的数据类型生成不同的代码而已。
比如下面这段代码,将无符号整数赋值为-1,此时x中保存的就是0xFFFFFFFF。如果将它当作无符号数,那么就是最大的整数4294967295
可以看到x>10输出了,strcpy也成功执行导致了缓冲区的溢出。
另外一种就是整数溢出的问题,比如下面的代码,x首先赋值成了最大的整数,也就是0xFFFFFFFF。此时,如果对x在进行加法操作,那么就会导致x的溢出,将高于32位的比特全部舍弃
可以看到,发生溢出以后,x的值变为了4。
所以,对于整数的使用不当,完全可能造成意料之外的后果,这就会产生漏洞。
在HEVD中,产生整数溢出漏洞的函数地址存在函数地址表中的第10个,也就是说IOCTRL为0x222003 + 9 * 4。
程序将IRP和CurrentStackLocation的指针入栈以后调用InterOverflowIoctlHandler,继续跟进这个函数
函数将输入缓冲区和输入缓冲区长度入栈以后,调用TriggerIntegerOverflow,继续跟进这个函数
函数首先将局部变量Dst初始化为0,随后对输入缓冲区进行可读的检查。
随后,函数会判断输入缓冲区的长度+4是否小于等于0x800,如果是的话则跳转到loc_4456E2,否则函数返回STATUS_INVALID_BUFFER_SIZE。要注意,此时的输入缓冲区的长度做了加法运算,那也就是说,如果输入缓冲区的长度是0xFFFFFFFC~0xFFFFFFFF,那么经过+4以后,就会产生溢出。
接着看,地址loc_4456E2。
注意刚开始运行这段代码的时候,esi为0,edi为输入缓冲区的地址,所以这段代码做的就是将输入缓冲区的内容复制到局部变量Dst中,每次复制4个字节大小的内容,如果遇到的整型数据是0x0BAD0B0B0的话,也会退出函数。
由上可以知道出:
函数会对输入缓冲区的长度进行加4操作,接着判断加4以后的值,是否小于0x800,如果是,那么程序就会继续执行将输入缓冲区中的内容赋值到局部变量中,直到输入缓冲区的内容被全部复制完或者遇到了0x0BAD0B0B0。
此时,通过构造输入缓冲区的长度为0xFFFFFFFC~0xFFFFFFFF中的一个,经过+4的操作以后,就会发生整数溢出,这就绕过了小于0x800的检查。此时,可以构造足够多的输入数据,让程序发生栈溢出漏洞。
赞赏
- [原创]CVE-2022-21882提权漏洞学习笔记 16461
- [原创]CVE-2021-1732提权漏洞学习笔记 19588
- [原创]CVE-2014-1767提权漏洞学习笔记 15230
- [原创]CVE-2018-8453提权漏洞学习笔记 18594
- [原创]CVE-2020-1054提权漏洞学习笔记 13585