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:

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 DESTINATION

Descargando de la tienda

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:

Alternativas

JAR a Java

Java Decompiler

Open Source Java Decompiler:

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

  1. Modificar código SMALI
  2. Construir APK usando apktool:
apktool b apktoolfolder -o modifiedAPK.apk
  1. 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.apk

Uber Apk Signer

Alternativa más simple:

APKLab

Herramienta VSCode para trabajar con APKs:

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:

Clutch

Clutch -i # List apps
Clutch -b <BundleID> # Dump app memory

El 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

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