Modifikation von iOS Apps

Eine Anleitung zur Moddifikation und Neupacken von iOS-Apps bei Sicherheitsaudits und Penetrationstests

Dies ist eine übersetzte Version. Das englische Original finden Sie hier.

TL:DR: Es ist per Cydia Impactor möglich, eine manipulierte iOS-Apps neu zu signieren. Das ist wesentlich einfacher als per XCode oder dem Codesign-Tool.

Vor kurzem mussten wir im Rahmen eines Penetrationstests eine iOS-App für einen Kunden analysieren. Wie viele Geschäftsanwendungen haben die Entwickler eine Reihe zusätzlicher Schutzmechanismen implementiert, darunter eine Jailbreak-Erkennung sowie Zertifikatspinning. In diesen Fällen verwenden wir in der Regel ein Framework wie  Frida, um diese Schutzmechanismen zu umgehen und besser mit der Anwendung interagieren sowie die Kommunikation mit dem serverseitigen Backend abfangen können.

Die Verwendung von Frida auf einem gejailbreakten Gerät hat den Vorteil, dass eine Manipulation der Programmdateien nicht notwendig ist, da der Frida-Server einen Agenten zur Laufzeit in das Program injiziert. Es ist aber auch möglich, Frida auf normalen iOS Gerät ohne Jailbraik zu verwenden allerdings muss in diesem Fall die (signierte) FridaGadget.dylib zur Anwendung hinzugefügt werden. Hierdurch wird die Signatur der iOS App ungültig, so dass diese neu signiert werden muss. Weitere Details finden sich in der offiziellen Frida Dokumentation.

Das Signieren einer modifizierten iOS-App kann eine gewisse Herausforderung darstellen, vor allem, wenn man keine umfassende Erfahrungen in der Entwicklung von iOS-Anwendungen besitzt. Zum Glück haben die Mitarbeiter von MWR Labs einen [großartigen Blogbeitrag] (https://labs.mwrinfosecurity.com/blog/repacking-and-resigning-ios-applications/) veröffentlicht, wo sie jeden Schritt detailliert beschreiben.

Wir verwendeten für unsere Analyse ein gejailbreaktes iPhone, weshalb wir die App nicht ändern mussten. Während es jedoch recht einfach war, die Jailbreak-Erkennung durch das Hooken von Funktionen wie “lstat” zu umgehen, stießen wir auf diverse Probleme beim Versuch das Zertifikats-Pinning zu deaktivieren. Das Hauptproblem war, dass wir nicht die “- isEqualToString”-Methode hooken konnten. So wie es aussieht waren wir nicht die ersten mit diesem Problem.

Aus Zeitgründen entschlossen wir uns dieses Problem nicht weiter zu analysieren stattdessen die iOS-Anwendung selbst zu patchen. Dies erfordert eine erneute Signierung der App, unser Ansatz (mittels Cydia Impactor) macht das recht einfach.

Ich werde den gesamten Vorgang (Entpacken/Packen/Neupacken/Signieren) nicht am Zertifikats-Pinning sondern an einer Jailbreak-Erkennung demonstrieren. Der Prozess ist jedoch praktisch identisch.

Entpacken der App

Wir haben die App per App Store auf einem jailbroken iPhone installiert. Da iOS-Apps für das jeweilige Gerät verschlüsselt sind, haben wir “Clutch” verwendet, um die unverschlüsselten Daten aus dem Speicher zu ziehen und in ein IPA-Archiv zu schreiben. Die IPA-Datei wurde im Anschluss per scp auf unser lokales System kopiert, soweit nichts neues…

h0ng10-iPhone:~ root# ./Clutch --dump de.mogwailabs.ios.unhackappleapp
Zipping UnhackableApp.app
ASLR slide: 0x100034000
Dumping <UnhackableApp> (arm64)
Patched cryptid (64bit segment)
Writing new checksum
DONE: /private/var/mobile/Documents/Dumped/de.mogwailabs.ios.unhackappleapp-iOS9.0-(Clutch-2.0.4)-3.ipa
Finished dumping de.mogwailabs.ios.unhackappleapp in 1.2 seconds

IPA-Dateien sind eigentlich ZIP-Archive, mann kann sie daher einfach per “unzip” entpacken. Die eigentliche Binärdatei der App finden Sie im Anschluss im Verzeichnis Payload/UnhackableApp.app.

$ unzip unhackableapp.ipa
Archive:  unhackableapp.ipa
  inflating: iTunesArtwork
  inflating: Payload/UnhackableApp.app/AppIcon20x20@2x.png
  inflating: Payload/UnhackableApp.app/AppIcon20x20@3x.png
  inflating: Payload/UnhackableApp.app/AppIcon29x29@2x.png
  inflating: Payload/UnhackableApp.app/AppIcon29x29@3x.png
  inflating: Payload/UnhackableApp.app/AppIcon40x40@2x.png
  inflating: Payload/UnhackableApp.app/AppIcon40x40@3x.png
  inflating: Payload/UnhackableApp.app/AppIcon60x60@2x.png
  inflating: Payload/UnhackableApp.app/AppIcon60x60@3x.png
  ...

Patching der Binärdateien

Wenn es um die statische Analyse von iOS-Binärcode geht, ist der Hopper disassembler (mein) Werkzeug der Wahl, primär da er eine sehr gute automatischen Annotierung für Objective-C-basierten Code bietet. In diesem Fall werden ich jedoch Binary Ninja verwenden da es eine sehr einfache Modifikation der iOS Binärdatei erlaubt. Binary Ninjas bietet für iOS Code nur begrenzte Annotation, aber man kann trotzdem gute Ergebnisse erzielen. Eine sehr nützliche Funktion ist die Medium Level IL, insbesondere wenn man nicht regelmäßig mit ARM Assemblycode arbeitet. Natürlich steht es jedem frei, beliebigen Disassembler zu verwenden.

In der Regel gestaltet sich die Identifikation von Jailbreak-Erkennungen recht einfach, beispielsweise in dem man nach Aufrufen für Funktionen wie “lstat” oder “exit” sucht. Diese Funktionen werden häufig zur Jailbreak-Erkennung aufgerufen, kommen in normalen iOS App-Code aber praktisch nicht vor. Durch die Analyse der Cross-Referenzen (also der Codestellen, die diese Funktionen aufrufen) lässt sich der eigentliche Jailbreak-Check recht einfach zu identifizieren.

Der Einfachheit halber habe ich die Jailbreak-Funktion in den nächsten Screenshots bereits mit einem besseren Namen (sub_jailbreakdetection) versehen.

iOS Crossreferenz mit BinaryNinja

Der folgende Screenshot zeigt den Einstiegspunkt der iOS App. Die Jailbreakerkennung wird direkt nach dem Start aufgerufen.

Einstiegspunkt der iOS App mit Aufruf der Jailbreak Erkennung

Wir können den Aufruf dieser Funktion “deaktivieren” indem wir ihn durch NOP (No Operation) Anweisungen ersetzen. In Binary Ninja gestaltet sich das sehr einfach, hier muss man einfach auf den Funktionsaufruf klicken und im Kontextmenü die Option “Patch -> Convert to NOP” im Kontextmenü auswählen.

Patchen der iOS App mit BinaryNinja

Im Anschluss müssen wir nur die modifizierte Datei per “File -> Save Contents” speichern und die usprüngliche Datei im entpackten IPA Archiv durch die gepatchte Variante ersetzen.

Repacking der iOS App

Normalerweise müssten wir nun unsere Version der iOS App signieren, dieser Schritt wird jedoch später von Cydia Impactor erledgt. Wir müssen nur das IPA Archiv mit Hilfe des folgenden Befehls erstellen:

zip -qr unhackableapp.ipa *

Signieren / Installation der neuen Version

Als finalen Schritt verwenden wir “Cydia Impactor” zur Re-Installation der modifizierten App auf dem iPhone. Cydia Impactor wird häufig zur Installation von Jailbreak-Apps auf eine iOS Gerät verwendet. Das Tool selbst ist nicht OpenSource, im wesentlichen macht es aber das Folgende:

  • Anmeldung am Apple-Account (mit den zur Verfügung gestellten Zugangsdaten)
  • Erstellung eines neuen Entwickler-Zertifikats, falls kein gültiges existieren sollte
  • Entpacken der Applikation, sowie Signierung mit dem Entwickler-Zertifikat
  • Erneutes Packen der Applikation
  • Installation der Applikation auf dem iOS Gerät

Das funktioniert einwandfrei mit gängigen Jailbreak Apps wie Yalu, es ist jedoch möglich Impactor mit beliebigen iOS Applikationen zu verwenden. Hierzu einfach die modifzierte IPA Datei in das Imactor-Fenster schieben und das Tool erledigt den Rest. Wie bei einem Jailbreak müssen Sie jedoch dem Developer-Zertifikat auf dem iOS Gerät vertrauen.

Wir möglich und verwenden Frida recht häufig, es hat sich jedoch gezeigt das es unter Umständen einfacher ist die entsprechenden Funktionen durch Binary-Patching der Applikation zu deaktivieren. Wenn die existierenden Frida-Scripte nicht funktionieren ist es daher womöglich einfach die App selbst zu ändern


Danke an Free Stocks auf Unsplash für das Titelbild.