15 KiB
Konfiguracja Frida w systemie iOS
Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLAN SUBSKRYPCJI!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.
Instalacja Fridy
Kroki do zainstalowania Fridy na urządzeniu z Jailbreakiem:
- Otwórz aplikację Cydia/Sileo.
- Przejdź do Zarządzanie -> Źródła -> Edytuj -> Dodaj.
- Wprowadź "https://build.frida.re" jako adres URL.
- Przejdź do nowo dodanego źródła Fridy.
- Zainstaluj pakiet Frida.
Jeśli korzystasz z Corellium, będziesz musiał pobrać wydanie Fridy ze strony https://github.com/frida/frida/releases (frida-gadget-[yourversion]-ios-universal.dylib.gz
) i rozpakować oraz skopiować do lokalizacji dylib, o którą Frida prosi, np.: /Users/[youruser]/.cache/frida/gadget-ios.dylib
Po zainstalowaniu możesz użyć na swoim komputerze polecenia frida-ls-devices
i sprawdzić, czy urządzenie się pojawia (twój komputer musi mieć do niego dostęp).
Wykonaj również polecenie frida-ps -Uia
w celu sprawdzenia działających procesów na telefonie.
Frida bez urządzenia z Jailbreakiem i bez łatania aplikacji
Sprawdź ten wpis na blogu dotyczący korzystania z Fridy na urządzeniach bez Jailbreaka bez łatania aplikacji: https://mrbypass.medium.com/unlocking-potential-exploring-frida-objection-on-non-jailbroken-devices-without-application-ed0367a84f07
Instalacja klienta Frida
Zainstaluj narzędzia Frida:
pip install frida-tools
pip install frida
Po zainstalowaniu serwera Frida i uruchomieniu i podłączeniu urządzenia, sprawdź, czy klient jest aktywny:
frida-ls-devices # List devices
frida-ps -Uia # Get running processes
Śledzenie Frida
Frida Trace to narzędzie, które umożliwia monitorowanie i analizowanie wywołań funkcji w czasie rzeczywistym na urządzeniach iOS. Działa poprzez wstrzykiwanie kodu JavaScript do aplikacji, co umożliwia przechwytywanie i analizowanie danych.
Konfiguracja Frida na urządzeniu iOS
Aby skonfigurować Fridę na urządzeniu iOS, wykonaj następujące kroki:
-
Zainstaluj Fridę na swoim urządzeniu iOS. Możesz to zrobić za pomocą narzędzia Cydia lub poprzez pobranie pliku IPA z oficjalnej strony Fridy i zainstalowanie go za pomocą narzędzia Cydia Impactor.
-
Po zainstalowaniu Fridy na urządzeniu, uruchom aplikację Frida z ekranu głównego.
-
W aplikacji Frida wybierz opcję "Start Server", aby uruchomić serwer Frida na urządzeniu.
-
Następnie otwórz terminal na swoim komputerze i wykonaj poniższą komendę, aby połączyć się z serwerem Frida na urządzeniu:
frida-ps -U
Po wykonaniu tych kroków będziesz gotowy do korzystania z Fridy Trace na urządzeniu iOS. Możesz teraz monitorować i analizować wywołania funkcji w aplikacjach na urządzeniu w czasie rzeczywistym.
# 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 '*[* *]'
Pobierz wszystkie klasy i metody
- Autouzupełnianie: Po prostu wykonaj polecenie
frida -U <program>
- Pobierz wszystkie dostępne klasy (filtrowane za pomocą ciągu znaków)
{% code title="/tmp/script.js" %}
// 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 %}
- Pobierz wszystkie metody klasy (filtrowane za pomocą ciągu znaków)
{% code title="/tmp/script.js" %}
// 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 %}
- Wywołaj funkcję
// 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
Z dokumentacji: Stalker to silnik śledzenia kodu Frida. Pozwala na śledzenie wątków, przechwytując każdą funkcję, każdy blok, nawet każdą instrukcję, która jest wykonywana.
Przykład implementacji Frida Stalker znajduje się pod adresem https://github.com/poxyran/misc/blob/master/frida-stalker-example.py
Oto kolejny przykład dołączania Frida Stalker za każdym razem, gdy wywoływana jest funkcja:
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" %}
To jest interesujące z punktu widzenia debugowania, ale dla fuzzingu, ciągłe .follow()
i .unfollow()
jest bardzo nieefektywne.
{% endhint %}
Fpicker
fpicker to zestaw narzędzi do fuzzingu oparty na Frida, który oferuje różne tryby fuzzingu dla fuzzingu w procesie, takie jak tryb AFL++ lub tryb pasywnego śledzenia. Powinien działać na wszystkich platformach obsługiwanych przez Fridę.
- Zainstaluj fpicker & radamsa
# 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
- Przygotuj system plików:
# 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
- Skrypt Fuzzer (
examples/wg-log/myfuzzer.js
):
{% code title="examples/wg-log/myfuzzer.js" %}
// 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 %}
- Skompiluj fuzzer:
# From inside fpicker clone
## Compile from "myfuzzer.js" to "harness.js"
frida-compile examples/wg-log/myfuzzer.js -o harness.js
- Wywołaj fuzzer
fpicker
używającradamsa
:
{% code overflow="wrap" %}
# 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" %} W tym przypadku nie restartujemy aplikacji ani nie przywracamy stanu po każdym payloadzie. Jeśli Frida znajdzie crash, następne wejścia po tym payloadzie mogą również spowodować crash aplikacji (ponieważ aplikacja znajduje się w niestabilnym stanie), nawet jeśli wejście nie powinno spowodować crashu aplikacji.
Ponadto, Frida będzie podłączona do sygnałów wyjątków iOS, więc gdy Frida znajdzie crash, prawdopodobnie nie zostanie wygenerowany raport o crashu iOS.
Aby temu zapobiec, na przykład, możemy zrestartować aplikację po każdym crashu Frida. {% endhint %}
Logi i Crashe
Możesz sprawdzić konsolę macOS lub log
cli, aby sprawdzić logi macOS.
Możesz również sprawdzić logi z iOS za pomocą idevicesyslog
.
Niektóre logi pomijają informacje, dodając <private>
. Aby wyświetlić wszystkie informacje, musisz zainstalować pewien profil z https://developer.apple.com/bug-reporting/profiles-and-logs/, aby włączyć te prywatne informacje.
Jeśli nie wiesz, co zrobić:
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
Możesz sprawdzić awarie w:
- iOS
- Ustawienia → Prywatność → Analityka i ulepszenia → Dane analityczne
/private/var/mobile/Library/Logs/CrashReporter/
- macOS:
/Library/Logs/DiagnosticReports/
~/Library/Logs/DiagnosticReports
{% hint style="warning" %} iOS przechowuje tylko 25 awarii tej samej aplikacji, więc musisz to wyczyścić, w przeciwnym razie iOS przestanie tworzyć awarie. {% endhint %}
Samouczki Frida dla Androida
{% content-ref url="../android-app-pentesting/frida-tutorial/" %} frida-tutorial {% endcontent-ref %}
Odwołania
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLAN SUBSKRYPCJI!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.