Tutorial de Frida 1

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Este es un resumen del post: https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1
APK: https://github.com/t0thkr1s/frida-demo/releases
Código fuente: https://github.com/t0thkr1s/frida-demo

Python

Frida te permite insertar JavaScript code dentro de funciones de una aplicación en ejecución. Pero puedes usar python para call los hooks e incluso para interact con los hooks.

Este es un script de python sencillo que puedes usar con todos los ejemplos propuestos en este tutorial:

#hooking.py
import frida, sys

with open(sys.argv[1], 'r') as f:
jscode = f.read()
process = frida.get_usb_device().attach('infosecadventures.fridademo')
script = process.create_script(jscode)
print('[ * ] Running Frida Demo application')
script.load()
sys.stdin.read()

Llama al script:

python hooking.py <hookN.js>

Es útil saber cómo usar python con frida, pero para estos ejemplos también podrías invocar directamente Frida usando las herramientas de línea de comandos de frida:

frida -U --no-pause -l hookN.js -f infosecadventures.fridademo

Hook 1 - Boolean Bypass

Aquí puedes ver cómo hook un boolean method (checkPin) de la clase: infosecadventures.fridademo.utils.PinUtil

//hook1.js
Java.perform(function () {
console.log("[ * ] Starting implementation override...")
var MainActivity = Java.use("infosecadventures.fridademo.utils.PinUtil")
MainActivity.checkPin.implementation = function (pin) {
console.log("[ + ] PIN check successfully bypassed!")
return true
}
})
python hooking.py hook1.js

Mirar: La funcion recibe como parametro un String, no hace falta overload?

Hook 2 - Function Bruteforce

Función no estática

Si quieres llamar a una función no estática de una clase, primero necesitas una instancia de esa clase. Luego, puedes usar esa instancia para llamar a la función.
Para ello, podrías encontrar una instancia existente y usarla:

Java.perform(function () {
console.log("[ * ] Starting PIN Brute-force, please wait...")
Java.choose("infosecadventures.fridademo.utils.PinUtil", {
onMatch: function (instance) {
console.log("[ * ] Instance found in memory: " + instance)
for (var i = 1000; i < 9999; i++) {
if (instance.checkPin(i + "") == true) {
console.log("[ + ] Found correct PIN: " + i)
break
}
}
},
onComplete: function () {},
})
})

En este caso esto no funciona ya que no hay ninguna instancia y la función es estática

Función estática

Si la función es estática, simplemente podrías llamarla:

//hook2.js
Java.perform(function () {
console.log("[ * ] Starting PIN Brute-force, please wait...")
var PinUtil = Java.use("infosecadventures.fridademo.utils.PinUtil")

for (var i = 1000; i < 9999; i++) {
if (PinUtil.checkPin(i + "") == true) {
console.log("[ + ] Found correct PIN: " + i)
}
}
})

Hook 3 - Recuperando argumentos y valor de retorno

Puedes hookear una función y hacer que imprima el valor de los argumentos pasados y el valor de retorno:

//hook3.js
Java.perform(function () {
console.log("[ * ] Starting implementation override...")

var EncryptionUtil = Java.use(
"infosecadventures.fridademo.utils.EncryptionUtil"
)
EncryptionUtil.encrypt.implementation = function (key, value) {
console.log("Key: " + key)
console.log("Value: " + value)
var encrypted_ret = this.encrypt(key, value) //Call the original function
console.log("Encrypted value: " + encrypted_ret)
return encrypted_ret
}
})

Hooking en versiones recientes de Android (14/15/16)

  • Desde Frida 17.1.x+, Java hooking en Android 14–16 es estable de nuevo (ART quick entrypoint offsets fueron corregidos). Si Java.choose no devuelve nada en Android 14+, actualiza frida-server/gadget y los paquetes CLI/Python a >=17.1.5.
  • Las aplicaciones con comprobaciones anti-debug tempranas a menudo mueren antes de attach. Usa spawn para que los hooks se carguen antes de onCreate:
frida -U -f infosecadventures.fridademo -l hook1.js --no-pause
  • Cuando existen múltiples overloads, selecciona explícitamente el target:
var Cls = Java.use("com.example.Class")
Cls.doThing.overload('java.lang.String', 'int').implementation = function(s, i) {
return this.doThing(s, i)
}

Inyección más sigilosa con Zygisk Gadget

Algunas apps detectan ptrace o frida-server. Los módulos Magisk/Zygisk pueden cargar frida-gadget dentro de Zygote para que ningún proceso sea ptraced:

  1. Instala un módulo Zygisk gadget (p. ej., zygisk-gadget) y reinicia.
  2. Configura el paquete objetivo y un retraso opcional para omitir las comprobaciones de inicio:
adb shell "su -c 'echo infosecadventures.fridademo,5000 > /data/local/tmp/re.zyg.fri/target_packages'"
  1. Inicia la app y conéctate al nombre del gadget:
frida -U -n Gadget -l hook3.js

Debido a que el gadget es inyectado por Zygote, las comprobaciones de integridad del APK permanecen intactas y las comprobaciones básicas de ptrace/Frida suelen fallar.

Importante

En este tutorial has hooked methods usando el nombre del método y .implementation. Pero si hubiese más de un método con el mismo nombre, necesitarás especificar el método que quieres hookear indicando el tipo de los argumentos.

Puedes ver eso en the next tutorial.

References

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks