Backend, Mobile

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.

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.

Ex-programista

Rozwija 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.

Podobne artykuły

[wpdevart_facebook_comment curent_url="https://geek.justjoin.it/poznajcie-needle-narzedzie-analizy-aplikacji-mobilnych-ios/" order_type="social" width="100%" count_of_comments="8" ]