# iOS Pentesting {{#include ../../banners/hacktricks-training.md}} ## iOS Osnove {{#ref}} ios-basics.md {{#endref}} ## Testno Okruženje Na ovoj stranici možete pronaći informacije o **iOS simulatoru**, **emulatorima** i **jailbreak-u:** {{#ref}} ios-testing-environment.md {{#endref}} ## Početna Analiza ### Osnovne iOS Testne Operacije Tokom testiranja **several operations are going to be suggested** (connect to the device, read/write/upload/download files, use some tools...). Stoga, ako ne znate kako da izvršite neku od ovih radnji, molimo vas da **počnete da čitate stranicu**: {{#ref}} basic-ios-testing-operations.md {{#endref}} > [!TIP] > Za sledeće korake **aplikacija treba da bude instalirana** na uređaju i treba da je već preuzela **IPA datoteku** aplikacije.\ > Pročitajte stranicu [Basic iOS Testing Operations](basic-ios-testing-operations.md) da biste saznali kako to da uradite. ### Osnovna Staticka Analiza Neki zanimljivi iOS - IPA dekompilatori: - [https://github.com/LaurieWired/Malimite](https://github.com/LaurieWired/Malimite) - [https://ghidra-sre.org/](https://ghidra-sre.org/) Preporučuje se korišćenje alata [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) za izvođenje automatske Staticke Analize na IPA datoteci. Identifikacija **zaštita prisutnih u binarnom kodu**: - **PIE (Position Independent Executable)**: Kada je omogućeno, aplikacija se učitava na nasumičnu adresu u memoriji svaki put kada se pokrene, što otežava predviđanje njene početne adrese u memoriji. ```bash otool -hv | grep PIE # Trebalo bi da uključuje PIE flag ``` - **Stack Canaries**: Da bi se proverila integritet stoga, ‘canary’ vrednost se postavlja na stek pre pozivanja funkcije i ponovo se proverava kada funkcija završi. ```bash otool -I -v | grep stack_chk # Trebalo bi da uključuje simbole: stack_chk_guard i stack_chk_fail ``` - **ARC (Automatic Reference Counting)**: Da bi se sprečili uobičajeni problemi sa oštećenjem memorije ```bash otool -I -v | grep objc_release # Trebalo bi da uključuje _objc_release simbol ``` - **Enkriptovana Binarna Datoteka**: Binarna datoteka treba da bude enkriptovana ```bash otool -arch all -Vl | grep -A5 LC_ENCRYPT # Kriptid treba da bude 1 ``` **Identifikacija Osetljivih/Neosiguranih Funkcija** - **Slabi Hashing Algoritmi** ```bash # Na iOS uređaju otool -Iv | grep -w "_CC_MD5" otool -Iv | grep -w "_CC_SHA1" # Na linuxu grep -iER "_CC_MD5" grep -iER "_CC_SHA1" ``` - **Neosigurane Nasumične Funkcije** ```bash # Na iOS uređaju otool -Iv | grep -w "_random" otool -Iv | grep -w "_srand" otool -Iv | grep -w "_rand" # Na linuxu grep -iER "_random" grep -iER "_srand" grep -iER "_rand" ``` - **Neosigurana ‘Malloc’ Funkcija** ```bash # Na iOS uređaju otool -Iv | grep -w "_malloc" # Na linuxu grep -iER "_malloc" ``` - **Neosigurane i Ranljive Funkcije** ```bash # Na iOS uređaju otool -Iv | grep -w "_gets" otool -Iv | grep -w "_memcpy" otool -Iv | grep -w "_strncpy" otool -Iv | grep -w "_strlen" otool -Iv | grep -w "_vsnprintf" otool -Iv | grep -w "_sscanf" otool -Iv | grep -w "_strtok" otool -Iv | grep -w "_alloca" otool -Iv | grep -w "_sprintf" otool -Iv | grep -w "_printf" otool -Iv | grep -w "_vsprintf" # Na linuxu 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" ``` ### Osnovna Dinamička Analiza Pogledajte dinamičku analizu koju [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) vrši. Moraćete da se krećete kroz različite prikaze i komunicirate sa njima, ali će se povezati sa nekoliko klasa dok radite druge stvari i pripremiće izveštaj kada završite. ### Listing Instaliranih Aplikacija Koristite komandu `frida-ps -Uai` da odredite **bundle identifier** instaliranih aplikacija: ```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 ``` ### Osnovna Enumeracija i Hooking Naučite kako da **enumerišete komponente aplikacije** i kako lako da **hook-ujete metode i klase** sa objection: {{#ref}} ios-hooking-with-objection.md {{#endref}} ### IPA Struktura Struktura **IPA datoteke** je suštinski kao **zipovana paketa**. Preimenovanjem ekstenzije u `.zip`, može se **dekompresovati** da bi se otkrio njen sadržaj. Unutar ove strukture, **Bundle** predstavlja potpuno upakovanu aplikaciju spremnu za instalaciju. Unutra, naći ćete direktorijum nazvan `.app`, koji obuhvata resurse aplikacije. - **`Info.plist`**: Ova datoteka sadrži specifične konfiguracione detalje aplikacije. - **`_CodeSignature/`**: Ovaj direktorijum uključuje plist datoteku koja sadrži potpis, osiguravajući integritet svih datoteka u paketu. - **`Assets.car`**: Kompresovana arhiva koja čuva datoteke resursa poput ikona. - **`Frameworks/`**: Ova fascikla sadrži nativne biblioteke aplikacije, koje mogu biti u obliku `.dylib` ili `.framework` datoteka. - **`PlugIns/`**: Ovo može uključivati ekstenzije aplikacije, poznate kao `.appex` datoteke, iako one nisu uvek prisutne. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): Koristi se za čuvanje trajnih podataka vaše aplikacije za offline korišćenje, za keširanje privremenih podataka i za dodavanje funkcionalnosti poništavanja u vašu aplikaciju na jednom uređaju. Da bi se podaci sinhronizovali između više uređaja u jednom iCloud nalogu, Core Data automatski odražava vašu šemu u CloudKit kontejneru. - [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): Datoteka `PkgInfo` je alternativni način za određivanje tipa i kodova kreatora vaše aplikacije ili paketa. - **en.lproj, fr.proj, Base.lproj**: To su jezički paketi koji sadrže resurse za te specifične jezike, i podrazumevani resurs u slučaju da jezik nije podržan. - **Bezbednost**: Direktorijum `_CodeSignature/` igra ključnu ulogu u bezbednosti aplikacije verifikovanjem integriteta svih datoteka u paketu putem digitalnih potpisa. - **Upravljanje Resursima**: Datoteka `Assets.car` koristi kompresiju za efikasno upravljanje grafičkim resursima, što je ključno za optimizaciju performansi aplikacije i smanjenje njene ukupne veličine. - **Frameworks i PlugIns**: Ovi direktorijumi naglašavaju modularnost iOS aplikacija, omogućavajući programerima da uključe ponovo upotrebljive biblioteke koda (`Frameworks/`) i prošire funkcionalnost aplikacije (`PlugIns/`). - **Lokalizacija**: Struktura podržava više jezika, olakšavajući globalni doseg aplikacije uključivanjem resursa za specifične jezičke pakete. **Info.plist** **Info.plist** služi kao kamen temeljac za iOS aplikacije, obuhvatajući ključne konfiguracione podatke u obliku **ključ-vrednost** parova. Ova datoteka je neophodna ne samo za aplikacije već i za ekstenzije aplikacija i frameworke koji su upakovani unutar. Struktuirana je u XML ili binarnom formatu i sadrži kritične informacije koje se kreću od dozvola aplikacije do bezbednosnih konfiguracija. Za detaljno istraživanje dostupnih ključeva, možete se obratiti [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc). Za one koji žele da rade sa ovom datotekom u pristupačnijem formatu, konverzija u XML može se lako postići korišćenjem `plutil` na macOS-u (dostupno nativno na verzijama 10.2 i novijim) ili `plistutil` na Linuxu. Komande za konverziju su sledeće: - **Za macOS**: ```bash $ plutil -convert xml1 Info.plist ``` - **Za Linux**: ```bash $ apt install libplist-utils $ plistutil -i Info.plist -o Info_xml.plist ``` Među mnoštvom informacija koje **Info.plist** datoteka može otkriti, značajni unosi uključuju stringove dozvola aplikacije (`UsageDescription`), prilagođene URL sheme (`CFBundleURLTypes`), i konfiguracije za App Transport Security (`NSAppTransportSecurity`). Ovi unosi, zajedno sa drugim poput eksportovanih/importovanih prilagođenih tipova dokumenata (`UTExportedTypeDeclarations` / `UTImportedTypeDeclarations`), mogu se lako pronaći pregledanjem datoteke ili korišćenjem jednostavne `grep` komande: ```bash $ grep -i Info.plist ``` **Data Paths** U iOS okruženju, direktorijumi su posebno dodeljeni za **sistemske aplikacije** i **aplikacije instalirane od strane korisnika**. Sistemske aplikacije se nalaze u direktorijumu `/Applications`, dok se aplikacije instalirane od strane korisnika nalaze pod `/var/mobile/containers/Data/Application/`. Ove aplikacije imaju jedinstveni identifikator poznat kao **128-bit UUID**, što otežava ručno lociranje fascikle aplikacije zbog nasumičnosti imena direktorijuma. > [!WARNING] > Kako aplikacije u iOS moraju biti u sandboxu, svaka aplikacija će takođe imati fasciklu unutar **`$HOME/Library/Containers`** sa **`CFBundleIdentifier`** aplikacije kao naziv fascikle. > > Međutim, obe fascikle (fascikle podataka i kontejnera) imaju datoteku **`.com.apple.mobile_container_manager.metadata.plist`** koja povezuje obe datoteke u ključnoj `MCMetadataIdentifier`). Da bi se olakšalo otkrivanje direktorijuma instalacije aplikacije instalirane od strane korisnika, **objection tool** pruža korisnu komandu, `env`. Ova komanda otkriva detaljne informacije o direktorijumu za dotičnu aplikaciju. Ispod je primer kako koristiti ovu komandu: ```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 ``` Alternativno, ime aplikacije može se pretraživati unutar `/private/var/containers` koristeći `find` komandu: ```bash find /private/var/containers -name "Progname*" ``` Komande kao što su `ps` i `lsof` se takođe mogu koristiti za identifikaciju procesa aplikacije i listanje otvorenih fajlova, redom, pružajući uvide u aktivne putanje direktorijuma aplikacije: ```bash ps -ef | grep -i lsof -p | grep -i "/containers" | head -n 1 ``` **Bundle directory:** - **AppName.app** - Ovo je Application Bundle kao što je viđeno ranije u IPA, sadrži osnovne podatke aplikacije, statički sadržaj kao i kompajlirani binarni fajl aplikacije. - Ova direktorija je vidljiva korisnicima, ali **korisnici ne mogu pisati u nju**. - Sadržaj u ovoj direktoriji **nije backup-ovan**. - Sadržaj ove fascikle se koristi za **validaciju potpisa koda**. **Data directory:** - **Documents/** - Sadrži sve podatke koje generišu korisnici. Krajnji korisnik aplikacije pokreće kreiranje ovih podataka. - Vidljivo korisnicima i **korisnici mogu pisati u nju**. - Sadržaj u ovoj direktoriji je **backup-ovan**. - Aplikacija može onemogućiti putanje postavljanjem `NSURLIsExcludedFromBackupKey`. - **Library/** - Sadrži sve **fajlove koji nisu specifični za korisnika**, kao što su **keš**, **preferencije**, **kolačići** i konfiguracione datoteke (plist). - iOS aplikacije obično koriste poddirektorije `Application Support` i `Caches`, ali aplikacija može kreirati prilagođene poddirektorije. - **Library/Caches/** - Sadrži **polu-permanentne keširane fajlove.** - Nevidljivo korisnicima i **korisnici ne mogu pisati u nju**. - Sadržaj u ovoj direktoriji **nije backup-ovan**. - OS može automatski obrisati fajlove iz ove direktorije kada aplikacija nije pokrenuta i kada je prostor za skladištenje nizak. - **Library/Application Support/** - Sadrži **permanentne** **fajlove** neophodne za rad aplikacije. - **Nevidljivo** **korisnicima** i korisnici ne mogu pisati u nju. - Sadržaj u ovoj direktoriji je **backup-ovan**. - Aplikacija može onemogućiti putanje postavljanjem `NSURLIsExcludedFromBackupKey`. - **Library/Preferences/** - Koristi se za čuvanje svojstava koja mogu **ostati čak i nakon ponovnog pokretanja aplikacije**. - Informacije se čuvaju, nešifrovane, unutar sandbox-a aplikacije u plist datoteci nazvanoj \[BUNDLE_ID].plist. - Svi parovi ključ/vrednost sačuvani koristeći `NSUserDefaults` mogu se naći u ovoj datoteci. - **tmp/** - Koristite ovu direktoriju za pisanje **privremenih fajlova** koji ne moraju da opstanu između pokretanja aplikacije. - Sadrži nepermanentne keširane fajlove. - **Nevidljivo** korisnicima. - Sadržaj u ovoj direktoriji nije backup-ovan. - OS može automatski obrisati fajlove iz ove direktorije kada aplikacija nije pokrenuta i kada je prostor za skladištenje nizak. Pogledajmo bliže Application Bundle (.app) direktoriju iGoat-Swift unutar Bundle direktorije (`/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 Unutar foldera `.app` naći ćete binarni fajl pod nazivom ``. Ovo je fajl koji će biti **izvršen**. Možete izvršiti osnovnu inspekciju binarnog fajla pomoću alata **`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) [...] ``` **Proverite da li je aplikacija enkriptovana** Pogledajte da li ima ikakvog izlaza za: ```bash otool -l | grep -A 4 LC_ENCRYPTION_INFO ``` **Rastavljanje binarnog koda** Rastavi tekstualni deo: ```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 ``` Da bi se odštampao **Objective-C segment** uzorka aplikacije, može se koristiti: ```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 ``` Da biste dobili kompaktiniji Objective-C kod, možete koristiti [**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; }; ``` Međutim, najbolje opcije za dekompilaciju binarnog koda su: [**Hopper**](https://www.hopperapp.com/download.html?) i [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/). ## Čuvanje podataka Da biste saznali kako iOS čuva podatke na uređaju, pročitajte ovu stranicu: {{#ref}} ios-basics.md {{#endref}} > [!WARNING] > Sledeća mesta za čuvanje informacija treba proveriti **odmah nakon instalacije aplikacije**, **nakon provere svih funkcionalnosti** aplikacije i čak nakon **izlaska iz jednog korisnika i prijavljivanja u drugog**.\ > Cilj je pronaći **nezaštićene osetljive informacije** aplikacije (lozinke, tokeni), trenutnog korisnika i prethodno prijavljenih korisnika. ### Plist **plist** datoteke su strukturirane XML datoteke koje **sadrže parove ključ-vrednost**. To je način za čuvanje trajnih podataka, tako da ponekad možete pronaći **osetljive informacije u ovim datotekama**. Preporučuje se da proverite ove datoteke nakon instalacije aplikacije i nakon intenzivnog korišćenja da vidite da li su napisani novi podaci. Najčešći način za trajno čuvanje podataka u plist datotekama je korišćenjem **NSUserDefaults**. Ova plist datoteka se čuva unutar sandbox-a aplikacije u **`Library/Preferences/.plist`** Klasa [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) pruža programski interfejs za interakciju sa podrazumevanim sistemom. Podrazumevani sistem omogućava aplikaciji da prilagodi svoje ponašanje prema **preferencama korisnika**. Podaci sačuvani pomoću `NSUserDefaults` mogu se pregledati u paketu aplikacije. Ova klasa čuva **podatke** u **plist** **datoteci**, ali je namenjena za korišćenje sa malim količinama podataka. Ovi podaci se ne mogu više direktno pristupiti putem pouzdanog računara, ali se mogu pristupiti obavljanjem **rezervne kopije**. Možete **izvući** informacije sačuvane korišćenjem **`NSUserDefaults`** koristeći `ios nsuserdefaults get` iz objection-a. Da biste pronašli sve plist datoteke koje koristi aplikacija, možete pristupiti `/private/var/mobile/Containers/Data/Application/{APPID}` i pokrenuti: ```bash find ./ -name "*.plist" ``` Da biste konvertovali fajlove iz **XML ili binarnog (bplist)** formata u XML, dostupne su različite metode u zavisnosti od vašeg operativnog sistema: **Za macOS korisnike:** Iskoristite `plutil` komandu. To je ugrađeni alat u macOS-u (10.2+), dizajniran za ovu svrhu: ```bash $ plutil -convert xml1 Info.plist ``` **Za Linux korisnike:** Prvo instalirajte `libplist-utils`, a zatim koristite `plistutil` da konvertujete vaš fajl: ```bash $ apt install libplist-utils $ plistutil -i Info.plist -o Info_xml.plist ``` **Tokom Objection Sesije:** Za analizu mobilnih aplikacija, specifična komanda omogućava direktno konvertovanje plist fajlova: ```bash ios plist cat /private/var/mobile/Containers/Data/Application//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) je okvir za upravljanje model slojem objekata u vašoj aplikaciji. [Core Data može koristiti SQLite kao svoj trajni skladište](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), ali sam okvir nije baza podataka.\ CoreData po defaultu ne enkriptuje svoje podatke. Međutim, dodatni sloj enkripcije može se dodati CoreData. Pogledajte [GitHub Repo](https://github.com/project-imas/encrypted-core-data) za više detalja. Možete pronaći informacije o SQLite Core Data aplikacije na putanji `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support` **Ako možete otvoriti SQLite i pristupiti osetljivim informacijama, onda ste pronašli pogrešnu konfiguraciju.** ```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) je skladište ključ/vrednost izgrađeno na vrhu SQLite-a.\ Pošto su Yap baze podataka sqlite baze, možete ih pronaći koristeći predloženu komandu u prethodnom odeljku. ### Other SQLite Databases Uobičajeno je da aplikacije kreiraju svoje vlastite sqlite baze podataka. Mogu **čuvati** **osetljive** **podatke** na njima i ostaviti ih nešifrovane. Stoga, uvek je zanimljivo proveriti svaku bazu podataka unutar direktorijuma aplikacija. Stoga idite u direktorijum aplikacije gde su podaci sačuvani (`/private/var/mobile/Containers/Data/Application/{APPID}`) ```bash find ./ -name "*.sqlite" -or -name "*.db" ``` ### Firebase Real-Time Databases Razvijači mogu da **čuvaju i sinhronizuju podatke** unutar **NoSQL cloud-hostovane baze podataka** putem Firebase Real-Time Databases. Podaci se čuvaju u JSON formatu i sinhronizuju se svim povezanim klijentima u realnom vremenu. Možete pronaći kako da proverite pogrešno konfigurisane Firebase baze podataka ovde: {{#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/) nude moćnu alternativu za skladištenje podataka, koju Apple ne pruža. Po defaultu, **čuvaju podatke nešifrovane**, a šifrovanje je dostupno kroz specifičnu konfiguraciju. Baze podataka se nalaze na: `/private/var/mobile/Containers/Data/Application/{APPID}`. Da biste istražili ove datoteke, možete koristiti komande kao: ```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*" ``` Za pregled ovih datoteka baze podataka, preporučuje se alat [**Realm Studio**](https://github.com/realm/realm-studio). Za implementaciju enkripcije unutar Realm baze podataka, može se koristiti sledeći kod: ```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)") } ``` ### Couchbase Lite Databases [Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) se opisuje kao **lagani** i **ugrađeni** sistem za baze podataka koji prati **orijentisani na dokumente** (NoSQL) pristup. Dizajniran da bude nativan za **iOS** i **macOS**, nudi mogućnost besprekornog sinhronizovanja podataka. Da bi se identifikovale potencijalne Couchbase baze podataka na uređaju, sledeći direktorijum treba pregledati: ```bash ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/ ``` ### Cookies iOS čuva kolačiće aplikacija u **`Library/Cookies/cookies.binarycookies`** unutar svake aplikacione fascikle. Međutim, programeri ponekad odluče da ih sačuvaju u **keychain** jer se pomenuti **kolačić fajl može pristupiti u rezervnim kopijama**. Da biste pregledali kolačić fajl, možete koristiti [**ovaj python skript**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) ili koristiti objection-ov **`ios cookies get`.**\ **Takođe možete koristiti objection da** konvertujete ove fajlove u JSON format i pregledate podatke. ```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 Podrazumevano, NSURLSession čuva podatke, kao što su **HTTP zahtevi i odgovori u Cache.db** bazi podataka. Ova baza podataka može sadržati **osetljive podatke**, ako su tokeni, korisnička imena ili bilo koje druge osjetljive informacije keširane. Da biste pronašli keširane informacije, otvorite direktorijum podataka aplikacije (`/var/mobile/Containers/Data/Application/`) i idite na `/Library/Caches/`. **WebKit keš se takođe čuva u Cache.db** datoteci. **Objection** može otvoriti i interagovati sa bazom podataka pomoću komande `sqlite connect Cache.db`, jer je to n**ormalna SQLite baza podataka**. Preporučuje se **onemogućavanje keširanja ovih podataka**, jer može sadržati osetljive informacije u zahtevu ili odgovoru. Sledeća lista prikazuje različite načine za postizanje ovog cilja: 1. Preporučuje se uklanjanje keširanih odgovora nakon odjave. To se može uraditi pomoću metode koju je obezbedio Apple pod nazivom [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses). Ovu metodu možete pozvati na sledeći način: `URLCache.shared.removeAllCachedResponses()` Ova metoda će ukloniti sve keširane zahteve i odgovore iz Cache.db datoteke. 2. Ako ne trebate koristiti prednost kolačića, preporučuje se da jednostavno koristite [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) konfiguracionu osobinu URLSession-a, koja će onemogućiti čuvanje kolačića i keševa. [Apple dokumentacija](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral): `An ephemeral session configuration object is similar to a default session configuration (see default), except that the corresponding session object doesn’t store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file.` 3. Keš se takođe može onemogućiti postavljanjem Cache Policy na [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed). To će onemogućiti čuvanje keša na bilo koji način, bilo u memoriji ili na disku. ### Snapshots Kad god pritisnete dugme za početnu stranu, iOS **uzima snimak trenutnog ekrana** kako bi mogao da izvrši prelaz na aplikaciju na mnogo glatkiji način. Međutim, ako su **osetljivi** **podatci** prisutni na trenutnom ekranu, biće **sačuvani** u **slici** (koja **ostaje** **i nakon** **ponovnog pokretanja**). Ovo su snimci koje možete takođe pristupiti dvostrukim dodirom na početni ekran da biste prešli između aplikacija. Osim ako iPhone nije jailbreak-ovan, **napadač** treba da ima **pristup** **uređaju** **otključanom** da bi video ove snimke ekrana. Podrazumevano, poslednji snimak se čuva u sandbox-u aplikacije u `Library/Caches/Snapshots/` ili `Library/SplashBoard/Snapshots` folderu (pouzdani računari ne mogu pristupiti datotečnom sistemu od iOS 7.0). Jedan od načina da se spreči ovo loše ponašanje je da se stavi prazan ekran ili ukloni osetljivi podatak pre nego što se uzme snimak koristeći funkciju `ApplicationDidEnterBackground()`. Sledeći je primer metode za otklanjanje problema koja će postaviti podrazumevani snimak ekrana. 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]; } ``` Ovo postavlja pozadinsku sliku na `overlayImage.png` svaki put kada se aplikacija pozadinski pokrene. Sprečava curenje osetljivih podataka jer će `overlayImage.png` uvek zameniti trenutni prikaz. ### Keychain Za pristup i upravljanje iOS keychain-om, dostupni su alati poput [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper), pogodnih za jailbroken uređaje. Pored toga, [**Objection**](https://github.com/sensepost/objection) pruža komandu `ios keychain dump` za slične svrhe. #### **Skladištenje akreditiva** Klasa **NSURLCredential** je idealna za čuvanje osetljivih informacija direktno u keychain-u, zaobilazeći potrebu za NSUserDefaults ili drugim omotačima. Da bi se akreditivi sačuvali nakon prijave, koristi se sledeći Swift kod: ```swift NSURLCredential *credential; credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent]; [[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace]; ``` Da bi se izvukle ove sačuvane kredencijale, koristi se Objectionova komanda `ios nsurlcredentialstorage dump`. ## **Prilagođene Tastature i Keš Tastature** Sa iOS 8.0 i novijim verzijama, korisnici mogu instalirati ekstenzije prilagođenih tastatura, koje se mogu upravljati pod **Podešavanja > Opšte > Tastatura > Tastature**. Iako ove tastature nude proširenu funkcionalnost, predstavljaju rizik od beleženja pritisaka tastera i slanja podataka na spoljne servere, iako su korisnici obavešteni o tastaturama koje zahtevaju pristup mreži. Aplikacije mogu, i trebale bi, ograničiti korišćenje prilagođenih tastatura za unos osetljivih informacija. **Preporuke za Bezbednost:** - Preporučuje se onemogućavanje tastatura trećih strana radi poboljšane bezbednosti. - Budite svesni funkcija automatskog ispravljanja i automatskih predloga podrazumevane iOS tastature, koje mogu sačuvati osetljive informacije u keš datotekama smeštenim u `Library/Keyboard/{locale}-dynamic-text.dat` ili `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. Ove keš datoteke treba redovno proveravati na prisustvo osetljivih podataka. Preporučuje se resetovanje rečnika tastature putem **Podešavanja > Opšte > Resetuj > Resetuj rečnik tastature** za brisanje keširanih podataka. - Presretanje mrežnog saobraćaja može otkriti da li prilagođena tastatura prenosi pritiske tastera na daljinu. ### **Prevencija Keširanja Polja za Tekst** Protokol [UITextInputTraits](https://developer.apple.com/reference/uikit/uitextinputtraits) nudi svojstva za upravljanje automatskim ispravljanjem i sigurnim unosom teksta, što je od suštinskog značaja za sprečavanje keširanja osetljivih informacija. Na primer, onemogućavanje automatskog ispravljanja i omogućavanje sigurnog unosa teksta može se postići sa: ```objectivec textObject.autocorrectionType = UITextAutocorrectionTypeNo; textObject.secureTextEntry = YES; ``` Pored toga, programeri bi trebali osigurati da tekstualna polja, posebno ona za unos osetljivih informacija kao što su lozinke i PIN-ovi, onemoguće keširanje postavljanjem `autocorrectionType` na `UITextAutocorrectionTypeNo` i `secureTextEntry` na `YES`. ```objectivec UITextField *textField = [[UITextField alloc] initWithFrame:frame]; textField.autocorrectionType = UITextAutocorrectionTypeNo; ``` ## **Logs** Debugging code često uključuje korišćenje **logging**. Postoji rizik jer **logovi mogu sadržati osetljive informacije**. Ranije, u iOS 6 i starijim verzijama, logovi su bili dostupni svim aplikacijama, što je predstavljalo rizik od curenja osetljivih podataka. **Sada, aplikacije su ograničene na pristup samo svojim logovima**. Uprkos ovim ograničenjima, **napadač sa fizičkim pristupom** otključanom uređaju može i dalje iskoristiti ovu situaciju povezivanjem uređaja sa računarom i **čitajući logove**. Važno je napomenuti da logovi ostaju na disku čak i nakon deinstalacije aplikacije. Da bi se smanjili rizici, preporučuje se da se **temeljno interaguje sa aplikacijom**, istražujući sve njene funkcionalnosti i unose kako bi se osiguralo da se ne beleže osetljive informacije nenamerno. Kada pregledate izvorni kod aplikacije u potrazi za potencijalnim curenjima, tražite i **predefinisane** i **prilagođene logovanje izjave** koristeći ključne reči kao što su `NSLog`, `NSAssert`, `NSCAssert`, `fprintf` za ugrađene funkcije, i sve pominjanja `Logging` ili `Logfile` za prilagođene implementacije. ### **Monitoring System Logs** Aplikacije beleže razne informacije koje mogu biti osetljive. Da bi se pratili ovi logovi, alati i komande kao što su: ```bash idevice_id --list # To find the device ID idevicesyslog -u (| grep ) # To capture the device logs ``` su korisni. Pored toga, **Xcode** pruža način za prikupljanje konzolnih logova: 1. Otvorite Xcode. 2. Povežite iOS uređaj. 3. Idite na **Window** -> **Devices and Simulators**. 4. Izaberite svoj uređaj. 5. Pokrenite problem koji istražujete. 6. Koristite dugme **Open Console** da biste pregledali logove u novom prozoru. Za naprednije logovanje, povezivanje sa shell-om uređaja i korišćenje **socat** može omogućiti praćenje logova u realnom vremenu: ```bash iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock ``` Slede komande za posmatranje aktivnosti logova, što može biti neprocenjivo za dijagnostikovanje problema ili identifikovanje potencijalnog **data leakage** u logovima. ## Backupi **Auto-backup funkcije** su integrisane u iOS, olakšavajući kreiranje kopija podataka uređaja putem iTunes (do macOS Catalina), Finder (od macOS Catalina nadalje) ili iCloud. Ove kopije obuhvataju skoro sve podatke uređaja, osim veoma osetljivih elemenata kao što su detalji o Apple Pay-u i konfiguracije Touch ID-a. ### Bezbednosni Rizici Uključivanje **instaliranih aplikacija i njihovih podataka** u backupove postavlja pitanje potencijalnog **data leakage** i rizik da **modifikacije backupa mogu promeniti funkcionalnost aplikacije**. Preporučuje se da **ne čuvate osetljive informacije u običnom tekstu** unutar bilo kog direktorijuma aplikacije ili njenih poddirektorijuma kako biste umanjili ove rizike. ### Isključivanje Fajlova iz Backupova Fajlovi u `Documents/` i `Library/Application Support/` se po defaultu čuvaju u backupu. Programeri mogu isključiti specifične fajlove ili direktorijume iz backupova koristeći `NSURL setResourceValue:forKey:error:` sa `NSURLIsExcludedFromBackupKey`. Ova praksa je ključna za zaštitu osetljivih podataka od uključivanja u backupove. ### Testiranje na Ranljivosti Da biste procenili bezbednost backupa aplikacije, počnite sa **kreiranjem backupa** koristeći Finder, a zatim ga locirajte koristeći smernice iz [Apple-ove zvanične dokumentacije](https://support.apple.com/en-us/HT204215). Analizirajte backup za osetljive podatke ili konfiguracije koje bi mogle biti promenjene da utiču na ponašanje aplikacije. Osetljive informacije se mogu tražiti koristeći alate komandne linije ili aplikacije kao što je [iMazing](https://imazing.com). Za enkriptovane backupove, prisustvo enkripcije može se potvrditi proverom ključa "IsEncrypted" u "Manifest.plist" fajlu na korenu backupa. ```xml ... Date 2021-03-12T17:43:33Z IsEncrypted ... ``` Za rad sa enkriptovanim bekapima, Python skripte dostupne u [DinoSec-ovom GitHub repozitorijumu](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts), kao što su **backup_tool.py** i **backup_passwd.py**, mogu biti korisne, iako potencijalno zahtevaju prilagođavanje za kompatibilnost sa najnovijim verzijama iTunes/Finder-a. [**iOSbackup** alat](https://pypi.org/project/iOSbackup/) je još jedna opcija za pristup datotekama unutar bekapa zaštićenih lozinkom. ### Modifikovanje ponašanja aplikacije Primer menjanja ponašanja aplikacije kroz modifikacije bekapa prikazan je u [Bither bitcoin wallet aplikaciji](https://github.com/bither/bither-ios), gde je PIN za zaključavanje UI-a sačuvan unutar `net.bither.plist` pod ključem **pin_code**. Uklanjanjem ovog ključa iz plist-a i vraćanjem bekapa uklanja se zahtev za PIN-om, omogućavajući neograničen pristup. ## Sažetak o testiranju memorije za osetljive podatke Kada se radi sa osetljivim informacijama sačuvanim u memoriji aplikacije, ključno je ograničiti vreme izlaganja ovih podataka. Postoje dva osnovna pristupa za istraživanje sadržaja memorije: **kreiranje dump-a memorije** i **analiza memorije u realnom vremenu**. Obe metode imaju svoje izazove, uključujući mogućnost propuštanja kritičnih podataka tokom procesa dump-a ili analize. ## **Preuzimanje i analiza dump-a memorije** Za uređaje sa i bez jailbreak-a, alati kao što su [objection](https://github.com/sensepost/objection) i [Fridump](https://github.com/Nightbringer21/fridump) omogućavaju dump-ovanje memorije procesa aplikacije. Kada se dump-uje, analiza ovih podataka zahteva različite alate, u zavisnosti od prirode informacija koje tražite. Da biste izvukli stringove iz dump-a memorije, mogu se koristiti komande kao što su `strings` ili `rabin2 -zz`: ```bash # Extracting strings using strings command $ strings memory > strings.txt # Extracting strings using rabin2 $ rabin2 -ZZ memory > strings.txt ``` Za detaljniju analizu, uključujući pretragu specifičnih tipova podataka ili obrazaca, **radare2** nudi opsežne mogućnosti pretrage: ```bash $ r2 [0x00000000]> /? ... ``` ## **Analiza Memorije u Runtime-u** **r2frida** pruža moćnu alternativu za inspekciju memorije aplikacije u realnom vremenu, bez potrebe za dump-ovanjem memorije. Ovaj alat omogućava izvršavanje komandi pretrage direktno u memoriji pokrenute aplikacije: ```bash $ r2 frida://usb// [0x00000000]> /\ ``` ## Slomljena Kriptografija ### Loši Procesi Upravljanja Ključevima Neki programeri čuvaju osetljive podatke u lokalnoj memoriji i enkriptuju ih sa ključem koji je hardkodiran/predvidljiv u kodu. To ne bi trebalo da se radi jer bi neki proces obrnute inženjeringa mogao omogućiti napadačima da izvuku poverljive informacije. ### Korišćenje Nesigurnih i/ili Zastarelih Algoritama Programeri ne bi trebali koristiti **zastarele algoritme** za obavljanje **provera** autorizacije, **čuvanje** ili **slanje** podataka. Neki od ovih algoritama su: RC4, MD4, MD5, SHA1... Ako se **hash** koriste za čuvanje lozinki, na primer, treba koristiti hash koji je otporan na brute-force sa solju. ### Provera Glavne provere koje treba izvršiti su da se utvrdi da li možete pronaći **hardkodirane** lozinke/tajne u kodu, ili da li su one **predvidljive**, i da li kod koristi neku vrstu **slabe** **kriptografije**. Zanimljivo je znati da možete **pratiti** neke **crypto** **biblioteke** automatski koristeći **objection** sa: ```swift ios monitor crypt ``` Za **više informacija** o iOS kriptografskim API-ima i bibliotekama, posetite [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) ## Lokalna autentifikacija **Lokalna autentifikacija** igra ključnu ulogu, posebno kada je u pitanju zaštita pristupa na udaljenom kraju putem kriptografskih metoda. Suština je da bez pravilne implementacije, mehanizmi lokalne autentifikacije mogu biti zaobiđeni. Apple-ov [**Local Authentication framework**](https://developer.apple.com/documentation/localauthentication) i [**keychain**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) pružaju robusne API-je za programere kako bi olakšali dijaloge za autentifikaciju korisnika i sigurno upravljali tajnim podacima, redom. Secure Enclave osigurava ID otiska prsta za Touch ID, dok Face ID zavisi od prepoznavanja lica bez kompromitovanja biometrijskih podataka. Da bi integrisali Touch ID/Face ID, programeri imaju dva izbora API-ja: - **`LocalAuthentication.framework`** za visoko nivo korisničke autentifikacije bez pristupa biometrijskim podacima. - **`Security.framework`** za pristup uslugama keychain-a na nižem nivou, osiguravajući tajne podatke biometrijskom autentifikacijom. Različiti [open-source wrapperi](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id) olakšavaju pristup keychain-u. > [!CAUTION] > Međutim, i `LocalAuthentication.framework` i `Security.framework` predstavljaju ranjivosti, jer prvenstveno vraćaju boolean vrednosti bez prenosa podataka za procese autentifikacije, što ih čini podložnim zaobilaženju (pogledajte [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)). ### Implementacija lokalne autentifikacije Da bi zatražili autentifikaciju od korisnika, programeri treba da koriste metodu **`evaluatePolicy`** unutar klase **`LAContext`**, birajući između: - **`deviceOwnerAuthentication`**: Zahteva Touch ID ili lozinku uređaja, neuspešno ako nijedno nije omogućeno. - **`deviceOwnerAuthenticationWithBiometrics`**: Isključivo zahteva Touch ID. Uspešna autentifikacija se označava boolean povratnom vrednošću iz **`evaluatePolicy`**, ističući potencijalnu sigurnosnu slabost. ### Lokalna autentifikacija koristeći Keychain Implementacija **lokalne autentifikacije** u iOS aplikacijama uključuje korišćenje **keychain API-a** za sigurno čuvanje tajnih podataka kao što su tokeni za autentifikaciju. Ovaj proces osigurava da podaci mogu biti pristupljeni samo od strane korisnika, koristeći njihovu lozinku uređaja ili biometrijsku autentifikaciju poput Touch ID. Keychain nudi mogućnost postavljanja stavki sa atributom `SecAccessControl`, koji ograničava pristup stavci dok korisnik uspešno ne autentifikuje putem Touch ID ili lozinke uređaja. Ova funkcija je ključna za poboljšanje sigurnosti. Ispod su primeri koda u Swift-u i Objective-C-u koji prikazuju kako sačuvati i preuzeti string iz keychain-a, koristeći ove sigurnosne funkcije. Primeri posebno pokazuju kako postaviti kontrolu pristupa da zahteva autentifikaciju putem Touch ID i osigurati da su podaci dostupni samo na uređaju na kojem su postavljeni, pod uslovom da je lozinka uređaja konfigurisana. {{#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? 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}} Sada možemo zatražiti sačuvani predmet iz keychain-a. Usluge keychain-a će prikazati dijalog za autentifikaciju korisniku i vratiti podatke ili nil u zavisnosti od toga da li je pružen odgovarajući otisak prsta ili ne. {{#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}} ### Detekcija Korišćenje okvira u aplikaciji može se takođe otkriti analizom liste deljenih dinamičkih biblioteka binarnog fajla aplikacije. To se može uraditi korišćenjem `otool`: ```bash $ otool -L .app/ ``` Ako se `LocalAuthentication.framework` koristi u aplikaciji, izlaz će sadržati obe sledeće linije (zapamtite da `LocalAuthentication.framework` koristi `Security.framework` u pozadini): ```bash /System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication /System/Library/Frameworks/Security.framework/Security ``` Ako se koristi `Security.framework`, biće prikazan samo drugi. ### Zaobilaženje lokalnog okvira za autentifikaciju #### **Objection** Kroz **Objection Biometrics Bypass**, koji se nalazi na [ovoj GitHub stranici](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass), dostupna je tehnika za prevazilaženje **LocalAuthentication** mehanizma. Suština ovog pristupa uključuje korišćenje **Frida** za manipulaciju funkcijom `evaluatePolicy`, osiguravajući da ona dosledno daje `True` rezultat, bez obzira na stvarni uspeh autentifikacije. Ovo je posebno korisno za zaobilaženje neispravnih procesa biometrijske autentifikacije. Da bi se aktiviralo ovo zaobilaženje, koristi se sledeća komanda: ```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 ``` Ova komanda pokreće sekvencu u kojoj Objection registruje zadatak koji efikasno menja ishod `evaluatePolicy` provere na `True`. #### Frida Primer korišćenja **`evaluatePolicy`** iz [DVIA-v2 aplikacije](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"]; }); } } ``` Da bi se postigao **bypass** lokalne autentifikacije, napisan je Frida skript. Ovaj skript cilja **evaluatePolicy** proveru, presrećući njen callback kako bi osigurao da vraća **success=1**. Menjanjem ponašanja callback-a, provera autentifikacije se efikasno zaobilazi. Skripta ispod se injektuje da bi se izmenio rezultat **evaluatePolicy** metode. Menja rezultat callback-a da uvek označava uspeh. ```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!"); } ``` Da biste ubrizgali Frida skriptu i zaobišli biometrijsku autentifikaciju, koristi se sledeća komanda: ```bash frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js ``` ## Izloženost Osetljive Funkcionalnosti Kroz IPC ### Prilagođeni URI Handleri / Deeplinks / Prilagođene Šeme {{#ref}} ios-custom-uri-handlers-deeplinks-custom-schemes.md {{#endref}} ### Univerzalni Linkovi {{#ref}} ios-universal-links.md {{#endref}} ### UIActivity Deljenje {{#ref}} ios-uiactivity-sharing.md {{#endref}} ### UIPasteboard {{#ref}} ios-uipasteboard.md {{#endref}} ### Ekstenzije Aplikacija {{#ref}} ios-app-extensions.md {{#endref}} ### WebViews {{#ref}} ios-webviews.md {{#endref}} ### Serijalizacija i Kodiranje {{#ref}} ios-serialisation-and-encoding.md {{#endref}} ## Mrežna Komunikacija Važno je proveriti da li ne dolazi do komunikacije **bez enkripcije** i takođe da li aplikacija ispravno **validira TLS sertifikat** servera.\ Da biste proverili ovakve probleme, možete koristiti proxy kao što je **Burp**: {{#ref}} burp-configuration-for-ios.md {{#endref}} ### Provera Hostname-a Jedan uobičajen problem prilikom validacije TLS sertifikata je provera da li je sertifikat potpisan od strane **pouzdanog** **CA**, ali **ne proverava** da li je **hostname** sertifikata hostname koji se pristupa.\ Da biste proverili ovaj problem koristeći Burp, nakon što poverite Burp CA na iPhone-u, možete **napraviti novi sertifikat sa Burp-om za drugi hostname** i koristiti ga. Ako aplikacija i dalje radi, onda je nešto ranjivo. ### Pinovanje Sertifikata Ako aplikacija ispravno koristi SSL Pinning, onda će aplikacija raditi samo ako je sertifikat onaj koji se očekuje. Kada testirate aplikaciju **to može biti problem jer će Burp poslužiti svoj sertifikat.**\ Da biste zaobišli ovu zaštitu unutar jailbroken uređaja, možete instalirati aplikaciju [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) ili instalirati [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device) Takođe možete koristiti **objection's** `ios sslpinning disable` ## Razno - U **`/System/Library`** možete pronaći okvire instalirane na telefonu koje koriste sistemske aplikacije - Aplikacije koje je korisnik instalirao iz App Store-a nalaze se unutar **`/User/Applications`** - A **`/User/Library`** sadrži podatke sačuvane od strane aplikacija na korisničkom nivou - Možete pristupiti **`/User/Library/Notes/notes.sqlite`** da biste pročitali beleške sačuvane unutar aplikacije. - Unutar foldera instalirane aplikacije (**`/User/Applications//`**) možete pronaći neke zanimljive datoteke: - **`iTunesArtwork`**: Ikona koju koristi aplikacija - **`iTunesMetadata.plist`**: Informacije o aplikaciji korišćene u App Store-u - **`/Library/*`**: Sadrži postavke i keš. U **`/Library/Cache/Snapshots/*`** možete pronaći snimak napravljen za aplikaciju pre nego što je poslata u pozadinu. ### Vruće Patchovanje/Prisilno Ažuriranje Programeri mogu daljinski **patch-ovati sve instalacije svoje aplikacije instantno** bez potrebe da ponovo podnose aplikaciju u App Store i čekaju da bude odobrena.\ U tu svrhu obično se koristi [**JSPatch**](https://github.com/bang590/JSPatch)**.** Ali postoje i druge opcije kao što su [Siren](https://github.com/ArtSabintsev/Siren) i [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker).\ **Ovo je opasan mehanizam koji bi mogli zloupotrebiti zlonamerni SDK-ovi, stoga se preporučuje da se proveri koja metoda se koristi za automatsko ažuriranje (ako postoji) i testira.** Možete pokušati da preuzmete prethodnu verziju aplikacije u tu svrhu. ### Treće Strane Značajan izazov sa **3rd party SDK-ovima** je **nedostatak granularne kontrole** nad njihovim funkcionalnostima. Programeri se suočavaju sa izborom: ili integrišu SDK i prihvate sve njegove funkcije, uključujući potencijalne sigurnosne ranjivosti i probleme sa privatnošću, ili potpuno odustanu od njegovih prednosti. Često, programeri nisu u mogućnosti da zakrpe ranjivosti unutar ovih SDK-ova sami. Štaviše, kako SDK-ovi stiču poverenje unutar zajednice, neki mogu početi da sadrže malver. Usluge koje pružaju SDK-ovi trećih strana mogu uključivati praćenje ponašanja korisnika, prikazivanje reklama ili poboljšanja korisničkog iskustva. Međutim, to uvodi rizik jer programeri možda nisu potpuno svesni koda koji izvršavaju ove biblioteke, što dovodi do potencijalnih rizika za privatnost i sigurnost. Ključno je ograničiti informacije koje se dele sa uslugama trećih strana na ono što je neophodno i osigurati da nijedni osetljivi podaci nisu izloženi. Implementacija usluga trećih strana obično dolazi u dva oblika: samostalna biblioteka ili pun SDK. Da bi se zaštitila privatnost korisnika, svi podaci koje se dele sa ovim uslugama trebaju biti **anonimizovani** kako bi se sprečilo otkrivanje ličnih identifikacionih informacija (PII). Da biste identifikovali biblioteke koje aplikacija koristi, može se koristiti komanda **`otool`**. Ovaj alat treba pokrenuti protiv aplikacije i svake deljene biblioteke koju koristi da bi otkrio dodatne biblioteke. ```bash otool -L ``` ## Zanimljive Ranljivosti & Studije Slučaja {{#ref}} air-keyboard-remote-input-injection.md {{#endref}} ## **Reference & Dodatni Resursi** - [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/) IOS besplatan kurs([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) <<< Objective-C verzija [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< Swift verzija - [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}}