hacktricks/mobile-pentesting/android-app-pentesting/smali-changes.md

12 KiB

Smali - Descompilación/[Modificación]/Compilación

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

A veces es interesante modificar el código de la aplicación para acceder a información oculta para ti (quizás contraseñas bien ofuscadas o banderas). Luego, podría ser interesante descompilar el apk, modificar el código y volver a compilarlo.

Referencia de opcodes: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Forma rápida

Usando Visual Studio Code y la extensión APKLab, puedes descompilar, modificar, compilar, firmar e instalar automáticamente la aplicación sin ejecutar ningún comando.

Otro script que facilita mucho esta tarea es https://github.com/ax/apk.sh****

Descompilar el APK

Usando APKTool puedes acceder al código smali y los recursos:

apktool d APP.apk

Si apktool te da algún error, intenta instalar la última versión

Algunos archivos interesantes que debes buscar son:

  • res/values/strings.xml (y todos los xml dentro de res/values/*)
  • AndroidManifest.xml
  • Cualquier archivo con extensión .sqlite o .db

Si apktool tiene problemas al decodificar la aplicación, echa un vistazo a https://ibotpeaches.github.io/Apktool/documentation/#framework-files o intenta usar el argumento -r (No decodificar recursos). Entonces, si el problema estaba en un recurso y no en el código fuente, no tendrás el problema (tampoco descompilarás los recursos).

Cambiar el código Smali

Puedes cambiar instrucciones, cambiar el valor de algunas variables o agregar nuevas instrucciones. Cambio el código Smali usando VS Code, luego instalas la extensión smalise y el editor te dirá si alguna instrucción es incorrecta.
Algunos ejemplos se pueden encontrar aquí:

O puedes ver a continuación algunos cambios en Smali explicados.

Recompilar el APK

Después de modificar el código, puedes recompilar el código usando:

apktool b . #In the folder generated when you decompiled the application

Compilará el nuevo APK dentro de la carpeta dist.

Si apktool muestra un error, intenta instalar la última versión

Firmar el nuevo APK

Luego, necesitarás generar una clave (se te pedirá una contraseña y alguna información que puedes completar al azar):

keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>

Finalmente, firma el nuevo APK:

jarsigner -keystore key.jks path/to/dist/* <your-alias>

Optimizar nueva aplicación

zipalign es una herramienta de alineación de archivos que proporciona optimizaciones importantes a los archivos de aplicación de Android (APK). Más información aquí.

zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk

Firmar el nuevo APK (¿de nuevo?)

Si prefieres usar [apksigner](https://developer.android.com/studio/command-line/apksigner)** en lugar de jarsigner, debes firmar el apk después de aplicar la optimización con zipaling**. PERO TEN EN CUENTA QUE** SOLO DEBES FIRMAR LA APLICACIÓN UNA VEZ** CON jarsigner (antes de zipalign) O CON aspsigner (después de zipaling).

apksigner sign --ks key.jks ./dist/mycompiled.apk

Modificando Smali

Para el siguiente código Java de Hello World:

public static void printHelloWorld() {
System.out.println("Hello World")
}

El código Smali sería:

.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

El conjunto de instrucciones Smali está disponible aquí.

Cambios ligeros

Modificar los valores iniciales de una variable dentro de una función

Algunas variables se definen al comienzo de la función utilizando el opcode const, puedes modificar sus valores o definir nuevas variables:

#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"

Operaciones básicas

Cambios en el código Smali

El código Smali es el lenguaje ensamblador utilizado en las aplicaciones de Android. Al realizar pruebas de penetración en aplicaciones Android, es posible que necesite realizar cambios en el código Smali para lograr ciertos objetivos. A continuación se presentan algunas operaciones básicas que puede realizar en el código Smali:

  • Modificar valores constantes: Puede cambiar los valores constantes utilizados en el código Smali para alterar el comportamiento de la aplicación. Esto puede incluir cambiar valores numéricos, cadenas de texto o cualquier otro tipo de constante utilizada en el código.

  • Modificar llamadas a métodos: Puede modificar las llamadas a métodos en el código Smali para redirigir el flujo de ejecución de la aplicación. Esto puede ser útil para realizar pruebas de penetración, como interceptar llamadas a métodos sensibles o modificar el comportamiento de la aplicación.

  • Agregar nuevas instrucciones: Puede agregar nuevas instrucciones al código Smali para agregar funcionalidad adicional a la aplicación. Esto puede incluir la adición de nuevas funciones, la manipulación de datos o cualquier otra operación que desee realizar en el código.

  • Eliminar instrucciones: Puede eliminar instrucciones del código Smali para eliminar funcionalidad no deseada de la aplicación. Esto puede ser útil para desactivar características no deseadas o eliminar código malicioso.

Al realizar cambios en el código Smali, es importante tener en cuenta la estructura y la sintaxis del código para evitar errores y asegurarse de que los cambios se realicen correctamente.

#Math
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
mul-int v0,v2,0x2 #v2*0x2 and save in v0

#Move the value of one object into another
move v1,v2

#Condtions
if-ge #Greater or equals
if-le #Less or equals
if-eq #Equals

#Get/Save attributes of an object
iget v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save this.o inside v0
iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside this.o

#goto
:goto_6 #Declare this where you want to start a loop
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
goto :goto_6 #Always go to: :goto_6

Cambios importantes

Registro

#Log win: <number>
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String
move-result-object v1 #Move to v1
const-string v5, "wins" #Save "win" inside v5
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"

Recomendaciones:

  • Si vas a utilizar variables declaradas dentro de la función (declaradas v0,v1,v2...), coloca estas líneas entre .local <número> y las declaraciones de las variables (const v0, 0x1)
  • Si deseas colocar el código de registro en medio del código de una función:
  • Añade 2 al número de variables declaradas: Ej: de .locals 10 a .locals 12
  • Las nuevas variables deben ser los siguientes números de las variables ya declaradas (en este ejemplo deberían ser v10 y v11, recuerda que comienza en v0).
  • Cambia el código de la función de registro y utiliza v10 y v11 en lugar de v5 y v1.

Toasting

Recuerda añadir 3 al número de .locals al comienzo de la función.

Este código está preparado para ser insertado en el medio de una función (cambia el número de las variables según sea necesario). Tomará el valor de this.o, lo transformará a String y luego hará un toast con su valor.

const/4 v10, 0x1
const/4 v11, 0x1
const/4 v12, 0x1
iget v10, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I
invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v11
invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v12
invoke-virtual {v12}, Landroid/widget/Toast;->show()V
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥