
Coverage-gesteuerter In-Process-Fuzzer für den iOS Bluetooth-Daemon (bluetoothd) unter Verwendung von FRIDA, mit Over-the-Air-Fuzzing für das MagicPairing-Protokoll und Crash-Replay-Funktionen.

ToothPicker ist ein In-Prozess-, abdeckungsgesteuerter Fuzzer für iOS. Er wurde entwickelt, um
gezielt den Bluetooth-Daemon bluetoothd von iOS anzugreifen und verschiedene Bluetooth-Protokolle
auf iOS zu analysieren. Da er mit FRIDA erstellt wurde, kann er an jede
Plattform angepasst werden, die FRIDA unterstützt.
Dieses Repository enthält außerdem einen Over-the-Air-Fuzzer mit einer beispielhaften Implementierung
zum Fuzzing des Apple MagicPairing-Protokolls mittels
InternalBlue. Zusätzlich enthält es das
Skript ReplayCrashFile.py, mit dem Abstürze verifiziert werden können, die der In-Prozess-Fuzzer
gefunden hat.
Dies ist ein sehr einfacher Fuzzer, der nur Bits und Bytes in aktiven Verbindungen umdreht. Keine Abdeckungssteuerung, keine Injektion, aber nett als Demo und zustandsbehaftet. Läuft nur mit Python+Frida, keine Module oder Installation erforderlich. Getestet auf iOS 13.5-14.3. Siehe inplace-fuzzer.
Der In-Prozess-Fuzzer funktioniert sofort auf verschiedenen iOS-Versionen (13.3-13.7 getestet), aber Symbole müssen angegeben werden. Andere iOS-Versionen erfordern Anpassungen an den Funktionsadressen. Zudem scheint FRIDAs Stalker einige Probleme mit dem iPhone 8 zu haben. Auf neueren iPhones, die PAC unterstützen, leidet die Leistung erheblich unter dem Signieren von Zeigern. Daher wird empfohlen, dies auf einem iPhone 7 auszuführen.
ToothPicker basiert auf der Codebasis von
frizzer. Es wurde jedoch für diese spezielle Anwendung
angepasst und ist daher nicht mehr mit der Originalversion kompatibel.
Es gibt Pläne, dies in Zukunft durch eine speziellere Komponente zu ersetzen.
Auf dem iPhone:
Auf Linux:
Für Arch-basiertes Linux:
# usbmuxd kommt normalerweise mit libimobiledevice
# aber um sicherzugehen, installieren wir es manuell
sudo pacman -S usbmuxd libimobiledevice python-virtualenv radamsa
# Verbinde das iPhone mit dem Computer
# Entsperre es.
# Falls ein Pairing-Popup erscheint, klicke auf "Trust"
# Falls kein Pairing-Popup erscheint:
idevicepair pair
# Jetzt sollte das Popup erscheinen, akzeptiere es und dann nochmal:
idevicepair pair
# Bei Verbindungsfehlern:
sudo systemctl restart usbmuxd
# oder iPhone und Computer erneut paaren
# Andere nützliche Befehle
# Für SSH auf das iPhone:
# Checkra1n hat einen SSH-Server auf Port 44
# Proxye den SSH-Port des Telefons auf lokalen Port 4444:
iproxy 4444 44
# Verbinden:
ssh root@localhost -p 4444
# Standardpasswort: alpine
# Zum Abrufen von Geräteinformationen des iPhones:
ideviceinfo
Für Debian Linux:
Fast das Gleiche wie oben. Ausnahmen:
radamsa muss aus dem Git-Repository installiert werden, da
es nicht paketiert ist.iproxy benötigt das zusätzliche Paket libusbmuxd-tools.Für macOS:
Etwas andere Befehle im Vergleich zum Arch-Linux-Setup...
brew install libimobiledevice usbmuxd radamsa npm
idevicepair pair
npm install frida-compile
pip3 install frida-tools
Auf macOS kann PacketLogger, das Teil der Additional Tools for Xcode ist, verschiedene Pakete decodieren, sobald das Bluetooth Debug Profile installiert ist. Wenn man außerdem iOS-Crashlogs mit Xcode öffnet, werden einige Symbole hinzugefügt.
Einrichtung:
frizzer einzurichten.frizzer ausführst.projects enthält ein Beispielprojekt zum Fuzzing des MagicPairing-Protokolls.MagicPairing-Harness in eine Datei.harness und installiere frida-compile.
Beachte, dass dies in diesem Ordner ausgeführt werden muss und direkt als Benutzer durch npm install frida-compile installiert werden kann.frida-compile ../projects/YOUR_PROJECT/YOUR_SPECIALIZED_HARNESS.JS -o ../projects/YOUR_PROJECT/harness.js aus.
Da dies im npm-Kontext installiert wurde, muss möglicherweise stattdessen npx frida-compile ausgeführt werden.
Jedes Mal, wenn sich die Harness ändert, muss frida-compile erneut ausgeführt werden.Fuzzing:
killall -9 bluetoothd aus, um bluetoothd frisch zu starten.mkdir crashes) und führe ../../frizzer/fuzzer.py fuzz -p . aus.Kurz gesagt, um ein neues Projekt zu starten, führe aus:
cd harness
npx frida-compile ../projects/YOUR_PROJECT/YOUR_SPECIALIZED_HARNESS.JS -o ../projects/YOUR_PROJECT/harness.js
cd ../projects/YOUR_PROJECT/
mkdir crashes
../../frizzer/fuzzer.py fuzz -p .
Du kannst mit einem anderen Seed beginnen, indem du frizzer/fuzzer.py fuzz --seed 1234 -p . verwendest.
Hinzufügen neuer iOS-Versionen:
Derzeit sind verschiedene iOS-Versionen in bluetoothd.js definiert. Diese findest du mit dem Ghidra-Versionierungstool, wenn du eine initiale Version hast, die alle erforderlichen Symbole enthält. Beachte, dass einige von ihnen nicht im ursprünglichen iOS-Binary benannt sind, also beginne idealerweise mit einer, die bereits annotiert wurde.
Jedes Mal, wenn bluetoothd.js geändert wird, musst du frida-compile erneut ausführen.
Erhöhen der bluetoothd-Kapazitäten:
iOS-Crashlogs werden unter Einstellungen -> Datenschutz -> Analyse & Verbesserungen -> Analysedaten gespeichert.
Wenn sie bluetoothd-Abstürze des Musters bluetoothd.cpu_resource-*.ips enthalten, deutet dies darauf hin,
dass der Absturz durch Überschreiten von Ressourcen verursacht wurde. Diese können wie folgt erhöht werden.
Auf einem iPhone 7 führe aus:
cd /System/Library/LaunchDaemons/
plistutil -i com.apple.jetsamproperties.D10.plist -o com.apple.jetsamproperties.D10.plist.txt
plistutil -i com.apple.jetsamproperties.D101.plist -o com.apple.jetsamproperties.D101.plist.txt
Auf dem iPhone SE2 befinden sich diese in com.apple.jetsamproperties.D79.plist:
cd /System/Library/LaunchDaemons/
plistutil -i com.apple.jetsamproperties.D79.plist -o com.apple.jetsamproperties.D79.plist.txt
Suche nach bluetoothd, aktualisiere die Priorität auf 19 (höchste gültige Priorität) und setze das Speicherlimit auf einen sehr hohen Wert.
Wende dieselben Änderungen auf beide Dateien an.
<dict>
<key>ActiveSoftMemoryLimit</key>
<integer>24000</integer>
<key>InactiveHardMemoryLimit</key>
<integer>24000</integer>
<key>EnablePressuredExit</key>
<false/>
<key>JetsamPriority</key>
<integer>19</integer>
</dict>
Schreibe die Änderungen zurück und starte bluetoothd neu.
plistutil -i com.apple.jetsamproperties.D10.plist.txt -o com.apple.jetsamproperties.D10.plist
plistutil -i com.apple.jetsamproperties.D101.plist.txt -o com.apple.jetsamproperties.D101.plist
killall -9 bluetoothd
Entsprechend auf dem iPhone SE2:
plistutil -i com.apple.jetsamproperties.D79.plist.txt -o com.apple.jetsamproperties.D79.plist
killall -9 bluetoothd
Löschen alter Logs:
iOS hört auf, Crashlogs für ein Programm zu speichern, nachdem das Limit von 25 erreicht ist. Wenn ein Crashlog mit Xcode (über Simulatoren & Geräte) geladen wird, werden einige Symbole zum Stacktrace hinzugefügt.
Sobald das Limit erreicht ist, können die Logs entweder über Xcode oder direkt auf dem iOS-Gerät gelöscht werden, indem sie im Ordner /var/mobile/Library/Logs/CrashReporter/ gelöscht werden.
A12+:
Ab dem iPhone XR/Xs wurde PAC eingeführt. Dies erfordert den Aufruf von sign() auf NativeFunction
in FRIDA. Während dies auf früheren CPUs ein No-Op ist, reduziert es die Geschwindigkeit auf neueren Geräten enorm, ist aber erforderlich, damit sie überhaupt funktionieren. Wir haben beobachtet, dass ToothPicker bei Verwendung eines iPhone SE2 anstelle eines iPhone 7 mit halber Geschwindigkeit arbeitet.
Die MagicPairing-Implementierung des Over-the-Air-Fuzzers erfordert, dass InternalBlue installiert ist und
kann durch Ausführen von python MagicPairingFuzzer.py TARGET_BD_ADDR gestartet werden.
Wenn du Abstürze reproduzieren möchtest, verwende das Skript ReplayCrashFile.py, das eine Crash-Datei übernehmen und eine Over-the-Air-Verbindung mit einer auf dem Absturz basierenden Nutzlast initiieren kann.