Apple iTunes <= 10.6.1.7 Extended M3U Stack Buffer Overflow
==========================
* VULNERABILITY OVERVIEW *
==========================
A stack based buffer overflow exists in Apple iTunes 10.4.0.80 to 10.6.1.7.
When opening an extended .m3u playlist file which contains an "#EXTINF:" tag
description iTunes will first open and read that file. An extended m3u playlist
file (http://en.wikipedia.org/wiki/M3U8) can look like this:
#EXTM3U
#EXTINF:4,A_lot_of_junk_to_copy
C:\what\ever.mp3
After reading the playlist, the "#EXTINF:" information is first stored in a heap
buffer. Then "#EXTINF:4," is stripped from that buffer and the content
(A_lot_of_junk_to_copy) is copied from the heap buffer to a 0x274 bytes sized
stack buffer without appropriate boundary checks using a REP MOVSD instruction.
The destination seems always to be the address of the stack buffer + offset 0x164,
thus leaving 0x110 bytes of space before reaching the boundary and overflowing
information after it (stored EBP, return address etc.)
This was observed using iTunes 10.6.1.7 on Windows. The MacOS version behaves in
the same way except that a library MEMMOVE function is used instead of REP MOVSD.
=========================
* VULNERABILITY DETAILS *
=========================
NOTES:
* For this analysis iTunes 10.6.1.7 with QuickTime 7.7.2 on Windows XP SP3 EN
was used. The file of interest with the vulnerability is iTunes.dll
* iTunes.dll had the base address of 0x10000000
* When attaching a debugger to iTunes the debug flag was reset to 0
(e.g.: mov BYTE [[fs:30]+2], 0 ). Once this was not the case, the process
terminated itself.
* Arrows (-->) indicate continuation on the following code block here.
VULNERABLE PROGRAM FLOW:
(+) allocation of stack buffer:
1016F6C2 CALL iTunes_1.10172430 ; -->
10172430 PUSH EBP
10172431 MOV EBP,ESP
10172433 AND ESP,FFFFFFF8
10172436 SUB ESP,274 ; -> create stack buffer with size 0x274
[...]
(+) calls to other functions which request the file, read it and store it
into a heap buffer. Then it is checked whether there exists an "#EXTINF:"
section and "#EXTINF:" is stripped from the heap buffer:
103BD205 PUSH iTunes_1.110D8174 ; ASCII "#EXTINF:"
103BD20A MOV ECX,1
103BD20F PUSH 8 ; length of "#EXTINF:"
103BD211 PUSH EBP ; pointer to heap buffer filled with "#EXTINF:,AAA..." from playlist
103BD212 LEA EDX,DWORD PTR DS:[ECX+7]
103BD215 CALL iTunes_1.100D6200 ; -> check if heap buffer begins with "#EXTINF:" => EAX = 0 if true
103BD21A ADD ESP,0C
103BD21D TEST EAX,EAX ; EAX = 0
103BD21F JNZ iTunes_1.103BD350
103BD225 SUB ESI,8 ; ESI => length of heap buffer - length of "#EXTINF:"
103BD228 ADD EBP,8 ; advance pointer in buffer to remove "#EXTINF:" => buffer: ",AAA..."
[...]
(+) call to function which copies heap buffer with content after "#EXTINF:,"
from the playlist into the stack buffer and causes an overflow if the
content is bigger than 0x110 bytes:
103BD2F9 PUSH ESI ; LENGTH of content after "#EXTINF:,"
103BD2FA ADD EAX,8 ; => EAX: Stack buffer address + offset 0x164
103BD2FD PUSH EBP ; SRC: Heap buffer content after "#EXTINF:,"
103BD2FE PUSH EAX ; DST: Stack buffer + offset 0x164 => 0x110 bytes of space left
103BD2FF CALL iTunes_1.10DD3300 ; -> call to vulnerable copy operation (good breakpoint address) -->
10DD3300 ; ---------- iTunes_1.10DD3300:
10DD3300 PUSH EBP
10DD3301 MOV EBP,ESP
10DD3303 PUSH EDI
10DD3304 PUSH ESI
10DD3305 MOV ESI,DWORD PTR SS:[EBP+C] ; SRC: Heap buffer with content after "#EXTINF:,"
10DD3308 MOV ECX,DWORD PTR SS:[EBP+10] ; LENGTH of content after "#EXTINF:,"
10DD330B MOV EDI,DWORD PTR SS:[EBP+8] ; DST: Stack buffer + offset 0x164
10DD330E MOV EAX,ECX
10DD3310 MOV EDX,ECX
10DD3312 ADD EAX,ESI
10DD3314 CMP EDI,ESI
10DD3316 JBE SHORT iTunes_1.10DD3320 ; jump taken
10DD3318 CMP EDI,EAX
10DD331A JB iTunes_1.10DD34C4
10DD3320
10DD3320 ; ---------- iTunes_1.10DD3320:
10DD3320 CMP ECX,100
10DD3326 JB SHORT iTunes_1.10DD3347 ; jump not taken
10DD3328 CMP DWORD PTR DS:[1146F100],0 ; here: *(0x1146F100) = 1 =>
10DD332F JE SHORT iTunes_1.10DD3347 ; jump not taken
10DD3331 PUSH EDI
10DD3332 PUSH ESI
10DD3333 AND EDI,0F
10DD3336 AND ESI,0F
10DD3339 CMP EDI,ESI
10DD333B POP ESI
10DD333C POP EDI
10DD333D JNZ SHORT iTunes_1.10DD3347 ; jump taken
10DD333F POP ESI
10DD3340 POP EDI
10DD3341 POP EBP
10DD3342 JMP iTunes_1.10DDD594 ; not reached
10DD3347
10DD3347 ; ---------- iTunes_1.10DD3347: copy routine
10DD3347 TEST EDI,3
10DD334D JNZ SHORT iTunes_1.10DD3364 ; jump not taken
10DD334F SHR ECX,2 ; divide length by 4
10DD3352 AND EDX,3
10DD3355 CMP ECX,8
10DD3358 JB SHORT iTunes_1.10DD3384 ; jump not taken
10DD335A REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] ; stack buffer overflow by copying ECX*4 bytes
10DD335C JMP DWORD PTR DS:[EDX*4+10DD3474]
===========
* EXPLOIT *
===========
LOCAL:
This flaw can be locally exploited if a user opens a malicious playlist via
"File"->"Library"->"Import Playlist..." in iTunes itself.
REMOTE:
This flaw can be remotely exploited if
1) a user opens a remote playlist (e.g.: http://evilserver.org/evilplay.m3u) by
using "Advanced"->"Open Stream" (and maybe other possibilities inside iTunes).
2) a user browses to a html page which has a itms:// source or link embedded
pointing to an evil playlist
(e.g: <iframe src="itms://evilserver.org/evilplay.m3u" />).
The itms:// source instructs the browser to open iTunes. iTunes then requests
the playlist with http and loads it.
However, Google Chrome, Internet Explorer, Firefox and Opera ask the user if
iTunes should be openend. Some iTunes users will surely have set itms to
open automatically. And Safari never asks the user, it always opens iTunes on
itms:// links or sources in html pages.
=======
* FIX *
=======
This vulnerability was fixed in iTunes 10.6.3.25 on June 11 2012 but is not
listed explicitly in http://support.apple.com/kb/HT5318
Feedback is welcome :)
Greetings,
Rh0