缓冲区溢出实验
缓冲区溢出实验
缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。
实验楼提供的是 64 位 Ubuntu linux
编译 32 位 C 程序的软件包:
$ sudo apt-get update
$ sudo apt-get install -y lib32z1 libc6-dev-i386
$ sudo apt-get install -y lib32readline-gplv2-dev
Ubuntu 和其他一些 Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:
sudo sysctl -w kernel.randomize_va_space=0
使用另一个 shell 程序代替 /bin/bash
进入32位linux环境,输入“/bin/bash”使用bash
shellcode
一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是 shellcode。
编写“20191220stack.c”文件,保存到 /tmp 目录下
通过代码可以知道,程序会读取一个名为“badfile”的文件,并将文件内容装入“buffer”。编译该程序,并设置 SET-UID。命令如下:
$ sudo su
$ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
$ chmod u+s stack
$ exit
注:
GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用 –fno-stack-protector关闭这种机制。
而-z execstack用于允许执行栈。
-g参数是为了使编译后得到的可执行文档能用gdb调试。
攻击程序
得到 shellcode 在内存中的地址
先运行攻击程序 exploit,再运行漏洞程序 stack,观察结果: