Poznajcie Needle, narzędzie do analizy aplikacji mobilnych iOS
Needle wspomaga analizę bezpieczeństwa aplikacji na platformie iOS. Składa się z modułów, które korzystają z wielu dostępnych na tej platformie narzędzi, znacznie upraszczając pracę z nimi. Został stworzony przez MWRLabs, czyli twórców popularnego w androidowym środowisku Drozera. Podobnie jak Drozer, działa w architekturze klient — serwer. Uruchamiany na komputerze klient przesyła polecenia do serwera działającego na urządzeniu mobilnym.
Michał Dardas. Ex-programista, rozwijający się jako tester bezpieczeństwa aplikacji mobilnych oraz webowych w firmie LogicalTrust. Doświadczenie nabyte podczas rozwijania projektów związanych z branżą bankową i tłumaczeniową daje mu lepszy wgląd w testowane aplikacje oraz wiedzę, jak chronić je z punktu widzenia programisty. Razem z serwisem Zaufana Trzecia Strona prowadzi otwarte warsztaty z bezpieczeństwa aplikacji mobilnych.
Zapoznamy się z procesem instalacji i konfiguracji oraz obsługą na przykładzie kilku modułów. Opis został przygotowany używając urządzenia z iOS 10. Część modułów może zachowywać się niepoprawnie lub nie działać na poszczególnych wersjach systemu.
Spis treści
Instalacja na urządzeniu
Wymagane są:
- urządzenie z iOS (8, 9 lub 10) po jailbreaku,
- Cydia,
- APT 0.7 Strict,
- Needle Agent — serwer.
Opcjonalne zależności:
- Frida — narzędzie do dynamicznego modyfikowania uruchomionych aplikacji, wykorzystywane przez niektóre moduły Needle.
- Clutch2 — narzędzie do deszyfrowania plików binarnych aplikacji, wykorzystywane przez jeden z modułów.
Proces instalacji
Do repozytoriów Cydii dodajemy:
http://mobiletools.mwrinfosecurity.com/cydia/
https://build.frida.re
Następnie możemy już zainstalować pakiety:
- NeedleAgent,
- Frida,
- Clutch2.
Instalacja klienta na komputerze
Needle oficjalnie ma wsparcie dla dwóch systemów — macOS i Kali Linux. Bez problemów można uruchomić narzędzie również na Ubuntu.
Instalacja zależności
Kali Linux
# Unix packages sudo apt-get install python2.7 python2.7-dev sshpass sqlite3 lib32ncurses5-dev # Python packages sudo pip install readline paramiko sshtunnel frida mitmproxy biplist
macOS
# Core dependencies brew install python brew install libxml2 xcode-select --install # Python packages sudo -H pip install --upgrade --user readline sudo -H pip install --upgrade --user paramiko sudo -H pip install --upgrade --user sshtunnel sudo -H pip install --upgrade --user frida sudo -H pip install --upgrade --user biplist # sshpass brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb # mitmproxy wget https://github.com/mitmproxy/mitmproxy/releases/download/v0.17.1/mitmproxy-0.17.1-osx.tar.gz tar -xvzf mitmproxy-0.17.1-osx.tar.gz sudo cp mitmproxy-0.17.1-osx/mitm* /usr/local/bin/
Instalacja Needle
Pobieramy projekt z GitHuba:
git clone https://github.com/mwrlabs/needle.git
lub
wget https://github.com/mwrlabs/needle/archive/master.zip unzip master.zip
Uruchomienie i konfiguracja
Uruchomienie serwera
Włączamy aplikację NeedleAgent na urządzeniu i aktywujemy przełącznik Listen.
Uruchomienie klienta
Klienta uruchamiamy na komputerze za pomocą polecenia:
python needle/needle/needle.py
Konfiguracja
Po uruchomieniu konieczne jest skonfigurowanie komunikacji między komputerem a urządzeniem. W opisywanym przypadku odbywała się ona za pośrednictwem Wi-Fi, jednak istnieje też możliwość komunikacji przez USB.
IP urządzenia (lub localhost dla połączenia USB):
[needle] > set IP 192.168.0.198 IP => 192.168.0.198
Port urządzenia, na którym uruchomiona jest usługa SSH:
[needle] > set PORT 22 PORT => 22
Hasło do konta root na urządzeniu. (Domyśle to alpine):
[needle] > set PASSWORD alpine PASSWORD => ********
Dodatkowo można jeszcze wyłączyć wyświetlanie w narzędziu aplikacji systemowych, co ułatwia wyszukiwanie zainstalowanych aplikacji.
[needle] > set HIDE_SYSTEM_APPS True HIDE_SYSTEM_APPS => True
Konfiguracja z pliku
Konfigurowanie Needle jest konieczne przy każdym uruchomieniu. Możemy to sobie ułatwić tworząc plik, który zawiera wybrane polecenia.
set IP 192.168.0.198 set PORT 22 set HIDE_SYSTEM_APPS True
Dodatkowy parametr -r, przy uruchamianiu Needle sprawi, że konfiguracja zostanie wczytana z pliku.
python needle/needle/needle.py -r needle_config
| \ | |______ |______ | \ | |______ | \_| |______ |______ |_____/ |_____ |______ Needle v1.3.2 [mwr.to/needle] [MWR InfoSecurity (@MWRLabs) - Marco Lancini (@LanciniMarco)] [*] Loading commands from resource file [needle] > set IP 192.168.0.198 IP => 192.168.0.198 [needle] > set PORT 22 PORT => 22 [needle] > set HIDE_SYSTEM_APPS True HIDE_SYSTEM_APPS => True [needle] > EOF [+] Resource file successfully loaded
W akcji
Po instalacji i konfiguracji, mając przed sobą ekran główny Needle, możemy zająć się analizą zainstalowanych aplikacji.
Polecenia
- show modules — wyświetla moduły,
- use <moduł> — wybiera moduł,
- show info — wyświetla informacje o wybranym module,
- show options — wyświetla ustawienia wybranego modułu,
- set <zmienna> <wartość> — przypisuje wartość do zmiennej,
- back — cofa wybór modułu,
- unset app — cofa wybór aplikacji,
- exec_command <polecenie> — wykonuje polecenie na urządzeniu,
- run — uruchamia wybrany moduł.
Wybór aplikacji
Aplikację wybieramy podczas pierwszego uruchomienia modułu lub po wywołaniu unset app.
[*] Target app not selected. Launching wizard... [+] Apps found: 0 - com.ppjb.carrier102.gr-b2a4274fd7effad67acd1f5b146e8691903c0cac-1500288363.35 1 - com.highaltitudehacks.dvia 2 - com.atebits.Tweetie2 [>][QUESTION] Please select a number: 1
Moduły
Metadata
Moduł binary/info/metadata wyświetla szczegółowe informacje na temat aplikacji. Do dalszej analizy przydatne są:
- data directory — katalog z danymi aplikacji,
- binary directory — katalog z plikami binarnymi aplikacji,
- URL Handlers — schematy URL używane przez aplikację,
- Apple Transport Security Settings – ustawienia rozluźniające restrykcje mechanizmu, który wymusza używanie HTTPS,
- Entitlements — uprawnienia aplikacji.
Moduł wybieramy za pomocą polecenia:
use binary/info/metadata
a następnie uruchamiamy:
run
Z otrzymanej odpowiedzi wynika, że:
- dane aplikacji znajdują się w /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B,
- pliki binarne znajdują się w /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app,
- Aplikacja posiada swój schemat URL dvia,
- Aplikacja zezwala na komunikację protokołem HTTP.
[needle] > use binary/info/metadata [needle][metadata] > run [*] Checking connection with device... [V] Connection not present, creating a new instance [V] [AGENT] Connecting to agent (192.168.0.198:4444)... [+] [AGENT] Successfully connected to agent (192.168.0.198:4444)... [V] [SSH] Connecting (192.168.0.198:22)... [+] [SSH] Connected (192.168.0.198:22) [*] Target app not selected. Launching wizard... [+] Apps found: 0 - com.ppjb.carrier102.gr-b2a4274fd7effad67acd1f5b146e8691903c0cac-1500288363.35 1 - com.highaltitudehacks.dvia 2 - com.atebits.Tweetie2 [>][QUESTION] Please select a number: 1 [+] Target app: com.highaltitudehacks.dvia [*] Retrieving app's metadata... [*] Pulling: /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Info.plist -> /root/.needle/tmp/plist [+] Name : DVIA [+] Binary Name : DamnVulnerableIOSApp [+] Bundle Executable : DamnVulnerableIOSApp [+] Bundle ID : com.highaltitudehacks.dvia [+] Bundle Type : User [+] UUID : 9CE2809B-AD4F-4FBF-AB18-198062E39903 [+] Team ID : [+] Signer Identity : Apple iPhone OS Application Signing [+] Bundle Directory : /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903 [+] Binary Directory : /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app [+] Binary Path : /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp [+] Data Directory : /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B [+] Bundle Package Type : APPL [+] App Version : 2.0 [+] Architectures : arm64 [+] Platform Version : 9.2 [+] SDK Version : 9.2 [+] Minimum OS : 7.0 [+] URL Handlers [+] ['dvia'] [+] Apple Transport Security Settings [!] NSAllowsArbitraryLoads : 1 [+] Entitlements [+] application-identifier : com.highaltitudehacks.dvia [*] No Application Extensions found
Keyboard autocomplete
iOS posiada mechanizm autokorekty, który przechowuje słowa wpisywane na klawiaturze. Aplikacje powinny wyłączać autokorektę dla pól z wrażliwymi danymi. Moduł storage/caching/keyboard_autocomplete pozwala to zweryfikować poprzez wyświetlenie wszystkich zapamiętanych wyrazów.
[needle] > use storage/caching/keyboard_autocomplete [needle][keyboard_autocomplete] > run [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [*] Running strings over keyboard autocomplete databases... [+] The following content has been found: DynamicDictionary-5 emails notes p4ssw0rd secret [*] Saving output to file: /root/.needle/output/keyboard_autocomplete.txt
Property list
Format plist służy do przechowywania informacji w formie klucz — wartość. Zapisywane w nim są m.in. informacje o aplikacji oraz ustawienia użytkowników. Moduł storage/data/files_plist wyszukuje wszystkie pliki plist powiązane z aplikacją i umożliwia wyświetlanie ich zawartości.
[needle] > use storage/data/files_plist [needle][files_plist] > run [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [+] Target app: com.highaltitudehacks.dvia [*] Looking for Plist files... [*] Retrieving data protection classes... [*] The following Plist files have been found: 0 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/.com.apple.mobile_container_manager.metadata.plist 1 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Base.lproj/Main.storyboardc/Info.plist 2 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Info.plist 3 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Model.momd/VersionInfo.plist 4 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Watch/DamnVulnerableIOSApp WatchKit App.app/Base.lproj/Interface.plist 5 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Watch/DamnVulnerableIOSApp WatchKit App.app/Info.plist 6 - [found ] /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Watch/DamnVulnerableIOSApp WatchKit App.app/PlugIns/DamnVulnerableIOSApp WatchKit Extension.appex/Info.plist 7 - [found ] /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B/.com.apple.mobile_container_manager.metadata.plist 8 - [found ] /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B/Documents/userInfo.plist 9 - [found ] /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B/Library/Preferences/com.apple.EmojiCache.plist 10 - [found ] /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B/Library/Preferences/com.highaltitudehacks.dvia.plist [>][QUESTION] Please select a number: 8 [*] Pulling: /private/var/mobile/Containers/Data/Application/09ACB084-A5A6-45F2-B421-5AF4BE3A1E0B/Documents/userInfo.plist -> /root/.needle/tmp/plist { 'password': 'p4ssw0rd', 'username': 'user123'} [*] Saving output to file: /root/.needle/output/plist_datadir_Documents_userInfo.plist
Strings
Znajomość stringów znajdujących się w pliku binarnym aplikacji znacznie ułatwia analizę. Wśród nich można znaleźć np. informacje o ukrytych opcjach aplikacji albo wykorzystywanych zewnętrznych usługach sieciowych, czasem łącznie z zaszytymi w kodzie hasłami. Aplikacje pobrane z AppStore są zaszyfrowane, dlatego przed przeszukaniem pliku konieczne jest odszyfrowanie go. Moduł binary/reversing/strings automatyzuje ten proces z wykorzystaniem narzędzia Clutch2.
Uruchomienie tego modułu może okazać się problematyczne w porównaniu do pozostałych.
Przy pierwszej próbie uruchomienia dowiadujemy się, że moduł ten nie jest wspierany na obecnej wersji systemu (iOS 10). Można jednak spróbować wykonać drobną modyfikację w kodzie Needle.
[needle] > use binary/reversing/strings [needle][strings] > run [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [!] FrameworkException: This module is not currently supported by the iOS version of the device in use (iOS 10)
Otwieramy plik needle/core/utils/contants.py
vim needle/needle/core/utils/constants.py
i komentujemy w nim linię jak poniżej. Sprawi to, że Needle nie będzie blokował modułu w iOS 10.
MODULES_DISABLED = { '10': [ 'binary/installation/install', 'binary/installation/pull_ipa', 'binary/reversing/class_dump', # 'binary/reversing/strings' ] }
Restartujemy Needle (mając przygotowany plik konfiguracyjny warto pamiętać o -r). Przy kolejnej próbie odpalenia modułu dowiadujemy się, że nie mamy uprawnień do uruchomienia Clutch2.
[needle] > use binary/reversing/strings [needle][strings] > run [?] Attention! The folder chosen to store local output is not empty: /root/.needle/output [?] Do you want to back it up first? [?] Y: the content will be archived in a different location, then the folder will be emptied [?] N: no action will be taken (destination files might be overwritten in case of filename clash) [y/n]: n [*] Checking connection with device... [V] Connection not present, creating a new instance [V] [AGENT] Connecting to agent (192.168.0.198:4444)... [+] [AGENT] Successfully connected to agent (192.168.0.198:4444)... [V] [SSH] Connecting (192.168.0.198:22)... [+] [SSH] Connected (192.168.0.198:22) [*] Target app not selected. Launching wizard... [+] Apps found: 0 - com.ppjb.carrier102.gr-b2a4274fd7effad67acd1f5b146e8691903c0cac-1500288363.35 1 - com.highaltitudehacks.dvia 2 - com.atebits.Tweetie2 [>][QUESTION] Please select a number: 1 [+] Target app: com.highaltitudehacks.dvia [*] Retrieving app's metadata... [*] Pulling: /private/var/containers/Bundle/Application/9CE2809B-AD4F-4FBF-AB18-198062E39903/DamnVulnerableIOSApp.app/Info.plist -> /root/.needle/tmp/plist [*] Decrypting the binary... [!] Clutch2 could not be run successfully so the binary could not be decrypted [!] Exception: Please confirm that Clutch2 is marked as executable (using chmod +x /usr/bin/Clutch* from a device shell)
Rozwiązujemy to nadając prawa do wykonywania.
[needle][strings] > exec_command chmod +x /usr/bin/Clutch2 [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [*] Executing: chmod +x /usr/bin/Clutch2
Ostatecznie moduł udaje się uruchomić.
[needle][strings] > run [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [+] Target app: com.highaltitudehacks.dvia [*] Decrypting the binary... [?] The app might be already decrypted. Trying to retrieve the IPA... [*] Unpacking the IPA... [V] Analyzing binary... [V] Analyzing resources... [+] The following strings have been found: T@"NSArray",R,D,N _generateNonce _hasKnownObject: setSwiftListIvar: T@"<GAITracker>",N,V_tracker T@,R,N,VsortingBlock ecommerce_macro_data Autocreator was not cleared before dealloc. T@"NSString",C,V_startKeyDocID hasUsageContextArray UIRuntimeEventConnection @"YapDatabaseFullTextSearchConnection" errorWithCode:withFailedFilePath:withFormat: TB,N,V_transitionInProgress gcacheExpirationSeconds Invalid value N7tightdb7CompareINS_8NotEqualExNS_7SubexprES2_EE 4f3-bi-TPr.text
Class Dump
Nagłówki klas aplikacji są kolejnym cennym źródłem informacji. Pozwalają w prosty sposób zapoznać się ze strukturą aplikacji. Moduł binary/reversing/class_dump_frida_enum-all-methods wykorzystuje narzędzie Frida do odczytania nazw klas i metod w wybranej aplikacji.
Przed pierwszym uruchomieniem modułu należy uruchomić serwer Fridy.
[needle] > exec_command /usr/sbin/frida-server -D [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [*] Executing: /usr/sbin/frida-server -D
[needle] > use binary/reversing/class_dump_frida_enum-all-methods [needle][class_dump_frida_enum-all-methods] > run [*] Checking connection with device... [+] Already connected to: 192.168.0.198 [+] Target app: com.swaroop.iGoat [*] Setting up local port forwarding to enable communications with the Frida server... [*] Launching the app... [V] Retrieving the PID... [V] PID found: 1069 [*] Attaching to process: 1068 [*] Parsing payload [?] Script terminated abruptly [?] timeout was reached [+] "Class: FigIrisAutoTrimmerMotionSampleExport" [+] { "class": "FigIrisAutoTrimmerMotionSampleExport", "method": "+ initialize" } [+] "Class: _CNZombie_" [+] { "class": "_CNZombie_", "method": "+ initialize" }
Pozostałe moduły
Needle jest pełen modułów, inne warte sprawdzenia to:
- binary/info/checksums — oblicza sumy kontrolne dla pliku binarnego.
- binary/info/compilation_checks — sprawdza czy plik binarny posiada odpowiednie zabezpieczenia (szyfrowanie, stack canaries, ARC, PIE).
- binary/info/universal_links — wyświetla Universal Links zdefiniowane dla aplikacji.
- dynamic/ipc/open_uri — uruchamia podany URI.
- static/code_checks — analizuje kod źródłowy (jeśli jest dostępny) pod kątem podatności.
- storage/backup/icloud_content_frida — wyświetla listę plików, które trafiają do kopii zapasowych.
- storage/data/container — wyświetla i pobiera zawartość katalogów Bundle i Data.
- storage/data/files_binarycookies — wyświetla Binary Cookies używane przez aplikację.
- storage/data/files_cachedb — wyświetla pliki tymczasowe Cache.db.
- storage/data/files_sql — wyświetla pliki zawierające bazy danych.
- storage/data/keychain_dump_frida — wyciąga zawartość Keychain, która należy do aplikacji.
Artykuł został pierwotnie opublikowany na logicaltrust.github.io.