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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
iOS ๊ธฐ๋ณธ
ํ ์คํธ ํ๊ฒฝ
์ด ํ์ด์ง์์๋ iOS simulator, emulators ๋ฐ jailbreaking์ ๋ํ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค:
์ด๊ธฐ ๋ถ์
๊ธฐ๋ณธ iOS ํ ์คํธ ์์
ํ ์คํธ ์ค์ ์ฌ๋ฌ ์์ ์ด ์ ์๋ ๊ฒ์ ๋๋ค (connect to the device, read/write/upload/download files, use some toolsโฆ). ๋ฐ๋ผ์ ์ด๋ฌํ ์์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฅธ๋ค๋ฉด ํด๋น ํ์ด์ง๋ฅผ ๋จผ์ ์ฝ๊ธฐ ์์ํ์ธ์:
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ํ๋ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ์ธ์:
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:
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:
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์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
์ด ๋ฐ์ดํฐ๋ ์์ฒญ์ด๋ ์๋ต์ ๋ฏผ๊ฐํ ์ ๋ณด๊ฐ ํฌํจ๋ ์ ์์ผ๋ฏ๋ก ์ด ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ์ง ์๋๋ก ๊ถ์ฅํฉ๋๋ค. ์๋ ๋ชฉ๋ก์ ์ด๋ฅผ ๋ฌ์ฑํ๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
- ๋ก๊ทธ์์ ํ ์บ์๋ ์๋ต์ ์ ๊ฑฐํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค. ์ด๋ Apple์์ ์ ๊ณตํ๋
removeAllCachedResponses๋ฉ์๋๋ก ์ํํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ ์ ์์ต๋๋ค:
URLCache.shared.removeAllCachedResponses()
์ด ๋ฉ์๋๋ Cache.db ํ์ผ์์ ๋ชจ๋ ์บ์๋ ์์ฒญ๊ณผ ์๋ต์ ์ ๊ฑฐํฉ๋๋ค.
- ์ฟ ํค์ ์ด์ ์ ์ฌ์ฉํ ํ์๊ฐ ์๋ค๋ฉด URLSession์ .ephemeral ๊ตฌ์ฑ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค. ์ด๋ ์ฟ ํค์ ์บ์ ์ ์ฅ์ ๋นํ์ฑํํฉ๋๋ค.
An ephemeral session configuration object is similar to a default session configuration (see default), except that the corresponding session object doesnโt store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file.
- 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๋ ์ฝ์ ๋ก๊ทธ๋ฅผ ์์งํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค:
- Xcode๋ฅผ ์ฝ๋๋ค.
- iOS ์ฅ์น๋ฅผ ์ฐ๊ฒฐํฉ๋๋ค.
- Window -> Devices and Simulators๋ก ์ด๋ํฉ๋๋ค.
- ์ฅ์น๋ฅผ ์ ํํฉ๋๋ค.
- ์กฐ์ฌ ์ค์ธ ๋ฌธ์ ๋ฅผ ์ฌํํฉ๋๋ค.
- 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๋ฅผ ํตํ ๋ฏผ๊ฐํ ๊ธฐ๋ฅ ๋ ธ์ถ
Custom URI Handlers / Deeplinks / Custom Schemes
iOS Custom URI Handlers / Deeplinks / Custom Schemes
Universal Links
UIActivity Sharing
UIPasteboard
App Extensions
WebViews
Serialisation and Encoding
iOS Serialisation and Encoding
๋คํธ์ํฌ ํต์
์ํธํ ์์ด ํต์ ์ด ๋ฐ์ํ์ง ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ด ์๋ฒ์ TLS certificate๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฒ์ฆํ๊ณ ์๋์ง ํ์ธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํ์ธํ๊ธฐ ์ํด Burp์ ๊ฐ์ ํ๋ก์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
ํธ์คํธ๋ช ๊ฒ์ฌ
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
์ฐธ๊ณ ๋ฐ ์ถ๊ฐ ์๋ฃ
- https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering
- iOS & Mobile App Pentesting - INE
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/
- https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage
- https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060
- https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064
- https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054
- https://github.com/ivRodriguezCA/RE-iOS-Apps/ iOS ๋ฌด๋ฃ ์ฝ์ค(https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)
- https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577
- https://www.slideshare.net/RyanISI/ios-appsecurityminicourse
- https://github.com/prateek147/DVIA
- https://github.com/prateek147/DVIA-v2
- https://github.com/OWASP/MSTG-Hacking-Playground%20
- OWASP iGoat https://github.com/OWASP/igoat <<< Objective-C ๋ฒ์ https://github.com/OWASP/iGoat-Swift <<< Swift ๋ฒ์
- https://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/nabla-c0d3/ssl-kill-switch2
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


