萌新入坑pwn,一直在做栈溢出的题目,这题集合了__libc_csu_init,覆写got表,mmap和mprotect的运用,知识点丰富,在此做个总结,和学pwn的同学一起进步,大佬也请过过目,指正下不足之处,向大佬们看齐,题目,libc版本和exp都放在附件中,请自取。
下面进入正题,这里假设system和execve被禁用,实际上这种情况很常见,利用mprotect和mmap来解决,简单来说mmap函数创建一块内存区域,将一个文件映射到该区域,进程可以像操作内存一样操作文件。mprotect函数可以改变一块内存区域的权限(以页为单位),这里通常把bss的权限改为可读可写可执行,一般来说64位下mprotect(0x600000,0x1000,7)(起始地址,长度,权限)32位下mprotect(0x804A000,0x400,7),长度都是对齐的,记住有三个参数在这里。
原函数定义:
int mprotect(const void start, size_t len, int prot);
void mmap( void *start , size_t length , int prot , int flags , int fd , off_t offsize);
更具体的请查证资料,这里能理解到就行,下面开始看题目学习:
一开始检查程序的保护机制:
只有堆栈不可执行的权限,可以改got表,没有栈溢出保护(可能有栈溢出漏洞)
ida分析:
明显的栈溢出漏洞,通过爆破可以检测出栈大小:136(覆盖ebp)
思路:
这里假设不能使用system和execve函数的话,想到是自己生成shellcode,放在bss段中,然而bss是不可执行的,要改写那个权限,就要用到mprotect和mmap,64位下我们优先使用mprotcet,需要先求出这个mprotect函数的真实地址,然后在got表中调用,然而原本的got表是没有的,所以我们要覆盖已有函数A的got表地址,这样下一次调用A函数就直接调用mprotect函数。然后我们再覆盖B函数的got为bss段的地址,调用B函数就可以运行bss段中的shellcode了。还有一个问题,64位下的ROP gadget
发现没有三个参数同时满足的,想到可以使用__libc_csu_init里面的那个rop链(如不懂请看中级ROP技术),这样搞清楚了,接下来就是敲代码的事了。
没有合适的ROP
有合适的ROP,接下来就是写脚本了:
中级ROP技术我们用一个函数来整理(因为会多次用到)
最后实现各种操作:
先本地测试:
最后远程getsehll:
总结:中级ROP适用于64位下的需要3位参数的函数,一般在ROPGadget中很难找齐,就可以这么用,方便,同时掌握改写内存权限和覆盖got表的能力,一举三得!能力得到提升,继续加油。
- level5.zip 下载