1.逆向及Bof基础实践说明
1.1实践目标
- 实践对象:pwn1的linux可执行文件
- 实践目的:使程序执行另一个代码(ShellCode)
- 实践内容:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
1.2基础知识
- 熟悉Linux基本操作
- 能看懂常用指令,如管道(|),输入、输出重定向(>)等。
- 理解Bof的原理。
- 能看得懂汇编、机器指令、EIP、指令地址。
- 会使用gdb,vi。
2.直接修改程序机器指令,改变程序执行流程
知识要求等内容详见实验指导,此处不再赘述。
2.1反汇编查看目标地址
将pwn1文件复制到主文件夹中,并重命名为20164305(便于后续实践使用),然后使用反汇编语句 objdump -d 20164305 | more 对其进行反汇编,得到如下结果:
红色框中的"call 8048491 "是汇编指令
- 是说这条指令将调用位于地址8048491处的foo函数;
- 其对应机器指令为“e8 d7ffffff”,e8即跳转之意。
- 本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令呢,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值(当前指令的下一地址+目标地址偏移量=执行下一条指令地址)。
2.2使用vi修改可执行文件
想要调用shell,就要将call指令的目标地址由d7ffffff变为c3ffffff(804847d-80484ba的补码)。
2.2.1使用vi打开文件并切换数据显示模式
输入 :%!xxd ,将文件转为16进制编码显示。
2.2.2找到修改位置并完成修改
按实验指导书方法,输入 /e8d7 找到待修改数据(有的同学的系统可能会提示这是无效地址或者地址不存在,这是因为 e8d7 在十六进制表示时不连续,中间有空格符,可以通过查找 e8 找到 e8d7 位置,如下图所示)
选中修改位置,完成修改,输入 :wq 存盘退出。
2.3查看文件修改情况并运行
使用 vi 检查指令是否修改正确
运行程序,发现程序调用shell,内容1完成。
3 .通过构造输入参数,造成BOF攻击,改变程序执行流
与内容1不同,内容2主要通过构造缓冲区溢出,覆盖(实际为更改)目标地址达到调用shell的目的。
3.1 确认输入字符串哪几个字符会覆盖到返回地址
在做这一步时,我建议先初步看一下实验指导书里的步骤,然后通过手动输入不同长度的字符串自行判断是否覆盖到返回地址。
但不排除第一次就能确认输入字符串的哪4位可以覆盖返回地址,比如说......(我是第一次就成功了)
输入 gdb 20164351 ,在gdb内输入指令 r 执行文件,并输入测试数据(如下图)。
输入 info r 查看寄存器信息,通过查询ascll表,发现eip中存放数据为3444(真的很巧),就可以立即判定哪四位会覆盖到返回地址。
tips:是3444而不是4443的原因是Linux中栈空间是向下增长的,一个寄存器中的数据是倒序的(应该是这样)。
3.2 构造输入字符串
- 根据内容1中的getshell内存地址,修改输入字符串(注意要将实际地址反序录入),然后利用prel构建输入文件。
- 执行文件,检查是否调用shell
4. 注入Shellcode并执行
4.1 准备一段Shellcode
shellcode就是一段机器指令(code),具体代码如下
\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\
- 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
- 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
4.2 准备工作
- 下载execstack并安装
- 按实验进行配置
4.3 构造要注入的payload
Linux下有两种基本构造攻击buf的方法:
- retaddr+nop+shellcode(恶意代码小于缓冲区大小)
- nop+shellcode+retaddr(恶意代码大于缓冲区大小)
实验过程如下(与实验指导过程一致,只不过寄存器地址不同)
- retaddr+nop+shellcode 构建
- 这里要注意每个人电脑的retaddr不一定与实验报告一致,要根据自己电脑显示内容确定retaddr位置。
按照测试后的结果,修改返回地址运行文件,发现与实验指导相同,shell没办法用。按照指导分析原因,发现push指令把payload覆盖掉了。
为什么第一步构建方法不行,我做完第二步才反应过来。
- nop+shellcode+retaddr
与第一种构建方法类似,找到retaddr(与第一种位置一致),然后将retddr替换成他的下一位构建payload。
结果第二种成功了,那为什么第一种没有成功,原因在于shellcode的代码占用空间大于缓存区(以下均为个人理解,望指正)。那缓冲区有多大呢?
我认为在内容2和构建nop+shellcode+retaddr的代码中已经很明显了,应该是32字节,而shellcode的代码长度大约为50字节超过缓冲区大小,导致push指令执行,进而shellcode代码被清空,无法调用。如果在第二步就留意输入字符串的长度,那么第三部就会少走一些弯路。
实验收获:在今后的实验过程中,不能仅仅按照实验指导完成实验,还要理解实验指导中每一步的含义,才会真正的有所收获。
实验问题:什么是漏洞?漏洞有什么危害?
1.漏洞是一种安全策略缺陷。2.漏洞可能会被入侵或者控制,造成信息丢失威胁系统安全。