Reversing Interpreted Languages
Managed Code
Managed code es código de programa que requiere y se ejecutará solo bajo la administración de una Common Language Infrastructure ( CLI); Virtual Execution System ( VES); virtual machine ( ej. .NET, CoreFX, .NET Framework); Common Language Runtime ( CLR); o Mono. El término fue acuñado por Microsoft.
Lenguajes Interpretados
Un lenguaje interpretado es un lenguaje de programación cuyas implementaciones ejecutan instrucciones directamente y libremente, sin compilar previamente un programa en instrucciones de machine language. Ejemplos:
- JAVA
- .NET ( C#, VB.net, etc.)
- Python
Lenguajes Intermedios
Java usa un “intermediate language” llamado Bytecode.
- El bytecode es el lenguaje ejecutado por la Java virtual machine
- A diferencia del assembler, es un lenguaje mucho más fácil de leer
- Gracias a esta estructura de lenguaje intermedio + máquina virtual, Java puede ejecutarse en muchas plataformas diferentes
Reverse Engineering de APKs
Reverse engineering es un proceso por el que un elemento se deconstruye para revelar su diseño, arquitectura, código o extraer información.
¿Por qué es más fácil en Android?
Es más fácil hacer reverse engineering de aplicaciones Android porque la mayoría se escriben en Java/Kotlin.
- Java/Kotlin se compilan a bytecodes
Anatomía de un APK
Un APK es simplemente un archivo .ZIP/.JAR que puede renombrarse a .zip y extraerse.
Elementos almacenados en un APK
- AndroidManifest.xml** — Declaraciones y permisos de Android
- META-INF/** — JAR manifest, SHA1 hashes, signature y certificate chain
- classes.dex** — App bytecode en formato DEX
- lib/** — App libraries
- assets/** — Assets de la aplicación
Dalvik & Smali
La mayoría de aplicaciones Android se escriben en Java. Hay alternativas, mostly web-based:
- Apache Cordova
- React Native O usando el NDI:
- C++ El código Java no se ejecuta dentro de una Java Virtual Machine ( JVM) como lo hace en aplicaciones de computadora. En Android, el código Java se enlaza en un Dalvik EXecutable ( DEX).
- Originalmente la máquina virtual era Dalvik
- Las versiones recientes de Android usan Android Runtime ( ART)
Reverse Engineering de DEX
El proceso de reverse engineering consiste en convertir ese código DEX en código Java.
SMALI
DEX puede descompilarse a SMALI y luego a Java. Smali es una representación legible por humanos de Dalvik bytecode ( Assembler). Ejemplo:
.method public static printHelloWorld ()V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World"
invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println ( Ljava/lang/String;)V
return-void
.end method
Cuándo usar SMALI
A veces es mejor trabajar con SMALI al hacer reverse engineering de código Android:
- Muchas aplicaciones pueden descompilarse a Java, pero los decompilers pueden tener bugs
- Si el decompiler retorna código malo, es necesario volver al código SMALI
Descompilar un APK
apktool
Open-source tool para reverse engineering de apps:
- Es una herramienta de consola
- Es una aplicación Java ( escrita en Java)
- Requiere Java para ejecutar Última versión disponible en: https://ibotpeaches.github.io/Apktool/install/ Uso:
java -jar apktool.jar
apktool d FILE.apk -o uah
Obtener el APK
Usando ADB
adb shell pm list packages
adb shell pm path com.android.systemui
adb pull /data/app/yourpackagename/base.apk DESTINATIONDescargando de la tienda
- APK Downloaders:
- https://apps.evozi.com/apk-downloader/
- http://apkleecher.com/
- https://apk-dl.com/
- https://apkcombo.com/
AndroidManifest.xml
AndroidManifest.xml está codificado en el APK.
- Extraerlo no es suficiente
- apktool lo hará legible
DEX a JAR
Los archivos DEX pueden convertirse en JAR que usen Java byte codes, que no requieren SMALI.
jadx ( Recomendado)
Dex to Java decompiler, la opción más actualizada:
- https://github.com/skylot/jadx
- Tiene una interfaz gráfica para inspeccionar directamente APKs
- Uso:
jadx -d out classes.dex
Alternativas
- Dex2jar:** https://github.com/pxb1988/dex2jar
- enjarify:** https://github.com/google/enjarify
JAR a Java
Java Decompiler
Open Source Java Decompiler:
- https://java-decompiler.github.io/
- Necesita Java byte codes como input ( ej. .jar)
Alternativas Comerciales
Code Obfuscation
Code obfuscation es una técnica que intenta hacer difícil para los humanos leer el código:
- Cambia nombres de variables y métodos a strings aleatorios/encriptados
- Android Studio incorpora herramientas para shrinking y obfuscation: R8 ( anteriormente Proguard)
PROGUARD
- 8 años más viejo que Android
- Creado por Eric Lafortune
- Diseñado para Java
- Muy popular
- Funcionalidades:
- Code shrinking
- Resource shrinking
- Obfuscation
- Optimizer
- Gratuito
- Reemplazado por R8
Modificar y Firmar APKs
Modificar SMALI Code
- Modificar código SMALI
- Construir APK usando apktool:
apktool b apktoolfolder -o modifiedAPK.apk
- Después de modificar, es necesario usar un certificado y firmar la aplicación
Sign APKs
Las signatures controlan que no podamos crear versiones de una aplicación e impersonar al creador. Podemos crear nuestro propio certificado para instalar la aplicación modificada:
keytool -genkey -v -keystore my-key.keystore -keyalg RSA \
-keysize 2048 -validity 10000
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 \
-keystore my-key.keystore modifiedAPK.apkUber Apk Signer
Alternativa más simple:
APKLab
Herramienta VSCode para trabajar con APKs:
- Ctrl + Shift + P : APKLab: Open an APK
- https://github.com/APKLab/APKLab
Rebuild y Sign APK
- Right click o desde apktool.yml : APKLab: Rebuild the APK
- Directory .dist
- Right click en .apk : APKLab: Install the APK
- O usar:
.adb.exe install -r APK
Smalise
Plugin para VSCode para trabajar con código SMALI:
- Syntax Highlighting
- Show Symbol Definitions
- Go To/Peek Definition
App Pentesting
Todas las aplicaciones deberían pasar por un proceso de auditoría y un ciclo de desarrollo seguro de software.
.IPA App Analysis ( iOS)
El reverse engineering y scanning de aplicaciones iOS es bastante tedioso debido a encriptación/DRM.
FairPlay DRM
FairPlay es un digital rights management ( DRM) desarrollado por Apple.
- Cuando creas una cuenta Apple se genera un par de claves Public/Private
- Cuando compras una aplicación y la descargas de la app store, Apple genera un header encriptado con tu clave pública
- Si otro usuario intenta ejecutar una aplicación que no le pertenece ( no la descargó de iTunes o App Store), la aplicación no funcionará, ya que no puede desencriptar el header con su clave privada
Reversing .IPA
Desencriptar el Binario
Se necesita un dispositivo jailbroken. Hacer memory dump en tiempo de ejecución para obtener una versión desencriptada de la aplicación:
- https://github.com/KJCracks/Clutch
- Puede instalarse desde Cydia
- Cada jailbreak puede variar Si se usa LiberiOS, es mejor usar bfinject:
- https://github.com/BishopFox/bfinject
Clutch
Clutch -i # List apps
Clutch -b <BundleID> # Dump app memoryEl ejecutable encriptado se encontrará en la carpeta /private/var. Clutch deja el binario en /tmp. Se puede ver la diferencia entre intentar extraer información de una clase encriptada y una desencriptada.
.IPA Class Dump
Una vez que tenemos la app desencriptada, podemos extraer las clases:
Objective-C
- Class-dump:** Extrae clases, métodos y variables
Swift
- class-dump-swift:** Para Swift
- dsdump:** Alternativa más moderna
- https://github.com/DerekSelander/dsdump
Reverse Engineering iOS
Los class dumps proporcionan clases, métodos y variables, pero todavía nos falta mucha información. Es necesario usar un disassembler:
- Este es un proceso más complicado que en Android
- Necesitas entender assembler
Herramientas
- IDA Pro**
- Hopper:** https://www.hopperapp.com/
- Radare2**