Exp1 PC平台逆向破解 20165110 石钰

Exp1 PC平台逆向破解 20165110 石钰

一、实践目标

1.实验背景

实践对象是pwn1的Linux可执行文件,该程序的正常该程序正常执行流程是:main调用foo函数(oo函数会简单回显任何用户输入的字符串)该程序还包含一个getShell代码片段,会返回一个可用Shell。但是在正常情况下这个代码是不会被运行的。

2.实验内容

(1)手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

(2)利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

(3)注入一个自己制作的shellcode并运行这段shellcode。

二、实验步骤

1.实验一

(1)实验要求

修改可执行文件,改变程序执行流程,直接跳转到getShell函数

(2)具体步骤

预备知识:了解Call指令为跳转指令,EIP寄存器用于存放返回地址,反汇编指令为objdump.

首先通过终端进入pwn1所在的文件夹中,将pwn1做一个备份pwn20165110,然后开始后续操作。
首先输入objdump -d pwn20165110 | more指令将pwn1文件进行反汇编操作,找到main函数中指令 call 8048491 <foo>该指令用于跳转到foo函数中,如果我们想要让main函数不跳转到函数中只需要修改call后面的地址将其地址修改为函数的地址0804847d。

随后输入vi pwn这时显示的一堆ASIC码值无法阅读

随后输入%!xxd -r转化成16进制显示

使用/d7命令查找e87ffffff找到我们需要修改的机器指令的位置,找到后按r修改d7为c3(计算方式:0x0804847d-0x08048491+0xffffffd7=0xffffffc3)

然后使用:%!xxd -r转回ASCI码模式,再输入:wq!保存更改后的文件并退回终端页面。此时再次使用objdump -d pwn20165110查看pwn20165110的机器指令和汇编指令,即可发现main函数中的call的返回地址已经转变,说明修改已经成功。

此时运行./pwn20165110文件即可成功获取shell。

2.实验二

(1)实验要求

利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

(2)具体步骤

预备知识:BOF攻击的相关知识
该攻击是因为向缓冲区中填入过多的数据,而超出边界导致数据外溢,覆盖了相邻的内存空间。可以利用缓冲区溢出改写数据、改变程序执行流程干扰系统运行,破坏系统完全性,任意执行恶意代码。
函数调用过程有三个步骤,分别为:

prologue:保存当前的栈基址(ebp)
call:调用参数和返回地址(eip)压栈,跳转到函数入口
return:恢复调用者原有栈
本实验利用的是foo函数的BOF漏洞,在执行foo函数时构造一个超出buff大小的字符串将堆栈中的返回地址构造成我们需要的地址即可实现出发getshell函数。

首先我们再次将pwn1文件进行备份,新文件命名为pwn20165110_2。
首先使用gdb pwn20165110_2命令进入调试该文件状态,随后输入r执行pwn20165110_2文件,此时要求输入字符串我输入的是11...22...33...44...55...总计40个字符,随后可以发现终端显示这样一段字符Segmentation fault,出现了错误0x35353535 in ?? ()表示该地址并不存在,

我还进行了其他尝试:

我们可以使用x/16x,输入相应的地址来查看其具体内容从而找到其缓冲区的真正大小,
我们还可以通过对函数地址的计算可以得出缓冲区总共的大小(0x80484ae-0x8048491=0x0000001c)

1c转化为十进制即为28,也就是我们需要构造一个buff长度为28+4=32位,最后4位是返回地址,我们填入的是刚才查找的shellcode的起始地址0x080484d7由于本虚拟机为小端优先所以我们将最后四位构造成\xd7\x84\x04\x08即可实现
将我们需要往pwn 20165110_2中输入的字符串先放入一个名为input文件中,
还有一种方式时直接进行输入,下图以两种方式得出的结果:

随后可以输入xxd input可以查看我们刚才注入的信息,将这个文件作为输入执行pwn,即可攻击成功。

3.实验三

(1)实验要求

注入一个自己制作的shellcode并运行这段shellcode。

(2)具体步骤

预备知识:BOF攻击共有两种模型分别为NSR溢出模型,RNS溢出模型。其中NSR溢出模型,nop,shellcode,ret;RNS溢出模型,ret,nop,shellcode。
NSR模型:

RNS模型:

首先要先设置堆栈可执行,但是我输入相关命令的时候告知我没有相关命令,需要重新下载,我执行apt-get install execstack时报出找不到该软件,后来经过排查发现是源的问题,我更新了一个源后,即可顺利安装指令。执行

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

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

此外,需要关闭地址随机化,否则每次操作esp的地址都会发生变化,这会非常麻烦。输入相关指令echo "0" > /proc/sys/kernel/randomize_va_space关闭。

由于该实验我们需要构造一个shellcode,这里的构造方法同实验二相似

perl -e 'print "A" x 32;print "\x4\x3\x2\x1\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"' > input_shellcode

随后在终端运行(cat input_shellcode;cat) | ./pwn1
打开一个新的终端(一定要打开一个新的!!!)输入ps -ef | grep pwn20165110_3即可看见当前运行的pwn20165110_3的端口号(3188)

随后进行gdb操作attach 3188进行调试。

输入指令```disassenmbl foo``进行反编译查看具体指令的地址,将断点设置在call gets@plt处,

输入c继续程序,在另一个终端界面按下回车,在回到单步调试的界面输入info r esp查看栈底指针的位置。
随后就是坑了,我一开始将地址值-1c后去寻找该地址的地方,怎么也找不到我的shellcode,我还因为害怕自己出错翻来覆去进行多次操作,后来我才意识到我将模型弄错了,这是一个rns的模型将shellcode放在了ret的后面所以这时应该将地址值进行+4(4为返回地址的长度)即0xffffd29c + 0x00000004 = 0xffffd2a0

即可完成实验三。

附录:实验过程中出现的错误截图(解决方案已在上文中提到)



posted on 2019-03-15 00:15  小orangegood  阅读(154)  评论(0编辑  收藏

导航