实验七-缓冲区溢出 实验报告

实验七-缓冲区溢出 实验报告

实验指导书内容

一、准备:输入命令安装一些用于编译 32 位 C 程序的软件包

二、实验步骤:
1、初始设置:
(1)关闭地址空间随机化

(2)设置zsh程序,关闭shell程序

2、shellcode
一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是 shellcode。

汇编版

3、漏洞程序
(1)在 /tmp 目录下新建一个 stack.c 文件:

(2)按 i 键切换到插入模式,输入如下内容:


(3)通过代码可以知道,程序会读取一个名为“badfile”的文件,并将文件内容装入“buffer”。编译该程序,并设置 SET-UID。命令如下:

(解释:GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用 –fno-stack-protector 关闭这种机制。 而 -z execstack 用于允许执行栈。-g 参数是为了使编译后得到的可执行文档能用 gdb 调试。)

4、攻击程序
我们的目的是攻击刚才的漏洞程序,并通过攻击获得 root 权限。
(1)在 /tmp 目录下新建一个 exploit.c 文件,输入如下内容:



或者直接下载代码:
wget
http://labfile.oss.aliyuncs.com/courses/231/exploit.c
注意上面的代码,\x??\x??\x??\x?? 处需要添上 shellcode 保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。而 strcpy(buffer+100,shellcode); 这一句又告诉我们,shellcode 保存在 buffer + 100 的位置。下面我们将详细介绍如何获得我们需要添加的地址。
(2)现在我们要得到 shellcode 在内存中的地址,输入命令进入 gdb 调试:
gdb stack
disass main
结果:

esp 中就是 str 的起始地址,所以我们在地址 0x080484ee 处设置断点。
b *0x080484ee
r
i r $esp

最后获得的这个 0xffffcfb0 就是 str 的地址。
根据语句 strcpy(buffer + 100,shellcode); 我们计算 shellcode 的地址为 0xffffcfb0 + 0x64 = 0xffffd014
(3)现在修改 exploit.c 文件,将 \x??\x??\x??\x?? 修改为计算的结果 \x14\xd0\xff\xff,注意顺序是反的。
然后,编译 exploit.c 程序:
gcc -m32 -o exploit exploit.c

5、攻击结果
先运行攻击程序 exploit,再运行漏洞程序 stack,观察结果:

可见,通过攻击,获得了root 权限!
如果不能攻击成功,提示”段错误“,那么请重新使用 gdb 反汇编,计算内存地址。

缓冲区溢出的原理

通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。

缓冲区溢出的防范

有四种基本的方法保护缓冲区免受缓冲区溢出的攻击和影响。
1、完整性检查
在程序指针失效前进行完整性检查。虽然这种方法不能使得所有的缓冲区溢出失效,但它能阻止绝大多数的缓冲区溢出攻击。
2、非执行的缓冲区
通过使被攻击程序的数据段地址空间不可执行,从而使得攻击者不可能执行被植入被攻击程序输入缓冲区的代码,这种技术被称为非执行的缓冲区技术。在早期的Unix系统设计中,只允许程序代码在代码段中执行。但是Unix和MS Windows系统由于要实现更好的性能和功能,往往在数据段中动态地放入可执行的代码,这也是缓冲区溢出的根源。为了保持程序的兼容性,不可能使得所有程序的数据段不可执行。
但是可以设定堆栈数据段不可执行,这样就可以保证程序的兼容性。Linux和Solaris都发布了有关这方面的内核补丁。因为几乎没有任何合法的程序会在堆栈中存放代码,这种做法几乎不产生任何兼容性问题,除了在Linux中的两个特例,这时可执行的代码必须被放入堆栈。
3、信号传递
Linux通过向进程堆栈释放代码然后引发中断来执行在堆栈中的代码来实现向进程发送Unix信号。非执行缓冲区的补丁在发送信号的时候是允许缓冲区可执行的。
4、GCC的在线重用
研究发现gcc在堆栈区里放置了可执行的代码作为在线重用之用。然而,关闭这个功能并不产生任何问题,只有部分功能似乎不能使用。
非执行堆栈的保护可以有效地对付把代码植入自动变量的缓冲区溢出攻击,而对于其它形式的攻击则没有效果。通过引用一个驻留的程序的指针,就可以跳过这种保护措施。其它的攻击可以采用把代码植入堆或者静态数据段中来跳过保护。

posted @ 2022-12-15 22:51  童诗嘉20221409  阅读(259)  评论(0编辑  收藏  举报