Reverse Enginering Android APKs usando Android sin root.
Instala Termux de la PlayStore.
Actualiza.
pkg update & upgrade
Instala software útil:
pkg install aapt
pkg install apksigner
pkg install apktool
pkg install dpkg
pkg install git
git clone https://github.com/Lexiie/Termux-Jadx
dpkg -i ./jadx-0.6.1_all.deb
pkg install nano
pkg install nodejs (el npm que viene incluido es muy útil y hay varias herramientas para nodejs útiles para reversing)
pkg install openssl-tool
pkg install radare2
pkg install vim
pkg install wget
pkg install zip
Si no se encuentra algún soft en el repo que viene por defecto, installa también el unstable y prueba de nuevo:
pkg install unstable-repo
Puede que quieras usar tus herramientas o de terceros en algún lenguaje de programación. Hay más en otros repos no oficiales. Puedes ver todos los paquetes disponibles con el comando:
pkg list-all
O usar git clone como en uno de los comandos anteriores e instalar manualmente.
Ahora que tienes todas la herramientas, vamos a hacer algunos retos.
Crea una carpeta donde quieras, yo voy a crear RE/CC de Reverse Enginering y Cracking Challenges.
mkdir RE
cd RE
mkdir CC
cd CC
Y descargamos los retos.
wget https://github.com/OWASP/owasp-mstg/tree/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk
Copiamos desde la ruta de descarga a la ruta de trabajo que creamos. Si no sabes la ruta usa el comando pwd para ver la ruta actual. En mi caso queda:
cp /data/data/com.termux/files/home/storage/downloads/UnCrackable-Level1.apk /data/data/com.termux/files/home/RE/CC/
Si te da problemas de acceso usa el comando termux-setup-storage y ya deberías tener la ruta disponible.
Cuando lo tenga al usar el comando ls dentro de la ruta /RE/CC podrás ver que tienes el uncrackable ahí.
Ahora tenemos varias herramientas que podemos usar para desempaquetarlo en distintos archivos. La más conocida es el zip. Si le cambias la extensión a .zip puedes abrirlo con el zip de toda la vida.
Algunas requieren root, por ese motivo nos bajamos el jadx. También puedes usar Apis online si no tienes root. Por ejemplo http://www.javadecompilers.com/apk también es muy usado el dex2jar incluso puedes instalarlo directamente con el r2pm (el manager de packetes de radare). Requieren root. Si tienes tu Android root instala el tsu con pkg install tsu que es un wraper del su para termux.
También comentar que puedes instalar el UnCrackable.apk sin problemas. Es una aplicación que pide una contraseña para acceder, la cual no conocemos.
Pues vamos a desempacar directamente el .apk
jadx --deobf UnCrackable-Level1.apk
Si usas el comando ls vas a ver que a parte del .apk se creo un .jobf y una carpeta con el mismo nombre del archivo.
Entramos con cd y seguimos la ruta hasta encontrar los .java
cd UnCrackable-Level1
cd sg
cd vantagepoint
cd uncrackable1
En este ruta tenemos el MainActivity.java que suele ser la actividad principal del programa.
Si hacemos un nano o vim al .java:
nano MainActivity.java
bajamos un poco y ya vemos el
if (C0005a.m6a(obj)) {
create.setTitle("Sucess!"); dentro de la clase public void verify()
2 Líneas más arriba del if vemos la declaración y definición del String obj que es el texto que el usuario ponga en la aplicación, porque se está obteniendo de un EditText que es la versión de Android de un InputText.
Como vemos no tiene mucho más código, ni realiza intentos a otras aplicaciones ni a otras actividades de la aplicación.
Salimos de nano con control + X y si hacemos ls vemos que en la misma carpeta tenemos el C0005a.java al que de referencia en el código.
Lo abrimos con nano o vim y vamos a buscar el método m6a.
vim C0005a.java
Es la primera subclase de C0005a y como vemos es de tipo boolean. Como en el MainActivity estaba dentro de un if, necesitamos que devuelva true.
Podemos modificar el código si queremos y meterle un ! en la condición del if, y siempre que se ponga mal la contraseña actuará al revés.
Si miramos el resto de archivos veremos la clave cifrada, el tipo de cifrado, la contraseña del cifrado el modo de bloque...
Podemos sacar la clave con el comando
echo 5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc= | openssl enc -aes-128-ecb -base64 -d -nopad -K 8d127684cbc37c17616d806cf50473cc
Ya estaría el reto completado. Hay muchas más formas de obtener el código o strings importantes para resolver el reto.
Por ejemplo podemos obtener el archivo classes.dex descomprimiendo el archivo.
cp UnCrackable-Level1.apk UnCrackable-Level1.zip
unzip UnCrackable-Level1.zip
Despues lo abrimos en el rabin2 o en el radare2.
rabin2 -izq classes.dex
Para cuando tengas muchos resultados, si buscas algo en concreto añade grep para filtrar:
rabin2 -izq classes.dex |grep "http"
Con radare2 se pueden hacer muchas cosas y analizar binarios de todo tipo.
r2 classes.dex
>aaa
>fs
>ii
>VV para salir dale a Q
>s main
>exit
Ahora vamos a resolver el reto otra vez pero vamos a hacerlo parcheando la app en vez de sacando el string.
Esta vez vamos a usar el apktool en lugar del jadx para obtener el código .smali que es una versión human readable (ensamblador) del bytecode que ejecuta Dalvik Virtual Machine.
apktool d -f UnCrackable-Level1.apk
-f sirve para sobrescribir la carpeta que nos creó el jadx, que ya no la necesitamos.
Ahora vamos a buscar el MainActivity.smali
cd UnCrackable-Level1
cd smali
cd sg
cd vantagepoint
cd uncrackable1
vim MainActivity.smali
Si miramos en el código encontraremos donde dice sucess.
Justo encima tenemos un condicional if que dice, if-eqz p1, :cond_0
Vamos a negar la condición para que siempre que pongas la contraseña mal nos deje "pasar".
Para saber como hacerlo están aquí los op codes de smali:
http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
Es decir solo necesitamos cambiar el if-eqz por el if-nez y guardar el archivo.
Ahora lo buildeamos, lo alineamos y finalmente lo firmamos, es este orden siempre y cuando se usen estas herramientas.
Nos vamos a la ruta RE/CC y buildeamos.
apktool b -d UnCrackable-Level1 build.apk
cd UnCrackable-Level
cd dist
Dentro de dist tenemos el apk generado. Lo tenemos que alinear.
zipalign -f -v 4 UnCrackable-Level1.apk aligned.apk
apksigner autokey aligned.apk firmada.apk
Lo ideal es usar el keytools para generar el keystore y firmas la app para máxima compatibilidad. En algunos dispositivos me corre la app sin problemas, y en otros me da error. Si teneis root o quereis rooterlo podeis bajaros el kingoroot de su página oficial y bajaros el paquete de reversing que viene en la wiki de termux. Con root se puede usar software más adecuado y bajarse suits enteras.
Ahora la puedes copiar de vuelta a descargas e intalarla. Una vez instalada pongas la contraseña que poñas verás que la aplicación te la valida como correcta a pesar de no serlo, ya que en vez de comprobar: "Es el texto introducido igual a la contraseña? Entonces valida." con el cambio que hicimos en el código pasa a ser "Si el texto introducido no es igual a la contraseña, Entonces valida". A alto nivel eso es lo que hicimos.
Otra forma que se me ocurre de resolver el reto sería debuggeando la aplicación ponieno breakpoints y analizando la memoria para ver el string directamente descifrado.
Espero que os sirva!