iOS Basics

Support HackTricks

Separacja uprawnień i piaskownica

W iOS istnieje rozróżnienie w uprawnieniach między aplikacjami dostępnymi dla użytkownika a podstawowymi procesami systemowymi. Aplikacje działają pod tożsamością użytkownika mobile, podczas gdy kluczowe procesy systemowe działają jako root. To rozdzielenie jest wzmocnione mechanizmem piaskownicy, który narzuca surowe ograniczenia dotyczące działań, jakie mogą podejmować aplikacje. Na przykład, nawet jeśli aplikacje dzielą tę samą tożsamość użytkownika, nie mają prawa dostępu ani modyfikacji danych innych aplikacji.

Aplikacje są instalowane w określonym katalogu (private/var/mobile/Applications/{random ID}) i mają ograniczony dostęp do odczytu niektórych obszarów systemowych i funkcji, takich jak SMS i połączenia telefoniczne. Dostęp do chronionych obszarów wywołuje prośbę o zgodę użytkownika.

Ochrona danych

iOS oferuje deweloperom API Ochrony Danych, zbudowane na Secure Enclave Processor (SEP) — dedykowanym koprocesorze do operacji kryptograficznych i zarządzania kluczami. SEP zapewnia integralność ochrony danych za pomocą unikalnego klucza specyficznego dla urządzenia, UID urządzenia, wbudowanego w niego.

Po utworzeniu pliku generowany jest unikalny klucz szyfrowania AES o długości 256 bitów, który szyfruje zawartość pliku. Ten klucz szyfrowania, wraz z identyfikatorem klasy, jest następnie szyfrowany za pomocą klucza klasy i przechowywany w metadanych pliku. Odszyfrowanie pliku polega na użyciu klucza systemowego do uzyskania dostępu do metadanych, odzyskaniu klucza klasy za pomocą identyfikatora klasy, a następnie odszyfrowaniu unikalnego klucza szyfrowania pliku.

iOS definiuje cztery klasy ochrony dla bezpieczeństwa danych, które określają, kiedy i jak dane mogą być dostępne:

  • Pełna ochrona (NSFileProtectionComplete): Dane są niedostępne, dopóki urządzenie nie zostanie odblokowane za pomocą kodu dostępu użytkownika.

  • Chronione, chyba że otwarte (NSFileProtectionCompleteUnlessOpen): Umożliwia dostęp do pliku nawet po zablokowaniu urządzenia, pod warunkiem, że plik był otwarty, gdy urządzenie zostało odblokowane.

  • Chronione do pierwszej autoryzacji użytkownika (NSFileProtectionCompleteUntilFirstUserAuthentication): Dane są dostępne po pierwszym odblokowaniu przez użytkownika po uruchomieniu, pozostając dostępnymi nawet jeśli urządzenie zostanie zablokowane ponownie.

  • Brak ochrony (NSFileProtectionNone): Dane są chronione tylko przez UID urządzenia, co ułatwia szybkie zdalne usuwanie danych.

Szyfrowanie wszystkich klas, z wyjątkiem NSFileProtectionNone, polega na kluczu pochodzącym zarówno z UID urządzenia, jak i kodu dostępu użytkownika, co zapewnia, że odszyfrowanie jest możliwe tylko na urządzeniu z poprawnym kodem dostępu. Od iOS 7 domyślną klasą ochrony jest "Chronione do pierwszej autoryzacji użytkownika".

Deweloperzy mogą korzystać z FileDP, narzędzia do sprawdzania klasy ochrony danych plików na iPhonie.

# Example code to use FileDP for checking file protection class
# Note: Ensure your device is jailbroken and has Python installed to use FileDP.
# Installation and usage of FileDP:
git clone https://github.com/abjurato/FileDp-Source
cd FileDp-Source
python filedp.py /path/to/check

Keychain

W iOS, Keychain służy jako bezpieczny szyfrowany kontener do przechowywania wrażliwych informacji, dostępny tylko dla aplikacji, która go przechowuje lub tych, które są wyraźnie autoryzowane. To szyfrowanie jest wzmacniane przez unikalne hasło generowane przez iOS, które samo w sobie jest szyfrowane za pomocą AES. Proces szyfrowania wykorzystuje funkcję PBKDF2, łącząc kod dostępu użytkownika z solą pochodzącą z UID urządzenia, komponentem, do którego dostęp ma tylko układ scalony secure enclave. W konsekwencji, nawet jeśli kod dostępu użytkownika jest znany, zawartość Keychain pozostaje niedostępna na jakimkolwiek urządzeniu innym niż to, na którym pierwotnie została zaszyfrowana.

Zarządzanie i dostęp do danych Keychain są obsługiwane przez demona securityd, w oparciu o konkretne uprawnienia aplikacji, takie jak Keychain-access-groups i application-identifier.

Operacje API Keychain

API Keychain, szczegółowo opisane w dokumentacji usług Keychain Apple, zapewnia niezbędne funkcje do zarządzania bezpiecznym przechowywaniem:

  • SecItemAdd: Dodaje nowy element do Keychain.

  • SecItemUpdate: Aktualizuje istniejący element w Keychain.

  • SecItemCopyMatching: Pobiera element z Keychain.

  • SecItemDelete: Usuwa element z Keychain.

Brute-forcing hasła Keychain polega na atakowaniu zaszyfrowanego klucza bezpośrednio lub próbie odgadnięcia kodu dostępu na samym urządzeniu, co jest znacznie utrudnione przez egzekwowanie opóźnienia między nieudanymi próbami przez secure enclave.

Konfigurowanie ochrony danych elementów Keychain

Poziomy ochrony danych dla elementów Keychain są ustawiane za pomocą atrybutu kSecAttrAccessible podczas tworzenia lub aktualizacji elementu. Poziomy te, zgodnie z określeniami Apple, określają, kiedy i jak elementy Keychain są dostępne:

  • kSecAttrAccessibleAlways: Dostępne w każdej chwili, niezależnie od statusu blokady urządzenia.

  • kSecAttrAccessibleAlwaysThisDeviceOnly: Zawsze dostępne, ale nie włączone do kopii zapasowych.

  • kSecAttrAccessibleAfterFirstUnlock: Dostępne po pierwszym odblokowaniu po restarcie.

  • kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly: To samo co powyżej, ale nieprzenoszalne na nowe urządzenia.

  • kSecAttrAccessibleWhenUnlocked: Dostępne tylko wtedy, gdy urządzenie jest odblokowane.

  • kSecAttrAccessibleWhenUnlockedThisDeviceOnly: Dostępne po odblokowaniu, nie włączone do kopii zapasowych.

  • kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly: Wymaga kodu dostępu do urządzenia, nie włączone do kopii zapasowych.

AccessControlFlags dodatkowo precyzują metody dostępu, umożliwiając uwierzytelnianie biometryczne lub użycie kodu dostępu.

Ostrzeżenie o urządzeniach z jailbreakiem

Na urządzeniach z jailbreakiem, ochrona Keychain jest naruszona, co stanowi znaczące ryzyko bezpieczeństwa.

Trwałość danych Keychain

W przeciwieństwie do danych specyficznych dla aplikacji, które są usuwane po odinstalowaniu aplikacji, dane Keychain pozostają na urządzeniu. Ta cecha może umożliwić nowym właścicielom urządzenia z drugiej ręki dostęp do danych aplikacji poprzedniego właściciela po prostu przez ponowne zainstalowanie aplikacji. Programiści są zachęcani do proaktywnego usuwania danych Keychain po instalacji aplikacji lub podczas wylogowywania, aby zminimalizować to ryzyko. Oto przykład kodu Swift demonstrujący, jak usunąć dane Keychain po pierwszym uruchomieniu aplikacji:

let userDefaults = UserDefaults.standard

if userDefaults.bool(forKey: "hasRunBefore") == false {
// Remove Keychain items here

// Update the flag indicator
userDefaults.set(true, forKey: "hasRunBefore")
userDefaults.synchronize() // Forces the app to update UserDefaults
}

Możliwości aplikacji

W dziedzinie rozwoju aplikacji, sandboxing odgrywa kluczową rolę w zwiększaniu bezpieczeństwa. Proces ten zapewnia, że każda aplikacja działa w swoim unikalnym katalogu domowym, co zapobiega jej dostępowi do plików systemowych lub danych należących do innych aplikacji. Egzekwowanie tych ograniczeń odbywa się poprzez polityki sandbox, które są częścią Trusted BSD (MAC) Mandatory Access Control Framework.

Programiści mają możliwość skonfigurowania określonych możliwości lub uprawnień dla swoich aplikacji, takich jak Ochrona danych lub Udostępnianie Keychain. Te uprawnienia są stosowane natychmiast po zainstalowaniu aplikacji. Niemniej jednak, aby uzyskać dostęp do niektórych chronionych zasobów, aplikacja musi uzyskać wyraźną zgodę od użytkownika w momencie pierwszej próby. Osiąga się to poprzez użycie ciągów celów lub ciągów opisów użycia, które są prezentowane użytkownikom w powiadomieniu o żądaniu uprawnień.

Dla tych, którzy mają dostęp do kodu źródłowego, weryfikacja uprawnień zawartych w pliku Info.plist może być przeprowadzona poprzez:

  1. Otworzenie projektu w Xcode.

  2. Zlokalizowanie i otwarcie pliku Info.plist.

  3. Wyszukiwanie kluczy z prefiksem "Privacy -", z opcją wyświetlenia surowych kluczy/wartości dla jasności.

W przypadku pliku IPA, można postępować według następujących kroków:

  1. Rozpakowanie IPA.

  2. Zlokalizowanie pliku Info.plist w Payload/<nazwa_aplikacji>.app/.

  3. Konwersja pliku do formatu XML, jeśli to konieczne, dla łatwiejszej inspekcji.

Na przykład, ciągi celów w pliku Info.plist mogą wyglądać następująco:

<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is used to provide turn-by-turn directions to your destination.</string>

Device Capabilities

Plik Info.plist aplikacji określa możliwości urządzenia, które pomagają App Store filtrować aplikacje pod kątem zgodności z urządzeniem. Są one zdefiniowane pod kluczem UIRequiredDeviceCapabilities. Na przykład:

<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>

Ten przykład wskazuje, że aplikacja jest zgodna z zestawem instrukcji armv7. Programiści mogą również określić możliwości, takie jak nfc, aby zapewnić, że ich aplikacja jest dostępna tylko dla urządzeń obsługujących NFC.

Uprawnienia

Uprawnienia to kolejny kluczowy aspekt rozwoju aplikacji iOS, działający jako pary klucz-wartość, które przyznają aplikacjom pozwolenie na wykonywanie określonych operacji wykraczających poza kontrole w czasie wykonywania. Na przykład, włączenie Ochrony Danych w aplikacji polega na dodaniu konkretnego uprawnienia w projekcie Xcode, co jest następnie odzwierciedlane w pliku uprawnień aplikacji lub w osadzonym pliku mobilnym dla IPA.

Odniesienia

Support HackTricks

Last updated