Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
● Rompiendo en Equipo
● Última Edición:15-03-2019
Comenzamos con un crackme hecho en C++, el cual hemos colocado Themida Versión demo 2.4., un
crackme que ya pasamos en la lista.
Para el desarrollo de este escrito se hará uso del debugger x64dbg, así como el uso de analizadores como
die, exeinfope, protection id, rdg packer detector
Herramientas
Frase
"Dicen que el tiempo lo cambia todo, pero en realidad eres tú quien debe cambiar las cosas"
— Andy Warhol
Analizando un protegido de Themida/Oreans
Analizando el Ejecutable
Los analizadores refieren
-=[ ProtectionID v0.6.9.0 DECEMBER]=-
(c) 2003-2017 CDKiLLER & TippeX
Build 24/12/17-21:05:42
Ready...
Scanning -> C:\Users\PC\Desktop\crackme-themida.exe
File Compression State : 0 (Not Compressed)
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 1684992 (019B600h) Byte(s) | Machine: 0x14C (I386)
Compilation TimeStamp : 0x43134F64 -> Mon 29th Aug 2005 18:09:40 (GMT)
[TimeStamp] 0x43134F64 -> Mon 29th Aug 2005 18:09:40 (GMT) | PE Header | - | Offset: 0x00000088 | VA: 0x00400088 | -
[File Heuristics] -> Flag #1 : 00000000000001001100000000110011 (0x0004C033)
[Entrypoint Section Entropy] : 4.43 (section #5) "snvbmblc" | Size : 0x200 (512) byte(s)
[DllCharacteristics] -> Flag : (0x0000) -> NONE
[SectionCount] 6 (0x6) | ImageSize 0x433000 (4403200) byte(s)
[ModuleReport] [IAT] Modules -> kernel32.dll | comctl32.dll
[!] Themida/Winlicense detected !
- Scan Took : 0.94 Second(s) [00000005Eh (94) tick(s)] [88 of 580 scan(s) done]
Analizando un protegido de Themida/Oreans
¿Corre en el debugger?
Al abrir el crackme con el debugger no se evidencia TLS (thread local storage),
El Entry Point (EP) carga dentro del debugger sin problema:
<Rutina 1>
esta rutina lo que hace es modificar el int en 832008 para cuando esté en EIP: 83201c
Antes Despues
puede parecer simple, pero para este proceso usa xor, suma y encode/decode según los valores.
Analizando un protegido de Themida/Oreans
cmp byte cc es característico de verificar bp pero aquí ha convertido de int3 en add , en el lugar que apunta es
hacia un salto
<Rutina 2>
irá a la direccion en 832043 (RET)
el que me mostrará el entrypoint característico de los themida/winlicense
las instrucciones fld en ollydbg apuntan a cerrar la ventana, el cual x64dbg no posee este error
si seguimos avanzando con f7 en la rutina 3, tenemos una estructura pushad/popad para comparar un byte
vamos de a poco viendo como descomprime entre pushad y popad y verifica pequeñas estructuras de pe
luego de descomprimir
lo corremos con F9 y salta una excepcion (es una instrucción privilegiada), si, la que encontramos hace no
mucho
, asi que obviamente va a tomar control con un custom SEH pero no le vamos a dar bola aun
corre un toque más y salta la ventanita de “Is debugger” detected” (cracker detected)
Anti Debugging
Si ponemos un breakpoint en CreateFileA y CreateFileW con la esperanza de caer cuando trate de localizar
files del sistema, el themida se nos pone loquito y se queda en un bucle muy loco triggereando excepciones
la vamos a hacer más fácil y en vez de usar las de alto nivel, nos vamos a ir low-level , colocando breakpoint
en ZwCreateFile que es la última función que ejecutará antes de entrar en ring0 y como la version que
tenemos no tiene módulos en ring0 sabemos que por ahi va a tener que pasar puede emular las apis, pero las
de bajo nivel las va a tener que usar para hacer la magia borramos los breakpoint de CreateFileW/A y
seteamos uno en ZwCreateFile, pasa la excepción del principio y ya hittea
Aca para ver el nombre del file que se esta queriendo accesar no es tan fácil como en CreateFile, tenemos
que ir al tercer argumento que es el puntero a la estructura ObjectAttributes
ya arranca mirando si encuentra a nuestro viejo y querido SOFTICE, por diossssss estamos en 2018
ahora que sabemos como ver los filenames que trata de abrir el themida vamos a loguear eso. La segunda
ejecución usa hasta las mismas direcciones
Si miramos el call stack podemos notar como el módulo principal llama directamente a funciones de ntdll
Follow DWORD in Disassembler a esa dirección y caemos en la zona donde chequea si esta softice (a alguno
le tocará tracear esto)
Analizando un protegido de Themida/Oreans
las direcciones están offseteadas desde la primer instrucción en .text para orientarnos fácilmente
volviendo al traceo de files, vemos que sigue con la exception:
LISTO, comienza abriendo dlls, clavado que va a copiar todo a memoria y emular las apis
después de esto ya tenemos ventana, así que debe usar funciones de ntdll para chequear anti debugging
Analizando un protegido de Themida/Oreans
Emulación de dlls
Ya vimos que abre para algo ntdll, vamos a investigar qué hace con eso, parados en el ZwCreateFile cuando
se lo hace a ntdll, vamos a hacer ejecutar hasta el RET con el último botoncito
eso hace que nos guarde el handle en el puntero que se le pasó como primer argumento
0x20 es la cantidad de bytes a requestear y el buffer donde deja todo es en 0060928d, aca me hizo dudar un
poco porque los bytes no arrancaron con MZ, por si las dudas chequee en la pestaña handles que no le
erremos
En el Entry Point, las primeras instrucciones solo quiere obtener la dirección de EIP
el call 832009 apunta a dos instrucciones adelante, después con el “pop eax” deja en EAX la dirección del int3
ya con EIP en EAX, lo storea en EBX y usa EAX para sumarle un offset y quedar apuntando al principio de la
zona .text
y si a EIP (storeado en EAX y EBX) le restamos este valor, queda apuntando al principio de .text
antes chequea que el int3 debajo del call siga ahi, “AUN NO SE PARA QUE”
uint32
decodear(DWORD *address, uint32 size_in_bytes, DWORD xor_key, DWORD
valor_a_sumar) {
unsigned int i = size_in_bytes;
while( i != 0) {
address[i/4] = address[i/4] ^ xor_key + valor_a_sumar;
i--;
}
return address;
}
mas/menos es asi, lo que hay que entender es que xorea y suma la zona encodeada de a DWORDS
obviamente la zona encodeada ya viene en el binario, con lo cual podríamos poner lo que queremos en esas
zonas, y controlar lo desencodeado porque una suma y un xor son completamente reversibles
lo que vamos a hacer es invertir el salto, obviamente no va a andar bien el ejecutable, pero es una PoC para
ver como se parchea eso
Analizando un protegido de Themida/Oreans
cuando decodifica:
si nosotros queremos poner un JMP fijo ahí, tenemos que cambiar el 0x75 por 0xEB
cambiando el 0x63 por 0xd5 hacemos que se desencodee bien, cambiamos y parcheamos
Analizando un protegido de Themida/Oreans
ahora lo cargamos y corremos hasta el desencoder, lo corremos con F8 y caemos en la siguiente zona
lo unico que hace es recibir el return address para retornar a la zona des-encodeada
esto nos va a venir bien a la hora de parchear cosas que complican el trabajo, como las instrucciones rdtsc
Analizando un protegido de Themida/Oreans
Conclusiones:
Es un packer con muchas opciones y capas, lo que hace que se pierda mucho tiempo, tiene opciones de
encontrar oep, iat,tiene puntos estratégicos para reparar la iat , reparar entradas a puntos de máquina virtual ,
genera un tamaño llamativo, posee crc, múltiples thread, detección de muchas opciones haciendo que las
opciones que ofrece sean cumplidas, sin duda requiere al menos de una semana o bien mucho tiempo libre
para analizar este tipo de aplicaciones.
Palabras Finales:
No hay mal que por Bien no venga, de seguro alguien con tiempo puede fácilmente modificarlo si logra vencer
el crc, asi que desde ahi, podemos decir que la máquina virtual es lo más fuerte que posee aun.
Saludos cordiales
Equipo analizador de Themida 2.x