一、实验内容
-
缓冲区溢出定义:
缓冲区溢出是一种程序错误,在这种情况下,数据被写入到内存中的缓冲区时超过了该缓冲区所能容纳的最大容量。当超过缓冲区的边界时,额外的数据会溢出到相邻的内存位置中,覆盖掉其他数据或指令,导致程序行为异常或系统安全漏洞。 -
缓冲区溢出的原因:
编程错误:开发者在编写代码时没有正确检查输入数据的长度或没有正确地管理内存资源。
缺乏验证:当接收来自外部(如用户输入)的数据时,如果没有正确的输入验证机制来确保数据不会超出预期范围,就可能导致溢出。
使用不安全函数:某些编程语言中的函数(例如 C 语言中的 strcpy 或 gets)如果使用不当,很容易导致缓冲区溢出。
动态内存管理不当:在动态分配内存的情况下,如果释放内存后没有正确地清除指针或者重复释放同一块内存区域,也可能引发相关问题。
设计缺陷:软件设计阶段没有考虑到所有可能的输入情况,或者没有为潜在的大输入量留有足够的处理空间。
二、实验过程
1. 直接修改程序机器指令,改变程序执行流程
- 下载目标文件pwn1,拖入虚拟机,改名为pwn20222416。
- 正常运行该文件,可以回显输入的字符串。
- 使用“objdump -d pwn20222316 | more”命令,反汇编并找到函数调用的相关指令。
可以看到main中80484b5位置是跳转到foo函数的指令。
跳转指令中,e8是跳转的意思,d7ffffff为补码,表示当前地址+(-41),所以要调用getShell函数,需要改变后面四个字节。
根据计算,0804847d-80484ba=ffffffc3,应该是-61,即-0x3d,补码为c3ffffff。
- 修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。
1.vi进入pwn2,在乱码界面按Esc键,然后输入:%!xxd
2.输入/e8d7,找到e8d7,修改d7为c3
3.输入:%!xxd -r
4.输入:wq退出
- 再次反汇编,检验是否修改正确。
可以看到该条指令现在调用的是getShell函数
- 运行修改后文件。
此时可以进入shell。
2. 通过构造输入参数,造成BOF攻击,改变程序执行流
- 对pwn20222316_BOF反汇编。
该可执行文件正常运行是调用函数foo。foo函数有Buffer overflow漏洞:foo读入字符串,但系统只预留了(28)字节的缓冲区,超出部分会造成溢出。
- 检查gdb环境
1.在终端中输入gdb -v,若找不到该命令,则需进行安装操作
2.输入sudo apt-get install gdb
3.输入gdb-v检查是否安装成功
- 分析覆盖返回地址的字符
启动gdb,输入1111111122222222333333334444444455555555,使用info r查看EIP寄存器中的数据,发现eip的值是0x35353535,即5555的ascii码。
再输入另一个特定的过长字符串,查看eip的值为0x34333231,即4321的ascii码。这就确定了应该如何设置攻击字符串,即将第33至第36个字符设置为804847d按字节的倒序。
- 利用perl软件生成包含这样字符串的一个文件。
- 用“xxd input20222316”命令查看文件内容,可以发现内容正确。
- 将input的输入,通过管道符“|”作为pwn的输入。
可以发现程序调用了getShell函数,可以获取shell了。
3. 注入Shellcode并执行
- 准备一段Shellcode
- 关闭地址随机化
1.先通过execstack - s 指令来设置堆栈可执行
2.再用 execstack -q 指令查询文件的堆栈是否可执行
3.检查发现randomize_va_space为2,即地址随机化保护是开启的
关闭地址随机化
4.检查发现randomize_va_space为0,即地址随机化保护是关闭的
- 构造要注入的payload
Linux下有两种基本构造攻击buf的方法:
- retaddr+nop+shellcode
- nop+shellcode+retaddr
- 在终端1中入攻击buf,回车一次即可,
不要出现指导书里的乱码。
- 打开终端2,用gdb调试该程序
输入ps -ef | grep pwn20222316,找到pwn20222316的进程号
打开gdb,调试该程序
通过设置断点,来查看注入buf的内存地址(终端1按回车)
- 重新生成input_shellcode
- 注入input_shellcode,并执行。
三、问题及解决方案
- 问题1:输入sudo apt-get install execstack ,提示Unable to locate package
- 问题1解决方案:https://blog.csdn.net/weixin_43729943/article/details/104221462
- 问题2:最后一个注入Shellcode总提示broken pipe
- 问题2解决方案:虚拟机配置有问题,重新按步骤安装了一遍虚拟机解决。
四、学习感悟、思考等
通过本次实验,我对缓冲区溢出攻击有了更深的了解,对于linux系统的各种命令也有了更深的认识。
参考资料
- 逆向与Bof基础(https://gitee.com/wildlinux/NetSec/blob/master/ExpGuides/0x11_MAL_逆向与Bof基础.md#1-逆向及bof基础实践说明)