คลัง
mobile

iOS IPA Analysis

iOS IPA Analysis ครอบคลุมการวิเคราะห์แอป iOS: โครงสร้าง IPA, static analysis (class-dump/Hopper/strings), การหา secret/endpoint, dynamic analysis ด้วย Frida/objection (bypass SSL pinning + jailbreak detection), keychain dumping, และ binary decryption บทนี้มีคำสั่งครบ + lab + troubleshooting (เนื้อหาเพื่อฝึกใน lab/CTF/ระบบที่ได้รับอนุญาตเท่านั้น)

IntermediateAdvanced#ios#ipa#mobile#frida#objection#jailbreak#ssl-pinning#ctf

1. โครงสร้าง IPA

IPA เป็นไฟล์ ZIP ที่มี Payload/App.app/ ข้างในมี: Mach-O binary (executable หลัก), Info.plist (metadata, URL scheme, permission), embedded.mobileprovision (provisioning), _CodeSignature/, assets ต่างจาก Android: binary เป็น Mach-O (ไม่ใช่ dex) และมักถูก encrypt (FairPlay DRM)

ดูข้างใน IPA
unzip app.ipa -d app_ipa
ls app_ipa/Payload/*.app/

# ดู Info.plist (URL scheme, permission)
plutil -p app_ipa/Payload/*.app/Info.plist

# ดู binary architecture
file app_ipa/Payload/*.app/AppName
otool -hv app_ipa/Payload/*.app/AppName
เนื้อหานี้เพื่อฝึกในสภาพแวดล้อมที่ได้รับอนุญาต (CTF, lab, mobile pentest) เท่านั้น

2. Binary Decryption (FairPlay)

แอปจาก App Store ถูก encrypt ต้อง decrypt ก่อน static analysis ทำบนเครื่อง jailbroken (dump จาก memory ตอนรัน)

decrypt
# เช็คว่า encrypt ไหม (cryptid 1 = encrypted)
otool -l App | grep -A4 LC_ENCRYPTION_INFO

# decrypt บน jailbroken device
frida-ios-dump -u <udid> <app-name>     # dump + decrypt อัตโนมัติ
# หรือ
objection -g <app> explore
# ios bundle list_bundle_id แล้วใช้ tool ขณะรัน

3. Static Analysis

class-dump + strings + Hopper
# dump Objective-C class/method headers
class-dump app_ipa/Payload/*.app/AppName > classes.h
grep -iE 'flag|secret|password|key|login|admin' classes.h

# strings
strings app_ipa/Payload/*.app/AppName | grep -iE 'flag|http|api|secret'

# Info.plist: URL scheme (deep link attack), ATS exception
plutil -p Info.plist | grep -iE 'URLScheme|NSAppTransport|NSAllowsArbitrary'

# decompile ใน Hopper/Ghidra (Mach-O ARM64)
ที่ซ่อนทำไมต้องดู
Info.plist URL schemedeep link → เรียก action ภายในแอป
strings ใน binaryAPI endpoint, hardcoded key
class-dump headersmethod ที่เกี่ยว auth/crypto/license
Keychaincredential/token เก็บใน keychain
NSUserDefaults / plistconfig/secret เก็บแบบไม่เข้ารหัส

4. Dynamic Analysis — Frida/objection

objection (iOS)
objection -g <app> explore

# ใน objection:
ios sslpinning disable                 # bypass SSL pinning
ios jailbreak disable                  # bypass jailbreak detection
ios keychain dump                      # ดึง keychain (credential!)
ios nsuserdefaults get                 # ดู config/secret
ios hooking list classes
ios hooking watch method "-[LoginVC checkPassword:]" --dump-args
  • bypass SSL pinning → proxy (Burp) → ทดสอบ API เหมือน web
  • keychain dump → credential/token ที่เก็บไว้
  • hook method auth/license → return true
  • bypass jailbreak detection (ถ้าแอปเช็ค)

5. Lab Walkthrough

  1. 1unzip IPA → class-dump ดู method, strings หา endpoint/secret
  2. 2ดู Info.plist: URL scheme → ลองเรียก deep link app://action
  3. 3ถ้า encrypted: decrypt ด้วย frida-ios-dump บน jailbroken device
  4. 4dynamic: objection -g app exploreios sslpinning disable → proxy → ดู API
  5. 5ios keychain dump → เจอ token/credential
  6. 6flag มักอยู่: strings, keychain, API response, หรือ logic ที่ reverse

6. Troubleshooting

อาการสาเหตุ / แก้
strings น้อย/อ่านไม่ออกbinary encrypted (FairPlay) — decrypt ก่อน
objection connect failต้อง jailbroken + frida-server; เช็ค device
class-dump ว่างSwift app (ไม่ใช่ ObjC) — ใช้ Hopper/Ghidra แทน
SSL pinning ปิดแล้วยังไม่เห็น trafficcustom pinning — Frida hook เฉพาะ
ไม่มี jailbroken deviceใช้ simulator (แต่ decrypt ไม่ได้) หรือ sideload + frida gadget

7. Indicators & Quick Reference

สัญญาณ: Payload/*.app = IPA, cryptid 1 = encrypted (ต้อง decrypt), URL scheme ใน Info.plist = deep link attack, keychain = credential
  • iOS = Mach-O binary (ไม่ใช่ dex), มัก encrypt (ต่างจาก Android)
  • decrypt ก่อน static (frida-ios-dump บน jailbroken)
  • objection รองรับทั้ง iOS/Android (ios sslpinning/keychain/jailbreak)
  • endpoint ที่เจอ → ทดสอบเหมือน web API
  • flag มักอยู่: strings, keychain, NSUserDefaults, API response

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติเจอโจทย์ได้ไฟล์ .ipa มา (หรือมี jailbroken device อยู่ตรงหน้า) มีแค่ Kali เปล่าๆ — บาง step ต้องพึ่ง jailbroken device เสริม เพราะ toolchain iOS บางตัวรันบน Kali ตรงๆ ไม่ได้ ทำตามนี้ทีละขั้น ถ้าติดให้ดู decision tree ด้านล่าง

  1. 1แตก IPA ก่อน: พิมพ์ unzip app.ipa -d app_ipa แล้วเข้าไปดู app_ipa/Payload/*.app/ ควรเห็น Mach-O binary + Info.plist
  2. 2ดู metadata: พิมพ์ plutil -p app_ipa/Payload/*.app/Info.plist (ถ้า Kali ไม่มี plutil ให้ลง libplist-utils แล้วใช้ plistutil -i Info.plist แทน) ดู URL scheme, permission, ATS setting
  3. 3เช็คว่า binary encrypt ไหม: พิมพ์ otool -l AppName | grep -A4 LC_ENCRYPTION_INFO ถ้า cryptid 1 แปลว่า encrypted ต้อง decrypt ก่อนอ่าน logic จริง
  4. 4ถ้ามี jailbroken device: dump+decrypt อัตโนมัติด้วย frida-ios-dump -u <udid> <app-name> ได้ binary ที่ decrypt แล้วมาแทน
  5. 5ถ้าไม่มี jailbroken device จริง: ใช้ MobSF (docker) อัปโหลด IPA ให้สแกน static ให้ หรือใช้บริการ Corellium (จำลอง iOS jailbroken จากคลาวด์)
  6. 6static analysis: พิมพ์ class-dump AppName > classes.h (ปกติต้องรันบน macOS — ถ้า Kali ไม่มี toolchain ให้ใช้ MobSF/Hopper ทดแทน) แล้ว grep -iE 'flag|secret|key|password' classes.h
  7. 7หา string ตรงๆ ในไฟล์ (ทำบน Kali ได้เลย): พิมพ์ strings AppName | grep -iE 'flag|http|api|secret'
  8. 8ถ้ามี jailbroken device: ต่อ frida แล้วเช็ค process ก่อน: frida-ps -U ควรเห็น process ของแอปที่รันอยู่
  9. 9hook ด้วย objection: พิมพ์ objection -g com.app.bundleid explore แล้วลอง ios sslpinning disable, ios jailbreak disable
  10. 10ดึง credential ที่เก็บไว้: ใน objection prompt พิมพ์ ios keychain dump ดูว่ามี token/password หลุดมาไหม
  11. 11ถ้าทุกทางตันเพราะไม่มี jailbroken device เลย: ย้อนกลับไปทำ static ให้ละเอียดที่สุด (strings/class-dump/plist) แล้วพึ่ง MobSF หรือ Corellium แทน dynamic
Decision Tree: จาก IPA ไปจนถึง flag/exploit
ได้ .ipa มา — unzip แล้วเช็ค encryption ก่อน
unzip app.ipa -d app_ipa; otool -l AppName | grep LC_ENCRYPTION_INFO
cryptid 0 (ไม่ encrypt)static
cryptid 1 (encrypted, FairPlay)needdecrypt
ต้อง decrypt ก่อนอ่าน logic จริง
decrypt ทำได้เฉพาะบนเครื่อง jailbroken (dump จาก memory ตอนรัน)
มี jailbroken device หรือใช้ Corelliumdecryptok
ไม่มี jailbroken device เลยnodevice
decrypt สำเร็จด้วย frida-ios-dump
frida-ios-dump -u <udid> <app> ได้ binary ที่ decrypt แล้ว
ไปต่อ static analysis กับ binary ที่ decrypt แล้วstatic
static analysis: class-dump/strings/plutil
class-dump AppName > classes.h; strings AppName | grep flag
เจอ flag/secret แบบ plaintextflagfound
เจอ hardcoded cloud key (AWS/Firebase) ใน strings/plistcloudkey
เจอ URL scheme/deep link ที่น่าสงสัยใน Info.plisturlscheme
เจอ logic check (jailbreak detection/license/premium) แต่ไม่เจอ flaglogiccheck
ไม่เจอทั้งหมด (Swift app, class-dump ว่างเปล่า)swiftcase
เจอ flag/secret แบบ plaintext แล้ว — จบ
เจอ URL scheme / deep link ใน Info.plist
ลองเรียก deep link เช่น app://action ดูว่าข้าม auth หรือ trigger logic ได้ไหม
เจอ client-side check (jailbreak detection/license/premium)
logic ป้องกันฝั่ง client เท่านั้น
ต้อง bypass runtimedynamic
class-dump ว่างเปล่า (แอปเป็น Swift ไม่ใช่ Objective-C)
class-dump อ่านเฉพาะ Objective-C metadata — ต้องใช้ Hopper/Ghidra/IDA แกะ Swift binary แทน
มีเครื่องมือ decompiler อื่นเปิดใน Hopper/Ghidra วิเคราะห์ Mach-O ต่อ
ใช้ Frida/objection hook runtime (ต้อง jailbroken device)
objection -g app explore -> ios sslpinning disable / ios jailbreak disable / ios keychain dump
hook ติด bypass ผ่าน + keychain dump ได้ credentialdynamicok
ปิด pinning แล้วเจอ backend APIapipivot
ไม่มี jailbroken device ให้ต่อnodevice
bypass สำเร็จ ได้ credential/flag/ผ่านเงื่อนไข — จบ
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
unzip + ดู plist/binary เบื้องต้นunzip, otool, stringsปกติมีใน Kali (binutils) อยู่แล้ว-
อ่าน Info.plist แบบสวยๆplutil (macOS)บน Kali ใช้ libplist-utils (plistutil) แทน-
decrypt binary ที่ encrypt (FairPlay)frida-ios-dumpต้องมี jailbroken device + frida-server บนเครื่องนั้นCorellium (จำลอง jailbroken cloud ถ้าไม่มีเครื่องจริง)
class-dump Objective-C headersclass-dumpต้องรันบน macOS จริง (ไม่มี native port ที่สมบูรณ์บน Linux)MobSF (อัปโหลด IPA ให้ scan header ให้)
dynamic hook / bypass pinningfrida-tools, objectionpip install frida-tools objection แล้วต้องมี jailbroken device คู่กัน-
decompile Mach-O เต็มรูปแบบ (โดยเฉพาะ Swift)Ghidraติดตั้ง Ghidra (โหลดจาก GitHub release, รันได้บน Kali)-
scan อัตโนมัติแบบไม่ง้อ jailbreak-MobSF (docker run มาตรฐานเดียวกับฝั่ง Android)MobSF cloud demo (ถ้าเปิดให้ใช้)
เช็ค hash/reputation เบื้องต้น--VirusTotal
🚑 ถ้าตันสนิท ลองท่าถัดไป: ไม่มี jailbroken device เลยและแอปมี Android version คู่กัน → ลองรื้อฝั่ง android-apk-analysis แทน เพราะไม่ต้อง jailbreak | เจอ hardcoded AWS/cloud key → ไปทดสอบสิทธิ์จริงที่ aws-iam-privesc หรือ aws-s3-attacks | bypass pinning แล้วเจอ backend API ที่ใช้ JWT/session → ไปเจาะลึกที่ jwt-attacks | ต้อง hook ลึกกว่าที่ objection ให้ได้ (native function, anti-hook) → อ่านเทคนิคเต็มที่ frida

หัวข้อที่เชื่อมโยง

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้