实验一 逆向破解与BOF
目录
一、实践内容
1.1 具体内容
1.手工修改可执行文件,使其从跳转原来的foo函数到getShell函数
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
3.注入一个自己制作的shellcode并运行这段shellcode
1.2 对应的实际操作场景
1.运行原本不可访问的代码片段
2.强行修改程序执行流
3.以及注入运行任意代码
二、实践目的
2.1 实践目的
· 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
· 掌握反汇编与十六进制编程器
· 能正确修改机器指令改变程序执行流程
· 能正确构造payload进行bof攻击
2.2 实践基础知识
· 管道|
(1)“|”是管道命令操作符,简称管道符。
(2)利用Linux所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。
(3)连续使用管道意味着第一个命令的输出会作为 第二个命令的输入,第二个命令的输出又会作为第三个命令的输入。
· ls -l | more
该命令列出当前目录中的文档,并把输出送给more命令作为输入,more命令分页显示文件列表。
· call指令
call指令是调用子程序,后面紧跟的应该是子程序名或者过程名
· 相关寄存器
(1)EIP存储着下一条指令的地址,每执行一条指令,该寄存器变化一次。
(2)EBP存储着当前函数栈底的地址,栈底通常作为基址,我们可以通过栈底地址和偏移相加减来获取变量地址
(3)ESP始终指向栈顶,只要ESP指向变了,那么当前栈顶就变了
· 反汇编指令
objdump -d <file(s)>: 将代码段反汇编;
· shellcode(一段机器指令(code))
通常这段机器指令的目的是为获取一个交互式的shell(类似windows下的 cmdexe),所以这段机器指令被称为shellcode。
三、实验过程
3.1 第一部分 手工修改可执行文件,跳转到getShell函数
· 步骤一 对目标文件pwn1进行反汇编,得到相应的汇编代码(如下图1分析)
核心代码: objdump -d pwn20192420rwl | more
代码分析:利用objdump这条反汇编指令,对目标文件进行反汇编,利用more指令对反汇编结果进行分页。
图1
· 步骤二 找到call指令的原目标地址(如下图2分析)
(1)由于EIP的值是下一条指令的地址,由上图1所示,是80484ba。foo函数的地址为8048491。
(2)由foo地址减去EIP中的值,得到的即为d7ffffff(call指令的目标地址)
图2
· 步骤三 修改call指令的目标地址(如下图3分析)
(1)如图1所示,getShell函数地址为804847d。
(2)由getShell函数地址减去EIP中的值,得到的即为c3ffffff(call指令的最终目标地址)
(3)使用vi pwn20192420rwl对目标文件进行编辑,按下ESC键后,输入:%!xxd得到文件十六进制的内容
(4)利用/d7查找对应位置
(5)修改d7ffffff为c3ffffff
图3
· 步骤四 对修改后的文件再次进行反汇编,查看call指令目标地址是否修改成功(如图4分析)
图4
· 步骤五 运行修改后的pwn20192420rwl(如下图5分析)
图5
3.2 第二部分 通过构造输入参数,造成BOF攻击,触发getShell函数
· 步骤一 寻找输入字符串中哪几位字符能够覆盖到函数的返回地址(如图6分析)
(1)输入gdb pwn20192420rwl命令至命令行,进入调试界面
(2)输入r开始运行,然后输入字符串1111111122222222333333334444444412345678
(3)输入info r,查看寄存器详细信息(主要是EIP),发现是字符串1234覆盖掉了返回地址
(4)图中的31、32、33、34分别表示1234的ASCII码值的十六进制
(5)确认用getShell的内存地址(0804847d)来覆盖掉返回地址,根据EIP的地址确认字节序的大小端
图6
· 步骤二 利用getShell函数地址作为input文件的输入(如图7分析)
(1)输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input_20192420rwl
(2)利用xxd input_20192420rwl检验input文件中的输入是否跟预期相符
(3)利用(cat input_20192420rwl; cat) | ./pwn20192420rwl命令作为pwn文件输入,查看最终结果。
图7
3.3 第三部分 注入一个自己制作的shellcode并运行这段shellcode
· 步骤一 关闭地址随机化(如图8分析)
(1)以管理员身份打开文件夹中名为“randomize_va_space”的文件,并将其值改为0
图8
· 步骤二 打开一个终端注入这段攻击buf,并打开另一个终端进行调试(如图9分析)
(1)进入调试终端,输入命令ps -ef | grep pwn20192420rwl查看pwn文件对应的进程号
(2)输入attach命令连接这个进程
(3)输入disassemble foo命令查看foo函数部分的反汇编代码
(4)通过设置端点(break命令)来查看注入buf的内存位置
图9
· 步骤三 修改返回地址(如图10分析)
(1)在调试界面输入info r esp找到对应内存位置
(2)修改返回地址为0xffffd0f0(nops开始的地方,也可以将返回地址设置在31,也就是shellcode开始的地方)
图10
· 步骤四 结果验证 (如图11分析)
(1)利用命令(cat input_20192420rwl; cat) | ./pwn20192420rwl对注入结果进行验证
图11
四、问题及解决方案
4.1 问题一
描述:在完成第三部分的实践时,没有关闭地址随机化,导致每次找到的内存地址都不一样,一直得不到自己想要的结果
解决方案:观看云班课的教学视频,以及结合实验指导书找到办法(在管理员模式下把randomize_va_space文件的内容改为0)
4.2 问题二
描述:在完成第二部分的实践时因不清楚字节序的大小端问题,导致输入的字符串没有按照本应该返回的地址返回到getShell函数部分
解决方案: 通过在网上搜索和对比视频内容,弄清楚了字节序的大小端问题,并在最后的尝试中实现了成功返回到想要的函数地址
4.3 问题三
描述:在第二部分的实践中分析字符串覆盖的返回地址时,没有弄清楚数字在内存中的值到底对应什么
解决方案:通过在网上查询发现了这其实是跟ASCII码值有关,将ASCII码值的十六进制形式与目标数字进行比较后果然得到了答案
五、学习感悟及思考
这是本学期网络攻防课的第一次实验,本次实验的目的是结合逆向技术实现缓冲区溢出攻击。在这次实验中我收获最多的莫过于学到了很多汇编相关的知识以及一些简单的攻击方法。在这次实验中也遇到了很多问题,比如如何正确寻找返回地址,如何实现自己编写的shellcode注入等,但是在老师和同学的帮助下我还是一一解决了这些问题,还在linux指令操作上面也实现了自我的进步。通过这次实验,我也意识到了学好网络攻防课的核心在于实践,虽然老师课上讲的东西很多,但是通过自己的实践将这些知识灵活运用,却是对知识的最好把握,相信在之后的实验课中能够学到更多的东西,提升自己的能力。
六、参考资料
· 逆向逆向及Bof基础实践说明 https://gitee.com/wildlinux/NetSec/blob/master/ExpGuides
· 理解大小端字节序 https://www.cnblogs.com/fan-yuan/p/10406315.html