Random IRC quote :      <pancake> hace falta una pagina en la hackstory de 48bits llena de penes

Debuggeando código JITeado de ActionScript

Luego de leer el paper presentado por Dionysus Blazakis en Black Hat DC 2010, me dieron ganas de ver un poco de que trata el rollo, pues sin tener conocimientos de como funciona ActionScript, nos la rebuscamos para debuggear con el Ollydbg el código JITeado de un ActionScript.


Herramientas a utilizar:

Ollydbg
IDA
Java JRE ( el compilador del redtamarin es un jar )
redtamarin ( http://code.google.com/p/redtamarin )
Alchemy ( http://labs.adobe.com/downloads/alchemy.html )
Process explorer o task manager 🙂

En su blog hace tiempo escribió una entrada llamada “Getting Pointers from Leaky Interpreters», en la que explica como armando diccionarios de hash tables, se puede obtener un puntero hacia nuestro código.

En ese post, el mostró un ejemplo hecho en actionscript que en ese momento no supo como compilarlo como SWF, pero menciono que compilador estaba utilizando a la hora de sus pruebas.
Nuestro objetivo sera crear un SWF con un texto al estilo “Hola mundo”, y algunos XORs asi probamos que tan bien nos va identificando el código.

Primer paso: Herramientas.

Para poder generar nuestro swf a partir de un archivo .as ( actionscript ), necesitaremos descargar el redtamarin y el Alchemy.
El redtamarin es el compilador ( asc.jar ) que utilizaremos para nuestro actionscript, el Alchemynos dara la lib playerglobal.abc.
Copiaremos este ultimo file dentro del folder del tamarin como primer paso.

Segundo paso: example.as

package {

import flash.display.*;
import flash.text.*;

public class example extends Sprite {
public function example() {
var text = new TextField();
text.width = 400;
text.x = 0;
text.y = 0;
text.text = ‘looking for help’;
addChild(text);
}
}
}

Creo que no hace falta describir que hace esto xD

Tercer paso: Hacer nuestro swf !

Para generar un swf a partir de nuestro example.as iremos al cmd y ejecutaremos el asc.jar de la siguiente manera:

java -jar asc.jar -swf example,400,400 -import builtin.abc -import playerglobal.abc example.as

Lo único a comentar aquí es que el parámetro swf tiene como parámetros: classname,width,height.

El resultado de la ejecución en nuestro caso es: example.swf, 645 bytes written

Para ver nuestro swf podemos simplemente volcarlo dentro de nuestro navegador, o hacer algún simple html que lo cargue:

<object width="550" height="400">
<param name="movie" value="example.swf">
<embed src="example.swf" width="550" height="400">
</embed>
</object>

Vemos que va bien.. ahora le agregamos un simple while(true) para que podamos usarlo para encontrar el código JITeado.

package {

import flash.display.*;
import flash.text.*;

public class example extends Sprite {
public function example() {
var text = new TextField();
text.width = 400;
text.x = 0;
text.y = 0;
text.text = ‘looking for help’;
addChild(text);
while(true);
var a = (0xAAAAAAAA ^ 0xBBBBBBBB ^ 0xCCCCCCCC ^ 0xDDDDDDDD );
}
}
}

Aprovechamos y también le agregamos algunos valores para que los xoree, y de paso ver si lo podemos identificar en el debugger mientras vamos traceando. 🙂

Cuarto paso: Debuggear el codigo JITeado.

Abrimos nuestro html, y antes de cargar el swf nos pide permiso para ejecutarlo, aquí nos attacheareamos con el Olly al IE8 en nuestro caso y veremos mínimo dos procesos del iexplore.exe corriendo, vamos a attacheanos al que tiene como window name Sysfader.

El taskmanager o el process explorer lo dejaremos minimizado al tray asi podemos estimar que cuando entramos al loop infinito en nuestro código JITeado.

Le daremos Run al Olly, parara algunas veces en memory breakpoints en el flash10b pero nosotros seguiremos hasta que no tire excepciones y el cpu este como mencionamos anteriormente trabajando de manera constante al 100% ( en caso de que sea single core ), en este momento pausamos el proceso.

Iremos a la ventana de Threads, y buscaremos el nuestro que estará en el heap, ya que la mayoría van a estar parados en la ntdll sera sencillo encontrar el único thread diferente.

Aquí pueden pasar dos cosas: la primera es que no estemos en el loop infinito, entonces empezaremos de 0 nuevamente, o bien puede ocurrir que encontremos el thread parado en el heap como en este caso:

Ahora veamos el codigo algo mas completo:

<span style="font-size: x-small;">019C01E1 MOV EAX,DWORD PTR DS:[25EB0D8]
019C01E7 TEST EAX,EAX
019C01E9 JNZ 019C025F
019C01EF MOV EAX,1
019C01F4 TEST EAX,EAX
019C01F6 JNZ 019C01E1
019C01FC PREFIX REPNE:
019C01FD MOVUPS XMM0,DQWORD PTR DS:[25815E0]
019C0204 PREFIX REPNE:
019C0205 MOVUPS XMM1,DQWORD PTR DS:[25815E8]
019C020C PREFIX REPNE:
019C020D MOVUPS DQWORD PTR SS:[EBP-2C],XMM1
019C0211 PREFIX REPNE:
019C0212 MOVUPS DQWORD PTR SS:[ESP-8],XMM0
019C0217 SUB ESP,8
019C021A CALL Flash10d.101F1C30
019C021F ADD ESP,8
019C0222 MOV EBX,EAX
019C0224 PUSH DWORD PTR SS:[EBP-28]
019C0227 PUSH DWORD PTR SS:[EBP-2C]
019C022A CALL Flash10d.101F1C30
019C022F ADD ESP,8
<strong>019C0232 XOR EBX,EAX</strong>
019C0234 PREFIX REPNE:
019C0235 MOVUPS XMM0,DQWORD PTR DS:[25815F0]
019C023C PREFIX REPNE:
019C023D MOVUPS DQWORD PTR SS:[ESP-8],XMM0
019C0242 SUB ESP,8
019C0245 CALL Flash10d.101F1C30
019C024A ADD ESP,8<strong>
019C024D XOR EBX,EAX
019C024F XOR EBX,DDDDDDDD</strong><strong> ; It looks familiar right ? 🙂
019C0255 MOV EAX,4
019C025A JMP 019C0267
019C025F MOV ECX,DWORD PTR SS:[EBP+8]
019C0262 CALL Flash10d.1020E410</span>

Quinto paso: Automatizando con un script

Hay varios caminos para tomar a la hora de llegar a donde empieza realmente nuestro código JITeado, adjunto un simple ODbgScript que mediante hardware breakpoints en VirtualProtect nos guiara hacia la presa 😉
Ejecutarlo una vez que tira la primer excepción como explicamos mas arriba en el posteo.

; Get_my_JITed_AS.osc by sick

var cont
var address
var VirtualProtect

mov cont, 0
gpa "VirtualProtect", "kernel32.dll"
mov VirtualProtect, $RESULT
bphws VirtualProtect, "x"

gogo:
erun

cooking:
eob SALCHICHACONPURE

SALCHICHACONPURE:
cmp eip, VirtualProtect
je vptect
cmp eip, address
je isdone
jmp gogo

vptect:
cmp [esp+8], 100
jb gogo
mov address, [esp+4]
bphws address, "x"
jmp gogo

isdone:
inc cont
cmp cont, 1
mov address2, address
je gogo

add address, 60
bphws address, "x"
cmp cont, 2
je gogo

De aquí en mas pueden agregarle código a su Actionscript y seguir jugando 😉

Se agradece a Acid y Gera que colaboraron con el debugging del engine de Flash.

2 Comentarios para “Debuggeando código JITeado de ActionScript”

  1. NCR
    Comment por NCR | 02/16/10 at 9:55 am

    Estas hecho todo un hacker!!!

  2. Comment por Paglo Rago | 02/16/10 at 11:32 pm

    Carlos Calvo rulz

Se han cerrado los comentarios