前言
原来PWN题都是用ubuntu做的啊!入门以来的这个学期我都用的是kali真的是太捞了,期间出现了各种各样莫名其妙的问题,
这是我在XMAN4遇到libcsearcher时碰到搜索结果不匹配时发现的,尴尬的是组会时槐师傅(其实是所有师傅)都说用ubuntu,
原来他们以前有教过,谁叫我是半路出家,头铁的用了半年kali。
X64汇编
与X86最大的不同之处就是X64的地址,寄存器,数据,都变成了8个byte,更重要的是,为了防止对栈溢出的滥用,X64不再采用
X86的压栈式的传参方式,而是采用专用的寄存器保存函数的参数,它们是RDI,RSI,RDX,RCX,R8和 R9。只有参数数量大于6
个时才会使用栈保存后面的参数。
内存异常
可以使用的内存地址不超过0x00007fffffffffff,否则会抛出异常(非法访问)。
漏洞
存在任意长read,会导致栈溢出。
劫持程序流
与X86类似,栈溢出覆盖返回地址,
garget
为了达成某些目的,我们需要给调用的函数合适的参数,如’/bin/sh’,在X86中,直接将参数写在payload里面,伪造栈帧,因为
它通过压栈传参。而X64就要复杂一些,构造栈帧不再有效,需要将参数传入寄存器,而这就是我们寻找garget的原因。
garget是什么
garget就是程序中的一句汇编语句,可以连续执行,一条接着一条,形如:pop xxx;ret;达到给寄存器赋值的目的,还可以连续不断的
延伸下去。
寻找 garget
对于这道题,由于采用了动态链接,程序本身并不大,所以找不到太多合适的garget,有一个操作就是在libc中寻找,libc多大啊,1
>ROPgarget --binary libc.so.6 --only "ret|pop" | grep "rdi"
因为我们的最终目标是执行system(“/bin/sh”)所以我们需要一个pop rdi;ret,这是可以找的到的。
计算libc基址
程序提供了libc真实地址,libc偏移量计算与X86下计算方法相同。
再计算出”bin/sh”,pop_ret的真实地址,可以开始构建payload了。
payload
‘a’*(0x90-4)+pop_ret_addr+binsh_addr+sys_addr
exp
1 | from pwn import * |