记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

CVE-2017-9128复现与分析

2020-04-21 13:03

前言

cve信息

The quicktime_video_width function in lqt_quicktime.c in libquicktime 1.2.4 allows remote attackers to cause a denial of service (heap-based buffer over-read and application crash) via a crafted mp4 file.

通过攻击者精心构造的一个mp4文件,能够使得libquicktime 1.2.4在调用

quicktime_video_width函数时造成堆空间越界读的操作,最后会导致程序crash,可引发拒绝服务

exp-db上是这么写的

the quicktime_video_width function in lqt_quicktime.c in libquicktime 1.2.4 can cause a denial of service(heap-buffer-overflow and application crash) via a crafted mp4 file.


./lqtplay libquicktime_1.2.4_quicktime_video_width_heap-buffer-overflow.mp4


=================================================================
==10979==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000009d00 at pc 0x7f36a1017a37 bp 0x7ffe65a90010 sp 0x7ffe65a90008
READ of size 4 at 0x602000009d00 thread T0
#0 0x7f36a1017a36 in quicktime_video_width /home/a/Downloads/libquicktime-1.2.4/src/lqt_quicktime.c:998
#1 0x7f36a1017a36 in quicktime_init_maps /home/a/Downloads/libquicktime-1.2.4/src/lqt_quicktime.c:1633
#2 0x7f36a101af13 in quicktime_read_info /home/a/Downloads/libquicktime-1.2.4/src/lqt_quicktime.c:1891
#3 0x7f36a10204a8 in do_open /home/a/Downloads/libquicktime-1.2.4/src/lqt_quicktime.c:2026
#4 0x7f36a0ff15da in quicktime_open /home/a/Downloads/libquicktime-1.2.4/src/lqt_quicktime.c:2075
#5 0x47fad2 in qt_init /home/a/Downloads/libquicktime-1.2.4/utils/lqtplay.c:987
#6 0x47fad2 in main /home/a/Downloads/libquicktime-1.2.4/utils/lqtplay.c:1852
#7 0x7f369e8d7ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
#8 0x47f3dc in _start (/home/a/Downloads/libquicktime-1.2.4/utils/.libs/lqtplay+0x47f3dc)


0x602000009d00 is located 4 bytes to the right of 12-byte region [0x602000009cf0,0x602000009cfc)
allocated by thread T0 here:
#0 0x4692f9 in malloc (/home/a/Downloads/libquicktime-1.2.4/utils/.libs/lqtplay+0x4692f9)
#1 0x7f36a12543ba in quicktime_read_dref_table /home/a/Downloads/libquicktime-1.2.4/src/dref.c:66


SUMMARY: AddressSanitizer: heap-buffer-overflow /home/a/Downloads/libquicktime-1.2.4/src/lqt_quicktime.c:998 quicktime_video_width
Shadow bytes around the buggy address:
0x0c047fff9350: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff9360: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff9370: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
0x0c047fff9380: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff9390: fa fa fd fa fa fa fd fa fa fa 01 fa fa fa 00 04
=>0x0c047fff93a0:[fa]fa 00 04 fa fa 00 fa fa fa 00 fa fa fa 00 00
0x0c047fff93b0: fa fa 00 00 fa fa 00 00 fa fa 00 fa fa fa 00 00
0x0c047fff93c0: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 fa
0x0c047fff93d0: fa fa 00 00 fa fa 00 fa fa fa fd fd fa fa fd fd
0x0c047fff93e0: fa fa fd fd fa fa 00 04 fa fa 00 00 fa fa fd fa
0x0c047fff93f0: fa fa 00 fa fa fa 00 00 fa fa 00 00 fa fa 00 fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==10979==ABORTING


POC:
libquicktime_1.2.4_quicktime_video_width_heap-buffer-overflow.mp4
CVE:
CVE-2017-9128
---------------------
qflb.wu () dbappsecurity com cn

Proofs of Concept:
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/42148.zip

从上面的信息错误是由ASAN报错指出的,估计是用fuzz结合ASAN跑出来的漏洞

poc可从上面的链接中下载,其中包含了很多mp4文件,只有libquicktime_1.2.4_quicktime_video_width_heap-buffer-overflow.mp4

是我们本次验证cve所需要的

编译安装

libquicktime-1.2.4下载链接

按常规操作,用configure来产生Makefile,然后再用make,make install

但是在我的Ubuntu1604下编译安装出来的没有lqtplay,这是因为没有安装相应的libc库,具体解决办法是找到 libquicktime-1.2.4\utils目录下的qltplay.c文件,根据里面include的头文件去安装libc库

这里可以使用apt-file来查找到这些库所在的包

sudo apt-get install apt-file
sudo apt-file update
apt-file search xx/XXXX.h

触发漏洞

gdb lqtplay

r libquicktime_1.2.4_quicktime_video_width_heap-buffer-overflow.mp4

产生报错

给quicktime_video_width下断点,再次运行

int quicktime_video_width(quicktime_t *file, int track)
{
if((track < 0) || (track >= file->total_vtracks))
return 0;
return file->vtracks[track].track->mdia.minf.stbl.stsd.table->width;

}

一步步si

可以看到最后一步取出数据时用了[rax+0x30],而此时rax为0x627bd0,来康康对应的chunk信息

可以看到这个堆块大小只有0x20,而取数据时却用了0x30的偏移导致越界读取

这可能是因为在这个过程中:

file->vtracks[track].track->mdia.minf.stbl.stsd.table->width;

有某些结构体是没有初始化的,具体原因,下面来一步步分析

漏洞分析

分析一波函数回溯

return file->vtracks[track].track->mdia.minf.stbl.stsd.table->width;中的各种数据结构类型:

quicktime_s 结构体指针file

quicktime_video_map_t 结构体数组vtracks

quicktime_trak_t 结构体指针track

quicktime_mdia_t 结构体mdia

quicktime_minf_t 结构体minf

quicktime_stbl_t 结构体stbl

quicktime_stsd_t 结构体stsd

quicktime_stsd_table_t 结构体指针table

int 整型width

从qt_init函数开始记录各种结构的的初始情况:

  • qt_init(stdout,argv[1]);

  • quicktime_open(argv[1],1,0);

  • do_open(argv[1],1,0, LQT_FILE_QT_OLD, NULL, NULL);

    • quicktime_t *new_file;

    • new_file = calloc(1, sizeof(*new_file))

      new_file->log_callback = log_cb;

      new_file->log_data = log_data;

    • quicktime_init(new_file);

      1. file->max_riff_size = 0x40000000;
    • new_file->wr = wr;

      new_file->rd = rd;
      new_file->mdat.atom.start = 0;
    • quicktime_file_open(new_file, filename, 1, 0);

    • quicktime_read_info(new_file)

      • file->file_position = 0;
      • quicktime_init_maps(file);
        • file->vtracks[i].track = file->moov.trak[track];
        • quicktime_init_video_map(&file->vtracks[i], file->wr, (lqt_codec_info_t*)0);
          • vtrack->current_position = 0;
            vtrack->cur_chunk = 0;
            vtrack->io_cmodel = BC_RGB888;
          • quicktime_init_vcodec(vtrack, 1, 0);
            • char *compressor = vtrack->track->mdia.minf.stbl.stsd.table[0].format;
        • lqt_get_default_rowspan(file->vtracks[i].stream_cmodel, quicktime_video_width(file, i), &file->vtracks[i].stream_row_span, &file->vtracks[i].stream_row_span_uv);

可以看到,通过上面的一系列分析,并没有发现明显的初始化file->vtracks[track].track->mdia.minf.stbl.stsd.table的地方,因此当调用quicktime_video_width函数时,直接访问该结构体成员变量,就会造成堆访问的异常

进一步分析quicktime_read_info函数,根据gdb源码调试结果,在quicktime_read_info函数中,执行流程如下:

  1. int result = 0, got_header = 0;
    int64_t start_position = quicktime_position(file);
    quicktime_atom_t leaf_atom;
    uint8_t avi_avi[4];
    int got_avi = 0;

    quicktime_set_position(file, 0LL);

  2. do
    {
    file->file_type = LQT_FILE_AVI;
    result = quicktime_atom_read_header(file, &leaf_atom);
    if(!result && quicktime_atom_is(&leaf_atom, "RIFF"))
    {
    .........
    }
    else
    {
    result = 0;////////////1
    break;
    }
    }while(1);

  3. if(!got_avi)
    file->file_type = LQT_FILE_NONE;
    quicktime_set_position(file, 0LL);

  4. if(file->file_type == LQT_FILE_AVI)
    {

    ​ ..........

    ​ }

    else if(!(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML)))

    {

    ​ do
    ​ {

    ​ .....

    ​ result = quicktime_atom_read_header(file, &leaf_atom);

    ​ .....

    ​ 该do-while循环执行三次,分别处理ftype、 mdat、movv box

    ​ }

    }

  5. if(got_header)
    {
    quicktime_init_maps(file);
    }

可以看到,在这个流程中,不存在初始化赋值file->vtracks[track].track->mdia.minf.stbl.stsd.table的地方

对于这部分赋值的代码在这里

if(!got_avi) 
file->file_type = LQT_FILE_NONE;
quicktime_set_position(file, 0LL);

/* McRoweSoft AVI section */
if(file->file_type == LQT_FILE_AVI)
{
/* Import first RIFF */
do
{
result = quicktime_atom_read_header(file, &leaf_atom);
if(!result)
{
if(quicktime_atom_is(&leaf_atom, "RIFF"))
{
quicktime_read_riff(file, &leaf_atom);
/* Return success */
got_header = 1;
}
}
}while(!result &&
!got_header &&
quicktime_position(file) < file->total_length);

/* Construct indexes. */
if(quicktime_import_avi(file))
return 1;
}

使用010editor打开poc.mp4文件,可以看到ftype、 mdat、movv格式的box

由于在mp4文件中没有检测到AVI的格式类型的box,因此got_avi=0,于是导致了file->file_type = LQT_FILE_NONE,因此导致无法进入if语句if(file->file_type == LQT_FILE_AVI),最终导致无法执行quicktime_import_avi(file),该函数中包含了对file->vtracks[track].track->mdia.minf.stbl.stsd.table初始化赋值的代码

至此漏洞复现分析完毕,有兴趣复现分析一波的可下载附件

CVE-2017-9128 poc.zip (0.027 MB) 下载附件

知识来源: xz.aliyun.com/t/7585

阅读:41202 | 评论:0 | 标签:CVE

想收藏或者和大家分享这篇好文章→复制链接地址

“CVE-2017-9128复现与分析”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

❤人人都能成为掌握黑客技术的英雄⛄️

ADS

标签云

本页关键词