这道题目我没有写出Exploit,因为编码时候里面几个细节处理出错。但对程序的逆向分析已完成,这里就学习一下别人写Exploit的思路。主要参考:绿盟科技网络攻防赛资料下载
0x01 题目要求
题目要求如下:
1.找出Exploit.exe中的漏洞。简单分析漏洞的成因,包括漏洞类型、相关的反汇编或伪C代码以及说明信息等。
2.在开启DEP+ASLR的系统里运行Exploit.弹出计算器。
0x02 漏洞分析
首先脱掉ASPack壳,OEP如下:
使用IDA分析,发现这是一个Socket server程序,监听在2994端口。支持三个命令:ENCRYPT、STATUS和EXIT
main函数中大都是Socket的逻辑代码,其中重点需要关注这2个函数:ShellExecuteA()和sub_401120()。
以下是sub_401120()函数主要代码:
观察发现,STATUS命令的处理中打印了内存地址,存在一处Information Leakage漏洞。
接下来分析ENCRYPT命令的处理逻辑,即sub_401120()函数,它主要调用sub_401030()函数,我们将其重命名为encrypt()
encrypt()函数做了两件事,一是使用rand()函数产生一个随机字符数组keys,二是将传入数据与keys异或后拷贝给大小为200bytes的栈内存。
而我们可以传入的数据最长可以是0XFFFF,显然超过200字节,因此这里会造成栈溢出。
0x03 漏洞利用Exploit
由于题目要求在开启DEP+ASLR的系统上成功执行Exploit,因此想到两种利用方法,一是通过VirtualProtect()关闭DEP,栈上注入shellcode执行。二是构造ROP链绕过ASLR+DEP。
无论哪种利用方法,首先要解决的问题是,我们传入的数据都会被encrypt()函数加密,也就是与keys的异或操作,而keys又是通过rand()随机生成。因此输入的数据首先要进行逆编码。好消息是,这里使用的rand()是以时间作种子的伪随机,其值可以预测。
方法二、ROP Bypass ASLR+DEP
下面代码是第二种,通过ROP实现的Exploit(学习作者思路时稍有修改):
由于Python的rand()函数与Windows库函数实现不一样,因此要调用C库函数。这里作者没有将其集成到Exploit代码里,而是写了一个C程序,通过命令行与之通信:
以上利用过程分3步:
1.通过STATUS泄漏程序基地址,后面构造ROP Gadgets时可以通过它直接对指令寻址。
2.通过STATUS泄漏ESP地址。通过分析GetModuleHandleA代码可知道,其返回值存储于eax寄存器,而代码中又有一处mov esi, eax. 因此只要执行一段mov eax, esp; retn或mov esi, esp; retn 的Gadgets,然后跳转到push 5ACh处执行,就可以实现泄漏ESP的地址。
通过观察发现,helper()函数中恰有此指令。
3."calc.exe"字符串入栈,并重构ShellExecuteA函数栈,完成利用。
溢出后跳转到.text:0040153B处执行,其中ShellExecuteA函数后4个参数,由我们在栈上提供。
方法一、VirtualProtect关闭DEP
第一种方法中,helper(void)函数中提供了一处VirtualProtect指令可供使用:
贴一个关闭DEP利用的思路,来自@Chu同学: