Zgłębiaj swoją wiedzę w Bezpieczeństwie Mobilnym z 8kSec Academy. Opanuj bezpieczeństwo iOS i Androida dzięki naszym kursom w trybie samodzielnym i zdobądź certyfikat:
Instalacja Frida
Kroki do zainstalowania Frida na urządzeniu z jailbreakiem:
Otwórz aplikację Cydia/Sileo.
Przejdź do Zarządzaj -> Źródła -> Edytuj -> Dodaj.
Wprowadź "https://build.frida.re" jako URL.
Przejdź do nowo dodanego źródła Frida.
Zainstaluj pakiet Frida.
Jeśli używasz Corellium, musisz pobrać wersję Frida z https://github.com/frida/frida/releases (frida-gadget-[twojawersja]-ios-universal.dylib.gz) i rozpakować oraz skopiować do lokalizacji dylib, o którą prosi Frida, np.: /Users/[twojuser]/.cache/frida/gadget-ios.dylib
Po zainstalowaniu możesz użyć na swoim PC komendy frida-ls-devices i sprawdzić, czy urządzenie się pojawia (twój PC musi mieć do niego dostęp).
Wykonaj również frida-ps -Uia, aby sprawdzić działające procesy telefonu.
Frida bez urządzenia z jailbreakiem i bez patchowania aplikacji
Z zainstalowanym serwerem Frida i działającym oraz podłączonym urządzeniem, sprawdź, czy klient działa:
frida-ls-devices# List devicesfrida-ps-Uia# Get running processes
Frida Trace
# Functions## Trace all functions with the word "log" in their namefrida-trace-U<program>-i"*log*"frida-trace-U<program>-i"*log*"|swiftdemangle# Demangle names# Objective-C## Trace all methods of all classesfrida-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 binaryfrida-trace-U-W<if-plugin-bin>-m'*[* *]'
Pobierz wszystkie klasy i metody
Auto uzupełnianie: Wystarczy wykonać frida -U <program>
Pobierz wszystkie dostępne klasy (filtruj według ciągu)
Uzyskaj wszystkiemetodyklasy (filtruj według ciągu)
/tmp/script.js
// frida -U <program> -l /tmp/script.jsvar 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.");}
Wywołaj funkcję
// Find the address of the function to callconstfunc_addr=Module.findExportByName("<Prog Name>","<Func Name>");// Declare the function to callconstfunc=newNativeFunction(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 arg0Interceptor.attach(wg_log_addr, {onEnter:function(args) {arg0 =newNativePointer(args[0]);}});// Wait untill a call to the func occurswhile (! 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 Fridy. Umożliwia śledzenie wątków, rejestrując każdą funkcję, każdy blok, a nawet każdą instrukcję, która jest wykonywana.
To kolejny przykład, aby dołączyć Frida Stalker za każdym razem, gdy funkcja jest wywoływana:
console.log("loading");constwg_log_addr=Module.findExportByName("<Program>","<function_name>");constwg_log=newNativeFunction(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 blockscompile:true,},onReceive:function (events) {constbbs=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}});
To jest interesujące z punktu widzenia debugowania, ale do fuzzingu, ciągłe .follow() i .unfollow() jest bardzo nieefektywne.
fpicker to zestaw fuzzingowy oparty na Frida, który oferuje różne tryby fuzzingu do fuzzingu w procesie, takie jak tryb AFL++ lub tryb pasywnego śledzenia. Powinien działać na wszystkich platformach obsługiwanych przez Frida.
# Get fpickergitclonehttps://github.com/ttdennis/fpickercdfpicker# Get Frida core devkit and prepare fpickerwgethttps://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.xztar-xf./*tar.xzcplibfrida-core.alibfrida-core-[yourOS].a#libfrida-core-macos.a# Install fpickermakefpicker-[yourOS]# fpicker-macos# This generates ./fpicker# Install radamsa (fuzzer generator)brewinstallradamsa
Przygotuj FS:
# From inside fpicker clonemkdir-pexamples/wg-log# Where the fuzzing script will bemkdir-pexamples/wg-log/out# For code coverage and crashesmkdir-pexamples/wg-log/in# For starting inputs# Create at least 1 input for the fuzzerechoHelloWorld>examples/wg-log/in/0
Skrypt Fuzzer (examples/wg-log/myfuzzer.js):
examples/wg-log/myfuzzer.js
// Import the fuzzer base classimport { Fuzzer } from"../../harness/fuzzer.js";classWGLogFuzzerextendsFuzzer {constructor() {console.log("WGLogFuzzer constructor called")// Get and declare the function we are going to fuzzvar wg_log_addr =Module.findExportByName("<Program name>","<func name to fuzz>");var wg_log_func =newNativeFunction(wg_log_addr,"void", ["pointer","pointer","pointer"], {});// Initialize the objectsuper("<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 functionthis.tag =Memory.allocUtf8String("arg2");// Get the first argument we need to pass from a call to the functino we want to fuzzvar 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 =newNativePointer(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 fuzzthis.debug_log(this.payload, len);// Pass the 2 first arguments we know the function needs and finally the payload to fuzzthis.target_function(this.wg_log_global_ptr,this.tag,this.payload);}}constf=newWGLogFuzzer();rpc.exports.fuzzer = f;
Skompiluj fuzzer:
# From inside fpicker clone## Compile from "myfuzzer.js" to "harness.js"frida-compileexamples/wg-log/myfuzzer.js-oharness.js
Wywołaj fuzzer fpicker za pomocą radamsa:
# Indicate fpicker to fuzz a program with the harness.js script and which folders to usefpicker-v--fuzzer-modeactive-eattach-p<Programtofuzz>-Dusb-oexamples/wg-log/out/-iexamples/wg-log/in/-fharness.js--standalone-mutatorcmd--mutator-command"radamsa"# You can find code coverage and crashes in examples/wg-log/out/
W tym przypadku nie restartujemy aplikacji ani nie przywracamy stanu po każdym ładunku. Więc, jeśli Frida znajdzie awarię, następne wejścia po tym ładunku mogą również spowodować awarię aplikacji (ponieważ aplikacja jest w niestabilnym stanie), nawet jeśli wejście nie powinno spowodować awarii aplikacji.
Ponadto, Frida będzie przechwytywać sygnały wyjątków iOS, więc gdy Frida znajdzie awarię, prawdopodobnie raporty o awariach iOS nie będą generowane.
Aby temu zapobiec, na przykład, moglibyśmy zrestartować aplikację po każdej awarii Fridy.
Logi i awarie
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 będą pomijać informacje, dodając <private>. Aby pokazać wszystkie informacje, musisz zainstalować jakiś profil z https://developer.apple.com/bug-reporting/profiles-and-logs/, aby włączyć te prywatne informacje.
Pogłęb swoją wiedzę w Mobile Security z 8kSec Academy. Opanuj bezpieczeństwo iOS i Android dzięki naszym kursom w trybie samodzielnym i zdobądź certyfikat: