Hacking The 3ds III: Análisis de memoria
Introduccción
Bienvenidos de nuevo. Finalmente, es hora de continuar hackeando la Nintendo 3DS. Anteriormente tratamos volcados de memoria donde pudimos encontrar cadenas de texto y otros contenidos, confirmando que los datos no estaban cifrados.
Identificando el código
A pesar de haber utilizado binvis y haber podido observar diferencias claras entre datos y código, no fue una herramienta suficientemente precisa para continuar. Antes de hacer nada más, intenté jugar todas mis bazas y analizar los volcados con cualquier programa que fuese posible. Concretamente, antes de probar ninguna herramienta de consola, quiero mencionar el programa Veles, una herramienta de código libre y multiplataforma para análisis visual. Puede ser bastante útil a la hora de analizar ciertos binarios. Algunas capturas:
Como se puede ver, es potencialmente una buena baza. La visión humana es buena a la hora de identificar patrones visuales.
Veles
Podemos seleccionar las diferentes parrtes del archivo que queremos analizar.
Tal vez más adelante utilizemos otras de sus características para extraer partes concretas del volcado.
La siguiente herramienta que probé fue cpu_rec de código libre y desarrollada por airbus seclab. En teoría, es capaz de detectar código de diferentes arquitecturas en un mismo archivo.
Una primera ejecución devolvió lo siguiente:
Aunque parece detectar un bloque de código ARM (ARMel) que empieza en la dirección 0x9f000 del archivo. No he sido capaz de obtener resultados más precisos.
Aunando Fuerzas
Hace algunos meses, decidí preguntar en “stack exchange” (más conocido como stack overflow) sobre técnicas conocidas o comunes a la hora de hackear entornos cerrados y hacer ingeniería inversa de cajas negras. Conocí a wisk (@wiskitki) y después de comentar el caso, tuvo muy buenas ideas, además de tener mucha práctica en cuanto a ingeniería inversa práctica se refiere. En primer lugar decidimos empezat con el análisis manual y cargar los volcados enteros en un desensamblador como IDA Pro. En su momento pensamos que era suficiente configurar el procesador a ARM, de la siguiente manera:
Inmediatamente después del autoanálisis, empezamos a observar cosas interesantes:
Estos volcados son extremadamente útiles. Contienen código y datos, especialmente estructuras como la de arriba, mediante la cual vamos a poder identificar la dirección bases en la que se cargan los programas (más sobre esto en los próximos posts). Simplemente mencionar que la diferencia entre la dirección del bloque case y la dirección de la tabla de salto es negativa, lo que supone que no podemos extraer de aquí la dirección base y que una MMU está implicada en el asunto. Es importante reconstruir con exactitud el espacio de memoria para poder hacer reversing, y aun estamos en ello.
Pero aún hay más!
Más tarde decidí probar a ejecutar la herramienta binwalk. Aquí la salida:
binwalk fcram.bin
DECIMAL HEXADECIMAL DESCRIPTION
7299258 0x6F60BA Intel x86 or x64 microcode, sig 0x021e0001, pf_mask 0x00, 1A5A-01-16, rev 0x529c0000, size 2048
7993402 0x79F83A Intel x86 or x64 microcode, sig 0x021e0001, pf_mask 0x00, 1A5A-01-16, rev 0x529c0000, size 2048
8000252 0x7A12FC Intel x86 or x64 microcode, sig 0x0f15202a, pf_mask 0x3030404, 1F36-15-26, rev 0x37464b5c, size 16843009
50306088 0x2FF9C28 Intel x86 or x64 microcode, sig 0x00000016, pf_mask 0x803e5ec, 1C4C-08-01, rev 0x3f800000, size 2048
50567676 0x30399FC Intel x86 or x64 microcode, pf_mask 0x00, 1AD4-08-05, rev 0x8051ad4, size 2048
60749628 0x39EF73C TROC filesystem, 4279375 file entries
60752768 0x39F0380 TROC filesystem, 4279375 file entries
66907642 0x3FCEDFA Base64 standard index table
66908802 0x3FCF282 TIFF image data, little-endian offset of first image directory: 8
66908816 0x3FCF290 TIFF image data, big-endian, offset of first image directory: 8
66909359 0x3FCF4AF JPEG image data, EXIF standard
66909371 0x3FCF4BB TIFF image data, little-endian offset of first image directory: 8
66909379 0x3FCF4C3 JPEG image data, EXIF standard
66909391 0x3FCF4CF TIFF image data, big-endian, offset of first image directory: 8
66909662 0x3FCF5DE TIFF image data, little-endian offset of first image directory: 8
66909674 0x3FCF5EA TIFF image data, big-endian, offset of first image directory: 8
67105288 0x3FFF208 SHA256 hash constants, little endian
67135863 0x4006977 LZMA compressed data, properties: 0xB8, dictionary size: 0 bytes, uncompressed size: 2560 bytes
67139959 0x4007977 LZMA compressed data, properties: 0xB7, dictionary size: 0 bytes, uncompressed size: 6912 bytes
67742218 0x409AA0A Minix filesystem, V1, little endian, 187 zones
67750612 0x409CAD4 Minix filesystem, V1, little endian, 21760 zones
67854766 0x40B61AE Minix filesystem, V1, big endian, 31231 zones
67954296 0x40CE678 MySQL ISAM index file Version 5
67954300 0x40CE67C MySQL ISAM index file Version 5
68035414 0x40E2356 MySQL MISAM compressed data file Version 7
68421348 0x41406E4 MySQL MISAM index file Version 3
69043542 0x41D8556 MySQL ISAM index file Version 5
69159852 0x41F4BAC MySQL MISAM compressed data file Version 7
69349091 0x4222EE3 mcrypt 2.2 encrypted data, algorithm: blowfish-448, mode: CBC, keymode: 8bit
69403564 0x42303AC MySQL MISAM compressed data file Version 7
69473406 0x424147E MySQL ISAM index file Version 5
69618190 0x4264A0E Minix filesystem, V1, big endian, 11810 zones
69879092 0x42A4534 MySQL ISAM index file Version 5
69938520 0x42B2D58 MySQL MISAM index file Version 8
70140594 0x42E42B2 Minix filesystem, V1, little endian, 1036 zones
70298452 0x430AB54 MySQL ISAM index file Version 5
70329090 0x4312302 MySQL MISAM index file Version 8
107215248 0x663F990 Intel x86 or x64 microcode, sig 0x0803b216, pf_mask 0x803b2b4, 19B4-08-01, rev 0x3f800000, size 2048
107216348 0x663FDDC Intel x86 or x64 microcode, sig 0x00000016, pf_mask 0x803b2b4, 1E00-08-01, rev 0x3f800000, size 2048
107280616 0x664F8E8 Intel x86 or x64 microcode, sig 0x0803b216, pf_mask 0x803b2b4, 190C-08-02, rev 0x3f800000, size 2048
108395492 0x675FBE4 Intel x86 or x64 microcode, sig 0x00000002, pf_mask 0x80000000, 1E14-08-13, rev 0x8131e14, size 2048
110505168 0x6962CD0 Nintendo DS Game ROM Image <-----
111811632 0x6AA1C30 SHA256 hash constants, little endian
113820944 0x6C8C510 SHA256 hash constants, little endian
118416828 0x70EE5BC LZMA compressed data, properties: 0x6E, dictionary size: 0 bytes, uncompressed size: 5600 bytes
118814824 0x714F868 XML document, version: "1.0"
119871116 0x725168C SHA256 hash constants, little endian
120699788 0x731BB8C TROC filesystem, 4279375 file entries
120882924 0x73486EC Certificate in DER format (x509 v3), header length: 4, sequence length: 887 <-----
120883815 0x7348A67 Certificate in DER format (x509 v3), header length: 4, sequence length: 602 <-----
120884421 0x7348CC5 Certificate in DER format (x509 v3), header length: 4, sequence length: 885 <-----
120885310 0x734903E Certificate in DER format (x509 v3), header length: 4, sequence length: 954
120886268 0x73493FC Certificate in DER format (x509 v3), header length: 4, sequence length: 863
120887135 0x734975F Certificate in DER format (x509 v3), header length: 4, sequence length: 807
120887946 0x7349A8A Certificate in DER format (x509 v3), header length: 4, sequence length: 1066
122021324 0x745E5CC CRC32 polynomial table, little endian
122025420 0x745F5CC CRC32 polynomial table, big endian
122225616 0x74903D0 SHA256 hash constants, little endian
122672248 0x74FD478 Certificate in DER format (x509 v3), header length: 4, sequence length: 1056
122674704 0x74FDE10 Private key in DER format (PKCS header length: 4, sequence length: 1190
122675936 0x74FE2E0 Certificate in DER format (x509 v3), header length: 4, sequence length: 1219
122677176 0x74FE7B8 Private key in DER format (PKCS header length: 4, sequence length: 1190
123549136 0x75D35D0 Certificate in DER format (x509 v3), header length: 4, sequence length: 893
123550033 0x75D3951 Certificate in DER format (x509 v3), header length: 4, sequence length: 1169
123551206 0x75D3DE6 Certificate in DER format (x509 v3), header length: 4, sequence length: 1056
123563013 0x75D6C05 Minix filesystem, V1, little endian, 30 char names, 37 zones
123936009 0x7631D09 Minix filesystem, V1, little endian, 30 char names, 38 zones
123936748 0x7631FEC Intel x86 or x64 microcode, sig 0x08032070, pf_mask 0xffffffff, 2070-08-03, rev 0x8032050, size 2048
124047924 0x764D234 Base64 standard index table
124925352 0x77235A8 SHA256 hash constants, little endian
131945708 0x7DD54EC SHA256 hash constants, little endian
132031212 0x7DEA2EC SHA256 hash constants, little endian
132644480 0x7E7FE80 TROC filesystem, 4279375 file entries
132717080 0x7E91A18 SHA256 hash constants, little endian
Tenemos algunos falsos positivos, como código Intel X86 (imposible, dado que la 3DS utiliza un procesador ARM). Sin embargo, he resaltado algunos resultados interesantes. El primero de ellos, es la detección de un binario de Nintendo DS. Dado que la 3DS es retrocompatible esto no es sorprendente. Lo que si es curioso, es que, analizando en detalle el volcado, encontramos los datos de un juego llamado PAPERPLANE (O simplemente “avión de papel”), un juego de dsi que compré en la eshop y que tenía instalado cuando realizé los volcados.
¿Pero qué es lo raro entonces? Lo extraño es que no ejecuté el código antes ni durante el volcado. Y sin embargo, ¡ahi está el código!
Aunque no lo he puesto en práctica, en teoría, este código podría extraerse al completo. El formato de los binarios de Nintendo DS lleva mucho tiempo documentado. No es código nativo que se ejecute con los máximos privilegios, pero, también sería un excelente punto de entrada para comenzar. Además, existiendo depuradores excelentes como no$gba y muchos otros, podríamos buscar vulnerabilidades en el modo retrocompatible. Sería una buena forma de dar el primer paso dentro del sistema para posteriormente intentar escalar privilegios o escapar del modo de retrocompatibilidad.
Aun así, quedan algunos resultados interesantes de binwalk. Utilizando el parámetro _binwalk -e_
extraemos todos los formatos encontrados en carpetas separadas. Desafortunadamente no obtuvimos mucho más, salvo algunos certificados en formato .DER que wisk leyó con OpenSSL:
Últimas consideraciones sobre reversing
Por último, intentamos descubrir más sobre que formatos privativos y personalizados pudieran usar los binarios de 3DS. En el futuro intentaremos encontrar firmas (a.k.a. MAGIC numbers) que identifiquen formatos desconocidos. Además, aunque hemos sido capaces de localizar el código dentro de los volcados no hemos logrado mapearlos correctamente.
Uno de los tests que llevé a cabo fue el de seguir la pista de las cadenas de texto. Pongamos por ejemplo “Configuración de la consola” , la cual aparece en la lista de Strings de IDA Pro. Están cerca de las direcciones de memoria donde se encuentran las mismas cadenas de texto en otros idiomas. Sin embargo, no existe ninguna referencia por parte del código a estas direcciones de memoria (xref). Esto sugiere que para acceder a estas cadenas tal vez se utilize un array de cadenas de texto o alguna estructura, pero, por el momento no he llegado a desentrañar este funcionamiento.
Conclusiones
Hemos progresado. Aun no he logrado ejecutar código de forma nativa, pero estoy mucho más cerca de ello y dispongo de mucha más información del sistema que anteriormente.
No podría terminar este post sin agradecerle su ayuda a @wisk, ¡quien ha aportado mucho a la investigación!