详解缓冲区溢出攻击(超级详细)

(4) 2024-04-20 12:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说详解缓冲区溢出攻击(超级详细),希望能够帮助你!!!。

一、预备知识
预备知识指需要先理解main函数反汇编代码。

注意:
1.实验环境
① VMware® Workstation 16 Pro
② 32位的Linux系统:Ubuntu16.04
2.gcc -fno-stack-protector编译程序

二、缓冲区溢出攻击
1.源代码
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第1张
2.对foo01函数反汇编代码进行分析
(1)foo01函数反汇编代码
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第2张
(2)分析
①push %ebp

保存main函数的ebp;

②mov %esp,%ebp

从esp起接下来栈中的内容为foo01,即esp是foo01函数的栈底

③为参数分配空间
foo01函数中,需要把buff,Lbuffer这两个参数“”给strcpy函数,再调用strcpy函数。

传 : 在栈中分配空间,并把数据mov到栈中

因为buff需要16Byte, Luffer占32Byte,共48Byte(0x30);
但是sub $0x48,%esp(不知道为啥减0x48)。

首先,把Lbuffer的数据($表示立即数)movl(双字,4Byte)到栈中,共32Byte(4*8)
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第3张

①红色框中的内容即"ABCD", A的ASCII码为65,即41H。
②采用的是小端模式:高字节保存在低地址。
③栈中的区段:[-0x39(%ebp), -0x1a(%ebp)]
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第4张

接着,理解buff在栈中的空间分配(存疑)
movb $0x0, -0x19(%ebp)
正好是Lbuffer栈中区段高地址( -0x1a(%ebp))上的一个Byte,被赋予了0。(相当于buff和Lbuffer之间画了条“三八线”???)
那么buffer在栈中的区段:[-0x9(%ebp), -0x18(%ebp)]
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第5张

这样的话,buff在栈中的区段上,空了8个Byte;Lbuffer在栈中的区段下,空了15个Byte,才符合sub $0x48,%esp。

那么为啥要这样做呢?
其实在预备知识中有过猜测,就是16字节对齐。
在分配空间之前,esp的值如下:
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第6张
正好空掉8个Byte,满足16字节对齐。

同理只有接着空16个Byte(1 + 15),保持16字节对齐。
因为esp-48,才满足16字节对齐
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第7张
④call 0x80482e0 <strcpy@plt>
调用strcpy函数。
缓冲区溢出的分析:
foo01函数反汇编代码第一句:push %ebp之前,
esp的值如下:
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第8张
这也是main函数的返回地址。
buff的首地址为-0x18(%ebp),距离0xbffff08c共28Byte(24(0x18) + 4(push后增加的))。

说明:-0x18(%ebp)中的ebp是已经push %ebp后(下同)。

而strcpy函数会将32Byte的内容覆盖掉栈区段[-0x18(%ebp), 0x8(%ebp)], 正好把返回地址给覆盖掉了。

⑤ret
把esp指向的栈中的数值赋给eip(程序计数器)
根据上述④的分析,这时的数值已经不再是返回地址了,而是0x44434241,即"ABCD"。
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第9张
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第10张
3.缓冲区溢出攻击
通过修改Lbuffer的内容(将"ABCD"改成期望的地址),就可以控制程序的执行流程,实现攻击。

4.抵抗缓冲区溢出攻击的方法
①地址随机化技术 :栈底(高地址)动态变化
②栈不可执行技术
③堆栈保护技术

三、调换buff和Lbuffer定义顺序,则不会出现段错误
1.源代码
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第11张
2.foo02函数的反汇编代码
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第12张
3.为参数分配空间
Lbuffer在栈中的区段:[-0x29(%ebp), -0xa(%ebp)], 共32Byte;
buff在栈中的区段:[-0x39(%ebp), -0x30(%ebp)],共16Byte;

为参数分配空间没有遵循从右至左的规则啊。按道理buff应该在高地址段。说明是按照定义顺序分配的。在foo01中,先定义buff,所以buff在高地址段。此处先定义Lbuffer,所以Lbuffer在高地址段。
上述的ebp是执行push %ebp之后。

4.执行strcpy(buff, Lbuffer)
Lbuffer的内容覆盖[-0x39(%ebp), -0x1a(%ebp)]。
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第13张
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第14张
5.故没有覆盖掉返回地址,能顺利返回:
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第15张
详解缓冲区溢出攻击(超级详细)_https://bianchenghao6.com/blog__第16张

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复