iOS Pentesting

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

iOS मूल बातें

iOS Basics

परीक्षण वातावरण

इस पृष्ठ पर आप iOS simulator, emulators और jailbreaking के बारे में जानकारी पा सकते हैं:

iOS Testing Environment

प्रारंभिक विश्लेषण

Basic iOS Testing Operations

परीक्षण के दौरान कई ऑपरेशन्स सुझाए जाएंगे (device से कनेक्ट करना, फ़ाइलें पढ़ना/लिखना/अपलोड/डाउनलोड करना, कुछ tools का उपयोग…)। इसलिए, यदि आप इन कार्यों में से किसी को करना नहीं जानते हैं तो कृपया पृष्ठ पढ़ना शुरू करें:

iOS Basic Testing Operations

Tip

अगले चरणों के लिए app को device में install किया होना चाहिए और application की IPA file पहले ही प्राप्त होनी चाहिए।
इसको करने का तरीका जानने के लिए Basic iOS Testing Operations पृष्ठ पढ़ें।

Basic Static Analysis

कुछ उपयोगी iOS - IPA फाइल decompilers:

IPA फाइल पर automatic Static Analysis करने के लिए टूल MobSF का उपयोग करने की सिफारिश की जाती है।

बाइनरी में मौजूद सुरक्षा की पहचान:

  • PIE (Position Independent Executable): सक्षम होने पर, एप्लिकेशन हर बार लॉन्च होने पर यादृच्छिक memory address पर लोड होता है, जिससे प्रारम्भिक memory address का अनुमान लगाना कठिन हो जाता है।
otool -hv <app-binary> | grep PIE   # It should include the PIE flag
  • Stack Canaries: stack की अखंडता को मान्य करने के लिए, एक ‘canary’ मान फ़ंक्शन कॉल से पहले stack पर रखा जाता है और फ़ंक्शन के अंत में फिर से मान्य किया जाता है।
otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
  • ARC (Automatic Reference Counting): सामान्य memory corruption त्रुटियों से बचाने के लिए
otool -I -v <app-binary> | grep objc_release   # It should include the _objc_release symbol
  • Encrypted Binary: बाइनरी को एन्क्रिप्ट किया जाना चाहिए
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT   # The cryptid should be 1

संवेदनशील/असुरक्षित फ़ंक्शनों की पहचान

  • Weak Hashing Algorithms
# 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"
  • Insecure Random Functions
# 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"
  • Insecure ‘Malloc’ Function
# On the iOS device
otool -Iv <app> | grep -w "_malloc"

# On linux
grep -iER "_malloc"
  • Insecure and Vulnerable Functions
# 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"

सामान्य Jailbreak detection विधियाँ

  • File System Checks: सामान्य jailbreak फ़ाइलों और निर्देशिकाओं की उपस्थिति की जाँच करें, जैसे /Applications/Cydia.app या /Library/MobileSubstrate/MobileSubstrate.dylib
  • Sandbox Violations: फ़ाइल सिस्टम के प्रतिबंधित क्षेत्रों तक पहुँचने का प्रयास करें, जो non-jailbroken devices पर ब्लॉक होना चाहिए।
  • API Checks: जाँच करें कि क्या प्रतिबंधित कॉल्स जैसे fork() (child process बनाने के लिए) या system() उपयोग किए जा सकते हैं, या /bin/sh मौजूद है।
  • Process Checks: ज्ञात jailbreak-संबंधित प्रक्रियाओं की उपस्थिति की निगरानी करें, जैसे Cydia, Substrate, या ssh
  • Kernel Exploits: उन kernel exploits की उपस्थिति की जाँच करें जो अक्सर jailbreaks में उपयोग होते हैं।
  • Environment Variables: jailbreak के संकेतों के लिए environment variables निरीक्षण करें, जैसे DYLD_INSERT_LIBRARIES
  • Libraries Check: उन लाइब्रेरीज की जाँच करें जो app process में लोड हुई हैं।
  • Check schemes: जैसे canOpenURL(URL(string: "cydia://"))

सामान्य Anti-Debugging detection विधियाँ

  • Check for Debugger Presence: यह जाँचने के लिए sysctl या अन्य तरीके उपयोग करें कि क्या कोई debugger जुड़ा हुआ है।
  • Anti-Debugging APIs: ptrace या SIGSTOP जैसी anti-debugging APIs के कॉल्स देखें, जैसे ptrace(PT_DENY_ATTACH, 0, 0, 0)
  • Timing Checks: कुछ ऑपरेशनों के लिए ली गई समय की गणना करें और debugging के संकेत के लिए अन्तर देखें।
  • Memory Checks: ज्ञात debugger artifacts या संशोधनों के लिए memory निरीक्षण करें।
  • Environment Variables: debugging सत्र का संकेत देने वाले environment variables की जाँच करें।
  • Mach Ports: पता लगाएं कि क्या mach exception ports debuggers द्वारा उपयोग में हैं।

Anti-Debugging & Anti-Tamper Techniques (Layered Checks)

वास्तविक दुनिया की apps अक्सर pre-exec, on-attach, और continuous checks की परतें लगाती हैं। देखने के लिए सामान्य पैटर्न (और परीक्षण के दौरान इन्हें neutralize कैसे करें):

  • Private API side-channel fingerprinting: private launch APIs (उदा., SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions) का दुरुपयोग इंस्टॉल्ड bundle IDs (com.opa334.TrollStore, org.coolstar.SileoStore, com.tigisoftware.Filza, आदि) के लिए return codes/logging के आधार पर probing के लिए किया जाता है। कॉल को hook करें और arguments/return values sanitize करके एक clean device का अनुकरण करें।
  • Self-attestation via code-signing state: csops() के साथ CS_OPS_ENTITLEMENTS_BLOB entitlements पढ़ता है; अनपेक्षित मान exit ट्रिगर करते हैं। इसे CRC32/MD5 जैसी integrity checks, certificate validation, Mach-O metadata जैसे LC_ENCRYPTION_INFO_64 के साथ जोड़ा जाता है ताकि re-signing या patching का पता चले। इन रूटीन को instrument करें और analysis के दौरान “expected” परिणाम फोर्स करें।
  • Kill-on-attach: ptrace(PT_DENY_ATTACH) को abort()/exit() के साथ मिलाया जाता है जब attach होता है। termination path को neutralize करके या ptrace को hook करके उसे बिना denial लागू किए सफल कर के bypass करें।
  • Crash forensics sabotage: crash से पहले CPU registers overwrite करके backtraces को नष्ट कर दिया जाता है। crash logs पर निर्भर रहने के बजाय detection path के पहले breakpoints/hooks रखना बेहतर है।
  • Jetsam-based termination: जानबूझकर memory pressure उत्पन्न करके jetsam ट्रिगर किया जाता है, जिससे कोई सामान्य crash log नहीं मिलता। detection logic के आसपास बड़ी allocations खोजें और logs रखने के लिए उन्हें cap/short-circuit करें।
  • Continuous checks with delayed enforcement: heartbeat timers detection को फिर से चलाते हैं और बाद में enforce करते हैं। timers/dispatch sources को trace करें और delayed kill path को bypass करके process को जीवित रखें।

Basic Dynamic Analysis

MobSF द्वारा किए जाने वाले dynamic analysis को देखें। आपको विभिन्न views में नेविगेट करना होगा और उनके साथ इंटरैक्ट करना होगा — यह कई classes को hook करेगा और एक रिपोर्ट तैयार करेगा जब आप पूरा कर लेंगे।

Listing Installed Apps

इंस्टॉल किए गए ऐप्स का bundle identifier पता करने के लिए frida-ps -Uai कमांड का उपयोग करें:

$ 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

बेसिक Enumeration & Hooking

जानें कि कैसे enumerate the components of the application और कैसे आसानी से hook methods and classes with objection:

iOS Hooking With Objection

IPA संरचना

एक IPA file की संरचना मूलतः एक zipped package जैसी होती है। इसके एक्सटेंशन को .zip में बदलकर इसे decompressed करके इसकी सामग्री देखी जा सकती है। इस संरचना के भीतर, एक Bundle एक पूरी तरह पैक किया हुआ application दर्शाता है जो installation के लिए तैयार है। अंदर, आपको <NAME>.app नाम का एक डायरेक्टरी मिलेगा, जो application’s resources को encapsulate करता है।

  • Info.plist: यह फ़ाइल application की specific configuration details रखती है।
  • _CodeSignature/: यह डायरेक्टरी एक plist फ़ाइल शामिल करती है जो एक signature रखती है, जिससे bundle में सभी फाइलों की integrity सुनिश्चित होती है।
  • Assets.car: एक compressed archive जो icons जैसे asset files को स्टोर करता है।
  • Frameworks/: यह फ़ोल्डर application’s native libraries रखता है, जो .dylib 또는 .framework फ़ाइलों के रूप में हो सकते हैं।
  • PlugIns/: इसमें application के extensions शामिल हो सकते हैं, जिन्हें .appex फ़ाइलों के रूप में जाना जाता है, हालांकि ये हमेशा मौजूद नहीं होते हैं.
  • Core Data: यह आपके application के permanent data को offline उपयोग के लिए सेव करने, temporary data को cache करने और single device पर undo functionality जोड़ने के लिए उपयोग किया जाता है। एक ही iCloud खाते में कई devices के बीच डेटा sync करने के लिए, Core Data स्वचालित रूप से आपके schema को एक CloudKit container में mirror कर देता है।
  • PkgInfo: PkgInfo फ़ाइल आपके application या bundle के type और creator codes निर्दिष्ट करने का एक वैकल्पिक तरीका है।
  • en.lproj, fr.proj, Base.lproj: ये उन specific भाषाओं के लिए resource वाले language packs हैं, और एक default resource प्रदान करते हैं यदि कोई भाषा समर्थित न हो।
  • Security: _CodeSignature/ डायरेक्टरी ऐप की security में महत्वपूर्ण भूमिका निभाती है, डिजिटल सिग्नेचर के माध्यम से सभी bundled फ़ाइलों की integrity की पुष्टि करके।
  • Asset Management: Assets.car फ़ाइल compression का उपयोग करके graphical assets का कुशल प्रबंधन करती है, जो application performance को optimize करने और कुल आकार घटाने के लिए महत्वपूर्ण है।
  • Frameworks and PlugIns: ये डायरेक्टरीज़ iOS applications की modularity को रेखांकित करती हैं, डेवलपर्स को reusable code libraries (Frameworks/) शामिल करने और app functionality (PlugIns/) बढ़ाने की अनुमति देती हैं।
  • Localization: यह संरचना कई भाषाओं का समर्थन करती है, और specific language packs के resources शामिल करके वैश्विक रूप से application पहुँच की सुविधा देती है।

Info.plist

Info.plist iOS applications के लिए एक आधारभूत फ़ाइल के रूप में कार्य करती है, जो key-value जोडों के रूप में प्रमुख configuration डेटा समाहित करती है। यह फ़ाइल न केवल applications बल्कि bundled app extensions और frameworks के लिए भी आवश्यक है। यह XML या binary फ़ॉर्मेट में संरचित होती है और app permissions से लेकर security configurations तक महत्वपूर्ण जानकारी रखती है। उपलब्ध keys के विस्तृत अन्वेषण के लिए, कोई Apple Developer Documentation देख सकता है।

जो लोग इस फ़ाइल के साथ अधिक सुलभ फ़ॉर्मेट में काम करना चाहते हैं, वे macOS पर plutil (version 10.2 और बाद में natively उपलब्ध) या Linux पर plistutil का उपयोग करके आसानी से XML conversion कर सकते हैं। Conversion के लिए commands इस प्रकार हैं:

  • macOS के लिए:
$ plutil -convert xml1 Info.plist
  • Linux के लिए:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

Among the myriad of information that the Info.plist file can divulge, notable entries include app permission strings (UsageDescription), custom URL schemes (CFBundleURLTypes), and configurations for App Transport Security (NSAppTransportSecurity). These entries, along with others like exported/imported custom document types (UTExportedTypeDeclarations / UTImportedTypeDeclarations), can be effortlessly located by inspecting the file or employing a simple grep command:

$ grep -i <keyword> Info.plist

डेटा पथ

iOS वातावरण में, निर्देशिकाएँ विशेष रूप से सिस्टम एप्लिकेशन और यूज़र-इंस्टॉल किए गए एप्लिकेशन के लिए निर्धारित की जाती हैं। सिस्टम एप्लिकेशन /Applications निर्देशिका में रहते हैं, जबकि यूज़र-इंस्टॉल किए गए ऐप्स /var/mobile/containers/Data/Application/ के अंतर्गत रखे जाते हैं। इन एप्लिकेशनों को एक अनूठा पहचानकर्ता दिया जाता है जिसे 128-bit UUID कहा जाता है, जिससे डायरेक्टरी नामों की यादृच्छिकता के कारण किसी ऐप के फ़ोल्डर को मैन्युअली ढूँढना कठिन हो जाता है।

Warning

चूंकि iOS में एप्लिकेशन को sandboxed होना आवश्यक है, प्रत्येक ऐप के पास $HOME/Library/Containers के अंदर भी एक फ़ोल्डर होगा जिसका नाम ऐप का CFBundleIdentifier होगा।

हालाँकि, दोनों फ़ोल्डरों (data & container folders) में फ़ाइल .com.apple.mobile_container_manager.metadata.plist होती है जो MCMetadataIdentifier कुंजी में दोनों को लिंक करती है).

एक यूज़र-इंस्टॉल किए गए ऐप के इंस्टॉलेशन डायरेक्टरी की खोज को सरल बनाने के लिए, objection tool एक उपयोगी कमांड, env, प्रदान करता है। यह कमांड संबंधित ऐप के लिए विस्तृत निर्देशिका जानकारी दिखाता है। नीचे इस कमांड के उपयोग का एक उदाहरण दिया गया है:

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

वैकल्पिक रूप से, ऐप का नाम /private/var/containers के भीतर find कमांड का उपयोग करके खोजा जा सकता है:

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

ps और lsof जैसे कमांड्स का उपयोग क्रमशः app के process की पहचान करने और open files को सूचीबद्ध करने के लिए भी किया जा सकता है, जिससे application के active directory paths के बारे में जानकारी मिलती है:

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

बंडल निर्देशिका:

  • AppName.app
  • यह Application Bundle है जैसा कि पहले IPA में देखा गया था; इसमें आवश्यक एप्लिकेशन डेटा, स्थैतिक सामग्री तथा एप्लिकेशन का कम्पाइल किया गया बाइनरी शामिल है।
  • यह निर्देशिका उपयोगकर्ताओं को दिखाई देती है, लेकिन उपयोगकर्ता इसमें लिख नहीं सकते
  • इस निर्देशिका की सामग्री बैकअप नहीं होती
  • इस फ़ोल्डर की सामग्री कोड सिग्नेचर सत्यापित करने के लिए उपयोग की जाती है।

डेटा निर्देशिका:

  • Documents/
  • यह सभी उपयोगकर्ता-जनित डेटा रखता है। यह डेटा एप्लिकेशन के अंतिम उपयोगकर्ता द्वारा निर्मित किया जाता है।
  • उपयोगकर्ताओं को दिखाई देता है और उपयोगकर्ता इसमें लिख सकते हैं
  • इस निर्देशिका की सामग्री बैकअप की जाती है
  • ऐप NSURLIsExcludedFromBackupKey सेट करके पाथ्स को अक्षम कर सकता है।
  • Library/
  • इसमें सभी फ़ाइलें जो उपयोगकर्ता-विशिष्ट नहीं हैं शामिल हैं, जैसे caches, preferences, cookies, और property list (plist) configuration फ़ाइलें।
  • iOS apps आमतौर पर Application Support और Caches उप-निर्देशिकाओं का उपयोग करते हैं, लेकिन ऐप कस्टम उप-निर्देशिकाएँ बना सकता है।
  • Library/Caches/
  • इसमें अर्ध-स्थायी कैश की गई फ़ाइलें।
  • उपयोगकर्ताओं के लिए अदृश्य है और उपयोगकर्ता इसमें लिख नहीं सकते
  • इस निर्देशिका की सामग्री बैकअप नहीं होती
  • जब ऐप चल नहीं रहा हो और स्टोरेज स्पेस कम हो, OS स्वचालित रूप से इस निर्देशिका की फ़ाइलें हटा सकता है।
  • Library/Application Support/
  • इसमें ऐप चलाने के लिए आवश्यक स्थायी फ़ाइलें शामिल हैं।
  • अदृश्य है उपयोगकर्ताओं के लिए और उपयोगकर्ता इसमें लिख नहीं सकते।
  • इस निर्देशिका की सामग्री बैकअप कीया जाता है
  • ऐप NSURLIsExcludedFromBackupKey सेट करके पाथ्स को अक्षम कर सकता है।
  • Library/Preferences/
  • उन properties को संग्रहीत करने के लिए उपयोग किया जाता है जो ऐप्लीकेशन के पुनः आरंभ के बाद भी बनाए रह सकते हैं
  • जानकारी application sandbox के अंदर बिना एन्क्रिप्ट किए एक plist फ़ाइल में सेव की जाती है जिसका नाम [BUNDLE_ID].plist होता है।
  • NSUserDefaults का उपयोग करके संग्रहीत किए गए सभी key/value जोड़े इस फ़ाइल में पाए जा सकते हैं।
  • tmp/
  • इस निर्देशिका का उपयोग उन अस्थायी फ़ाइलों को लिखने के लिए करें जिन्हें ऐप लॉन्च्स के बीच स्थायी रहने की आवश्यकता नहीं होती।
  • यह गैर-स्थायी cached फ़ाइलें रखता है।
  • अदृश्य उपयोगकर्ताओं के लिए।
  • इस निर्देशिका की सामग्री बैकअप नहीं होती।
  • जब ऐप चल नहीं रहा होता और स्टोरेज स्पेस कम हो, OS स्वचालित रूप से इस निर्देशिका की फ़ाइलें हटा सकता है।

आइए Bundle निर्देशिका के अंदर iGoat-Swift के Application Bundle (.app) निर्देशिका (/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 folder के अंदर आपको <application-name> नाम की एक binary file मिलेगी। यह वही file है जिसे executed किया जाएगा। आप binary का एक बुनियादी निरीक्षण tool otool से कर सकते हैं:

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

चेक करें कि ऐप एन्क्रिप्टेड है

देखें कि क्या इसके लिए कोई आउटपुट है:

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

बाइनरी को डिसअसेंबल करना

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

नमूना एप्लिकेशन के Objective-C segment को प्रिंट करने के लिए आप उपयोग कर सकते हैं:

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

एक अधिक संकुचित Objective-C कोड प्राप्त करने के लिए आप class-dump का उपयोग कर सकते हैं:

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

हालाँकि, बाइनरी को disassemble करने के लिए सबसे अच्छे विकल्प हैं: Hopper and IDA.

डेटा स्टोरेज

डिवाइस में iOS किस तरह डेटा स्टोर करता है यह जानने के लिए इस पृष्ठ को पढ़ें:

iOS Basics

Warning

निम्नलिखित स्थानों को जानकारी स्टोर करने के लिए एप्लिकेशन इंस्टॉल करने के तुरंत बाद, एप्लिकेशन की सभी कार्यक्षमताओं की जाँच करने के बाद और यहाँ तक कि एक यूज़र से लॉगआउट करके किसी दूसरे यूज़र में लॉग इन करने के बाद भी जांचना चाहिए।
उद्देश्य एप्लिकेशन की असुरक्षित संवेदनशील जानकारी (passwords, tokens), वर्तमान उपयोगकर्ता और पहले लॉग इन किए गए उपयोगकर्ताओं की जानकारी खोजना है।

Plist

plist फ़ाइलें संरचित XML फ़ाइलें हैं जो कुंजी-मूल्य जोड़े (key-value pairs) रखती हैं। यह स्थायी डेटा स्टोर करने का एक तरीका है, इसलिए कभी-कभी आप इन फ़ाइलों में संवेदनशील जानकारी पा सकते हैं। यह सलाह दी जाती है कि नए डेटा लिखे जा रहे हैं यह देखने के लिए इन फ़ाइलों की जांच ऐप इंस्टॉल करने के बाद और ऐप का अधिक उपयोग करने के बाद की जाए।

plist फ़ाइलों में डेटा बनाए रखने का सबसे सामान्य तरीका NSUserDefaults का उपयोग है। यह plist फ़ाइल ऐप सैंडबॉक्स के अंदर Library/Preferences/<appBundleID>.plist में सहेजी जाती है।

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 उपयोगकर्ता प्राथमिकताएँ. Data saved by NSUserDefaults can be viewed in the application bundle. This class stores डेटा in a plist फ़ाइल, but it’s meant to be used with small amounts of data.

यह डेटा अब भरोसेमंद कंप्यूटर द्वारा सीधे एक्सेस नहीं किया जा सकता, लेकिन एक backup करके एक्सेस किया जा सकता है।

आप objection के ios nsuserdefaults get का उपयोग करके NSUserDefaults में सहेजी गई जानकारी को dump कर सकते हैं

एप्लिकेशन द्वारा उपयोग किए गए सभी plist खोजने के लिए आप /private/var/mobile/Containers/Data/Application/{APPID} पर पहुँच सकते हैं और चलाएँ:

find ./ -name "*.plist"

फाइलों को XML or binary (bplist) फॉर्मेट से XML में कन्वर्ट करने के लिए, आपके ऑपरेटिंग सिस्टम के अनुसार विभिन्न तरीके उपलब्ध हैं:

macOS उपयोगकर्ताओं के लिए: plutil कमांड का उपयोग करें। यह macOS (10.2+) में बिल्ट-इन टूल है, जो इस उद्देश्य के लिए बनाया गया है:

$ plutil -convert xml1 Info.plist

Linux उपयोगकर्ताओं के लिए: सबसे पहले libplist-utils इंस्टॉल करें, फिर अपनी फ़ाइल को कन्वर्ट करने के लिए plistutil का उपयोग करें:

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

Objection Session के भीतर: मोबाइल एप्लिकेशन का विश्लेषण करने के लिए, एक विशिष्ट कमांड आपको सीधे plist फाइलों को कनवर्ट करने की अनुमति देता है:

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

Core Data

Core Data आपके एप्लिकेशन में ऑब्जेक्ट्स की मॉडल लेयर को प्रबंधित करने के लिए एक framework है। Core Data can use SQLite as its persistent store, लेकिन यह फ्रेमवर्क स्वयं कोई डेटाबेस नहीं है.\
CoreData डिफ़ॉल्ट रूप से अपने डेटा को एन्क्रिप्ट नहीं करता है। हालांकि, CoreData में एक अतिरिक्त एन्क्रिप्शन लेयर जोड़ी जा सकती है। अधिक जानकारी के लिए GitHub Repo देखें।

You can find the SQLite Core Data information of an application in the path /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support

यदि आप SQLite खोलकर संवेदनशील जानकारी तक पहुँच सकते हैं, तो इसका मतलब है कि आपने एक गलत कॉन्फ़िगरेशन पाया है।

-(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 एक key/value स्टोर है जो SQLite के ऊपर बनाया गया है।
चूंकि Yap databases SQLite डेटाबेस होते हैं, आप उन्हें पिछले सेक्शन में दिए गए कमांड का उपयोग करके पा सकते हैं।

अन्य SQLite डेटाबेस

यह सामान्य है कि ऐप्लिकेशन अपनी खुद की SQLite डेटाबेस बनाते हैं। वे उन पर संग्रहित संवेदनशील डेटा रख सकते हैं और उन्हें बिना एन्क्रिप्ट किए छोड़ देते हैं। इसलिए, ऐप्लिकेशन डायरेक्टरी के अंदर हर डेटाबेस की जाँच करना हमेशा दिलचस्प होता है। अतः उस application डायरेक्टरी में जाएँ जहाँ डेटा सहेजा जाता है (/private/var/mobile/Containers/Data/Application/{APPID})

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

Firebase Real-Time Databases

Firebase Real-Time Databases के माध्यम से डेवलपर्स को एक NoSQL cloud-hosted database के भीतर डेटा स्टोर और सिंक करने की सुविधा मिलती है। JSON फॉर्मेट में स्टोर किया गया डेटा वास्तविक समय में सभी कनेक्टेड क्लाइंट्स के साथ सिंक्रोनाइज़ हो जाता है।

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

Firebase Database

Realm databases

Realm Objective-C और Realm Swift Apple द्वारा प्रदान नहीं किए गए डेटा स्टोरेज के लिए एक शक्तिशाली विकल्प पेश करते हैं। डिफ़ॉल्ट रूप से, वे डेटा बिना एन्क्रिप्शन के स्टोर करते हैं, जबकि एन्क्रिप्शन विशिष्ट कॉन्फ़िगरेशन के माध्यम से उपलब्ध है।

The databases are located at: /private/var/mobile/Containers/Data/Application/{APPID}. To explore these files, one can utilize commands like:

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

इन डेटाबेस फाइलों को देखने के लिए, Realm Studio टूल सुझाया जाता है।

Realm डेटाबेस में एन्क्रिप्शन लागू करने के लिए, निम्नलिखित कोड स्निपेट का उपयोग किया जा सकता है:

// 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 डेटाबेस

Couchbase Lite को एक हल्का और एम्बेडेड डेटाबेस इंजन के रूप में वर्णित किया जाता है जो दस्तावेज़-उन्मुख (NoSQL) दृष्टिकोण का पालन करता है। यह iOS और macOS के लिए मूल रूप से डिज़ाइन किया गया है, और यह डेटा को निर्बाध रूप से sync करने की क्षमता प्रदान करता है।

किसी डिवाइस पर संभावित Couchbase डेटाबेस की पहचान करने के लिए, निम्नलिखित निर्देशिका की जाँच की जानी चाहिए:

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

Cookies

iOS ऐप्स के cookies को प्रत्येक ऐप के फ़ोल्डर के अंदर Library/Cookies/cookies.binarycookies में स्टोर करता है। हालाँकि, डेवलपर्स कभी-कभी इन्हें keychain में सेव करने का निर्णय लेते हैं क्योंकि उल्लेखित cookie file backups से access किया जा सकता है

cookies file का निरीक्षण करने के लिए आप this python script का उपयोग कर सकते हैं या objection के ios cookies get. का उपयोग करें।
आप objection का भी उपयोग कर सकते हैं इन फाइलों को JSON format में convert करके डेटा inspect करने के लिए।

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

डिफ़ॉल्ट रूप से NSURLSession डेटा स्टोर करता है, जैसे कि HTTP requests and responses in the Cache.db डेटाबेस में। यह डेटाबेस संवेदनशील जानकारी रख सकता है, अगर टोकन, उपयोगकर्ता नाम या कोई अन्य संवेदनशील जानकारी cache की गई हो। cached जानकारी खोजने के लिए ऐप का data directory खोलें (/var/mobile/Containers/Data/Application/<UUID>) और /Library/Caches/<Bundle Identifier> पर जाएँ। The WebKit cache is also being stored in the Cache.db file. Objection इस डेटाबेस को sqlite connect Cache.db कमांड से खोलकर इंटरैक्ट कर सकता है, क्योंकि यह एक normal SQLite database है।

सुझाव दिया जाता है कि इस डेटा की Caching बंद कर दी जाए, क्योंकि request या response में संवेदनशील जानकारी हो सकती है। नीचे दी गई सूची इसको हासिल करने के विभिन्न तरीके दिखाती है:

  1. लॉगआउट के बाद Cached responses हटाना सुझाया जाता है। यह Apple द्वारा दिए गए मेथड removeAllCachedResponses से किया जा सकता है। आप इस मेथड को निम्नानुसार कॉल कर सकते हैं:

URLCache.shared.removeAllCachedResponses()

यह मेथड Cache.db फाइल से सभी cached requests और responses हटा देगा।

  1. यदि आपको cookies का फायदा लेना जरूरी नहीं है तो URLSession की .ephemeral configuration property का उपयोग करने की सलाह दी जाती है, जो cookies और Caches को सेव करना डिसेबल कर देगी।

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 को .notAllowed पर सेट करके भी डिसेबल किया जा सकता है। यह किसी भी रूप में Cache को स्टोर करने को रोक देगा, चाहे memory में हो या disk पर।

Snapshots

जब भी आप home button दबाते हैं, iOS करंट स्क्रीन का एक snapshot लेता है ताकि एप्लिकेशन के बीच ट्रांज़िशन अधिक स्मूद हो सके। हालाँकि, अगर करंट स्क्रीन पर संवेदनशील डेटा मौजूद है, तो वह इस image में सेव हो जाएगा (जो reboots के पार भी persist करती है)। ये वही snapshots हैं जिन्हें आप apps के बीच स्विच करने के लिए home screen को डबल टैप करके भी एक्सेस कर सकते हैं।

जब तक iPhone jailbroken नहीं है, attacker को इन स्क्रीनशॉट्स को देखने के लिए device का अनब्लॉक्ड access चाहिए होता है। डिफ़ॉल्ट रूप से आखिरी snapshot application’s sandbox में Library/Caches/Snapshots/ या Library/SplashBoard/Snapshots फ़ोल्डर में स्टोर होता है (trusted computers iOX 7.0 से filesystem तक access नहीं कर सकते हैं)।

इस खराब व्यवहार को रोकने का एक तरीका है कि ApplicationDidEnterBackground() फ़ंक्शन का उपयोग करके snapshot लेने से पहले एक blank स्क्रीन दिखा दे या संवेदनशील डेटा हटा दे।

निम्न एक sample remediation मेथड है जो डिफ़ॉल्ट screenshot सेट करेगा।

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

यह एप्लिकेशन बैकग्राउंड होने पर overlayImage.png को बैकग्राउंड इमेज के रूप में सेट कर देता है। यह संवेदनशील डेटा leaks को रोकता है क्योंकि overlayImage.png हमेशा वर्तमान दृश्य को ओवरराइड कर देगा।

Keychain

iOS keychain तक पहुँचने और प्रबंधित करने के लिए, Keychain-Dumper जैसे टूल उपलब्ध हैं, जो jailbroken devices के लिए उपयुक्त हैं। इसके अलावा, Objection समान उद्देश्यों के लिए ios keychain dump कमांड प्रदान करता है।

क्रेडेंशियल्स स्टोर करना

NSURLCredential क्लास keychain में सीधे संवेदनशील जानकारी सहेजने के लिए उपयुक्त है, जिससे NSUserDefaults या अन्य रैपर की आवश्यकता टली जा सकती है। लॉगिन के बाद क्रेडेंशियल्स स्टोर करने के लिए, निम्न Swift कोड का उपयोग किया जाता है:

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

इन स्टोर की गई क्रेडेंशियल्स को निकालने के लिए, Objection का कमांड ios nsurlcredentialstorage dump उपयोग किया जाता है।

Custom Keyboards and Keyboard Cache

iOS 8.0 से, उपयोगकर्ता कस्टम कीबोर्ड एक्सटेंशंस इंस्टॉल कर सकते हैं, जिन्हें Settings > General > Keyboard > Keyboards के तहत प्रबंधित किया जा सकता है। हालांकि ये कीबोर्ड विस्तारित कार्यक्षमता प्रदान करते हैं, ये कीस्ट्रोक लॉगिंग और बाहरी सर्वरों को डेटा भेजने का जोखिम रखते हैं, हालांकि नेटवर्क एक्सेस की आवश्यकता वाले कीबोर्ड के बारे में उपयोगकर्ता को सूचित किया जाता है। Apps को संवेदनशील जानकारी दर्ज करने के लिए कस्टम कीबोर्ड के उपयोग को प्रतिबंधित करना चाहिए।

Security Recommendations:

  • बेहतर सुरक्षा हेतु थर्ड-पार्टी कीबोर्ड अक्षम करने की सलाह दी जाती है।
  • डिफ़ॉल्ट iOS कीबोर्ड की autocorrect और auto-suggestions सुविधाओं के बारे में सावधान रहें, जो संवेदनशील जानकारी को cache फाइलों में स्टोर कर सकती हैं, जो Library/Keyboard/{locale}-dynamic-text.dat या /private/var/mobile/Library/Keyboard/dynamic-text.dat में स्थित होती हैं। इन cache फाइलों की नियमित जांच संवेदनशील डेटा के लिए की जानी चाहिए। कैश्ड डेटा साफ़ करने के लिए Settings > General > Reset > Reset Keyboard Dictionary से keyboard dictionary रीसेट करने की सलाह दी जाती है।
  • नेटवर्क ट्रैफ़िक को इंटरसेप्ट करने से पता चल सकता है कि कोई कस्टम कीबोर्ड कीस्ट्रोक्स को दूरस्थ रूप से ट्रांसमिट कर रहा है या नहीं।

Preventing Text Field Caching

The UITextInputTraits protocol ऑटोकरेक्शन और secure text entry को प्रबंधित करने के लिए properties प्रदान करता है, जो संवेदनशील जानकारी के कैशिंग को रोकने के लिए आवश्यक हैं। उदाहरण के लिए, autocorrection को अक्षम करने और secure text entry को सक्षम करने के लिए निम्न किया जा सकता है:

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

इसके अतिरिक्त, डेवलपर्स को यह सुनिश्चित करना चाहिए कि टेक्स्ट फ़ील्ड — विशेष रूप से पासवर्ड और PINs जैसी संवेदनशील जानकारी दर्ज करने वाले फ़ील्ड — autocorrectionType को UITextAutocorrectionTypeNo और secureTextEntry को YES पर सेट करके कैशिंग अक्षम हो।

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

Logs

कोड की डिबगिंग अक्सर logging के उपयोग से होती है। जो जोखिम है क्योंकि logs में संवेदनशील जानकारी हो सकती है। पहले, iOS 6 और उससे पहले के संस्करणों में, logs सभी apps के लिए पहुँच योग्य थे, जिससे संवेदनशील डेटा leak का जोखिम था। अब, applications केवल अपने logs तक ही पहुँच सकते हैं

इन प्रतिबंधों के बावजूद, attacker with physical access एक अनलॉक्ड डिवाइस पर डिवाइस को कंप्यूटर से कनेक्ट करके और logs पढ़कर इसका फायदा उठा सकता है। यह ध्यान रखना महत्वपूर्ण है कि apps को uninstall करने के बाद भी logs डिस्क पर बने रहते हैं।

जोखिम कम करने के लिए, सलाह दी जाती है कि आप एप के साथ thoroughly interact with the app करें, उसकी सभी सुविधाओं और इनपुट्स को एक्सप्लोर करके यह सुनिश्चित करने के लिए कि कोई संवेदनशील जानकारी अनजाने में logged नहीं हो रही है।

जब आप app के source code की समीक्षा कर रहे हों potential leaks के लिए, दोनों predefined और custom logging statements की तलाश करें, जैसे कि built-in functions के लिए NSLog, NSAssert, NSCAssert, fprintf और custom implementations के लिए Logging या Logfile का कोई उल्लेख।

Monitoring System Logs

Apps विभिन्न प्रकार की जानकारी log करते हैं जो संवेदनशील हो सकती है। इन logs की निगरानी के लिए, निम्नलिखित tools और commands उपयोगी हैं:

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

उपयोगी होते हैं। इसके अलावा, Xcode कंसोल लॉग इकट्ठा करने का एक तरीका प्रदान करता है:

  1. Xcode खोलें।
  2. iOS डिवाइस कनेक्ट करें।
  3. Window -> Devices and Simulators पर जाएँ।
  4. अपना डिवाइस चुनें।
  5. जिस समस्या की आप जांच कर रहे हैं उसे ट्रिगर करें।
  6. लॉग नए विंडो में देखने के लिए Open Console बटन का उपयोग करें।

अधिक उन्नत लॉगिंग के लिए, डिवाइस शेल से कनेक्ट होकर और socat का उपयोग करके आप रीयल-टाइम लॉग मॉनिटरिंग प्राप्त कर सकते हैं:

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

लॉग गतिविधियों का निरीक्षण करने के लिए दिए गए कमांड्स का उपयोग किया जा सकता है, जो समस्याओं के निदान या लॉग में संभावित data leakage की पहचान के लिए अमूल्य हो सकते हैं।

बैकअप

Auto-backup features iOS में एकीकृत हैं, जो iTunes (up to macOS Catalina), Finder (from macOS Catalina onward), या iCloud के माध्यम से डिवाइस डेटा की प्रतियां बनाने की सुविधा प्रदान करते हैं। ये backups लगभग सभी डिवाइस डेटा को शामिल करते हैं, सिवाय अत्यधिक संवेदनशील तत्वों जैसे Apple Pay विवरण और Touch ID कॉन्फ़िगरेशन के।

सुरक्षा जोखिम

बैकअप में इंस्टॉल किए गए ऐप और उनका डेटा शामिल होने से संभावित data leakage और इस बात का जोखिम उठता है कि backup modifications could alter app functionality। इन जोखिमों को कम करने के लिए सलाह दी जाती है कि किसी भी ऐप की डायरेक्टरी या उसकी सबडायरेक्टरीज़ में संवेदनशील जानकारी को plaintext में न रखें।

बैकअप से फ़ाइलें बाहर करना

डिफ़ॉल्ट रूप से Documents/ और Library/Application Support/ में स्थित फ़ाइलें बैकअप की जाती हैं। डेवलपर्स NSURL setResourceValue:forKey:error: और NSURLIsExcludedFromBackupKey का उपयोग करके बैकअप से विशिष्ट फ़ाइलों या डायरेक्टरीज़ को exclude कर सकते हैं। यह अभ्यास संवेदनशील डेटा को बैकअप में शामिल होने से रोकने के लिए महत्वपूर्ण है।

कमजोरियों का परीक्षण

किसी ऐप की बैकअप सुरक्षा का आकलन करने के लिए, पहले Finder का उपयोग करके creating a backup करें, फिर उसे Apple’s official documentation के मार्गदर्शन से ढूंढें। बैकअप का विश्लेषण कर ऐसे संवेदनशील डेटा या कॉन्फ़िगरेशन खोजें जिन्हें बदलकर ऐप के व्यवहार को प्रभावित किया जा सकता है।

संवेदनशील जानकारी को command-line tools या iMazing जैसे एप्लिकेशन का उपयोग करके खोजा जा सकता है। एन्क्रिप्टेड बैकअप के लिए, एन्क्रिप्शन की उपस्थिति की पुष्टि बैकअप के रूट में मौजूद “Manifest.plist” फ़ाइल में “IsEncrypted” key की जांच करके की जा सकती है।

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

एन्क्रिप्टेड बैकअप्स से निपटने के लिए, DinoSec’s GitHub repo में उपलब्ध Python स्क्रिप्टें, जैसे backup_tool.py और backup_passwd.py, उपयोगी हो सकती हैं, हालाँकि नवीनतम iTunes/Finder वर्शन के साथ compatibility के लिए समायोजन की आवश्यकता पड़ सकती है। iOSbackup tool पासवर्ड-प्रोटेक्टेड बैकअप्स के भीतर फाइलों तक पहुँचने का एक और विकल्प है।

ऐप व्यवहार में परिवर्तन

ऐसा एक उदाहरण Bither bitcoin wallet app में दिखाया गया है, जहाँ UI lock PIN net.bither.plist में pin_code key के तहत स्टोर होता है। plist से इस key को हटाकर और बैकअप restore करके PIN requirement हटा दी जा सकती है, जिससे unrestricted access मिल जाता है।

संवेदनशील डेटा के लिए मेमोरी परीक्षण का सारांश

जब किसी एप्लिकेशन की मेमोरी में स्टोर संवेदनशील जानकारी से निपटा जा रहा हो, तो उस डेटा के exposure समय को सीमित रखना अत्यंत महत्वपूर्ण है। मेमोरी कंटेंट की जांच के दो मुख्य तरीके हैं: creating a memory dump और analyzing the memory in real time। दोनों विधियों में चुनौतियाँ होती हैं, जिनमें dump प्रक्रिया या विश्लेषण के दौरान महत्वपूर्ण डेटा छूट जाने की संभावना शामिल है।

Retrieving and Analyzing a Memory Dump

दोनों jailbroken और non-jailbroken devices के लिए, objection और Fridump जैसे टूल्स एप के process memory को dump करने की अनुमति देते हैं। एक बार dump हो जाने पर, इस डेटा का विश्लेषण करने के लिए विभिन्न टूल्स की आवश्यकता होती है, जो आप जिस जानकारी की तलाश कर रहे हैं उसकी प्रकृति पर निर्भर करता है।

memory dump से strings निकालने के लिए, strings या rabin2 -zz जैसे कमांड्स का उपयोग किया जा सकता है:

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

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

विशेष डेटा प्रकारों या पैटर्न की खोज सहित अधिक विस्तृत विश्लेषण के लिए, radare2 व्यापक खोज क्षमताएँ प्रदान करता है:

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

Runtime Memory Analysis

r2frida एक शक्तिशाली विकल्प प्रदान करता है जो किसी ऐप की memory को रीयल‑टाइम में निरीक्षण करने की अनुमति देता है, बिना किसी memory dump की आवश्यकता के। यह टूल चल रही application’s memory पर सीधे search commands चलाने में सक्षम बनाता है:

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

टूटी हुई Cryptography

खराब Key Management Processes

कुछ developers local storage में संवेदनशील डेटा सेव करते हैं और इसे कोड में hardcoded/predictable key से encrypt कर देते हैं। ऐसा नहीं करना चाहिए क्योंकि कुछ reversing से attackers confidential जानकारी extract कर सकते हैं।

Insecure और/या Deprecated Algorithms का उपयोग

Developers को authorisation के लिए deprecated algorithms का उपयोग करके checks, डेटा को store या send करने से बचना चाहिए। इनमें से कुछ algorithms हैं: RC4, MD4, MD5, SHA1… उदाहरण के लिए अगर पासवर्ड्स को hashes के रूप में store किया जाता है, तो brute-force resistant hashes का उपयोग किया जाना चाहिए साथ में salt।

जाँच

मुख्य जाँच यह है कि क्या आप कोड में hardcoded passwords/secrets ढूँढ सकते हैं, या क्या वे predictable हैं, और क्या कोड किसी प्रकार के weak cryptography algorithms का उपयोग कर रहा है।

यह जानना दिलचस्प है कि आप कुछ crypto libraries को स्वतः monitor कर सकते हैं objection का उपयोग करके:

ios monitor crypt

For अधिक जानकारी about iOS cryptographic APIs and libraries access https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography

लोकल ऑथेंटिकेशन

लोकल ऑथेंटिकेशन एक महत्वपूर्ण भूमिका निभाता है, विशेषकर तब जब क्रिप्टोग्राफिक तरीकों से रिमोट एंडपॉइंट पर एक्सेस की सुरक्षा की बात हो। मूल बात यह है कि सही तरीके से लागू न किए जाने पर लोकल ऑथेंटिकेशन मैकेनिज्म को बायपास किया जा सकता है।

Apple का Local Authentication framework और keychain डेवलपर्स को यूज़र ऑथेंटिकेशन डायलॉग दिखाने और गुप्त डेटा को सुरक्षित रूप से हैंडल करने के लिए मजबूत APIs प्रदान करते हैं। Secure Enclave Touch ID के लिए fingerprint ID को सुरक्षित करता है, जबकि Face ID चेहरे की पहचान पर निर्भर करता है बिना बायोमेट्रिक डेटा को उजागर किए।

Touch ID/Face ID को इंटीग्रेट करने के लिए डेवलपर्स के पास दो API विकल्प हैं:

  • LocalAuthentication.framework उच्च-स्तरीय यूज़र ऑथेंटिकेशन के लिए, बिना बायोमेट्रिक डेटा तक पहुँच के।
  • Security.framework निचले-स्तरीय keychain सर्विसेज़ तक पहुँच के लिए, जो गुप्त डेटा को बायोमेट्रिक ऑथेंटिकेशन से सुरक्षित करता है। विभिन्न open-source wrappers keychain एक्सेस को सरल बनाते हैं।

Caution

हालाँकि, दोनों LocalAuthentication.framework और Security.framework में कमजोरियाँ हैं, क्योंकि वे मुख्य रूप से boolean मान लौटाते हैं बिना ऑथेंटिकेशन प्रक्रियाओं के लिए डेटा ट्रांसमिट किए, जिससे इन्हें बायपास किया जा सकता है (संदर्भ के लिए देखें Don’t touch me that way, by David Lindner et al).

लोकल ऑथेंटिकेशन लागू करना

यूज़र्स को ऑथेंटिकेशन के लिए प्रेरित करने हेतु, डेवलपर्स को LAContext क्लास के भीतर evaluatePolicy मेथड का उपयोग करना चाहिए, और निम्न में से चुनना चाहिए:

  • deviceOwnerAuthentication: Touch ID या device passcode के लिए संकेत देता है; यदि दोनों सक्षम नहीं हैं तो विफल हो जाता है।
  • deviceOwnerAuthenticationWithBiometrics: केवल Touch ID के लिए संकेत देता है।

सफल ऑथेंटिकेशन evaluatePolicy से वापस आने वाले boolean मान से संकेतित होती है, जो एक संभावित सुरक्षा दोष को उजागर करती है।

Keychain का उपयोग करके लोकल ऑथेंटिकेशन

iOS ऐप्स में local authentication लागू करने के लिए keychain APIs का उपयोग करके ऑथेंटिकेशन टोकन जैसे गुप्त डेटा को सुरक्षित रूप से स्टोर किया जाता है। यह प्रक्रिया सुनिश्चित करती है कि ये डेटा केवल उपयोगकर्ता द्वारा ही एक्सेस किए जा सकते हैं, उनके device passcode या Touch ID जैसे बायोमेट्रिक ऑथेंटिकेशन का उपयोग करके।

keychain SecAccessControl attribute के साथ आइटम सेट करने की क्षमता प्रदान करता है, जो कि उपयोगकर्ता द्वारा Touch ID या device passcode के माध्यम से सफलतापूर्वक ऑथेंटिकेट किए बिना आइटम तक पहुँच को प्रतिबंधित करता है। यह फीचर सुरक्षा बढ़ाने के लिए अहम है।

नीचे Swift और Objective-C में कोड उदाहरण दिए गए हैं जो दिखाते हैं कि कैसे इन सुरक्षा फीचर्स का उपयोग करके keychain में एक string को सेव और रिट्रीव किया जाए। उदाहरण विशेष रूप से दिखाते हैं कि कैसे access control सेट किया जाए ताकि Touch ID ऑथेंटिकेशन की आवश्यकता हो और यह सुनिश्चित किया जा सके कि डेटा केवल उसी डिवाइस पर उपयोग योग्य हो जिस पर इसे सेट किया गया था, बशर्ते डिवाइस passcode कॉन्फ़िगर हो।

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

अब हम keychain से सेव किए गए आइटम का अनुरोध कर सकते हैं। Keychain services उपयोगकर्ता को प्रमाणीकरण संवाद दिखाएगा और डेटा या nil वापस करेगा, यह इस बात पर निर्भर करेगा कि क्या एक उपयुक्त fingerprint प्रदान किया गया था या नहीं।

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

पता लगाना

किसी app में frameworks के उपयोग का पता app binary की shared dynamic libraries की सूची का विश्लेषण करके भी लगाया जा सकता है। यह otool का उपयोग करके किया जा सकता है:

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

यदि LocalAuthentication.framework किसी ऐप में उपयोग किया गया है, तो आउटपुट में निम्नलिखित दोनों पंक्तियाँ शामिल होंगी (याद रखें कि LocalAuthentication.framework अंतर्निहित रूप से Security.framework का उपयोग करता है):

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

यदि Security.framework का उपयोग किया गया है, तो केवल दूसरा ही दिखाया जाएगा।

Local Authentication Framework Bypass

Objection

यह तकनीक Objection Biometrics Bypass, जो this GitHub page पर उपलब्ध है, LocalAuthentication मेकैनिज्म को पार करने के लिए इस्तेमाल की जाती है। इस विधि का मुख्य हिस्सा Frida का उपयोग करके evaluatePolicy फ़ंक्शन में हेरफेर करना है, ताकि यह वास्तविक authentication की सफलता की परवाह किए बिना लगातार True परिणाम दे। यह विशेष रूप से दोषपूर्ण biometric authentication प्रक्रियाओं को बायपास करने में उपयोगी है।

इस bypass को सक्रिय करने के लिए निम्नलिखित command का उपयोग किया जाता है:

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

यह कमांड एक ऐसी श्रृंखला शुरू कर देता है जहाँ Objection एक टास्क रजिस्टर करता है जो प्रभावी रूप से evaluatePolicy चेक के परिणाम को True में बदल देता है।

Frida

evaluatePolicy के उपयोग का एक उदाहरण DVIA-v2 application से:

+(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 का bypass हासिल करने के लिए एक Frida स्क्रिप्ट लिखी जाती है। यह स्क्रिप्ट evaluatePolicy चेक को लक्षित करती है, और उसके callback को intercept करके यह सुनिश्चित करती है कि वह success=1 लौटाए। callback के व्यवहार को बदलकर, authentication चेक प्रभावी रूप से bypass हो जाता है।

नीचे दी गई स्क्रिप्ट को inject किया जाता है ताकि evaluatePolicy method के परिणाम को बदल दिया जाए। यह callback के परिणाम को हमेशा success दिखाने के लिए बदल देती है।

// 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 को inject करके और biometric authentication को bypass करने के लिए, निम्नलिखित command का उपयोग किया जाता है:

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

IPC के माध्यम से संवेदनशील कार्यक्षमता का खुलासा

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

Network Communication

यह सुनिश्चित करना महत्वपूर्ण है कि कोई भी संचार बिना एन्क्रिप्शन के न हो और साथ ही यह भी कि application सर्वर के TLS certificate को ठीक से validate कर रहा है।
इन प्रकार के मुद्दों की जाँच के लिए आप Burp जैसे proxy का इस्तेमाल कर सकते हैं:

iOS Burp Suite Configuration

Hostname check

TLS certificate validate करते समय एक सामान्य समस्या यह है कि certificate को विश्वसनीय CA द्वारा साइन किया गया था यह चेक किया जाता है, लेकिन यह चेक नहीं किया जाता कि сертификेट का hostname वही है जिसे access किया जा रहा है।
Burp का उपयोग करके इस समस्या की जाँच करने के लिए, iPhone में Burp CA को trust करने के बाद, आप एक अलग hostname के लिए Burp के साथ नया certificate बना कर उपयोग कर सकते हैं। यदि application फिर भी काम करता है, तो कुछ न कुछ vulnerable है।

Certificate Pinning

यदि कोई application सही तरीके से SSL Pinning का उपयोग कर रहा है, तो application केवल तभी काम करेगा जब certificate वही हो जिसकी उम्मीद की जा रही है। टेस्टिंग के दौरान यह एक समस्या हो सकती है क्योंकि Burp अपनी ही certificate सर्व करेगा।
एक jailbroken device के अंदर इस सुरक्षा को bypass करने के लिए, आप application SSL Kill Switch इंस्टॉल कर सकते हैं या Burp Mobile Assistant इंस्टॉल कर सकते हैं।

आप objection का ios sslpinning disable भी उपयोग कर सकते हैं।

Misc

  • In /System/Library आप उन frameworks को पा सकते हैं जो सिस्टम applications द्वारा उपयोग के लिए फोन में इंस्टॉल होते हैं
  • App Store से user द्वारा इंस्टॉल की गई applications /User/Applications के अंदर स्थित होती हैं
  • और /User/Library में user level applications द्वारा सहेजा गया डेटा होता है
  • आप /User/Library/Notes/notes.sqlite तक पहुँच कर application के अंदर सहेजे गए नोट्स पढ़ सकते हैं।
  • किसी इंस्टॉल्ड application के फोल्डर के अंदर (/User/Applications/<APP ID>/) आप कुछ दिलचस्प फाइलें पा सकते हैं:
  • iTunesArtwork: ऐप द्वारा उपयोग किया गया आइकन
  • iTunesMetadata.plist: App Store में उपयोग होने वाली ऐप की जानकारी
  • /Library/*: इसमें preferences और cache होते हैं। /Library/Cache/Snapshots/* में आप उस snapshot को पा सकते हैं जो application को background में भेजने से पहले लिया गया था।

Hot Patching/Enforced Updateing

डेवलपर्स दूर से अपने ऐप की सभी इंस्टॉलेशनों को तुरंत patch कर सकते हैं बिना application को App Store में फिर से submit किए और approval का इंतजार किए।
इसके लिए आम तौर पर JSPatch का उपयोग किया जाता है। लेकिन अन्य विकल्प भी हैं जैसे Siren और react-native-appstore-version-checker
यह एक खतरनाक तंत्र है जिसे malicious third party SDKs द्वारा दुरुपयोग किया जा सकता है, इसलिए यह अनुशंसित है कि ऑटोमैटिक updating (यदि कोई हो) के लिए कौन सा method उपयोग किया जा रहा है उसे चेक किया जाए और टेस्ट किया जाए। इस उद्देश्य के लिए आप ऐप का कोई पिछला वर्शन डाउनलोड करके भी देख सकते हैं।

Third Parties

3rd party SDKs के साथ एक महत्वपूर्ण चुनौती उनकी functionalities पर granular control की कमी है। डेवलपर्स के सामने एक विकल्प होता है: या तो SDK को integrate करें और इसके सभी फीचर्स स्वीकार करें, जिसमें संभावित security vulnerabilities और privacy चिंताएँ शामिल हैं, या इसके लाभों को पूरी तरह से त्याग दें। अक्सर, डेवलपर्स इन SDKs में मौजूद vulnerabilities को स्वयं patch नहीं कर पाते। इसके अलावा, जैसे-जैसे SDKs समुदाय में trust प्राप्त करते हैं, कुछ में malware भी समा सकते हैं।

third-party SDKs द्वारा प्रदान की जाने वाली सेवाओं में user behavior tracking, advertisements दिखाना, या user experience enhancements शामिल हो सकते हैं। हालांकि, इससे जोखिम उत्पन्न होता है क्योंकि डेवलपर्स हमेशा उन लाइब्रेरीज़ द्वारा execute किए जा रहे कोड के बारे में पूरी तरह जागरूक नहीं होते, जिससे संभावित privacy और security जोखिम पैदा होते हैं। यह महत्वपूर्ण है कि third-party सेवाओं के साथ साझा की जाने वाली जानकारी को केवल आवश्यकतम तक सीमित रखा जाए और सुनिश्चित किया जाए कि कोई संवेदनशील डेटा उजागर न हो।

third-party सेवाओं का implementation आम तौर पर दो रूपों में होता है: standalone library या पूरा SDK। उपयोगकर्ता की गोपनीयता की सुरक्षा के लिए, इन सेवाओं के साथ साझा किया जाने वाला कोई भी डेटा anonymized होना चाहिए ताकि Personal Identifiable Information (PII) का खुलासा न हो।

किस लाइब्रेरी का उपयोग एक application कर रही है पहचानने के लिए, otool कमांड का उपयोग किया जा सकता है। यह टूल application और उसके द्वारा उपयोग की जाने वाली प्रत्येक shared library के खिलाफ चलाया जाना चाहिए ताकि अतिरिक्त libraries का पता चल सके।

otool -L <application_path>

दिलचस्प Vulnerabilities & Case Studies

Air Keyboard Remote Input Injection

Itunesstored Bookassetd Sandbox Escape

Zero Click Messaging Image Parser Chains

संदर्भ और अधिक संसाधन

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें