[NT] Apple Quicktime FLIC File Heap Overflow (Technical Details)
- From: SecuriTeam <support@xxxxxxxxxxxxxx>
- Date: 18 Sep 2006 18:34:08 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Apple Quicktime FLIC File Heap Overflow (Technical Details)
------------------------------------------------------------------------
SUMMARY
There is a flaw in QuickTime FLIC parser, the flaw is located within the
"COLOR_64 chunk" Quicktime parser. Since proper checking is not performed,
a large amount of heap can be overwritten with controlled values. This
flaw could lead to a remote code execution,if an attacker tricks the
victim to visit a malicious webpage with a specially crafted .fli
animation embedded.
DETAILS
Vulnerable Systems:
* Apple Quicktime version 7.1 and prior
Immune Systems:
* Apple Quicktime version 7.1.3
FLC/FLI format overview:
FLIC files are structured in a hierarchy of chunks. A chunk contains a
fixed part and a variable part. Every chunk starts with a 6-byte header,
that contains the size (four bytes) and the type (two bytes) for the chunk
FRAME CHUNK HEADER
typedef struct {
DWORD size; /* Size of the chunk, including subchunks */
WORD type; /* Chunk type: 0xF1FA */
WORD chunks; /* Number of subchunks */
WORD delay; /* Delay in milliseconds */
short reserved; /* Always zero */
ushort width; /* Frame width override (if non-zero) */
ushort height; /* Frame height override (if non-zero) */
} FRAME_TYPE;
Chunk type: 0xB COLOR_64 64-level colour palette
The data in the COLOR_64 chunk is organized in packets. The first word
next to the chunk header is the number of packets of the chunk. Each
packet is structured in a 1-byte skip count, a 1-byte copy count and a
series of 3-byte RGB values (the "copy count" gives us the number of RGB
triplets). If the copy count is zero, there are 256 RGB triplets in the
packet.
For example:
FF,40,r,g,b skip 0xFF entries (one entry= 4bytes), change 0x40 entries
Let's see QuickTime parses the chunk:
text:679FE4DA mov eax, [ebx]
text:679FE4DC mov cx, [eax+6] ;number of subchunks
text:679FE4E0 mov edx, [ebp+6Ch]
text:679FE4E3 mov esi, [edx]
text:679FE4E5 add eax, 6
text:679FE4E8 add esp, 4
text:679FE4EB add eax, 2 ;pointing to 1-byte skip field
text:679FE4EE test cx, cx
text:679FE4F1 jbe loc_679FE5A6
text:679FE4F7 movzx ecx, cx
text:679FE4FA mov [esp+24h+var_10], ecx ; save number of subchunks
text:679FE4FE mov edi, edi
text:679FE500
text:679FE500 loc_679FE500: ; CODE XREF: sub_679FE420+180#j
text:679FE500 movzx cx, byte ptr [eax] ; 1-byte skip field.
text:679FE504 inc eax
text:679FE505 test cx, cx
text:679FE508 jbe short loc_679FE510
text:679FE50A movzx edx, cx
text:679FE50D lea esi, [esi+edx*4] ; skip the bytes +align
text:679FE510 ; esi pointing to heap chunk
text:679FE510 loc_679FE510: ; CODE XREF: sub_679FE420+E8#j
text:679FE510 movzx cx, byte ptr [eax] ; 1-byte count field.
text:679FE514 inc eax
text:679FE515 test cx, cx
text:679FE518 jnz short loc_679FE521
text:679FE51A mov ecx, 100h ; if bytecount=0 bytecount=0100h
; so the entire palette changes.
text:679FE51F jmp short loc_679FE523
text:679FE521 ;
text:679FE521
text:679FE521 loc_679FE521: ; CODE XREF: sub_679FE420+F8#j
text:679FE521 jbe short loc_679FE59C
text:679FE523
text:679FE523 loc_679FE523: ; CODE XREF: sub_679FE420+FF#j
text:679FE523 movzx ecx, cx
text:679FE526 mov [esp+24h+arg_8], ecx ; counter= bytecount;
text:679FE52A lea ebx, [ebx+0]
text:679FE530
text:679FE530 loc_679FE530: ; CODE XREF: sub_679FE420+176#j
text:679FE530 mov cl, [eax] ; byte R (R,G,B)
text:679FE532 mov dl, [eax+1] ; byte G (R,G,B)
text:679FE535 mov bl, byte ptr [esp+24h+arg_0]
text:679FE539 inc eax
text:679FE53A inc eax ;ptr++
text:679FE53B mov byte ptr [esp+24h+arg_C], dl
text:679FE53F mov dl, [eax] ; byte B(R,G,B)
text:679FE541 inc eax
text:679FE542 test bl, bl
text:679FE544 mov byte ptr [esp+24h+arg_4], dl
text:679FE548 jz short loc_679FE574 ;RGB adjustment begin
text:679FE54A mov dl, cl
text:679FE54C shr dl, 4
text:679FE54F shl cl, 2
text:679FE552 or cl, dl
text:679FE554 mov dl, byte ptr [esp+24h+arg_C]
text:679FE558 mov bl, dl
text:679FE55A shr bl, 4
text:679FE560 or bl, dl
text:679FE562 mov dl, byte ptr [esp+24h+arg_4]
text:679FE566 mov byte ptr [esp+24h+arg_C], bl
text:679FE56A mov bl, dl
text:679FE56C shr bl, 4
text:679FE56F shl dl, 2
text:679FE572 or dl, bl
text:679FE574
text:679FE574 loc_679FE574: ; CODE XREF: sub_679FE420+128#j
text:679FE574 xor ebx, ebx
text:679FE576 mov bh, cl
text:679FE578 movzx ecx, dl
text:679FE57B add esi, 4
text:679FE57E mov bl, byte ptr [esp+24h+arg_C]
text:679FE582 shl ebx, 8
text:679FE585 or ebx, ecx ;RGB adjustment end
text:679FE587 mov ecx, [esp+24h+arg_8]
text:679FE58B mov [esi-4], ebx ; OVERFLOW
text:679FE58E inc word ptr [edi]
text:679FE591 dec ecx ; Copycount --
text:679FE592 mov [esp+24h+arg_8], ecx
text:679FE596 jnz short loc_679FE530
text:679FE598 mov ebx, [esp+24h+var_C]
text:679FE59C
text:679FE59C loc_679FE59C: ; CODE XREF:
sub_679FE420:loc_679FE521#j
text:679FE59C dec [esp+24h+var_10]
So, the flaw is that QuickTime allocates 0x100*sizeof(DWORD) in order to
copy just one palette. However, the parameters are directly copied from
FLC/FLI/CEL file without validate them. Thus, we can overwrite a large
amount of heap memory using controlled DWORD values. The total amount of
heap memory we could overwrite, is the result of the following formula:
Max = MaxNumberofSubChunks * ( sizeof(DWORD) * sizeof(PALETTE) )
Max = FFFFh * (4* 100h);
Max = 0x3FFFC00; a lot...
In addition, we could overwrite just certain blocks on the heap, thus
controlling the memory corrupted. How? Using the byte Skip field
,remember:
text:679FE50D lea esi, [esi+edx*4] ; skip the bytes +align
The amount of bytes overwritten each time also could be controlled using
CopyCount Field
The asm code previously explained would appear in C as follows:
[...]
ptr_heap=(LPVOID)malloc(0x100*sizeof(DWORD)); // chungootronics from the
outer space
[...]
for (i = 0; i < subchunks; i++) {
if(buf[stream++] != 0) ptr_heap += buf[stream]; // colors to skip
(distance )
CopyCount = buf[stream++]; // entries to change
if (CopyCount == 0) Copycount = 0x100; //(entire palette)
for (j = 0; j < CopyCount; j++)
{
..HEAP OVERFLOW
};
}
ADDITIONAL INFORMATION
The information has been provided by <mailto:advisories@xxxxxxxxxxxxxxx>
Reversemode.
The original article can be found at:
<http://www.reversemode.com/index.php?option=com_remository&Itemid=2&func=fileinfo&id=25> http://www.reversemode.com/index.php?option=com_remository&Itemid=2&func=fileinfo&id=25
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@xxxxxxxxxxxxxx
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@xxxxxxxxxxxxxx
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Prev by Date: [UNIX] ReviewPost File Inclusion (RP_PATH)
- Next by Date: [UNIX] Mailman Multiple Security Issues
- Previous by thread: [UNIX] ReviewPost File Inclusion (RP_PATH)
- Next by thread: [UNIX] Mailman Multiple Security Issues
- Index(es):
Relevant Pages
- [UNIX] RealNetworks RealPlayer and Helix Player Invalid Chunk Size Heap Overflow
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... RealNetworks RealPlayer
and Helix Player Invalid Chunk Size Heap Overflow ... The vulnerability specifically
exists in the handling of the 'chunked' ... (Securiteam) - Re: Heap fragmentation (2nd attempt)
... heap fragmentation depends on the malloc package much ... C> is the source
code to your own malloc package. ... a new memory location from the OS. ...
Why is free Oisn't it just simply adding the freed chunk at the end ... (comp.arch.embedded) - Re: Why are variables stored on the stack?
... the stack than the heap is spurious - if I recall, ... A stack is Oto
allocate a chunk, ... (comp.lang.c) - classes, pointers, vectors, and memory allocation
... ptr1 and ptr2 will be dynamically allocated in the heap, ... does A's memory
get enlarged as a whole chunk? ... is not enough space for the whole chunk, will A get
copied into another ... (comp.lang.cpp) - Re: GC in Jons raytracing benchmark
... Because if it does, then my limited-latency calculations, which depended on malloc
and free taking time logarithmic to the number of items on the heap, are out the window and I
need to redesign. ... data of the chunk you're freeing, probably coalesces it with the
two neighboring chunks into one bigger chunk, puts it on the right free-list or whatever and then returns.
... (comp.lang.lisp)