作者:CSysSec出品
CSysSec注: 本系列文章译自安全自由工作者Sploitfun的漏洞利用系列博客,从经典栈缓冲区漏洞利用堆漏洞利用,循序渐进,是初学者不可多得的好材料,本系列所有文章涉及的源码可以在这里找到。CSysSec计划在原基础上不断添加相关漏洞利用技术以及相应的Mitigation方法,欢迎推荐或自荐文章。
转载本文请务必注明,文章出处:《Linux(X86)漏洞利用系列-整型溢出利用》与作者信息:CSysSec出品
- 0X01 什么是整型上溢出(Integer Overflow)
- 0X02 整型下溢出(Integer underflow)
- 0X03 利用整型溢出漏洞
VM Setup: Ubuntu 12.04 (x86)
注:本文中overflow指上溢出,underflow指下溢出。默认情况下,溢出指的都是上溢出。
0X01 什么是整型上溢出
存储的数值大于支持的最大上限值,即为整型溢出。整型溢出本身不会直接导致任意代码执行,但是它会导致栈溢出或堆溢出,而后两者都会导致任意代码执行。本文我只谈论导致栈溢出的整型溢出,而导致堆溢出的整型溢出我会放在以后的文章中单独讲。
数据类型大小和范围:
当我们要存储的数值大于支持的最大上限值时,数值就会错乱。打个比方,如果我们把2147483648存进有符号整型数据,那么这串数字就会错乱,其值会变为-21471483648。这就叫做整型溢出,并且这种溢出有可能导致任意代码执行。
0X02 整型下溢出(Integer underflow)
与整型上溢出类似,存储数值小于支持的最小下限值,即为整型下溢出。打个比方,如果我们把-2147483649存进有符号整型数据,那么这串数字就会错乱,其值会变为21471483647。这就叫做整型下溢出。本文中我虽然只讲整型上溢出,但是同样的技术也适用于整型下溢出。
漏洞代码:
|
|
编译命令:
|
|
上述漏洞程序的第[1]行存在整型溢出。strlen()返回的类型是size_t(无符号整型),却被存储在无符号字符串类型中。因此,任意超过无符号字符串数据类型支持的最大上限值的数据都会导致整型溢出。这样一来,当密码长度为261时,261就会被错乱存储在‘passwd_len’变量中,值会变为5。正是由于这种整型溢出漏洞,第[2]行执行的边界检查才能被绕过,从而导致栈缓冲区溢出!而在这一篇文章中我们知道,栈缓冲区溢出会导致任意程序执行。
为了让大家更好地理解漏洞利用代码,我们在对它做进一步的分析之前,先来反汇编并画出漏洞代码的堆栈布局吧!
反汇编:
|
|
堆栈布局:
刚才讲到,一个长度为261的密码会绕过边界检查,并且允许我们覆盖存储于栈内的返回地址。那么好,我们来通过发送一串A的方法进行测试。
0X03 利用整型溢出漏洞
测试第一步:这样做是否会覆盖返回地址?
|
|
测试第二步:来自目标缓冲区的偏移量是什么?
在这里我们来找找缓冲区‘passed_buf’中返回地址的偏移处于什么位置。之前我们已经反汇编并画出了validate_passwd()的堆栈布局,那么现在就试着找出代码的偏移位置信息吧!由堆栈布局可以看出,返回地址位于缓冲区‘passwd_buf’的偏移(0x18)处。(0x18)计算方式如下:
0X03 0x18 = 0xb + 0x1 + 0x4 + 0x4 + 0x4
其中:
- 0xb 是 ‘passwd_buf’ 大小
- 0x1 是 ‘passwd_len’ 大小
- 0x4 是 对齐空间
- 0x4 是 EDI
- 0x4 是调用者的EBP
这样一来,用户输入 “A” 24 + “B” 4 + “C” * 233,就能以一串“A”覆盖passwd_buf, passwd_len, 对齐空间和调用者的EBP,以“BBBB”覆盖返回地址,以一串C覆盖剩余空间。
|
|
上述输出结果表明攻击者已然获得返回地址的控制权限。存储于栈(0xbffff1fc)中的返回地址已被“BBBB”覆盖。掌握了以上信息,我们就可以写出能实现任意代码执行的漏洞利用代码了。
漏洞利用代码:
执行上述漏洞利用程序可以获取root shell,如下所示
|
|
参考文章:
转载本文请务必注明,文章出处:《Linux(X86)漏洞利用系列-整型溢出利用》与作者信息:CSysSec出品