# Configurazione di Frida su iOS
Impara l'hacking di AWS da zero a esperto conhtARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
* Se vuoi vedere la tua **azienda pubblicizzata su HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PACCHETTI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
* Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com)
* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di [**NFT esclusivi**](https://opensea.io/collection/the-peass-family)
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Condividi i tuoi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
## Installazione di Frida
**Passaggi per installare Frida su un dispositivo Jailbroken:**
1. Apri l'app Cydia/Sileo.
2. Vai su Gestisci -> Sorgenti -> Modifica -> Aggiungi.
3. Inserisci "https://build.frida.re" come URL.
4. Vai alla nuova sorgente di Frida appena aggiunta.
5. Installa il pacchetto Frida.
Se stai usando **Corellium**, dovrai scaricare la versione di Frida da [https://github.com/frida/frida/releases](https://github.com/frida/frida/releases) (`frida-gadget-[tua versione]-ios-universal.dylib.gz`) e decomprimere e copiare nella posizione dylib richiesta da Frida, ad esempio: `/Users/[tuo utente]/.cache/frida/gadget-ios.dylib`
Dopo l'installazione, puoi utilizzare il comando **`frida-ls-devices`** sul tuo PC e verificare che il dispositivo appaia (il tuo PC deve essere in grado di accedervi).\
Esegui anche **`frida-ps -Uia`** per verificare i processi in esecuzione sul telefono.
## Frida senza dispositivo Jailbroken e senza patch dell'app
Consulta questo post sul blog su come utilizzare Frida su dispositivi non jailbroken senza patch dell'app: [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)
## Installazione del client Frida
Installa **gli strumenti di Frida**:
```bash
pip install frida-tools
pip install frida
```
Con il server Frida installato e il dispositivo in esecuzione e connesso, **verifica** se il client sta **funzionando**:
```bash
frida-ls-devices # List devices
frida-ps -Uia # Get running processes
```
## Frida Trace
Frida Trace is a powerful dynamic instrumentation tool that allows you to trace function calls and monitor the behavior of an iOS application in real-time. It can be used for various purposes, such as debugging, reverse engineering, and vulnerability analysis.
To configure Frida Trace in iOS, follow these steps:
1. **Install Frida**: First, you need to install Frida on your iOS device. You can do this by using the Frida command-line tools or by downloading the Frida package from the official website.
2. **Connect to the iOS device**: Once Frida is installed, connect your iOS device to your computer using a USB cable. Make sure that the device is unlocked and the screen is active.
3. **Start the Frida server**: Open a terminal window and start the Frida server by running the following command:
```
frida-server -l 0.0.0.0
```
This will start the Frida server and listen for incoming connections on all network interfaces.
4. **Install the Frida client**: On your computer, install the Frida client by running the following command:
```
pip install frida-tools
```
This will install the Frida client, which allows you to interact with the Frida server running on the iOS device.
5. **Connect to the iOS application**: To trace a specific iOS application, you need to know its bundle identifier. You can find this information by opening the application's Info.plist file or by using tools like `ideviceinstaller` or `frida-ps`.
Once you have the bundle identifier, run the following command to connect to the application:
```
frida -U -l
```
Replace `` with the path to your Frida script and `` with the bundle identifier of the application you want to trace.
6. **Write the Frida script**: In your Frida script, you can define the functions you want to trace and specify the actions to be performed when these functions are called. You can also access and modify the arguments and return values of the traced functions.
Here is an example of a Frida script that traces the `NSLog` function:
```javascript
Interceptor.attach(Module.findExportByName(null, 'NSLog'), {
onEnter: function(args) {
console.log('NSLog called with arguments: ' + args[0].readUtf8String());
}
});
```
Save your Frida script with a `.js` extension.
7. **Run the Frida script**: Finally, run the Frida script by executing the following command:
```
frida -U -l
```
This will start the tracing process and display the output in the terminal window.
By following these steps, you can configure Frida Trace in iOS and start tracing the behavior of iOS applications in real-time.
```bash
# Functions
## Trace all functions with the word "log" in their name
frida-trace -U -i "*log*"
frida-trace -U -i "*log*" | swift demangle # Demangle names
# Objective-C
## Trace all methods of all classes
frida-trace -U -m "*[* *]"
## Trace all methods with the word "authentication" from classes that start with "NE"
frida-trace -U -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 -m '*[* *]'
```
### Ottenere tutte le classi e i metodi
* Completamento automatico: Esegui semplicemente `frida -U `
* Ottenere **tutte** le **classi** disponibili (filtrate per stringa)
{% code title="/tmp/script.js" %}
```javascript
// frida -U -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 %}
* Ottieni **tutti** i **metodi** di una **classe** (filtrati per stringa)
{% code title="/tmp/script.js" %}
```javascript
// frida -U -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 %}
* **Chiamare una funzione**
```javascript
// Find the address of the function to call
const func_addr = Module.findExportByName("", "");
// 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
[Dalla documentazione](https://frida.re/docs/stalker/#:~:text=Stalker%20is%20Frida's%20code%20tracing,every%20instruction%20which%20is%20executed.): Stalker è il motore di tracciamento del codice di Frida. Consente di seguire i thread, catturando ogni funzione, ogni blocco e persino ogni istruzione eseguita.
Ecco un esempio che implementa Frida Stalker in [https://github.com/poxyran/misc/blob/master/frida-stalker-example.py](https://github.com/poxyran/misc/blob/master/frida-stalker-example.py)
Questo è un altro esempio per attaccare Frida Stalker ogni volta che viene chiamata una funzione:
```javascript
console.log("loading");
const wg_log_addr = Module.findExportByName("", "");
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" %}
Questo è interessante per scopi di debug, ma per il fuzzing, essere costantemente **`.follow()`** e **`.unfollow()`** è molto inefficiente.
{% endhint %}
## [Fpicker](https://github.com/ttdennis/fpicker)
[**fpicker**](https://github.com/ttdennis/fpicker) è una **suite di fuzzing basata su Frida** che offre una varietà di modalità di fuzzing per il fuzzing in-process, come ad esempio una modalità AFL++ o una modalità di tracciamento passivo. Dovrebbe funzionare su tutte le piattaforme supportate da Frida.
* [**Installare 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
```
* **Preparare il file system:**
```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 Fuzzer** (`examples/wg-log/myfuzzer.js`):
{% code title="examples/wg-log/myfuzzer.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("", "");
var wg_log_func = new NativeFunction(
wg_log_addr,
"void", ["pointer", "pointer", "pointer"], {
});
// Initialize the object
super("", 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 %}
* **Compilare** il fuzzer:
```bash
# From inside fpicker clone
## Compile from "myfuzzer.js" to "harness.js"
frida-compile examples/wg-log/myfuzzer.js -o harness.js
```
* Chiama il fuzzer **`fpicker`** utilizzando **`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 -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" %}
In questo caso **non stiamo riavviando l'app o ripristinando lo stato** dopo ogni payload. Quindi, se Frida trova un **crash**, i **successivi input** dopo quel payload potrebbero anche **far crashare l'app** (perché l'app è in uno stato instabile) anche se l'**input non dovrebbe far crashare** l'app.
Inoltre, Frida si aggancerà ai segnali di eccezione di iOS, quindi quando **Frida trova un crash**, probabilmente non verrà generato un **report di crash di iOS**.
Per prevenire ciò, ad esempio, potremmo riavviare l'app dopo ogni crash di Frida.
{% endhint %}
### Log e Crash
Puoi controllare la **console di macOS** o il **cli `log`** per controllare i log di macOS.\
Puoi controllare anche i log da iOS utilizzando **`idevicesyslog`**.\
Alcuni log ometteranno informazioni aggiungendo **``**. Per mostrare tutte le informazioni è necessario installare alcuni profili da [https://developer.apple.com/bug-reporting/profiles-and-logs/](https://developer.apple.com/bug-reporting/profiles-and-logs/) per abilitare quelle informazioni private.
Se non sai cosa fare:
```sh
vim /Library/Preferences/Logging/com.apple.system.logging.plist
Enable-Private-Data
killall -9 logd
```
Puoi controllare i crash in:
* **iOS**
* Impostazioni → Privacy → Analytics e miglioramenti → Dati di analisi
* `/private/var/mobile/Library/Logs/CrashReporter/`
* **macOS**:
* `/Library/Logs/DiagnosticReports/`
* `~/Library/Logs/DiagnosticReports`
{% hint style="warning" %}
iOS memorizza solo 25 crash della stessa app, quindi è necessario pulirli o iOS smetterà di crearli.
{% endhint %}
## Tutorial Frida Android
{% content-ref url="../android-app-pentesting/frida-tutorial/" %}
[frida-tutorial](../android-app-pentesting/frida-tutorial/)
{% endcontent-ref %}
## Riferimenti
* [https://www.briskinfosec.com/blogs/blogsdetail/Getting-Started-with-Frida](https://www.briskinfosec.com/blogs/blogsdetail/Getting-Started-with-Frida)
Impara l'hacking di AWS da zero a eroe conhtARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
* Se vuoi vedere la tua **azienda pubblicizzata in HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PACCHETTI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
* Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com)
* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusive [**NFT**](https://opensea.io/collection/the-peass-family)
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Condividi i tuoi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.