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

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

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

二、缓冲区溢出攻击
1.源代码
详解缓冲区溢出攻击(超级详细)_第1张图片
2.对foo01函数反汇编代码进行分析
(1)foo01函数反汇编代码
详解缓冲区溢出攻击(超级详细)_第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)
详解缓冲区溢出攻击(超级详细)_第3张图片

①红色框中的内容即"ABCD", A的ASCII码为65,即41H。
②采用的是小端模式:高字节保存在低地址。
③栈中的区段:[-0x39(%ebp), -0x1a(%ebp)]
在这里插入图片描述

接着,理解buff在栈中的空间分配(存疑)
movb $0x0, -0x19(%ebp)
正好是Lbuffer栈中区段高地址( -0x1a(%ebp))上的一个Byte,被赋予了0。(相当于buff和Lbuffer之间画了条“三八线”???)
那么buffer在栈中的区段:[-0x9(%ebp), -0x18(%ebp)]
在这里插入图片描述

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

那么为啥要这样做呢?
其实在预备知识中有过猜测,就是16字节对齐。
在分配空间之前,esp的值如下:
在这里插入图片描述
正好空掉8个Byte,满足16字节对齐。

同理只有接着空16个Byte(1 + 15),保持16字节对齐。
因为esp-48,才满足16字节对齐
在这里插入图片描述
④call 0x80482e0
调用strcpy函数。
缓冲区溢出的分析:
foo01函数反汇编代码第一句:push %ebp之前,
esp的值如下:
在这里插入图片描述
这也是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"。
在这里插入图片描述
在这里插入图片描述
3.缓冲区溢出攻击
通过修改Lbuffer的内容(将"ABCD"改成期望的地址),就可以控制程序的执行流程,实现攻击。

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

三、调换buff和Lbuffer定义顺序,则不会出现段错误
1.源代码
详解缓冲区溢出攻击(超级详细)_第4张图片
2.foo02函数的反汇编代码
详解缓冲区溢出攻击(超级详细)_第5张图片
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)]。
在这里插入图片描述
在这里插入图片描述
5.故没有覆盖掉返回地址,能顺利返回:
在这里插入图片描述
在这里插入图片描述

你可能感兴趣的:(#,汇编语言,GDB,网络安全,安全,编程语言)