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

์ดˆ๊ธฐ ๋ถ„์„

๊ธฐ๋ณธ iOS ํ…Œ์ŠคํŠธ ์ž‘์—…

ํ…Œ์ŠคํŠธ ์ค‘์— ์—ฌ๋Ÿฌ ์ž‘์—…์ด ์ œ์•ˆ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค (connect to the device, read/write/upload/download files, use some toolsโ€ฆ). ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅธ๋‹ค๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ๋จผ์ € ์ฝ๊ธฐ ์‹œ์ž‘ํ•˜์„ธ์š”:

iOS Basic Testing Operations

Tip

๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์ง„ํ–‰ํ•˜๋ ค๋ฉด ์•ฑ์ด ๋””๋ฐ”์ด์Šค์— ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ IPA ํŒŒ์ผ์„ ์ด๋ฏธ ํ™•๋ณดํ–ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Basic iOS Testing Operations ํŽ˜์ด์ง€๋ฅผ ์ฝ์œผ์„ธ์š”.

๊ธฐ๋ณธ ์ •์  ๋ถ„์„

ํฅ๋ฏธ๋กœ์šด iOS - IPA ํŒŒ์ผ ๋””์ปดํŒŒ์ผ๋Ÿฌ ๋ช‡ ๊ฐ€์ง€:

IPA ํŒŒ์ผ์— ๋Œ€ํ•ด ์ž๋™ ์ •์  ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋„๊ตฌ MobSF๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

๋ฐ”์ด๋„ˆ๋ฆฌ์— ์ ์šฉ๋œ ๋ณดํ˜ธ ๊ธฐ๋Šฅ ์‹๋ณ„:

  • PIE (Position Independent Executable): ํ™œ์„ฑํ™”๋˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ๋ฌด์ž‘์œ„ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์— ๋กœ๋“œ๋˜์–ด ์ดˆ๊ธฐ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์˜ˆ์ธกํ•˜๊ธฐ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
otool -hv <app-binary> | grep PIE   # It should include the PIE flag
  • Stack Canaries: ์Šคํƒ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ „์— โ€˜canaryโ€™ ๊ฐ’์„ ์Šคํƒ์— ๋ฐฐ์น˜ํ•˜๊ณ  ํ•จ์ˆ˜๊ฐ€ ๋๋‚  ๋•Œ ๋‹ค์‹œ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
  • ARC (Automatic Reference Counting): ์ผ๋ฐ˜์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์†์ƒ ์ทจ์•ฝ์ ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
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

๋ฏผ๊ฐ/์ทจ์•ฝ ํ•จ์ˆ˜ ์‹๋ณ„

  • ์•ฝํ•œ ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
# 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"
  • ๋ถˆ์•ˆ์ „ํ•œ ๋žœ๋ค ํ•จ์ˆ˜
# 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"
  • ๋ถˆ์•ˆ์ „ํ•œ โ€˜Mallocโ€™ ํ•จ์ˆ˜
# On the iOS device
otool -Iv <app> | grep -w "_malloc"

# On linux
grep -iER "_malloc"
  • ์•ˆ์ „ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ทจ์•ฝํ•œ ํ•จ์ˆ˜๋“ค
# 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 ํƒ์ง€ ๋ฐฉ๋ฒ•

  • ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ฒ€์‚ฌ: /Applications/Cydia.app ๋˜๋Š” /Library/MobileSubstrate/MobileSubstrate.dylib๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ jailbreak ํŒŒ์ผ ๋ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ์กด์žฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒŒ๋“œ๋ฐ•์Šค ์œ„๋ฐ˜: non-jailbroken devices์—์„œ ์ฐจ๋‹จ๋˜์–ด์•ผ ํ•˜๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ์ œํ•œ ์˜์—ญ์— ์ ‘๊ทผ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
  • API ๊ฒ€์‚ฌ: fork() ๊ฐ™์€ ๊ธˆ์ง€๋œ ํ˜ธ์ถœ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ system()์„ ์‚ฌ์šฉํ•ด /bin/sh๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋กœ์„ธ์Šค ๊ฒ€์‚ฌ: Cydia, Substrate, ssh์™€ ๊ฐ™์€ ์•Œ๋ ค์ง„ jailbreak ๊ด€๋ จ ํ”„๋กœ์„ธ์Šค์˜ ์กด์žฌ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
  • ์ปค๋„ ์ต์Šคํ”Œ๋กœ์ž‡: jailbreak์— ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ปค๋„ ์ต์Šคํ”Œ๋กœ์ž‡์˜ ์กด์žฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜: DYLD_INSERT_LIBRARIES์™€ ๊ฐ™์€ jailbreak ์‹ ํ˜ธ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
  • ๋กœ๋“œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™•์ธ: ์•ฑ ํ”„๋กœ์„ธ์Šค์— ๋กœ๋“œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ์Šคํ‚ด ํ™•์ธ: ์˜ˆ: canOpenURL(URL(string: โ€œcydia://โ€)).

์ผ๋ฐ˜์ ์ธ ์•ˆํ‹ฐ-๋””๋ฒ„๊น… ํƒ์ง€ ๋ฐฉ๋ฒ•

  • ๋””๋ฒ„๊ฑฐ ์กด์žฌ ํ™•์ธ: sysctl ๋˜๋Š” ๊ธฐํƒ€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ฒ„๊ฑฐ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ์•ˆํ‹ฐ-๋””๋ฒ„๊น… API: ptrace ๋˜๋Š” SIGSTOP ๊ฐ™์€ ์•ˆํ‹ฐ-๋””๋ฒ„๊น… API ํ˜ธ์ถœ(ptrace(PT_DENY_ATTACH, 0, 0, 0) ๋“ฑ)์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ํƒ€์ด๋ฐ ๊ฒ€์‚ฌ: ํŠน์ • ์ž‘์—…์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜์—ฌ ๋””๋ฒ„๊น…์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ถˆ์ผ์น˜๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์‚ฌ: ์•Œ๋ ค์ง„ ๋””๋ฒ„๊ฑฐ ์œ ๋ฌผ ๋˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜: ๋””๋ฒ„๊น… ์„ธ์…˜์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • Mach ํฌํŠธ: ๋””๋ฒ„๊ฑฐ๊ฐ€ mach ์˜ˆ์™ธ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ๋™์  ๋ถ„์„

MobSF๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์  ๋ถ„์„์„ ํ™•์ธํ•˜์„ธ์š”. ๋‹ค์–‘ํ•œ ๋ทฐ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ์—ฌ๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ํ›„ํ‚นํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ์™„๋ฃŒํ•˜๋ฉด ๋ณด๊ณ ์„œ๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.

์„ค์น˜๋œ ์•ฑ ๋‚˜์—ด

์„ค์น˜๋œ ์•ฑ์˜ 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ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ objection์œผ๋กœ hook methods and classesํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ์„ธ์š”:

iOS Hooking With Objection

IPA ๊ตฌ์กฐ

The structure of an IPA file is essentially that of a zipped package. By renaming its extension to .zip, it can be decompressed to reveal its contents. Within this structure, a Bundle represents a fully packaged application ready for installation. Inside, you will find a directory named <NAME>.app, which encapsulates the applicationโ€™s resources.

  • Info.plist: ์ด ํŒŒ์ผ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŠน์ • ๊ตฌ์„ฑ ์„ธ๋ถ€์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • _CodeSignature/: ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์—๋Š” ์„œ๋ช…์„ ํฌํ•จํ•œ plist ํŒŒ์ผ์ด ์žˆ์–ด ๋ฒˆ๋“ค ๋‚ด ๋ชจ๋“  ํŒŒ์ผ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • Assets.car: ์•„์ด์ฝ˜๊ณผ ๊ฐ™์€ ์ž์‚ฐ ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” ์••์ถ• ์•„์นด์ด๋ธŒ์ž…๋‹ˆ๋‹ค.
  • Frameworks/: ์ด ํด๋”๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๋ฉฐ .dylib ๋˜๋Š” .framework ํŒŒ์ผ ํ˜•ํƒœ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • PlugIns/: ์ด ํด๋”์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ™•์žฅ(์˜ˆ: .appex ํŒŒ์ผ)์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•ญ์ƒ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. * Core Data: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜๊ตฌ ๋ฐ์ดํ„ฐ๋ฅผ ์˜คํ”„๋ผ์ธ์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ์ €์žฅํ•˜๊ณ , ์ž„์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹œํ•˜๋ฉฐ, ๋‹จ์ผ ๊ธฐ๊ธฐ์—์„œ undo ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‹จ์ผ iCloud ๊ณ„์ •์˜ ์—ฌ๋Ÿฌ ๊ธฐ๊ธฐ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋ ค๋ฉด Core Data๊ฐ€ ์ž๋™์œผ๋กœ ์Šคํ‚ค๋งˆ๋ฅผ CloudKit ์ปจํ…Œ์ด๋„ˆ์— ๋ฏธ๋Ÿฌ๋งํ•ฉ๋‹ˆ๋‹ค.
  • PkgInfo: PkgInfo ํŒŒ์ผ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋˜๋Š” ๋ฒˆ๋“ค์˜ type ๋ฐ creator ์ฝ”๋“œ๋ฅผ ์ง€์ •ํ•˜๋Š” ๋Œ€์ฒด ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
  • en.lproj, fr.proj, Base.lproj: ํŠน์ • ์–ธ์–ด์šฉ ๋ฆฌ์†Œ์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ์–ธ์–ด ํŒฉ์ด๋ฉฐ, ํ•ด๋‹น ์–ธ์–ด๊ฐ€ ์ง€์›๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์˜ ๊ธฐ๋ณธ ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • Security: _CodeSignature/ ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” ๋””์ง€ํ„ธ ์„œ๋ช…์„ ํ†ตํ•ด ๋ฒˆ๋“ค๋œ ๋ชจ๋“  ํŒŒ์ผ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๊ฒ€์ฆํ•จ์œผ๋กœ์จ ์•ฑ ๋ณด์•ˆ์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • Asset Management: Assets.car ํŒŒ์ผ์€ ์••์ถ•์„ ์‚ฌ์šฉํ•ด ๊ทธ๋ž˜ํ”ฝ ์ž์‚ฐ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐ ์ „์ฒด ํฌ๊ธฐ ๊ฐ์†Œ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
  • Frameworks and PlugIns: ์ด๋Ÿฌํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” iOS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“ˆ์„ฑ์„ ๊ฐ•์กฐํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Frameworks/)๋ฅผ ํฌํ•จํ•˜๊ณ  ์•ฑ ๊ธฐ๋Šฅ์„ ํ™•์žฅ(PlugIns/)ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • Localization: ์ด ๊ตฌ์กฐ๋Š” ์—ฌ๋Ÿฌ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜์—ฌ ํŠน์ • ์–ธ์–ด ํŒฉ์šฉ ๋ฆฌ์†Œ์Šค๋ฅผ ํฌํ•จํ•จ์œผ๋กœ์จ ๊ธ€๋กœ๋ฒŒ ์•ฑ ํ™•์žฅ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Info.plist

Info.plist๋Š” iOS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ์š”์†Œ๋กœ, key-value ์Œ ํ˜•ํƒœ๋กœ ์ฃผ์š” ๊ตฌ์„ฑ ๋ฐ์ดํ„ฐ๋ฅผ ์บก์Аํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋ฟ ์•„๋‹ˆ๋ผ ๋ฒˆ๋“ค๋œ ์•ฑ ํ™•์žฅ๊ณผ ํ”„๋ ˆ์ž„์›Œํฌ์—๋„ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. XML ๋˜๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜•์‹์œผ๋กœ ๊ตฌ์กฐํ™”๋˜๋ฉฐ, ์•ฑ ๊ถŒํ•œ์—์„œ ๋ณด์•ˆ ๊ตฌ์„ฑ์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ‚ค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Apple Developer Documentation์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์ด ํŒŒ์ผ์„ ๋” ์ ‘๊ทผํ•˜๊ธฐ ์‰ฌ์šด ํ˜•์‹์œผ๋กœ ์ž‘์—…ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, macOS์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณต๋˜๋Š” plutil (10.2 ๋ฒ„์ „ ์ด์ƒ) ๋˜๋Š” Linux์—์„œ์˜ plistutil์„ ์‚ฌ์šฉํ•˜์—ฌ XML๋กœ ์‰ฝ๊ฒŒ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€ํ™˜ ๋ช…๋ น์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  • macOS์˜ ๊ฒฝ์šฐ:
$ plutil -convert xml1 Info.plist
  • Linux์šฉ:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

Info.plist ํŒŒ์ผ์ด ๋“œ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋งŽ์€ ์ •๋ณด ์ค‘์—์„œ ์ฃผ๋ชฉํ•  ๋งŒํ•œ ํ•ญ๋ชฉ์œผ๋กœ๋Š” ์•ฑ ๊ถŒํ•œ ๋ฌธ์ž์—ด (UsageDescription), ์ปค์Šคํ…€ URL ์Šคํ‚ด (CFBundleURLTypes), ๊ทธ๋ฆฌ๊ณ  App Transport Security ์„ค์ • (NSAppTransportSecurity) ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ•ญ๋ชฉ๋“ค์€ UTExportedTypeDeclarations / UTImportedTypeDeclarations ๊ฐ™์€ ๋‚ด๋ณด๋‚ด๊ธฐ/๊ฐ€์ ธ์˜ค๊ธฐ์šฉ ์ปค์Šคํ…€ ๋ฌธ์„œ ํƒ€์ž…๊ณผ ํ•จ๊ป˜, ํŒŒ์ผ์„ ์ง์ ‘ ๊ฒ€์‚ฌํ•˜๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ grep ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

$ grep -i <keyword> Info.plist

๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ

iOS ํ™˜๊ฒฝ์—์„œ๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์‹œ์Šคํ…œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์‚ฌ์šฉ์ž ์„ค์น˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์šฉ์œผ๋กœ ๊ฐ๊ฐ ์ง€์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ /Applications ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์œ„์น˜ํ•˜๊ณ , ์‚ฌ์šฉ์ž ์„ค์น˜ ์•ฑ์€ /var/mobile/containers/Data/Application/ ์•„๋ž˜์— ๋ฐฐ์น˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์€ 128-bit UUID๋ผ๋Š” ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ๋ถ€์—ฌ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ ‰ํ„ฐ๋ฆฌ ์ด๋ฆ„์ด ๋ฌด์ž‘์œ„์—ฌ์„œ ์ˆ˜๋™์œผ๋กœ ์•ฑ ํด๋”๋ฅผ ์ฐพ๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

Warning

iOS์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ƒŒ๋“œ๋ฐ•์Šค๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ, ๊ฐ ์•ฑ์€ $HOME/Library/Containers ์•ˆ์— ์•ฑ์˜ **CFBundleIdentifier**๋ฅผ ํด๋” ์ด๋ฆ„์œผ๋กœ ํ•˜๋Š” ํด๋”๋ฅผ ๋˜ํ•œ ๊ฐ–์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ๋‘ ํด๋”(๋ฐ์ดํ„ฐ & ์ปจํ…Œ์ด๋„ˆ ํด๋”) ๋ชจ๋‘์—๋Š” ๋‘ ํŒŒ์ผ์„ ์—ฐ๊ฒฐํ•˜๋Š” ํ‚ค MCMetadataIdentifier๊ฐ€ ์žˆ๋Š” .com.apple.mobile_container_manager.metadata.plist ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค).

์‚ฌ์šฉ์ž ์„ค์น˜ ์•ฑ์˜ ์„ค์น˜ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฐœ๊ฒฌ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด, 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

๋˜๋Š” find ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ /private/var/containers ๋‚ด์—์„œ ์•ฑ ์ด๋ฆ„์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

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

์˜ˆ๋ฅผ ๋“ค์–ด ps ๋ฐ lsof ๊ฐ™์€ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ๊ฐ ์•ฑ์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ์—ด๋ฆฐ ํŒŒ์ผ์„ ๋‚˜์—ดํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ™œ์„ฑ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ํ†ต์ฐฐ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

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

๋ฒˆ๋“ค ๋””๋ ‰ํ„ฐ๋ฆฌ:

  • AppName.app
  • ์ด์ „์— IPA์—์„œ ๋ณด์•˜๋˜ Application Bundle์ž…๋‹ˆ๋‹ค. ํ•„์ˆ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ, ์ •์  ์ฝ˜ํ…์ธ  ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปดํŒŒ์ผ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€๋งŒ, ์‚ฌ์šฉ์ž๋Š” ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋‚ด์šฉ์€ ๋ฐฑ์—…๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ด ํด๋”์˜ ๋‚ด์šฉ์€ ์ฝ”๋“œ ์„œ๋ช… ๊ฒ€์ฆ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ:

  • Documents/
  • ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ƒ์„ฑ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ์˜ ์ƒ์„ฑ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋ฉฐ ์‚ฌ์šฉ์ž๋Š” ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋‚ด์šฉ์€ ๋ฐฑ์—…๋ฉ๋‹ˆ๋‹ค.
  • ์•ฑ์€ NSURLIsExcludedFromBackupKey๋ฅผ ์„ค์ •ํ•˜์—ฌ ๊ฒฝ๋กœ๋ฅผ ๋ฐฑ์—…์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Library/
  • ์‚ฌ์šฉ์ž๋ณ„์ด ์•„๋‹Œ ํŒŒ์ผ๋“ค, ์˜ˆ๋ฅผ ๋“ค์–ด caches, preferences, cookies, ๋ฐ property list (plist) ๊ตฌ์„ฑ ํŒŒ์ผ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • iOS ์•ฑ์€ ๋ณดํ†ต Application Support ๋ฐ Caches ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ์•ฑ์€ ์ปค์Šคํ…€ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Library/Caches/
  • ๋ฐ˜์˜๊ตฌ์  ์บ์‹œ ํŒŒ์ผ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€ ์•Š์œผ๋ฉฐ ์‚ฌ์šฉ์ž๋Š” ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋‚ด์šฉ์€ ๋ฐฑ์—…๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • OS๋Š” ์•ฑ์ด ์‹คํ–‰ ์ค‘์ด ์•„๋‹ˆ๊ณ  ์ €์žฅ ๊ณต๊ฐ„์ด ๋ถ€์กฑํ•  ๋•Œ ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ํŒŒ์ผ๋“ค์„ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Library/Application Support/
  • ์•ฑ ์‹คํ–‰์— ํ•„์š”ํ•œ ์˜๊ตฌ์ ์ธ ํŒŒ์ผ๋“ค์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€ ์•Š์œผ๋ฉฐ ์‚ฌ์šฉ์ž๋Š” ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋‚ด์šฉ์€ ๋ฐฑ์—…๋ฉ๋‹ˆ๋‹ค.
  • ์•ฑ์€ NSURLIsExcludedFromBackupKey๋ฅผ ์„ค์ •ํ•˜์—ฌ ๊ฒฝ๋กœ๋ฅผ ๋ฐฑ์—…์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Library/Preferences/
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žฌ์‹œ์ž‘๋œ ์ดํ›„์—๋„ ์ง€์†๋  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ๋“ค์„ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์ •๋ณด๋Š” ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด๋ถ€์˜ [BUNDLE_ID].plist ํŒŒ์ผ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  • NSUserDefaults๋ฅผ ์‚ฌ์šฉํ•ด ์ €์žฅ๋œ ๋ชจ๋“  ํ‚ค/๊ฐ’ ์Œ์€ ์ด ํŒŒ์ผ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • tmp/
  • ์•ฑ ์‹คํ–‰ ๊ฐ„์— ์œ ์ง€๋  ํ•„์š”๊ฐ€ ์—†๋Š” ์ž„์‹œ ํŒŒ์ผ์„ ์“ฐ๋Š” ๋ฐ ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋น„์˜๊ตฌ์  ์บ์‹œ ํŒŒ์ผ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋‚ด์šฉ์€ ๋ฐฑ์—…๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • OS๋Š” ์•ฑ์ด ์‹คํ–‰ ์ค‘์ด ์•„๋‹ˆ๊ณ  ์ €์žฅ ๊ณต๊ฐ„์ด ๋ถ€์กฑํ•  ๋•Œ ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ํŒŒ์ผ๋“ค์„ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒˆ๋“ค ๋””๋ ‰ํ„ฐ๋ฆฌ(/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app) ๋‚ด๋ถ€์— ์žˆ๋Š” iGoat-Swift์˜ Application Bundle (.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

Inside the <application-name>.app folder you will find a binary file called <application-name>. <application-name>.app ํด๋” ์•ˆ์—๋Š” <application-name>๋ผ๋Š” binary ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ๋„๊ตฌ **otool**์„ ์‚ฌ์šฉํ•ด binary๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

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

๋ฐ”์ด๋„ˆ๋ฆฌ ๋””์Šค์–ด์…ˆ๋ธ”

ํ…์ŠคํŠธ ์„น์…˜์„ ๋””์Šค์–ด์…ˆ๋ธ”ํ•˜์„ธ์š”:

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

However, the best options to disassemble the binary are: Hopper and IDA.

๋ฐ์ดํ„ฐ ์ €์žฅ

To learn about how iOS stores data in the device read this page:

iOS Basics

Warning

๋‹ค์Œ์˜ ์ •๋ณด ์ €์žฅ ์œ„์น˜๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์น˜ ์งํ›„, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ํ™•์ธํ•œ ํ›„ ๋ฐ ์‹ฌ์ง€์–ด ํ•œ ์‚ฌ์šฉ์ž์—์„œ ๋กœ๊ทธ์•„์›ƒํ•˜๊ณ  ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋กœ ๋กœ๊ทธ์ธํ•œ ํ›„์—๋„ ํ™•์ธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋ชฉํ‘œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณดํ˜ธ๋˜์ง€ ์•Š์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด(๋น„๋ฐ€๋ฒˆํ˜ธ, ํ† ํฐ), ํ˜„์žฌ ์‚ฌ์šฉ์ž ๋ฐ ์ด์ „์— ๋กœ๊ทธ์ธํ–ˆ๋˜ ์‚ฌ์šฉ์ž๋“ค์˜ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Plist

plist ํŒŒ์ผ์€ ๊ตฌ์กฐํ™”๋œ XML ํŒŒ์ผ๋กœ ํ‚ค-๊ฐ’ ์Œ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์˜๊ตฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋ฏ€๋กœ ๋•Œ๋•Œ๋กœ ์ด๋Ÿฌํ•œ ํŒŒ์ผ์—์„œ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ ์„ค์น˜ ํ›„ ๋ฐ ์•ฑ์„ ์ง‘์ค‘์ ์œผ๋กœ ์‚ฌ์šฉํ•œ ํ›„์— ์ด ํŒŒ์ผ๋“ค์„ ํ™•์ธํ•˜์—ฌ ์ƒˆ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ธฐ๋ก๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

plist ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ ์ €์žฅํ•˜๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ NSUserDefaults์˜ ์‚ฌ์šฉ์ž…๋‹ˆ๋‹ค. ์ด plist ํŒŒ์ผ์€ ์•ฑ ์ƒŒ๋“œ๋ฐ•์Šค์˜ Library/Preferences/<appBundleID>.plist ์•ˆ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

NSUserDefaults ํด๋ž˜์Šค๋Š” ๊ธฐ๋ณธ ์‹œ์Šคํ…œ๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์‹œ์Šคํ…œ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž ์„ค์ •์— ๋”ฐ๋ผ ๋™์ž‘์„ ๋งž์ถคํ™”ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. NSUserDefaults๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฒˆ๋“ค์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” plist ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์ง€๋งŒ, ์†Œ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ์„ ๋ชฉ์ ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฐ์ดํ„ฐ๋Š” ๋” ์ด์ƒ ์‹ ๋ขฐ๋œ ์ปดํ“จํ„ฐ๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์ง€๋งŒ, 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

Within an 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๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฐ์ฒด ๋ชจ๋ธ ๊ณ„์ธต์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. Core Data can use SQLite as its persistent store, ํ•˜์ง€๋งŒ ํ”„๋ ˆ์ž„์›Œํฌ ์ž์ฒด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.\
CoreData๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ถ”๊ฐ€ ์•”ํ˜ธํ™” ๋ ˆ์ด์–ด๋ฅผ CoreData์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ GitHub Repo๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ SQLite Core Data ์ •๋ณด๋Š” ๊ฒฝ๋กœ /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ SQLite๋ฅผ ์—ด์–ด ๋ฏผ๊ฐํ•œ ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์ด๋Š” ๊ตฌ์„ฑ ์˜ค๋ฅ˜(misconfiguration)๋ฅผ ๋ฐœ๊ฒฌํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

-(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 ์œ„์— ๊ตฌ์ถ•๋œ ํ‚ค/๊ฐ’ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค.
YapDatabase๋Š” SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ด๋ฏ€๋กœ ์ด์ „ ์„น์…˜์—์„œ ์ œ์‹œํ•œ ๋ช…๋ น์œผ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐํƒ€ SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž์ฒด SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ํ”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค์—๋Š” ์ €์žฅ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๊ณ  ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ์ฑ„ ๋‚จ๊ฒจ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™ํ•˜์„ธ์š” (/private/var/mobile/Containers/Data/Application/{APPID})

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

Firebase Real-Time Databases

๊ฐœ๋ฐœ์ž๋Š” Firebase Real-Time Databases๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋Š” NoSQL ํด๋ผ์šฐ๋“œ ํ˜ธ์ŠคํŒ… ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋Š” JSON ํ˜•์‹์œผ๋กœ ์ €์žฅ๋˜๋ฉฐ, ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์— ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋™๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.

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

Firebase Database

Realm databases

Realm Objective-C and 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์— ๋„ค์ดํ‹ฐ๋ธŒ๋กœ ์„ค๊ณ„๋˜์–ด ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”๋ฅผ ์›ํ™œํ•˜๊ฒŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์žฅ์น˜์—์„œ ์ž ์žฌ์ ์ธ Couchbase ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‹๋ณ„ํ•˜๋ ค๋ฉด, ๋‹ค์Œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๊ฒ€์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

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

Cookies

iOS๋Š” ๊ฐ ์•ฑ ํด๋” ์•ˆ์˜ **Library/Cookies/cookies.binarycookies**์— ์•ฑ์˜ cookies๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋ฐœ์ž๋“ค์€ ๋•Œ๋•Œ๋กœ ์ด๋ฅผ keychain์— ์ €์žฅํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋Š”๋ฐ, ์–ธ๊ธ‰ํ•œ ์–ธ๊ธ‰๋œ cookie ํŒŒ์ผ์€ ๋ฐฑ์—…์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

cookies ํŒŒ์ผ์„ ๊ฒ€์‚ฌํ•˜๋ ค๋ฉด this python script์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ objection์˜ ios cookies get.
objection์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ํŒŒ์ผ์„ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์บ์‹œ

๊ธฐ๋ณธ์ ์œผ๋กœ NSURLSession์€ Cache.db ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— HTTP requests and responses in the Cache.db์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ํ† ํฐ, ์‚ฌ์šฉ์ž๋ช… ๋˜๋Š” ๊ธฐํƒ€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ์บ์‹œ๋˜์–ด ์žˆ๋‹ค๋ฉด ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์บ์‹œ๋œ ์ •๋ณด๋ฅผ ์ฐพ์œผ๋ ค๋ฉด ์•ฑ์˜ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ(/var/mobile/Containers/Data/Application/<UUID>)๋ฅผ ์—ด๊ณ  /Library/Caches/<Bundle Identifier>๋กœ ์ด๋™ํ•˜์„ธ์š”. WebKit cache is also being stored in the Cache.db ํŒŒ์ผ๋„ Cache.db์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. Objection๋Š” sqlite connect Cache.db ๋ช…๋ น์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ด๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” normal SQLite database์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด ๋ฐ์ดํ„ฐ๋Š” ์š”์ฒญ์ด๋‚˜ ์‘๋‹ต์— ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•˜์ง€ ์•Š๋„๋ก ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ๋ชฉ๋ก์€ ์ด๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค:

  1. ๋กœ๊ทธ์•„์›ƒ ํ›„ ์บ์‹œ๋œ ์‘๋‹ต์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” Apple์—์„œ ์ œ๊ณตํ•˜๋Š” removeAllCachedResponses ๋ฉ”์„œ๋“œ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

URLCache.shared.removeAllCachedResponses()

์ด ๋ฉ”์„œ๋“œ๋Š” Cache.db ํŒŒ์ผ์—์„œ ๋ชจ๋“  ์บ์‹œ๋œ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

  1. ์ฟ ํ‚ค์˜ ์ด์ ์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด URLSession์˜ .ephemeral ๊ตฌ์„ฑ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ฟ ํ‚ค์™€ ์บ์‹œ ์ €์žฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

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 Policy๋ฅผ .notAllowed๋กœ ์„ค์ •ํ•˜์—ฌ ์บ์‹œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋‚˜ ๋””์Šคํฌ ์–ด๋А ์ชฝ์—๋„ Cache๊ฐ€ ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์Šค๋ƒ…์ƒท

ํ™ˆ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค iOS๋Š” ์ „ํ™˜์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ํ˜„์žฌ ํ™”๋ฉด์˜ ์Šค๋ƒ…์ƒท์„ ์ฐ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ˜„์žฌ ํ™”๋ฉด์— ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” ์ด๋ฏธ์ง€์— ์ €์žฅ๋˜์–ด (์žฌ๋ถ€ํŒ…์„ ๊ฑธ์ณ ์ง€์†๋ฉ๋‹ˆ๋‹ค). ์ด๋Ÿฌํ•œ ์Šค๋ƒ…์ƒท์€ ํ™ˆ ๋ฒ„ํŠผ์„ ๋‘ ๋ฒˆ ํƒญํ•˜์—ฌ ์•ฑ ๊ฐ„ ์ „ํ™˜ํ•  ๋•Œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ƒ…์ƒท์ž…๋‹ˆ๋‹ค.

iPhone์ด ํƒˆ์˜ฅ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ด๋Ÿฌํ•œ ์Šคํฌ๋ฆฐ์ƒท์„ ๋ณด๋ ค๋ฉด attacker๊ฐ€ access๋ฅผ device์— ๋Œ€ํ•ด unblocked ์ƒํƒœ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งˆ์ง€๋ง‰ ์Šค๋ƒ…์ƒท์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒŒ๋“œ๋ฐ•์Šค์˜ Library/Caches/Snapshots/ ๋˜๋Š” Library/SplashBoard/Snapshots ํด๋”์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค (trusted computers๋Š” iOX 7.0๋ถ€ํ„ฐ ํŒŒ์ผ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค).

์ด๋Ÿฌํ•œ ๋™์ž‘์„ ๋ฐฉ์ง€ํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ApplicationDidEnterBackground() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šค๋ƒ…์ƒท์„ ์ฐ๊ธฐ ์ „์— ๋นˆ ํ™”๋ฉด์„ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๊ธฐ๋ณธ ์Šคํฌ๋ฆฐ์ƒท์„ ์„ค์ •ํ•˜๋Š” ์ƒ˜ํ”Œ ์ˆ˜์ • ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

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๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. overlayImage.png๊ฐ€ ํ•ญ์ƒ ํ˜„์žฌ ๋ทฐ๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ์˜ leaks๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

Keychain

iOS keychain์— ์ ‘๊ทผํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด, jailbroken ์žฅ์น˜์— ์ ํ•ฉํ•œ Keychain-Dumper์™€ ๊ฐ™์€ ๋„๊ตฌ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Objection๋Š” ์œ ์‚ฌํ•œ ๋ชฉ์ ์„ ์œ„ํ•ด ios keychain dump ๋ช…๋ น์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ž๊ฒฉ ์ฆ๋ช… ์ €์žฅ

NSURLCredential ํด๋ž˜์Šค๋Š” NSUserDefaults๋‚˜ ๊ธฐํƒ€ ๋ž˜ํผ๋ฅผ ์šฐํšŒํ•˜์—ฌ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ง์ ‘ keychain์— ์ €์žฅํ•˜๊ธฐ์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ ํ›„ ์ž๊ฒฉ ์ฆ๋ช…์„ ์ €์žฅํ•˜๋ ค๋ฉด, ๋‹ค์Œ Swift ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

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

To extract these stored credentials, Objectionโ€™s command ios nsurlcredentialstorage dump is utilized.

Custom Keyboards and Keyboard Cache

iOS 8.0 ์ดํ›„๋ถ€ํ„ฐ ์‚ฌ์šฉ์ž๋Š” custom keyboard extensions๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์„ค์ • > ์ผ๋ฐ˜ > ํ‚ค๋ณด๋“œ > ํ‚ค๋ณด๋“œ์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ‚ค๋ณด๋“œ๋Š” ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜์ง€๋งŒ ํ‚ค ์ž…๋ ฅ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜๊ฑฐ๋‚˜ ์™ธ๋ถ€ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ์œ„ํ—˜์ด ์žˆ์œผ๋ฉฐ, ๋„คํŠธ์›Œํฌ ์ ‘๊ทผ์ด ํ•„์š”ํ•œ ํ‚ค๋ณด๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆผ์ด ์ œ๊ณต๋œ๋‹ค. ์•ฑ์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด ์ž…๋ ฅ ์‹œ custom keyboards์˜ ์‚ฌ์šฉ์„ ์ œํ•œํ•ด์•ผ ํ•œ๋‹ค.

Security Recommendations:

  • ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋“œํŒŒํ‹ฐ ํ‚ค๋ณด๋“œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.
  • ๊ธฐ๋ณธ iOS ํ‚ค๋ณด๋“œ์˜ autocorrect ๋ฐ auto-suggestions ๊ธฐ๋Šฅ์ด Library/Keyboard/{locale}-dynamic-text.dat ๋˜๋Š” /private/var/mobile/Library/Keyboard/dynamic-text.dat์— ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ์„ ์ธ์ง€ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์บ์‹œ ํŒŒ์ผ์€ ์ •๊ธฐ์ ์œผ๋กœ ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์šฐ๊ธฐ ์œ„ํ•ด ์„ค์ • > ์ผ๋ฐ˜ > ์žฌ์„ค์ • > ํ‚ค๋ณด๋“œ ์‚ฌ์ „ ์žฌ์„ค์ •์„ ํ†ตํ•ด ํ‚ค๋ณด๋“œ ์‚ฌ์ „์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.
  • ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ๊ฐ€๋กœ์ฑ„๋ฉด custom keyboard๊ฐ€ ์›๊ฒฉ์œผ๋กœ ํ‚ค ์ž…๋ ฅ์„ ์ „์†กํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Preventing Text Field Caching

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;

๋˜ํ•œ ๊ฐœ๋ฐœ์ž๋Š” ํ…์ŠคํŠธ ํ•„๋“œ(ํŠนํžˆ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ฐ PIN๊ณผ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋Š” ํ•„๋“œ)๊ฐ€ autocorrectionType์„ UITextAutocorrectionTypeNo๋กœ, secureTextEntry๋ฅผ YES๋กœ ์„ค์ •ํ•˜์—ฌ ์บ์‹ฑ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

Logs

๋””๋ฒ„๊น…์€ ์ข…์ข… logging์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์œ„ํ—˜์ด ์žˆ๋Š”๋ฐ, logs์— ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณผ๊ฑฐ(iOS 6 ๋ฐ ์ด์ „ ๋ฒ„์ „)์—๋Š” ๋ชจ๋“  ์•ฑ์ด logs์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ leak ์œ„ํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ž์‹ ์˜ logs์—๋งŒ ์ ‘๊ทผํ•˜๋„๋ก ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ œ์•ฝ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์ž ๊ธˆ ํ•ด์ œ๋œ ์žฅ์น˜์— ๋Œ€ํ•œ ๋ฌผ๋ฆฌ์  ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ๋Š” ๊ณต๊ฒฉ์ž๋Š” ์žฅ์น˜๋ฅผ ์ปดํ“จํ„ฐ์— ์—ฐ๊ฒฐํ•˜๊ณ  logs๋ฅผ ์ฝ๋Š” ๊ฒƒ์œผ๋กœ ์ด๋ฅผ ์•…์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์„ ์‚ญ์ œํ•œ ํ›„์—๋„ logs๋Š” ๋””์Šคํฌ์— ๋‚จ์•„ ์žˆ๋‹ค๋Š” ์ ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์œ„ํ—˜์„ ์™„ํ™”ํ•˜๋ ค๋ฉด, ์•ฑ๊ณผ ์ฒ ์ €ํžˆ ์ƒํ˜ธ์ž‘์šฉํ•˜๋ฉด์„œ ๋ชจ๋“  ๊ธฐ๋Šฅ๊ณผ ์ž…๋ ฅ์„ ํ™•์ธํ•˜์—ฌ ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ logged๋˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์•ฑ์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ž ์žฌ์  leak์— ๋Œ€ํ•ด ๊ฒ€ํ† ํ•  ๋•Œ๋Š”, ์‚ฌ์ „ ์ •์˜๋œ ๋ฐ custom logging statements๋ฅผ ๋ชจ๋‘ ์ฐพ์•„๋ณด์„ธ์š”. ๋‚ด์žฅ ํ•จ์ˆ˜์šฉ ํ‚ค์›Œ๋“œ์ธ NSLog, NSAssert, NSCAssert, fprintf์™€, ์ปค์Šคํ…€ ๊ตฌํ˜„์˜ ๊ฒฝ์šฐ Logging ๋˜๋Š” Logfile ์–ธ๊ธ‰์„ ํ™•์ธํ•˜์„ธ์š”.

Monitoring System Logs

์•ฑ์€ ๋ฏผ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ logํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ logs๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

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๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—…

์ž๋™ ๋ฐฑ์—… ๊ธฐ๋Šฅ์€ iOS์— ํ†ตํ•ฉ๋˜์–ด ์žˆ์–ด iTunes(์ตœ๋Œ€ macOS Catalina), Finder(macOS Catalina ์ดํ›„) ๋˜๋Š” iCloud๋ฅผ ํ†ตํ•ด ๊ธฐ๊ธฐ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฑ์—…์€ Apple Pay ์ •๋ณด๋‚˜ Touch ID ์„ค์ •๊ณผ ๊ฐ™์€ ๊ณ ๋„๋กœ ๋ฏผ๊ฐํ•œ ํ•ญ๋ชฉ์„ ์ œ์™ธํ•œ ๊ฑฐ์˜ ๋ชจ๋“  ๊ธฐ๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

๋ณด์•ˆ ์œ„ํ—˜

๋ฐฑ์—…์— ์„ค์น˜๋œ ์•ฑ๊ณผ ๊ทธ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋˜๋ฉด ์ž ์žฌ์ ์ธ data leakage ๋ฌธ์ œ์™€ ๋ฐฑ์—… ์ˆ˜์ •์œผ๋กœ ์ธํ•ด ์•ฑ ๊ธฐ๋Šฅ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์œ„ํ—˜์„ ์™„ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์•ฑ์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋‚˜ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ **ํ‰๋ฌธ(plaintext)**์œผ๋กœ ์ €์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

๋ฐฑ์—…์—์„œ ํŒŒ์ผ ์ œ์™ธ

Documents/ ๋ฐ Library/Application Support/์˜ ํŒŒ์ผ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐฑ์—…๋ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” NSURL setResourceValue:forKey:error:์™€ NSURLIsExcludedFromBackupKey๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ํŒŒ์ผ์ด๋‚˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋ฐฑ์—…์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐฑ์—…์— ํฌํ•จ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์ทจ์•ฝ์  ํ…Œ์ŠคํŠธ

์•ฑ์˜ ๋ฐฑ์—… ๋ณด์•ˆ์„ ํ‰๊ฐ€ํ•˜๋ ค๋ฉด Finder๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐฑ์—…์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ Appleโ€™s official documentation์˜ ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ผ ํ•ด๋‹น ๋ฐฑ์—…์„ ์ฐพ์œผ์„ธ์š”. ๋ฐฑ์—…์„ ๋ถ„์„ํ•˜์—ฌ ์•ฑ ๋™์ž‘์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋‚˜ ์„ค์ •์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ๋ช…๋ น์ค„ ๋„๊ตฌ๋‚˜ iMazing ๊ฐ™์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉํ•ด ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•”ํ˜ธํ™”๋œ ๋ฐฑ์—…์˜ ๊ฒฝ์šฐ, ๋ฐฑ์—… ๋ฃจํŠธ์˜ โ€œManifest.plistโ€ ํŒŒ์ผ์—์„œ โ€œIsEncryptedโ€ ํ‚ค๋ฅผ ํ™•์ธํ•ด ์•”ํ˜ธํ™” ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<?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 ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ์กฐ์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. iOSbackup tool์€ ์•”ํ˜ธ๋กœ ๋ณดํ˜ธ๋œ ๋ฐฑ์—… ๋‚ด ํŒŒ์ผ์— ์ ‘๊ทผํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์ž…๋‹ˆ๋‹ค.

์•ฑ ๋™์ž‘ ๋ณ€๊ฒฝ

๋ฐฑ์—… ์ˆ˜์ •์„ ํ†ตํ•ด ์•ฑ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๋Š” ์˜ˆ๋กœ๋Š” Bither bitcoin wallet app์ด ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ๋Š” UI lock PIN์ด net.bither.plist์˜ pin_code ํ‚ค์— ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. plist์—์„œ ์ด ํ‚ค๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐฑ์—…์„ ๋ณต์›ํ•˜๋ฉด PIN ์š”๊ตฌ๊ฐ€ ์‚ฌ๋ผ์ ธ ์ œํ•œ ์—†๋Š” ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ…Œ์ŠคํŠธ ์š”์•ฝ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ๋‹ค๋ฃฐ ๋•Œ๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ์˜ ๋…ธ์ถœ ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์šฉ์„ ์กฐ์‚ฌํ•˜๋Š” ์ฃผ์š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€๋กœ, ๋ฉ”๋ชจ๋ฆฌ ๋คํ”„ ์ƒ์„ฑ๊ณผ ์‹ค์‹œ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ๋ถ„์„์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ๋คํ”„ ๊ณผ์ •์ด๋‚˜ ๋ถ„์„ ์ค‘์— ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋†“์น  ์ˆ˜ ์žˆ๋Š” ๋“ฑ์˜ ์–ด๋ ค์›€์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋คํ”„ ํš๋“ ๋ฐ ๋ถ„์„

ํƒˆ์˜ฅ ๋ฐ ๋น„ํƒˆ์˜ฅ ๊ธฐ๊ธฐ ๋ชจ๋‘์—์„œ objection๊ณผ Fridump ๊ฐ™์€ ๋„๊ตฌ๋Š” ์•ฑ์˜ ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋คํ”„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋คํ”„ํ•œ ํ›„์—๋Š” ์ฐพ๊ณ ์ž ํ•˜๋Š” ์ •๋ณด์˜ ์„ฑ๊ฒฉ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋คํ”„์—์„œ ๋ฌธ์ž์—ด์„ ์ถ”์ถœํ•˜๋ ค๋ฉด 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]> /?
...

๋Ÿฐํƒ€์ž„ ๋ฉ”๋ชจ๋ฆฌ ๋ถ„์„

r2frida๋Š” memory dump ์—†์ด๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋Œ€์•ˆ์ž…๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋Š” ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ง์ ‘ ๊ฒ€์ƒ‰ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค:

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

์ทจ์•ฝํ•œ ์•”ํ˜ธํ™”

๋ถ€์ ์ ˆํ•œ ํ‚ค ๊ด€๋ฆฌ ํ”„๋กœ์„ธ์Šค

์ผ๋ถ€ ๊ฐœ๋ฐœ์ž๋Š” ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜๊ณ  ์ฝ”๋“œ ๋‚ด์— hardcoded/predictable๋œ ํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฆฌ๋ฒ„์‹ฑ์œผ๋กœ ์ธํ•ด ๊ณต๊ฒฉ์ž๊ฐ€ ๊ธฐ๋ฐ€ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์•ˆ์ „ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜/๋˜๋Š” ๋” ์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ

๊ฐœ๋ฐœ์ž๋Š” ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์œ„ํ•œ deprecated algorithms์„ ์‚ฌ์šฉํ•˜์—ฌ checks, ๋ฐ์ดํ„ฐ๋ฅผ storeํ•˜๊ฑฐ๋‚˜ sendํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์˜ˆ๋กœ๋Š” RC4, MD4, MD5, SHA1 ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด hashes๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, salt์™€ ํ•จ๊ป˜ brute-force์— resistantํ•œ ํ•ด์‹œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ ๊ฒ€

์ฃผ์š” ์ ๊ฒ€ ํ•ญ๋ชฉ์€ ์ฝ”๋“œ ๋‚ด์— hardcoded๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ/์‹œํฌ๋ฆฟ์ด ์žˆ๋Š”์ง€, ๋˜๋Š” ๊ทธ๊ฒƒ๋“ค์ด predictableํ•œ์ง€, ๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์ข…๋ฅ˜์˜ weak cryptography ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํŠนํžˆ objection์„ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ถ€ crypto libraries๋ฅผ ์ž๋™์œผ๋กœ monitorํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค:

ios monitor crypt

iOS ์•”ํ˜ธํ™” API ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋กœ์ปฌ ์ธ์ฆ

๋กœ์ปฌ ์ธ์ฆ์€ ํŠนํžˆ ์•”ํ˜ธํ™”๋œ ๋ฐฉ๋ฒ•์œผ๋กœ ์›๊ฒฉ ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ๋ณดํ˜ธํ•  ๋•Œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์ง€ ์•Š์œผ๋ฉด ๋กœ์ปฌ ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์šฐํšŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Apple์˜ Local Authentication framework ๋ฐ keychain์€ ๊ฐ๊ฐ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ธ์ฆ ๋Œ€ํ™”์ƒ์ž๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋น„๋ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ•๋ ฅํ•œ API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Secure Enclave๋Š” Touch ID์˜ ์ง€๋ฌธ 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 ๋˜๋Š” ๊ธฐ๊ธฐ ์•”ํ˜ธ๋ฅผ ์š”๊ตฌํ•˜๋ฉฐ, ๋‘˜ ๋‹ค ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
  • deviceOwnerAuthenticationWithBiometrics: Touch ID๋งŒ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

์„ฑ๊ณต์ ์ธ ์ธ์ฆ์€ **evaluatePolicy**๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” boolean ๊ฐ’์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ, ์ด๋Š” ์ž ์žฌ์ ์ธ ๋ณด์•ˆ ๊ฒฐํ•จ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Keychain์„ ์‚ฌ์šฉํ•œ ๋กœ์ปฌ ์ธ์ฆ

iOS ์•ฑ์—์„œ ๋กœ์ปฌ ์ธ์ฆ์„ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ์ธ์ฆ ํ† ํฐ๊ณผ ๊ฐ™์€ ๋น„๋ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด keychain API๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ๋ฐ์ดํ„ฐ์— ๊ธฐ๊ธฐ ์•”ํ˜ธ๋‚˜ Touch ID ๊ฐ™์€ ์ƒ์ฒด ์ธ์ฆ์œผ๋กœ๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

keychain์€ SecAccessControl ์†์„ฑ์œผ๋กœ ํ•ญ๋ชฉ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ Touch ID ๋˜๋Š” ๊ธฐ๊ธฐ ์•”ํ˜ธ๋กœ ์„ฑ๊ณต์ ์œผ๋กœ ์ธ์ฆํ•  ๋•Œ๊นŒ์ง€ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” Swift ๋ฐ Objective-C๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ ์˜ˆ์ œ๋กœ, ์ด๋Ÿฌํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ๋ฌธ์ž์—ด์„ keychain์— ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์˜ˆ์ œ๋Š” ํŠนํžˆ Touch ID ์ธ์ฆ์„ ์š”๊ตฌํ•˜๋„๋ก ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์„ค์ •ํ•˜๊ณ , ๊ธฐ๊ธฐ ์•”ํ˜ธ๊ฐ€ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ์—๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •๋œ ๊ธฐ๊ธฐ์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ณด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

// 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๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ธ์ฆ ๋Œ€ํ™”์ƒ์ž๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์ ์ ˆํ•œ fingerprint๊ฐ€ ์ œ๊ณต๋˜์—ˆ๋Š”์ง€์— ๋”ฐ๋ผ data ๋˜๋Š” nil์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

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

ํƒ์ง€

์•ฑ์—์„œ ํ”„๋ ˆ์ž„์›Œํฌ ์‚ฌ์šฉ์€ ์•ฑ ๋ฐ”์ด๋„ˆ๋ฆฌ์˜ ๊ณต์œ  ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชฉ๋ก์„ ๋ถ„์„ํ•ด ํƒ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” 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 ์šฐํšŒ

Objection

์ด Objection Biometrics Bypass๋Š” this GitHub page์— ์œ„์น˜ํ•ด ์žˆ์œผ๋ฉฐ, LocalAuthentication ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ๋ฒ•์˜ ํ•ต์‹ฌ์€ Frida๋ฅผ ํ™œ์šฉํ•ด evaluatePolicy ํ•จ์ˆ˜๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ, ์‹ค์ œ ์ธ์ฆ ์„ฑ๊ณต ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ํ•ญ์ƒ True ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๊ฒฐํ•จ์ด ์žˆ๋Š” ์ƒ์ฒด ์ธ์ฆ ์ ˆ์ฐจ๋ฅผ ํšŒํ”ผํ•  ๋•Œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ์šฐํšŒ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

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

๋‹ค์Œ์€ DVIA-v2 application์—์„œ์˜ evaluatePolicy ์‚ฌ์šฉ ์˜ˆ์ž…๋‹ˆ๋‹ค:

+(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์„ ๊ฐ€๋กœ์ฑ„ success=1์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค. callback์˜ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•จ์œผ๋กœ์จ ์ธ์ฆ ๊ฒ€์‚ฌ๋Š” ์‚ฌ์‹ค์ƒ bypass๋œ๋‹ค.

์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋Š” evaluatePolicy ๋ฉ”์„œ๋“œ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ์ž…๋œ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” callback์˜ ๊ฒฐ๊ณผ๋ฅผ ํ•ญ์ƒ ์„ฑ๊ณต์„ ๋‚˜ํƒ€๋‚ด๋„๋ก ๋ณ€๊ฒฝํ•œ๋‹ค.

// 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 ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฃผ์ž…ํ•˜๊ณ  ์ƒ์ฒด ์ธ์ฆ์„ bypassํ•˜๋ ค๋ฉด, ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

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

๋„คํŠธ์›Œํฌ ํ†ต์‹ 

์•”ํ˜ธํ™” ์—†์ด ํ†ต์‹ ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์„œ๋ฒ„์˜ TLS certificate๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฒ€์ฆํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด Burp์™€ ๊ฐ™์€ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

iOS Burp Suite Configuration

ํ˜ธ์ŠคํŠธ๋ช… ๊ฒ€์‚ฌ

TLS certificate๋ฅผ ๊ฒ€์ฆํ•  ๋•Œ ํ”ํ•œ ๋ฌธ์ œ๋Š” ์ธ์ฆ์„œ๊ฐ€ trusted CA์— ์˜ํ•ด ์„œ๋ช…๋˜์—ˆ๋Š”์ง€๋งŒ ํ™•์ธํ•˜๊ณ , ์ธ์ฆ์„œ์˜ the hostname๊ฐ€ ์‹ค์ œ๋กœ ์ ‘์†ํ•˜๋ ค๋Š” ํ˜ธ์ŠคํŠธ๋ช…์ธ์ง€ ํ™•์ธํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ๋ฅผ Burp๋กœ ํ™•์ธํ•˜๋ ค๋ฉด, iPhone์—์„œ Burp CA๋ฅผ ์‹ ๋ขฐํ•œ ๋’ค Burp๋กœ ๋‹ค๋ฅธ hostname์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜๋ฉด ์ทจ์•ฝํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Certificate Pinning

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด SSL Pinning์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ธฐ๋Œ€ํ•œ ์ธ์ฆ์„œ์ผ ๋•Œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์‹œ Burp๊ฐ€ ์ž์ฒด ์ธ์ฆ์„œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
jailbroken ๊ธฐ๊ธฐ ๋‚ด์—์„œ ์ด ๋ณดํ˜ธ๋ฅผ ์šฐํšŒํ•˜๋ ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ SSL Kill Switch๋ฅผ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ Burp Mobile Assistant๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ objectionโ€™s ios sslpinning disable๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐํƒ€

  • /System/Library ์—๋Š” ์‹œ์Šคํ…œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • App Store์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์„ค์น˜ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ /User/Applications ๋‚ด๋ถ€์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค.
  • /User/Library ๋Š” ์‚ฌ์šฉ์ž ๋ ˆ๋ฒจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ €์žฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์— ์ €์žฅ๋œ ๋…ธํŠธ๋ฅผ ์ฝ์œผ๋ ค๋ฉด /User/Library/Notes/notes.sqlite ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ค์น˜๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํด๋”(/User/Applications/<APP ID>/) ๋‚ด๋ถ€์—๋Š” ํฅ๋ฏธ๋กœ์šด ํŒŒ์ผ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค:
    • iTunesArtwork: ์•ฑ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์•„์ด์ฝ˜
    • iTunesMetadata.plist: App Store์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์•ฑ ์ •๋ณด
    • /Library/*: ํ™˜๊ฒฝ์„ค์ •๊ณผ ์บ์‹œ๋ฅผ ํฌํ•จ. /Library/Cache/Snapshots/* ์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์ „ํ™˜๋˜๊ธฐ ์ „์— ์ˆ˜ํ–‰๋œ ์Šค๋ƒ…์ƒท์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Hot Patching/๊ฐ•์ œ ์—…๋ฐ์ดํŠธ

๊ฐœ๋ฐœ์ž๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ App Store์— ๋‹ค์‹œ ์ œ์ถœํ•˜๊ณ  ์Šน์ธ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ ๋„ ์›๊ฒฉ์œผ๋กœ ๋ชจ๋“  ์„ค์น˜๋ณธ์„ ์ฆ‰์‹œ ํŒจ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ์ผ๋ฐ˜์ ์œผ๋กœ JSPatch๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Siren์ด๋‚˜ react-native-appstore-version-checker์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์˜ต์…˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋Š” ์ œ3์ž ์•…์„ฑ SDK์— ์˜ํ•ด ์•…์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด๋ฏ€๋กœ ์ž๋™ ์—…๋ฐ์ดํŠธ์— ์–ด๋–ค ๋ฐฉ๋ฒ•์ด ์‚ฌ์šฉ๋˜๋Š”์ง€(์žˆ๋‹ค๋ฉด) ํ™•์ธํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์ด์ „ ๋ฒ„์ „์˜ ์•ฑ์„ ๋‹ค์šด๋กœ๋“œํ•ด ์‹œ๋„ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Third Parties

3rd party SDKs์˜ ์ค‘์š”ํ•œ ๋ฌธ์ œ์ ์€ ๊ทธ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•œ ์„ธ๋ถ„ํ™”๋œ ์ œ์–ด ๋ถ€์กฑ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” SDK๋ฅผ ํ†ตํ•ฉํ•˜๋ฉด ์ž ์žฌ์  ๋ณด์•ˆ ์ทจ์•ฝ์ ๊ณผ ๊ฐœ์ธ์ •๋ณด ๋ฌธ์ œ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ˆ˜์šฉํ•˜๊ฑฐ๋‚˜, ์•„์˜ˆ ์ด์ ์„ ํฌ๊ธฐํ•ด์•ผ ํ•˜๋Š” ์„ ํƒ์— ์ง๋ฉดํ•ฉ๋‹ˆ๋‹ค. ์ข…์ข… ๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฌํ•œ SDK ๋‚ด์˜ ์ทจ์•ฝ์ ์„ ์ง์ ‘ ํŒจ์น˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ SDK๊ฐ€ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋‚ด์—์„œ ์‹ ๋ขฐ๋ฅผ ์–ป์œผ๋ฉด ์ผ๋ถ€๋Š” ๋ฉ€์›จ์–ด๋ฅผ ํฌํ•จํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์„œ๋“œํŒŒํ‹ฐ SDK๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค๋Š” ์‚ฌ์šฉ์ž ํ–‰๋™ ์ถ”์ , ๊ด‘๊ณ  ํ‘œ์‹œ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ ๋“ฑ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์™„์ „ํžˆ ์•Œ์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ์ธ์ •๋ณด ๋ฐ ๋ณด์•ˆ ์œ„ํ—˜์„ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋“œํŒŒํ‹ฐ ์„œ๋น„์Šค์— ๊ณต์œ ํ•˜๋Š” ์ •๋ณด๋Š” ํ•„์š”ํ•œ ๊ฒƒ๋งŒ์œผ๋กœ ์ œํ•œํ•˜๊ณ  ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์„œ๋“œํŒŒํ‹ฐ ์„œ๋น„์Šค์˜ ๊ตฌํ˜„์€ ๋ณดํ†ต ๋…๋ฆฝ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜•ํƒœ์ด๊ฑฐ๋‚˜ ์ „์ฒด SDK ํ˜•ํƒœ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๊ฐœ์ธ์ •๋ณด๋ฅผ ๋ณดํ˜ธํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ์„œ๋น„์Šค์™€ ๊ณต์œ ๋˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋Š” ๊ฐœ์ธ ์‹๋ณ„ ์ •๋ณด(PII)๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ์ต๋ช…ํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹๋ณ„ํ•˜๋ ค๋ฉด otool ๋ช…๋ น์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ•ด๋‹น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฐ ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์‹คํ–‰๋˜์–ด ์ถ”๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

otool -L <application_path>

ํฅ๋ฏธ๋กœ์šด ์ทจ์•ฝ์  ๋ฐ ์‚ฌ๋ก€ ์—ฐ๊ตฌ

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 ์ง€์›ํ•˜๊ธฐ