mprotect技巧
题目简介
题目背景见正常exit问题
漏洞点分析
常规的分析不再赘述,这里主要记录一下这道题的另一个解法,也是一个NX保护开启情况下依然可以ret2shellcode的技巧
从上述链接的分析中可以看到程序开启了NX保护,按照常理来说基本不可能采用ret2shellcode的解法
但是发现这是一个静态编译的文件:
这里就想到大概率有mprotect函数,果不其然在IDA的Exports表里搜索到了mprotect函数,如图:
因此可以使用该函数破坏NX的保护,完成ret2shellcode
mprotect函数原理详见二进制总结:mprotect技巧
同时在上述链接给出的分析里我们可以找到gets函数作为输入
因此该方法中的漏洞点利用思路为:溢出劫持返回地址–>调用mprotect函数–>调用gets函数将shellcode读入指定内存区段–>最后返回到该内存段
漏洞点利用
首先使用vmmap查看一下程序有哪些内存段:
内存段的选取其实是任意的,只要是数据段即可(其实代码段也行,但害怕把某些重要指令破坏导致程序趋势……),总之最后我选择在0x80ec000处开始写入shellcode
接下来确定mprotect的地址,从Exports导出表里面可以看到该函数在0x806ec80
然后找到gets函数位置,可以通过readelf命令行工具寻找,这里就不贴图了,最后找到gets是在0x804f630
综上,可以写出如下的利用脚本:
1 | |
最后说一下这里的参数布置问题,需要一个比较巧妙的布置方法,payload2中的第一个p32(shellcodeStart)既是readShellcodeAddr,即gets函数的参数,又是mprotect函数调用完后,下一个需要跳转到的地址
同时,payload1和payload2是等价的,不过payload1采用先用mprotect函数赋权的策略,因此需要一段3个pop1个ret的gadget去把mprotect的参数pop走
更具体的关于32位程序下参数布置的细节,详见二进制总结:32位程序传参问题