目录
2.1 task 1 :Exploiting the Vulnerability.
2.2 task 2 :Protection in /bin/bash.
2.3 task 3 :Address Randomization.
1 实验描述
2 实验内容
首先需要进行一些相关准备工作:
1. 本次实验需要实现32位编译,但由于系统为64位Ubuntu Linux。
2. 输入命令安装一些用于编译32位C程序的相关操作:
完成后可进入linux32
3. 为了防止缓冲区溢出漏洞,利用保护机制: Address Randomization 地址空间随机化、Non-executable Stack 不可执行栈、“Stack Guard”三种。在利用缓冲区溢出漏洞实现攻击或者单独考量某种保护机制的有效性的过程中,我们需要禁用某些机制。
(1)内存地址随机化(Address Space Randomization)
基于Linux的操作系统一般使堆和栈的开始地址随机化,使得攻击者猜测确切的地址变得困难。使用如下指令关闭该功能。
$ su root
Password: (enter root password)
#sysctl -w kernel.randomize_va_space=0
(2)The StackGuard Protection Scheme
GCC编译器实现了一个被称为“Stack Guard”的安全机制来防御缓冲区溢出攻击。所以在编译漏洞程序时加上-fno-stack-protector参数来关闭该机制。
(3)Non-Executable Stack
Ubuntu曾经允许栈执行,但是现在程序必须声明栈是否允许执行。内核和链接器检查程序头的标志来判断是否允许栈被执行。GCC在模式情况下设置栈不可执行,所以需要在编译时加入-z execstack参数来允许栈执行。
4. gdb调试指令准备
(1)b main ——> 在main函数执行出设置断点
(2)p /x &str ——> 以十六进制打印str(字符串名)的存储地址
(3)disass main ——> 输出main(函数名)的反汇编代码
2.1 task 1 :Exploiting the Vulnerability
实验任务:要求在关闭所有保护机制的情况下,完成漏洞程序的设计,并实现攻击。设计思路:合理的填充badfile文件的内容,实现在用户程序stack.c读取该文件并拷贝到自己的缓冲区(即bof(char *str)函数栈帧存储空间)后,由于缓冲区溢出,执行bof函数的返回地址内存单元被覆盖且对应换成了shellcode的首地址,接下来用户程序执行shellcode并启动了带有用户程序权限的shell。
实验流程:
1. Ubuntu和其他一些Linux系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:
2. linux系统中,/bin/sh实际是指向/bin/bash或/bin/dash的一个符号链接。我们使用另一个shell程序(zsh)代替/bin/bash
3. 创建并保存“stack.c”文件,编译该程序,编译时确保加入-z execstack参数来允许栈执行,加上-fno-stack-protector参数来关闭“Stack Guard”的安全机制,并设置SET-UID。
4. 创建保存“exploit.c”文件,测算shellcode的地址
通过gdb stack 获取shellcode在内存中的地址:
其中esp中就是str起始地址:$0x214,%esp,所以我们在0x080484ee <+20>:处设置断点。
从上图可以看到,漏洞程序读取badfile 文件到缓冲区str,且str的地址为0xffffce50,计算上shellcode偏移量100(0x64),则shellcode地址为0xffffceb4。
函数调用过程中的堆栈帧结构:
5. 修改exploit.c文件
strcpy(buffer+100,shellcode); 表示:shellcode保存在 buffer+100 的位置。
6. 编译运行exploit.c程序,后先运行攻击程序exploit,再运行漏洞程序stack。
可见攻击成功。成功获得root权限。
2.2 task 2 :Protection in /bin/bash
实验任务:现在,我们让/ bin / sh指向/ bin / bash,并运行前面开发的相同攻击
实验流程:
1. 将软连接改回bash
2. 再回到/tmp下重复攻击操作
可见无法实现攻击。攻击失败是由于没有获得root权限。因为使用的bash程序,当shell运行时,没有root权限。此时,即便攻击程序攻击了漏洞程序,也无法获得root权限。
2.3 task 3 :Address Randomization
实验任务:打开Ubuntu的地址随机化。 我们在任务1中运行相同的攻击。
实验流程:
1. 软连接改回zsh
2. 打开地址随机化
3. 再次重复攻击操作
可见无法实现攻击,因为是由于地址空间随机化被开启,导致之前计算的地址与实际的地址出现了不同,从而不能完成攻击。
2.4 task 4 :Stack Guard
实验任务:到目前为止,我们在编译程序时禁用了GCC中的“Stack Guard”保护机制。 在此任务,可以考虑在存在Stack Guard的情况下重复任务1。 要做到这一点,应该在没有-fno-stack-protector'选项的情况下编译程序。
实验流程:
1. 在完成此任务之前,首先关闭地址随机化,否则不知道哪个保护有助于实现保护。
2. 在存在“Stack Guard”的情况下重复Task1
3. 再次重复攻击操作
攻击失败,可以看到此时报出两个错误,第一个是因分配空间不足引起的"stack smashing detected",第二个是段错误。该机制是检测ebp-0xc这个位置存放的4字节是否被改变。再次编译stack程序,发现该检测值会发生改变,是随机生成的,难以预测。
3 实验总结
通过本次实验,我进一步了解了shellcode攻击的基本原理和流程,同时对于linux的防御机制也有了更深的了解。通过尝试不同的防御以及对比,理解了上一次实验zsh存在的安全隐患。同时,通过本次实验gdb的操作,对于汇编知识的欠缺也有所弥补,了解了计算机偏底层的概念和逻辑。希望之后能再接再厉!加油~