[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:

Enter Cydia/APT URL

Następnie możemy już zainstalować pakiety:

  • NeedleAgent
  • Frida
  • Clutch2

Install NeedleAgent

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.

NeedleAgent

Uruchomienie klienta

Klienta uruchamiamy na komputerze za pomocą polecenia:

python needle/needle/needle.py

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.
Written on February 21, 2018 by Michał Dardas