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.
Podobne artykuły

Krytyczne spojrzenie na kod jest kluczowy dla jego skutecznej analizy. Jak analizować systemy legacy

Sieci neuronowe. PyTorch i praktyczny projekt od początku do końca

Od czego zacząć swoją przygodę w branży IT? Rozmowa z Jackiem Hrynczyszynem, Java Developerem

Kim jest Software Architect? Obowiązki, specjalizacje, kariera

Co nowego w Javie? Przegląd zmian, które przyniosło JDK 20

Efektywne zarządzanie Protocoll Buffers z “Buf”. Wszystko, co powinieneś wiedzieć

Czy Scala to wciąż dobry język dla programistów w 2023 roku?
