Saturday, April 04, 2009

TKADV2009-005

Today I released an advisory (TKADV2009-005) describing an integer overflow vulnerability in the Quicktime demuxer of xine-lib.

Debug session of the bug

tk@tk-desktop:~$ gdb -q xine

Adjusting the debugger environment:
(gdb) set disassembly-flavor intel

(gdb) directory /home/tk/Desktop/xine-lib-1.1.16.2/src/demuxers/
Source directories searched: /home/tk/Desktop/xine-lib-1.1.16.2/src/demuxers:$cdir:$cwd

(gdb) symbol-file /usr/lib/debug/usr/lib/xine/plugins/1.24/xineplug_decode_qt.so
Load new symbol table from "/usr/lib/debug/usr/lib/xine/plugins/1.24/xineplug_decode_qt.so"? (y or n) y
Reading symbols from /usr/lib/debug/usr/lib/xine/plugins/1.24/xineplug_decode_qt.so...done.

Set a breakpoint after calloc():
(gdb) break demux_qt.c:1550
No source file named demux_qt.c.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (demux_qt.c:1550) pending.

Now let xine play our poc movie file:
(gdb) r Desktop/xine-lib_QuickTime_Bug/poc2.mov 
Starting program: /usr/bin/xine Desktop/xine-lib_QuickTime_Bug/poc2.mov
[Thread debugging using libthread_db enabled]
[New Thread 0xb78646d0 (LWP 11878)]
Dies ist xine (X11 gui) - Ein freier Video-Player v0.99.6cvs.
(c) 2000-2007 Das xine Team.
[New Thread 0xb76edb90 (LWP 11881)]
[New Thread 0xb6eecb90 (LWP 11882)]
[New Thread 0xb5d60b90 (LWP 11883)]
[New Thread 0xb513bb90 (LWP 11884)]
[New Thread 0xb48b8b90 (LWP 11885)]
[New Thread 0xb3eb6b90 (LWP 11886)]
[New Thread 0xb32ccb90 (LWP 11887)]
[New Thread 0xb28feb90 (LWP 11888)]
[New Thread 0xb1cf2b90 (LWP 11889)]
[New Thread 0xb14f1b90 (LWP 11890)]
[New Thread 0xb0cf0b90 (LWP 11891)]
[New Thread 0xb0106b90 (LWP 11892)]
[New Thread 0xaf905b90 (LWP 11893)]
[New Thread 0xaed1bb90 (LWP 11894)]
[New Thread 0xadcf3b90 (LWP 11895)]
[New Thread 0xad4f2b90 (LWP 11896)]
[Switching to Thread 0xb78646d0 (LWP 11878)]

Breakpoint 1, parse_moov_atom (info=0x8ec1978, moov_atom=0x8ec19e8 "", bandwidth=1544000)
at demux_qt.c:1550
warning: Source file is more recent than executable.
1550       if (!trak->time_to_sample_table) {

(gdb) x/1i $eip
0xaccdefc8 <parse_moov_atom+1528>: test   eax,eax

EAX points to the overflow heap buffer allocated by calloc():
(gdb) i r eax
eax            0x8e48d18 149196056

Content of the heap (before the overflow):
(gdb) x/8x 0x8e48d18
0x8e48d18: 0x00000000 0x00000000 0x00000000 0x00000000
0x8e48d28: 0x00000000 0x00000029 0x00000000 0xade1bcae

Breakpoint after the first written bytes:
(gdb) break 1563
Breakpoint 2 at 0xaccdf052: file demux_qt.c, line 1563.

(gdb) c
Continuing.

Breakpoint 2, parse_moov_atom (info=0x8ec1928, moov_atom=0x8ec1998 "???]}??O?j??q?\212_?\022\177;J?w??h~/?o?]\204\032?_??`??\a????L?\234G?", bandwidth=0x178f40) at demux_qt.c:1565
1565       trak->time_to_sample_table[j].count = 0; /* terminate with zero */

The heap buffer is indeed overflowed with user controlled data from the Quicktime movie file:
(gdb) x/8x 0x8e48d18
0x8e48d18: 0x41414141 0x42424242 0x43434343 0x44444444
0x8e48d28: 0x45454545 0x46464646 0x47474747 0x48484848

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.