Exploitation of CVE-2009-1869

During the research of the Flash vulnerability I’ve managed to create a functional PoC.

The process of the exploit is the following:

  1. Spray the heap in order to achieve the following:
    1. The aforementioned path conditions would pass.
    2. A DWORD memory overwrite with user controlled target and value would take place when the vulnerability is triggered.
    3. Allocate a placeholder for the shellcode. The target of the memory overwrite would be some function pointer, the value would be the location of the shellcode’s placeholder.
  2. Trigger the vulnerability.
  3. Free the placeholder of the shellcode.
  4. Allocate the shellcode by spraying the heap.
  5. Trigger some function which calls the function pointer.

The reason that there are 2 passes for allocating the shellcode is the fact that after the arbitrary overwrite occurs, some random chunks are also written to the location of the shellcode, hence the block has to be freed and re-allocated.

The exploit contains the following components:

  1. Exploit.fla/as – main code
  2. HeapLib.as – ActionScript3 Heap Spraying library
    The Heap Spraying library bypasses the ActionScript’s maximum execution time limitation by using a Timer that allocates small chunks at each iteration.
    It provides two basics functions:
    1) alloc(value, size)
    2) free()
  3. TriggerVuln.swf -  malformed SWF which triggers the vulnerability (i.e: intf_count=0)
  4. TriggerFunc.fla – ActionScript2 code which triggers a call to the function pointer by invoking LoadVars.sendAndLoad
  5. Exploit.htm – HTML wrapper for the Exploit.as

The exploit has been tested against Windows XP SP3 with IE7. Flash is assumed to be loaded at VA 0x10000000. However, since the vulnerable code is wrapped by a permissive SEH handler, brute-force is possible (not covered by the PoC).

The binaries and source code of the PoC can be found here.

Advisory: Adobe Flash Player and AIR AVM2 intf_count Integer Overflow


Background

ActionScript code is compiled into ActionScript Byte Code segments, loaded by AVM2 (ActionScript Virtual Machine 2).
These segments are described by the abcFile structure:

        abcFile
        {
            u16 minor_version
            u16 major_version
            cpool_info constant_pool
            u30 method_count
            method_info method[method_count]
            u30 metadata_count
            metadata_info metadata[metadata_count]
            u30 class_count
            instance_info instance[class_count]
            class_info class[class_count]
            u30 script_count
            script_info script[script_count]
            u30 method_body_count
            method_body_info method_body[method_body_count]
        }

The value of class_count element is the number of entries in the instance and class arrays. Each instance entry is a variable length instance_info structure which specifies the characteristics of object instances created by a particular class:

        instance_info
        {
            u30 name
            u30 super_name
            u8 flags
            u30 protectedNs
            u30 intrf_count
            u30 interface[intrf_count]
            u30 iinit
            u30 trait_count
            traits_info trait[trait_count]
        }

The value of the intrf_count field is the number of entries in the interface array. The interface array contains indices into the multiname array of the constant pool; the referenced names specify the interfaces implemented by this class.

Vulnerability

An integer overflow exists in the AVM2 abcFile parser code which handles the intrf_count value of the instance_info structure.

When intrf_count is larger than 0x10000000, it is nullified due to an integer overflow. This results in an out of bounds pointer dereference. The out of bounds object contains arbitrary values (in the context of the code which handles the interfaces count element) which are manipulated in a way so that an arbitrary memory overwrite with an attacker supplied destination and value is possible.

The following is a detailed run trace which explains the vulnerability. Irrelevant instructions are omitted. Flash10b.ocx is assumed to be loaded at VA 10000000h.

    let <intrf_count> be 0x10000000

.text:10206B03  mov  edi, [esp+50h+var_2C]
; EDI=<intrf_count>=0x10000000
.text:10206B14  lea  edx, [edi+edi]
; EDX=<intrf_count*2>=0x20000000, m
ay not overflow (verified elsewhere) 
.text:10206B1B  call  sub_101EAC30 
.text:101EAC45  call  sub_101EAB90
 
.text:101EAB98  call  sub_101D1FF0
; this method calculates the nearest power of 2 for <intrf_count*2>  (i.e: stays 0x20000000) 
.text:101EABA0  add  eax, eax
; doubles that value (i.e: EAX=0x40000000) 
.text:101EABCC  lea  ecx, ds:0[eax*4]
; multiplies it by 4 (i.e: ECX=0x00000000) =>OVERFLOW<=
.text:101EABDA  call  sub_10224C62 
.text:10224C62  jmp   sub_10224363 
.text:10224363  mov   edx, [esp+arg_0]
; arg_0 is the overflown value (i.e: EDX=00000000)
.text:10224367  lea     eax, [edx+7]
.text:10224376  and     eax, 0FFFFFFF8h
; EAX=00000000            
.text:1022437A  mov     esi, eax        ; ESI=00000000 
.text:102243A4  mov     ecx, esi        ; ECX=00000000 
.text:102243A9  mov     eax, [eax+ecx*4-4]
; the overflown value is used as an index into pointer table, starting at EAX.
; since we can cause ECX to become 0x0000000, we may select an out of bounds
; pointer (eax-4). Tests show that it always contains a valid pointer to some
; object, with arbitrary values. i.e: EAX=&OutOfBoundsObject
.text:102243AD  mov     ecx, eax        ; ECX=&OutOfBoundsObject 
.text:102243C8  call    sub_10226D4D
.text:10226D53  mov     ebx, ecx 
      ; EBX=&OutOfBoundsObject
.text:10226D6C  mov     esi, [ebx+8]   
; ESI=&ArbitraryObjectA (usually: 0x55555555)
.text:10226D76  test    byte ptr [esi+2Ah], 1
; <PathConditionA >- must pass this in order to continue
.text:10226D7A  jz      short loc_10226DA5
.text:10226D7C  mov     eax, [ebx+38h]
; EAX=&ArbitraryObjectB, (usually 0x55555557) 
.text:10226D7F  cmp     byte ptr [eax+33Ch], 0
; <PathConditionB> - must pass this in order to continue
.text:10226D86  mov     ecx, ebx ; ECX=&OutOfBoundsObject
.text:10226D88  jnz     short loc_10226D9D
.text:10226D8A  push    esi
.text:10226D8B  call    sub_10226CAF

.text:10226CB0  mov     esi, [esp+4+arg_0]
; ESI=&ArbitraryObjectA, (usually 0x55555555)
.text:10226CB5  push    esi
.text:10226CB6  mov     edi, ecx ; EDI=&OutOfBoundsObject
.text:10226CB8  call    sub_102266CA
.text:102266CA  mov     eax, [esp+arg_0]
; EAX=ESI=&ArbitraryObjectA (usually 0x55555555)
.text:102266DB  mov     ecx, [eax+1Ch]
; ECX=arbitrary value  - usually *(0x55555571)
.text:102266CE  mov     edx, [eax+20h]
; EDX=arbitrary value  - usually *(0x55555575)
.text:102266DE  mov     [ecx+20h], edx;
; jackpot - a write of an arbitrary DWORD to an arbitrary VA

 

The following is an illustration of the pointer table and the out of bounds pointer which may be dereferenced:

    addr      val
    0017487C  00E82000 <- EAX-4 (ECX=0)
    00174880  001681C8 <- EAX   (ECX=1)
    00174884  00174AC8
    00174888  00174BD0
    0017488C  00174CD8
    00174890  00174DE0
    00174894  00174EE8
    00174898  00174FF0
    0017489C  001750F8
    001748A0  00175200
    001748A4  00175308
    001748A8  00175410
    001748AC  00175518
    001748B0  00175620
    001748B4  00175728
    001748B8  00175830
    001748BC  00175938
    001748C0  00175A40
    001748C4  00175B48
    001748C8  00175C50
    001748CC  00175D58

    The following is a memory dump of the out of bounds object:

    00E82000  44 51 55 55 55 45 55 75 55 55 55 55 55 55 55 55  
    00E82010  55 55 55 55 55 55 55 54 55 55 55 55 01 00 00 00  
    00E82020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50  
    00E82030  55 55 55 55 D5 55 55 55 57 55 55 55 55 55 55 55  
    00E82040  D5 5A 55 55 54 55 55 55 55 55 55 55 75 B5 56 55  
    00E82050  55 55 55 55 15 55 55 D5 55 55 AD 55 77 D5 55 55  
    00E82060  55 55 55 55 D5 D5 BA 56 55 55 55 55 55 55 6B 55  
    00E82070  B5 56 55 55 57 55 55 01 00 00 00 00 00 00 00 00  
    00E82080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
    00E82090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
    00E820A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
    00E820B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
    00E820C0  00 00 00 00 00 00 00 00 00 00                   

    To make things more clear:

    Let 'ArbitraryObjectA' be pointed by (&OutOfBoundsObject+0x8)
    Let 'ArbitraryObjectB' be pointed by (&OutOfBoundsObject+0x38)

    In order to reach the arbitrary overwrite, there are three conditions

    1)  intrf_count >= 0x10000000 // in order to overflow
    2)  PathConditionA: ((char *)ArbitraryObjectA)[0x2e]  == 1  //  .text:10226D76
    3)  PathConditionB: ((char *)ArbitraryObjectB)[0x33c] == 0  //  .text:10226D7F

    Given the conditions are passed, a memory DWORD overwrite of arbitrary target and value occurs:

    *(DWORD *)((*(DWORD *)(ArbitraryObjectA+0x1c))+0x20) = *(DWORD *)(ArbitraryObjectA+0x20)


Exploitation

Since the out of bounds object contains arbitrary values, the attacker may spray the heap so he/she would have control over ArbitraryObjectA and ArbitraryObjectB (they would be located at addresses which contain data controlled by the attacker). This may allow him/her to pass all aforementioned conditions and also control the value which is written  in the arbitrary memory MOV and the target of it. Achieving this may allow him the execute arbitrary code.

During the research of this vulnerability I’ve managed to create a functional exploit (demo: http://www.youtube.com/watch?v=wJb6a-J3i4c).

It should also be denoted that the vulnerable code is wrapped by an SEH handler which doesn't crash the application on Access Violation. This means that the exploitation process may try different base addresses and offsets in case of a failure.

Attack vector

Lure the victim to open a malicious SWF file

Impact

Remote Code Execution

Test Environment

  1. Adobe Flash Player 10.0.22.87
  2. Windows XP SP3.

Identifiers

1. CVE-ID: CVE-2009-1869
2. BID: 35907

Remediation

New versions of Adobe Flash Player (10.0.32.18) and AIR (1.5.2) have been released in order to address this vulnerability.

References

  1. "ActionScript Virtual Machine 2 (AVM2) Overview", Adobe Systems, Inc.
  2. Adobe’s advisory

Adobe Flash Player Integer Overflow Remote Code Execution

Adobe has just released a new version of Flash Player (10.0.32.18).

This update addresses a Remote Code Execution vulnerability (CVE-2009-1869) I reported to Adobe a month ago.

I would like to thank Adobe for the efficient way in which they handled this security issue.

A full advisory will be posted on Sunday. In the meanwhile, I’ve uploaded a video which demonstrates a successful exploitation of this vulnerability:

Apple QuickTime Image Description Atom Sign Extension Memory Corruption

Apple has just released a new version of QuickTime. This version includes a fix to a vulnerability I reported to them back in March.

I would like to thank Apple for the efficient way in which they handled this security issue.

The following is the advisory.

INTRODUCTION
According to QuickTime's specification, The sample description atom (STSD) stores information that allows QuickTime to decode samples in the media.

It has the following structure:

 0  DWORD   Size
4 DWORD Type
8 BYTE Version
9 BYTE[3] FLAGS
12 DWORD Number of entries
16 DWORD Sample description table


The structure of each entry in the sample description table varies by the media type, however the first four fields are the same for all media types:


 0  DWORD   Sample description size
4 DWORD Data format
6 BYTE[6] Reserved
12 WORD Data reference index

These four fields may be followed by additional data specific to the media type and data format.
For video media, the general sample description format is extended by the following structure:



14 WORD     Version
16 WORD Revision level
18 DWORD Vendor
22 DWORD Temporal quality
26 DWORD Spatial quality
30 WORD Width
32 WORD Height
34 DWORD Horizontal resolution
38 DWORD Vertical resolution
42 DWORD Data size
46 WORD Frame count
48 BYTE[32] Compressor name
80 WORD Depth
82 WORD Color table ID

VULNERABILITY DETAILS
When the data format field (offset 4 of the sample description table extension) is 'RPZA' (Apple Video), it is possible to trigger a sign extension vulnerability which leads to a buffer underflow.

The following is the faulty sign extended MOV: 

   MOVSX ECX,WORD PTR SS:[ESP+4C]


[ESP+4C] contains a user controlled input, which is equal to
"((width+(4-width%4))*4 & 0xFFFF" where 'width' is taken from the RPZA sample description entry (offset 30).

If width >= 0x5FFD, then [ESP+4C] >= 0x8000.
Sign-extending such values results in very large unsigned values, as their most significant word becomes 0xFFFF (so 0x8000 is sign-extended to 0xFFFF8000).


Deeper in the code, the user controllable sign-extended value is treated as the size of a structure.

A vector of this structure is walked over:


[1] At each iteration the base pointer is incremented by the user's controlled sign-extended value. This means that it is possible to force the pointer to reference memory regions below the vector's VA:


   ADD EAX,EDX ; EAX = vector, EDX = sign extended value

[2] At each iteration values are written to an element in the vector (a single structure) which is referenced by the incremented pointer. This means that it is possible to write to memory regions below the buffer's VA.


   MOV DWORD PTR DS:[EAX],EBX
MOV DWORD PTR DS:[EAX+4],EBX
MOV DWORD PTR DS:[EAX+4],EBX
MOV DWORD PTR DS:[EAX],EBX



IMPACT
By writing to memory regions below the buffer's VA, An attacker may overwrite crucial data such as function pointers, flags, heap structures and so forth. Doing so may allow an attacker
to alter the normal control flow of the application and execute arbitrary code.
A simple attack vector would be to lure the victim to browse to a web site controlled by the attacker, which serves a malicious QuickTime file that exploits this vulnerability.

TEST ENVIRONMENT
Windows XP Service Pack 3
QuickTime 7.6 (472)

REMEDIATION
A new version of QuickTime (7.6.2) has been released in order to address this issue.


IDENTIFIERS
1. CVE-ID: CVE-2009-0955
2. BID: 35166


REFERENCES
1. Apple's advisory, Apple Inc.
2. QuickTime File Format Specification, Apple Inc.
3. Apple QuickTime Image Description Atom Sign Extension Vulnerability, SecurityFocus 
4. QuickTime patched

Adobe Flash Player Update

Adobe just released a patch to a vulnerability I had reported to them.

The issue is due to a lack of input validation which allows a specially crafted SWF file to cause Flash Player to perform an arbitrary memory read.

Exploiting the issue results in DoS (i.e crashes the browser). Further analysis might show it may lead to arbitrary code execution as well.

More details about it can be found in Adobe's security bulletin (CVE-2009-0519).

I would like to thank Adobe for the efficient way in which they handled this security issue.

This update contains fixes to other vulnerabilities as well, so go update :)

Graphviz Buffer Overflow Code Execution

Graphviz just released a patch to a critical security issue I reported to them.

The following is the advisory:

Background
Graphviz is an open-source multi-platform graph visualization software. It takes a description of graphs in a simple text format (DOT language), and makes diagrams out of it in several useful formats (including SVG).

Description
A vulnerability exists in Graphviz's parsing engine which makes it possible to overflow a globally allocated array and corrupt memory by doing so.

parser.y (Graphviz 2.20.2):

34:  static Agraph_t        *Gstack[32];
35:  static int            GSP;
45:  static void push_subg(Agraph_t *g)
46:  {
47:       G = Gstack[GSP++] = g;
48:  }

As it can be seen, no bounds check is performed by the push_subg procedure, allowing one to overflow Gstack by pushing more than 32 (Agraph_t *) elements.

Impact/Severity
A malicious user can achieve an arbitrary code execution by creating a specially crafted DOT file and convince the victim to render it using Graphviz.

Below is a screenshot of a successful exploitation. When the  malicious DOT file is rendered, a shellcode which calls the MessageBoxA API is executed:

image

Affected versions
Graphviz 2.20.2 is affected by this vulnerability. Older versions are probably affected as well.

Workaround
Version 2.20.3 has been released in order to address this issue. A bounds check has been added in order to avoid an overflow.

parser.y (Graphviz 2.20.3):

34:  #define GSTACK_SIZE 64
35:  static Agraph_t      *Gstack[GSTACK_SIZE];
36:  static int            GSP;
45:
46:  static void push_subg(Agraph_t *g)
47:  {
48:      if (GSP >= GSTACK_SIZE) {
49:          agerr (AGERR, "Gstack overflow in graph parser\n"); exit(1);
50:      }
51:      G = Gstack[GSP++] = g;
52:  }

Acknowledgements
I would like to thank the Graphviz team (Stephen C. North, John Ellson, Emden R. Gansner and others) for their quick responses and fix (it took them only a day since my disclosure to release a patch!).

Untrusted Gateways - Open wireless networks

One should always ask himself if the wireless gateway he uses is trustworthy.

Depict yourself the following situation:

You are sitting in a coffee shop, seeking for wireless networks. what are you gonna do next? connect to a network which SSID's is similar to the coffee shop's name, or if none exists, connect to the first open network you find.

If the coffee shop doesn't have a wireless network, it gives a malicious user an opportunity to run his own network, on behalf of the coffee shop to attract clients. Otherwise, he will have to spoof the legitimate access-point's MAC, and race for new clients.

Everyone knows that open wireless networks are prone to sniffing, but most people are unaware of the fact that active attacks could take place as well, and it is especially easy if the malicious user controls the gateway.

This video demonstrates how an exe file is injected transparently into an innocent HTTP session.

What happens behind the scenes is the use of a transparent proxy I built, which terminates HTTP traffic, and searches for exe download patterns (Content-Type:\s+application/octet-stream to be exact). When it matches an exe pattern, it replaces the response with a malicious binary. The proxy runs on the gateway, which is fixed with an iptables rule (iptables -t nat -A PREROUTING -i [interface] -p tcp --dport 80 -j REDIRECT --to-ports [proxy interface]) that forwards all transit HTTP via the proxy.

By the use of PKI you can ensure you pass your malicious gateway without data mutation.
So consider yourself one of the following countermeasures:

1) Download binaries from SSL sites only (and verify the certificate!)
2) Use an SSL proxy (and again verify the certificate)
3) Tunnel traffic through a VPN
4) Tunnel traffic through SSH
5) Download signed binaries, and verify the digital signature.