[PL] Needle - analiza aplikacji mobilnych iOS
Wstęp
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.
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.
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:
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 informacja 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.