逆向破解与BUF
实践目标
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何 Shellcode。
三个实践内容如下
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
实验过程
利用修改程序文件获取shell
main//用于调用foo函数
foo//用于进行读写操作
getshell//用于获取shell权限,一般情况此函数不被调用
截图如下:
根据第一张图片可以看见程序中有一个getshell函数用于获取系统权限,我们只需要把这个函数的函数调用地址(由图一可得是0804847d)被main中原本调用foo的那一行汇编的地址减去后,可以得到我们应该如何构造0804849d中的操作数。
下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。
我们接下来将用到vim工具。我们打开后一开始是全部以ASCII编码展示的文件,我们需要用:%!xxd指令。
:%!xxd
解释:把所有的行(%)用本地(!)的xxd程序打开。
接下来可以直接使用/+'关键词'对我们需要的关键词进行查找。n为继续搜索。
修改时按下'i',修改完后使用':%!xxd -r'再用':wq'进行保存。
如下图所示:
修改前运行截图如下:
修改文件后运行截图如下:
利用栈缓冲区溢出获取shell
因为此程序中缓冲区大小为28字节,之后便是4字节的ebp,4字节的eip,其中ebp保存了上一个函数的基质,eip保留了下一条指令的地址,由于缓冲区满了之后输入会继续向ebp与eip覆盖.
C语言中栈的增长方向是向低地址,字符的输出也是优先低地址,ebp,eip比缓冲区地址高,因此我们要在字符串末尾构造getshell的函数地址。
由上次实验我们就已经知道了是0804847d,但是直接输入字符的话在后台会变成0x300x380x300x340x380x340x370x43,这明显不是可以寻址的有效函数地址。
因此我们需要用到工具perl获取\x08\x04\x84\x7d的ASCII字符,但是问题又来了,由于获取的字符有些是不在终端显示的,因此我们需要管道直接将获取到的字符输入到PWN的缓冲区。
运行效果如下图:
注入shellcode
这时就需要我们构造payload,缓冲区里的存放的数据可以使可执行代码,它所缺的仅仅是一次调用机会,而我们可以使用缓冲区溢出修改eip为payload中代码的起始地址。接下来是我的实验过程:
首先我们需要准备实验环境,如下两张图:
接下来是用
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
(cat input_shellcode;cat) | ./20192424pwn1
实验遇到困难
除此,在缓冲区溢出攻击的实验中,我发现:%!xxd -r 保存是必要的,否则不能正常进行实验