2019-2020-2 20175316盛茂淞《网络对抗技术》Exp1 PC平台逆向破解
一、实践目的
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
二、实践要求
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
这几种思路,基本代表现实情况中的攻击目标:
运行原本不可访问的代码片段
强行修改程序执行流
以及注入运行任意代码。
三、相关知识点
1.反汇编指令
objdump -d pwn1 | more
object dump
项目导出
-d disassemble
反汇编
|
管道符,把一个命令的标准输出传到另一个命令的标准输入中
more
分页显示
2.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
NOP汇编指令的机器码是“90”
JNE汇编指令的机器码是“75”
JE 汇编指令的机器码是“74”
JMP汇编指令的机器码是“eb”
CMP汇编指令的机器码是“39”
3.掌握反汇编与十六进制编程器
反汇编指令objdump -d filename
object dump
项目导出
d disassemble
反汇编
|
管道符,把一个命令的标准输出传到另一个命令的标准输入中
more
分页显示
- 十六进制编程器,是用来以16进制视图进行文本编辑的编辑工具软件。其实我们只需要用各系统都兼容的“vim”编辑器就可以实现十六进制编辑的功能。具体步骤如下:
- 输入命令vi pwn1查看可执行文件内容,为ASCII码形式显示;
- 输入:%!xxd将显示模式切换为16进制模式;
- 进行相关操作后,输入:%!xxd -r转换16进制为为ASCII码形式。
四、实践内容
(一)任务一 直接修改程序机器指令,改变程序执行流程
思路
- 找到getShell函数的位置
- 修改main函数中,call指令的参数,使得程序调用getShell函数
步骤
下载目标文件pwn1,使用objdump -d pwn1对pwn1反汇编:
主函数中
call 8048491 <foo>
的汇编指令将调用位于地址8048491处的foo
函数,其对应机器指令为e8 d7ffffff
,e8
为跳转之意。当解释执行e8
这条指令时,CPU就会执行EIP + d7ffffff
这个位置的指令。d7ffffff
是补码,80484ba +d7ffffff= 80484ba-0x29
是8048491的值- main函数调用
foo
,对应机器指令为e8 d7ffffff
- 那如果要修改后让它调用
getShell
,只要修改d7ffffff
为getShell-80484ba
对应的补码就可以 - 通过计算
804847d-80484ba
得到补码为c3ffffff
- 那如果要修改后让它调用
- 由此我们就修改可执行文件,将其中的call指令的目标地址由
d7ffffff
变为c3ffffff
以实现改变程序执行流程- 所以我们使用Esc+:%!xxd将其转换为16进制显示出来,/d7ff查找所需更改处,回车选中d,使用r修改,即rc+r3,:%!xxd -r将文件再次转换为机器代码,如果不这么做会导致无法运行,然后Esc+:wq保存退出。
- 运行pwn2,发现会得到shell提示符,证明我们的修改成功改变了程序执行流程
(二)任务二:利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
首先依旧是反汇编pwn1,可见运行时调用如下foo函数,有Buffer overflow漏洞,其指令lea只为用户预留了1c=28个字节,如果超出则会造成溢出,覆盖返回地址
我们使用gdb进行调试确定输入字符串到哪里时会覆盖到返回地址:
此时eip的值为0x35353535,35的ASCII码表对应为5,所以我们将所有的5改为12345678,确认具体是哪一位之后造成溢出: