mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 13:13:41 +00:00
434 lines
18 KiB
Markdown
434 lines
18 KiB
Markdown
# Configuración de Frida en iOS
|
|
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
|
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de Telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|
|
|
|
## Instalación de Frida
|
|
|
|
Ve a la aplicación **Cydia/Sileo** en tu dispositivo con Jailbreak y agrega el repositorio de Frida yendo a **Manage -> Sources -> Edit -> Add** e ingresa [**https://build.frida.re** ](https://build.frida.re). Esto agregará una nueva fuente en la lista de fuentes. Ve a la fuente de **Frida**, ahora deberías **instalar** el paquete de **Frida**.
|
|
|
|
![](https://miro.medium.com/max/614/0\*qSD26kBtgt\_UIZk1.png)
|
|
|
|
Si estás utilizando **Corellium**, deberás descargar la versión de Frida desde [https://github.com/frida/frida/releases](https://github.com/frida/frida/releases) (`frida-gadget-[yourversion]-ios-universal.dylib.gz`) y descomprimir y copiar en la ubicación de dylib que Frida solicita, por ejemplo: `/Users/[youruser]/.cache/frida/gadget-ios.dylib`
|
|
|
|
Después de instalarlo, puedes usar en tu PC el comando **`frida-ls-devices`** y verificar que el dispositivo aparezca (tu PC debe poder acceder a él).\
|
|
Ejecuta también **`frida-ps -Uia`** para verificar los procesos en ejecución del teléfono.
|
|
|
|
## Frida sin dispositivo con Jailbreak y sin parchear la aplicación
|
|
|
|
Consulta esta publicación de blog sobre cómo usar Frida en dispositivos sin Jailbreak sin parchear la aplicación: [https://mrbypass.medium.com/unlocking-potential-exploring-frida-objection-on-non-jailbroken-devices-without-application-ed0367a84f07](https://mrbypass.medium.com/unlocking-potential-exploring-frida-objection-on-non-jailbroken-devices-without-application-ed0367a84f07)
|
|
|
|
## Instalación del Cliente de Frida
|
|
|
|
Instala las **herramientas de Frida**:
|
|
```bash
|
|
pip install frida-tools
|
|
pip install frida
|
|
```
|
|
Con el servidor Frida instalado y el dispositivo en funcionamiento y conectado, **verifica** si el cliente está **funcionando**:
|
|
```bash
|
|
frida-ls-devices # List devices
|
|
frida-ps -Uia # Get running processes
|
|
```
|
|
## Rastreo con Frida
|
|
|
|
Frida is a dynamic instrumentation toolkit that allows you to inject JavaScript code into running processes. This can be particularly useful for analyzing and manipulating the behavior of iOS applications during penetration testing.
|
|
|
|
Frida es una herramienta de instrumentación dinámica que te permite inyectar código JavaScript en procesos en ejecución. Esto puede ser especialmente útil para analizar y manipular el comportamiento de las aplicaciones de iOS durante las pruebas de penetración.
|
|
|
|
To configure Frida for iOS pentesting, follow these steps:
|
|
|
|
Para configurar Frida para pruebas de penetración en iOS, sigue estos pasos:
|
|
|
|
1. Install Frida on your iOS device using Cydia or Sileo. You can find the Frida package in the default repositories.
|
|
|
|
Instala Frida en tu dispositivo iOS utilizando Cydia o Sileo. Puedes encontrar el paquete de Frida en los repositorios predeterminados.
|
|
|
|
2. Install Frida on your computer by running the following command:
|
|
|
|
Instala Frida en tu computadora ejecutando el siguiente comando:
|
|
|
|
```bash
|
|
pip install frida-tools
|
|
```
|
|
|
|
3. Connect your iOS device to your computer using a USB cable.
|
|
|
|
Conecta tu dispositivo iOS a tu computadora utilizando un cable USB.
|
|
|
|
4. Open a terminal and run the following command to list the processes running on your iOS device:
|
|
|
|
Abre una terminal y ejecuta el siguiente comando para listar los procesos en ejecución en tu dispositivo iOS:
|
|
|
|
```bash
|
|
frida-ps -U
|
|
```
|
|
|
|
This will display a list of processes along with their process IDs (PIDs).
|
|
|
|
Esto mostrará una lista de procesos junto con sus identificadores de proceso (PIDs).
|
|
|
|
5. Identify the process you want to trace and note its PID.
|
|
|
|
Identifica el proceso que deseas rastrear y anota su PID.
|
|
|
|
6. Run the following command to start tracing the process:
|
|
|
|
Ejecuta el siguiente comando para comenzar a rastrear el proceso:
|
|
|
|
```bash
|
|
frida-trace -U -p <PID> -i "<function_name>"
|
|
```
|
|
|
|
Replace `<PID>` with the process ID you noted in the previous step, and `<function_name>` with the name of the function you want to trace.
|
|
|
|
Reemplaza `<PID>` con el identificador de proceso que anotaste en el paso anterior, y `<function_name>` con el nombre de la función que deseas rastrear.
|
|
|
|
Frida will inject the specified JavaScript code into the process and start tracing the specified function.
|
|
|
|
Frida inyectará el código JavaScript especificado en el proceso y comenzará a rastrear la función especificada.
|
|
|
|
7. Perform the actions in the iOS application that trigger the function you are tracing.
|
|
|
|
Realiza las acciones en la aplicación de iOS que activan la función que estás rastreando.
|
|
|
|
8. Frida will display the function calls and their arguments in the terminal.
|
|
|
|
Frida mostrará las llamadas a la función y sus argumentos en la terminal.
|
|
|
|
9. Press Ctrl+C to stop the tracing.
|
|
|
|
Presiona Ctrl+C para detener el rastreo.
|
|
|
|
By following these steps, you can use Frida to trace and analyze the behavior of iOS applications during penetration testing.
|
|
|
|
Siguiendo estos pasos, puedes utilizar Frida para rastrear y analizar el comportamiento de las aplicaciones de iOS durante las pruebas de penetración.
|
|
```bash
|
|
# Functions
|
|
## Trace all functions with the word "log" in their name
|
|
frida-trace -U <program> -i "*log*"
|
|
frida-trace -U <program> -i "*log*" | swift demangle # Demangle names
|
|
|
|
# Objective-C
|
|
## Trace all methods of all classes
|
|
frida-trace -U <program> -m "*[* *]"
|
|
|
|
## Trace all methods with the word "authentication" from classes that start with "NE"
|
|
frida-trace -U <program> -m "*[NE* *authentication*]"
|
|
|
|
# Plug-In
|
|
## To hook a plugin that is momentarely executed prepare Frida indicating the ID of the Plugin binary
|
|
frida-trace -U -W <if-plugin-bin> -m '*[* *]'
|
|
```
|
|
### Obtener todas las clases y métodos
|
|
|
|
* Autocompletar: Simplemente ejecuta `frida -U <programa>`
|
|
|
|
<figure><img src="../../.gitbook/assets/image (687).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
* Obtener **todas** las **clases** disponibles (filtrar por cadena)
|
|
|
|
{% code title="/tmp/script.js" %}
|
|
```javascript
|
|
// frida -U <program> -l /tmp/script.js
|
|
|
|
var filterClass = "filterstring";
|
|
|
|
if (ObjC.available) {
|
|
for (var className in ObjC.classes) {
|
|
if (ObjC.classes.hasOwnProperty(className)) {
|
|
if (!filterClass || className.includes(filterClass)) {
|
|
console.log(className);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
console.log("Objective-C runtime is not available.");
|
|
}
|
|
```
|
|
{% endcode %}
|
|
|
|
* Obtener **todos** los **métodos** de una **clase** (filtrar por cadena)
|
|
|
|
{% code title="/tmp/script.js" %}
|
|
```javascript
|
|
// frida -U <program> -l /tmp/script.js
|
|
|
|
var specificClass = "YourClassName";
|
|
var filterMethod = "filtermethod";
|
|
|
|
if (ObjC.available) {
|
|
if (ObjC.classes.hasOwnProperty(specificClass)) {
|
|
var methods = ObjC.classes[specificClass].$ownMethods;
|
|
for (var i = 0; i < methods.length; i++) {
|
|
if (!filterMethod || methods[i].includes(filterClass)) {
|
|
console.log(specificClass + ': ' + methods[i]);
|
|
}
|
|
}
|
|
} else {
|
|
console.log("Class not found.");
|
|
}
|
|
} else {
|
|
console.log("Objective-C runtime is not available.");
|
|
}
|
|
```
|
|
{% endcode %}
|
|
|
|
* **Llamar a una función**
|
|
```javascript
|
|
// Find the address of the function to call
|
|
const func_addr = Module.findExportByName("<Prog Name>", "<Func Name>");
|
|
// Declare the function to call
|
|
const func = new NativeFunction(
|
|
func_addr,
|
|
"void", ["pointer", "pointer", "pointer"], {
|
|
});
|
|
|
|
var arg0 = null;
|
|
|
|
// In this case to call this function we need to intercept a call to it to copy arg0
|
|
Interceptor.attach(wg_log_addr, {
|
|
onEnter: function(args) {
|
|
arg0 = new NativePointer(args[0]);
|
|
}
|
|
});
|
|
|
|
// Wait untill a call to the func occurs
|
|
while (! arg0) {
|
|
Thread.sleep(1);
|
|
console.log("waiting for ptr");
|
|
}
|
|
|
|
|
|
var arg1 = Memory.allocUtf8String('arg1');
|
|
var txt = Memory.allocUtf8String('Some text for arg2');
|
|
wg_log(arg0, arg1, txt);
|
|
|
|
console.log("loaded");
|
|
```
|
|
## Frida Fuzzing
|
|
|
|
### Frida Stalker
|
|
|
|
Stalker es el **motor de rastreo** de Frida. Permite **seguir** hilos, **capturando** cada función, **cada bloque**, incluso cada instrucción que se ejecuta.
|
|
|
|
Tienes un ejemplo que implementa Frida Stalker en [https://github.com/poxyran/misc/blob/master/frida-stalker-example.py](https://github.com/poxyran/misc/blob/master/frida-stalker-example.py)
|
|
|
|
Este es otro ejemplo para adjuntar Frida Stalker cada vez que se llama a una función:
|
|
```javascript
|
|
console.log("loading");
|
|
const wg_log_addr = Module.findExportByName("<Program>", "<function_name>");
|
|
const wg_log = new NativeFunction(
|
|
wg_log_addr,
|
|
"void", ["pointer", "pointer", "pointer"], {
|
|
});
|
|
|
|
Interceptor.attach(wg_log_addr, {
|
|
onEnter: function(args) {
|
|
console.log(`logging the following message: ${args[2].readCString()}`);
|
|
|
|
Stalker.follow({
|
|
events: {
|
|
// only collect coverage for newly encountered blocks
|
|
compile: true,
|
|
},
|
|
onReceive: function (events) {
|
|
const bbs = Stalker.parse(events, {
|
|
stringify: false,
|
|
annotate: false
|
|
});
|
|
console.log("Stalker trace of write_msg_to_log: \n" + bbs.flat().map(DebugSymbol.fromAddress).join('\n'));
|
|
}
|
|
});
|
|
},
|
|
onLeave: function(retval) {
|
|
Stalker.unfollow();
|
|
Stalker.flush(); // this is important to get all events
|
|
}
|
|
});
|
|
```
|
|
{% hint style="danger" %}
|
|
Esto es interesante para fines de depuración, pero para el fuzzing, estar constantemente **`.follow()`** y **`.unfollow()`** es muy ineficiente.
|
|
{% endhint %}
|
|
|
|
## [Fpicker](https://github.com/ttdennis/fpicker)
|
|
|
|
[**fpicker**](https://github.com/ttdennis/fpicker) es una **suite de fuzzing basada en Frida** que ofrece una variedad de modos de fuzzing para el fuzzing en el proceso, como el modo AFL++ o el modo de trazado pasivo. Debería funcionar en todas las plataformas compatibles con Frida.
|
|
|
|
* [**Instalar fpicker**](https://github.com/ttdennis/fpicker#requirements-and-installation) **& radamsa**
|
|
```bash
|
|
# Get fpicker
|
|
git clone https://github.com/ttdennis/fpicker
|
|
cd fpicker
|
|
|
|
# Get Frida core devkit and prepare fpicker
|
|
wget https://github.com/frida/frida/releases/download/16.1.4/frida-core-devkit-16.1.4-[yourOS]-[yourarchitecture].tar.xz
|
|
# e.g. https://github.com/frida/frida/releases/download/16.1.4/frida-core-devkit-16.1.4-macos-arm64.tar.xz
|
|
tar -xf ./*tar.xz
|
|
cp libfrida-core.a libfrida-core-[yourOS].a #libfrida-core-macos.a
|
|
|
|
# Install fpicker
|
|
make fpicker-[yourOS] # fpicker-macos
|
|
# This generates ./fpicker
|
|
|
|
# Install radamsa (fuzzer generator)
|
|
brew install radamsa
|
|
```
|
|
* **Preparar el sistema de archivos:**
|
|
```bash
|
|
# From inside fpicker clone
|
|
mkdir -p examples/wg-log # Where the fuzzing script will be
|
|
mkdir -p examples/wg-log/out # For code coverage and crashes
|
|
mkdir -p examples/wg-log/in # For starting inputs
|
|
|
|
# Create at least 1 input for the fuzzer
|
|
echo Hello World > examples/wg-log/in/0
|
|
```
|
|
* **Script de Fuzzer** (`ejemplos/wg-log/mifuzzer.js`):
|
|
|
|
{% code title="ejemplos/wg-log/mifuzzer.js" %}
|
|
```javascript
|
|
// Import the fuzzer base class
|
|
import { Fuzzer } from "../../harness/fuzzer.js";
|
|
|
|
class WGLogFuzzer extends Fuzzer {
|
|
|
|
constructor() {
|
|
console.log("WGLogFuzzer constructor called")
|
|
|
|
// Get and declare the function we are going to fuzz
|
|
var wg_log_addr = Module.findExportByName("<Program name>", "<func name to fuzz>");
|
|
var wg_log_func = new NativeFunction(
|
|
wg_log_addr,
|
|
"void", ["pointer", "pointer", "pointer"], {
|
|
});
|
|
|
|
// Initialize the object
|
|
super("<Program nane>", wg_log_addr, wg_log_func);
|
|
this.wg_log_addr = wg_log_addr; // We cannot use "this" before calling "super"
|
|
|
|
console.log("WGLogFuzzer in the middle");
|
|
|
|
// Prepare the second argument to pass to the fuzz function
|
|
this.tag = Memory.allocUtf8String("arg2");
|
|
|
|
// Get the first argument we need to pass from a call to the functino we want to fuzz
|
|
var wg_log_global_ptr = null;
|
|
console.log(this.wg_log_addr);
|
|
Interceptor.attach(this.wg_log_addr, {
|
|
onEnter: function(args) {
|
|
console.log("Entering in the function to get the first argument");
|
|
wg_log_global_ptr = new NativePointer(args[0]);
|
|
}
|
|
});
|
|
|
|
while (! wg_log_global_ptr) {
|
|
Thread.sleep(1)
|
|
}
|
|
this.wg_log_global_ptr = wg_log_global_ptr;
|
|
console.log("WGLogFuzzer prepare ended")
|
|
}
|
|
|
|
|
|
// This function is called by the fuzzer with the first argument being a pointer into memory
|
|
// where the payload is stored and the second the length of the input.
|
|
fuzz(payload, len) {
|
|
// Get a pointer to payload being a valid C string (with a null byte at the end)
|
|
var payload_cstring = payload.readCString(len);
|
|
this.payload = Memory.allocUtf8String(payload_cstring);
|
|
|
|
// Debug and fuzz
|
|
this.debug_log(this.payload, len);
|
|
// Pass the 2 first arguments we know the function needs and finally the payload to fuzz
|
|
this.target_function(this.wg_log_global_ptr, this.tag, this.payload);
|
|
}
|
|
}
|
|
|
|
const f = new WGLogFuzzer();
|
|
rpc.exports.fuzzer = f;
|
|
```
|
|
{% endcode %}
|
|
|
|
* **Compila** el fuzzer:
|
|
```bash
|
|
# From inside fpicker clone
|
|
## Compile from "myfuzzer.js" to "harness.js"
|
|
frida-compile examples/wg-log/myfuzzer.js -o harness.js
|
|
```
|
|
* Llamar al fuzzer **`fpicker`** usando **`radamsa`**:
|
|
|
|
{% code overflow="wrap" %}
|
|
```bash
|
|
# Indicate fpicker to fuzz a program with the harness.js script and which folders to use
|
|
fpicker -v --fuzzer-mode active -e attach -p <Program to fuzz> -D usb -o examples/wg-log/out/ -i examples/wg-log/in/ -f harness.js --standalone-mutator cmd --mutator-command "radamsa"
|
|
# You can find code coverage and crashes in examples/wg-log/out/
|
|
```
|
|
{% endcode %}
|
|
|
|
{% hint style="danger" %}
|
|
En este caso **no estamos reiniciando la aplicación ni restaurando el estado** después de cada carga útil. Por lo tanto, si Frida encuentra un **crash**, las **siguientes entradas** después de esa carga útil también podrían **hacer que la aplicación se bloquee** (porque la aplicación está en un estado inestable), incluso si la **entrada no debería hacer que la aplicación se bloquee**.
|
|
|
|
Además, Frida se enganchará en las señales de excepción de iOS, por lo que cuando **Frida encuentra un crash**, probablemente no se generen **informes de crash de iOS**.
|
|
|
|
Para evitar esto, por ejemplo, podríamos reiniciar la aplicación después de cada crash de Frida.
|
|
{% endhint %}
|
|
|
|
### Registros y Crashes
|
|
|
|
Puede verificar la **consola de macOS** o la línea de comandos **`log`** para verificar los registros de macOS.\
|
|
También puede verificar los registros de iOS utilizando **`idevicesyslog`**.\
|
|
Algunos registros omitirán información agregando **`<private>`**. Para mostrar toda la información, debe instalar algún perfil desde [https://developer.apple.com/bug-reporting/profiles-and-logs/](https://developer.apple.com/bug-reporting/profiles-and-logs/) para habilitar esa información privada.
|
|
|
|
Si no sabe qué hacer:
|
|
```sh
|
|
vim /Library/Preferences/Logging/com.apple.system.logging.plist
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>Enable-Private-Data</key>
|
|
<true/>
|
|
</dict>
|
|
</plist>
|
|
|
|
killall -9 logd
|
|
```
|
|
Puedes verificar los fallos en: 
|
|
|
|
* **iOS**
|
|
* Configuración → Privacidad → Análisis y mejoras → Datos de análisis
|
|
* `/private/var/mobile/Library/Logs/CrashReporter/`
|
|
* **macOS**:
|
|
* `/Library/Logs/DiagnosticReports/`
|
|
* `~/Library/Logs/DiagnosticReports`
|
|
|
|
{% hint style="warning" %}
|
|
iOS solo almacena 25 fallos de la misma aplicación, así que debes limpiar eso o iOS dejará de crear fallos.
|
|
{% endhint %}
|
|
|
|
## Tutoriales de Frida para Android
|
|
|
|
{% content-ref url="../android-app-pentesting/frida-tutorial/" %}
|
|
[frida-tutorial](../android-app-pentesting/frida-tutorial/)
|
|
{% endcontent-ref %}
|
|
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
|
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de Telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|