macOS Library Injection
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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Caution
dyld์ ์ฝ๋๊ฐ ์คํ ์์ค์ด๋ฉฐ https://opensource.apple.com/source/dyld/์์ ์ฐพ์ ์ ์์ผ๋ฉฐ URL์ ์ฌ์ฉํ์ฌ tar๋ก ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค: https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz
Dyld ํ๋ก์ธ์ค
Dyld๊ฐ ๋ฐ์ด๋๋ฆฌ ๋ด์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์ธ์:
DYLD_INSERT_LIBRARIES
์ด๊ฒ์ Linux์ LD_PRELOAD์ ๊ฐ์ต๋๋ค. ์ด๋ ์คํ๋ ํ๋ก์ธ์ค๊ฐ ํน์ ๊ฒฝ๋ก์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋๋ก ์ง์ํ ์ ์๊ฒ ํด์ค๋๋ค(ํ๊ฒฝ ๋ณ์๊ฐ ํ์ฑํ๋ ๊ฒฝ์ฐ).
์ด ๊ธฐ์ ์ ๋ชจ๋ ์ค์น๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด โInfo.plistโ๋ผ๋ plist๋ฅผ ๊ฐ์ง๊ณ ์์ด ํ๊ฒฝ ๋ณ์๋ฅผ ํ ๋นํ ์ ์๋๋ก ํ๋ ASEP ๊ธฐ์ ๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
Tip
2012๋ ์ดํ Apple์
DYLD_INSERT_LIBRARIES์ ๊ถํ์ ๋ํญ ์ค์์ต๋๋ค.์ฝ๋๋ฅผ ํ์ธํ๊ณ **
src/dyld.cpp**๋ฅผ ํ์ธํ์ธ์.pruneEnvironmentVariablesํจ์์์DYLD_*๋ณ์๊ฐ ์ ๊ฑฐ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
processRestrictedํจ์์์ ์ ํ์ ์ด์ ๊ฐ ์ค์ ๋ฉ๋๋ค. ํด๋น ์ฝ๋๋ฅผ ํ์ธํ๋ฉด ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ฐ์ด๋๋ฆฌ๊ฐ
setuid/setgid์ ๋๋ค.- macho ๋ฐ์ด๋๋ฆฌ์
__RESTRICT/__restrict์น์ ์ด ์กด์ฌํฉ๋๋ค.- ์ํํธ์จ์ด์
com.apple.security.cs.allow-dyld-environment-variables๊ถํ์ด ์๋ ๊ถํ(๊ฐํ๋ ๋ฐํ์)์ด ์์ต๋๋ค.- ๋ฐ์ด๋๋ฆฌ์ ๊ถํ์ ํ์ธํ๋ ค๋ฉด:
codesign -dv --entitlements :- </path/to/bin>๋ ์ต์ ๋ฒ์ ์์๋ ์ด ๋ ผ๋ฆฌ๋ฅผ
configureProcessRestrictionsํจ์์ ๋ ๋ฒ์งธ ๋ถ๋ถ์์ ์ฐพ์ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ต์ ๋ฒ์ ์์ ์คํ๋๋ ๊ฒ์ ํจ์์ ์์ ๊ฒ์ฌ์ ๋๋ค(์ด๊ฒ์ macOS์์ ์ฌ์ฉ๋์ง ์์ iOS ๋๋ ์๋ฎฌ๋ ์ด์ ๊ณผ ๊ด๋ จ๋ if๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค).
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฒ์ฆ
๋ฐ์ด๋๋ฆฌ๊ฐ DYLD_INSERT_LIBRARIES ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ๋๋ก ํ์ฉํ๋๋ผ๋, ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ก๋ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ช
์ ํ์ธํ๋ฉด ์ฌ์ฉ์ ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ์ง ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ค๋ฉด ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ค์ ๊ถํ ์ค ํ๋๋ฅผ ๊ฐ์ ธ์ผ ํฉ๋๋ค:
com.apple.security.cs.disable-library-validationcom.apple.private.security.clear-library-validation
๋๋ ๋ฐ์ด๋๋ฆฌ๊ฐ ๊ฐํ๋ ๋ฐํ์ ํ๋๊ทธ ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฒ์ฆ ํ๋๊ทธ๋ฅผ ๊ฐ์ง์ง ์์์ผ ํฉ๋๋ค.
๋ฐ์ด๋๋ฆฌ์ ๊ฐํ๋ ๋ฐํ์์ด ์๋์ง ํ์ธํ๋ ค๋ฉด codesign --display --verbose <bin>์ ์ฌ์ฉํ์ฌ **CodeDirectory**์์ ํ๋๊ทธ ๋ฐํ์์ ํ์ธํ์ธ์: CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded
๋ฐ์ด๋๋ฆฌ์ ๊ฐ์ ์ธ์ฆ์๋ก ์๋ช ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ ์๋ ์์ต๋๋ค.
์ด๊ฒ์ (์ ์ฉ)ํ๋ ๋ฐฉ๋ฒ๊ณผ ์ ํ ์ฌํญ์ ํ์ธํ๋ ค๋ฉด:
macOS Dyld Hijacking & DYLD_INSERT_LIBRARIES
Dylib ํ์ด์ฌํน
Caution
Dylib ํ์ด์ฌํน ๊ณต๊ฒฉ์ ์ํํ๊ธฐ ์ํด์๋ ์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฒ์ฆ ์ ํ์ด ์ ์ฉ๋๋ค๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์.
Windows์ ๋ง์ฐฌ๊ฐ์ง๋ก MacOS์์๋ dylibs๋ฅผ ํ์ด์ฌํนํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์ด ์์์ ์ฝ๋๋ฅผ ์คํํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค(์ฌ์ค ์ผ๋ฐ ์ฌ์ฉ์์๊ฒ๋ TCC ๊ถํ์ด ํ์ํ ์ ์์ผ๋ฏ๋ก .app ๋ฒ๋ค ๋ด์์ ์ฐ๊ธฐ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ด์ฌํน์ด ๋ถ๊ฐ๋ฅํ ์ ์์ต๋๋ค).
๊ทธ๋ฌ๋ MacOS ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐฉ์์ Windows๋ณด๋ค ๋ ์ ํ์ ์
๋๋ค. ์ด๋ ์
์ฑ ์ํํธ์จ์ด ๊ฐ๋ฐ์๊ฐ ์ฌ์ ํ ์ด ๊ธฐ์ ์ ์ํ๋ฅผ ์ํด ์ฌ์ฉํ ์ ์์ง๋ง, ๊ถํ ์์น์ ์
์ฉํ ๊ฐ๋ฅ์ฑ์ ํจ์ฌ ๋ฎ์ต๋๋ค.
์ฐ์ , MacOS ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ก๋ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฒด ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ ๊ฒ์ด ๋ ์ผ๋ฐ์ ์ ๋๋ค. ๋์งธ, MacOS๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํด $PATH์ ํด๋๋ฅผ ๊ฒ์ํ์ง ์์ต๋๋ค.
์ด ๊ธฐ๋ฅ๊ณผ ๊ด๋ จ๋ ์ฃผ์ ์ฝ๋๋ **ImageLoader::recursiveLoadLibraries**์ ์์ต๋๋ค ImageLoader.cpp.
macho ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ 4๊ฐ์ง ๋ค๋ฅธ ํค๋ ๋ช ๋ น์ด ์์ต๋๋ค:
LC_LOAD_DYLIB๋ช ๋ น์ dylib๋ฅผ ๋ก๋ํ๋ ์ผ๋ฐ์ ์ธ ๋ช ๋ น์ ๋๋ค.LC_LOAD_WEAK_DYLIB๋ช ๋ น์ ์ด์ ๋ช ๋ น๊ณผ ์ ์ฌํ์ง๋ง, dylib๊ฐ ๋ฐ๊ฒฌ๋์ง ์์ผ๋ฉด ์ค๋ฅ ์์ด ์คํ์ด ๊ณ์๋ฉ๋๋ค.LC_REEXPORT_DYLIB๋ช ๋ น์ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ธฐํธ๋ฅผ ํ๋ก์(๋๋ ์ฌ์์ถ)ํฉ๋๋ค.LC_LOAD_UPWARD_DYLIB๋ช ๋ น์ ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ก ์์กดํ ๋ ์ฌ์ฉ๋ฉ๋๋ค(์ด๋ฅผ _์ํฅ ์์กด์ฑ_์ด๋ผ๊ณ ํฉ๋๋ค).
๊ทธ๋ฌ๋ dylib ํ์ด์ฌํน์๋ 2๊ฐ์ง ์ ํ์ด ์์ต๋๋ค:
- ๋๋ฝ๋ ์ฝํ ์ฐ๊ฒฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด LC_LOAD_WEAK_DYLIB๋ก ๊ตฌ์ฑ๋ ์กด์ฌํ์ง ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ค๊ณ ์๋ํจ์ ์๋ฏธํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ณต๊ฒฉ์๊ฐ ์์๋๋ ์์น์ dylib๋ฅผ ๋ฐฐ์นํ๋ฉด ๋ก๋๋ฉ๋๋ค.
- ๋งํฌ๊ฐ โ์ฝํโ์ด๋ผ๋ ๊ฒ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฐ๊ฒฌ๋์ง ์๋๋ผ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ณ์ ์คํ๋๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
- ์ด์ ๊ด๋ จ๋ ์ฝ๋๋
ImageLoaderMachO::doGetDependentLibrariesํจ์์ ์์ผ๋ฉฐ, ์ฌ๊ธฐ์lib->required๋ **LC_LOAD_WEAK_DYLIB**๊ฐ true์ผ ๋๋งfalse์ ๋๋ค. - ๋ฐ์ด๋๋ฆฌ์์ ์ฝํ ์ฐ๊ฒฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฐพ๊ธฐ (ํ์ด์ฌํน ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ํ ์๊ฐ ๋์ค์ ์์ต๋๋ค):
-
otool -l </path/to/bin> | grep LC_LOAD_WEAK_DYLIB -A 5 cmd LC_LOAD_WEAK_DYLIB cmdsize 56 name /var/tmp/lib/libUtl.1.dylib (offset 24) time stamp 2 Wed Jun 21 12:23:31 1969 current version 1.0.0 compatibility version 1.0.0
- **@rpath๋ก ๊ตฌ์ฑ๋จ**: Mach-O ๋ฐ์ด๋๋ฆฌ๋ **`LC_RPATH`** ๋ฐ **`LC_LOAD_DYLIB`** ๋ช
๋ น์ ๊ฐ์ง ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ช
๋ น์ **๊ฐ**์ ๋ฐ๋ผ **๋ผ์ด๋ธ๋ฌ๋ฆฌ**๋ **๋ค๋ฅธ ๋๋ ํ ๋ฆฌ**์์ **๋ก๋**๋ฉ๋๋ค.
- **`LC_RPATH`**๋ ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ผ๋ถ ํด๋์ ๊ฒฝ๋ก๋ฅผ ํฌํจํฉ๋๋ค.
- **`LC_LOAD_DYLIB`**๋ ๋ก๋ํ ํน์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฒฝ๋ก๋ฅผ ํฌํจํฉ๋๋ค. ์ด๋ฌํ ๊ฒฝ๋ก๋ **`@rpath`**๋ฅผ ํฌํจํ ์ ์์ผ๋ฉฐ, ์ด๋ **`LC_RPATH`**์ ๊ฐ์ผ๋ก **๋์ฒด๋ฉ๋๋ค**. **`LC_RPATH`**์ ์ฌ๋ฌ ๊ฒฝ๋ก๊ฐ ์๋ ๊ฒฝ์ฐ ๋ชจ๋ ๊ฒฝ๋ก๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์:
- **`LC_LOAD_DYLIB`**์ `@rpath/library.dylib`๊ฐ ํฌํจ๋๊ณ **`LC_RPATH`**์ `/application/app.app/Contents/Framework/v1/` ๋ฐ `/application/app.app/Contents/Framework/v2/`๊ฐ ํฌํจ๋ ๊ฒฝ์ฐ, ๋ ํด๋๊ฐ `library.dylib`๋ฅผ ๋ก๋ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. **`[...] /v1/`์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด ๊ณต๊ฒฉ์๊ฐ ๊ทธ๊ณณ์ ๋ฐฐ์นํ์ฌ `[...]/v2/`์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋๋ฅผ ํ์ด์ฌํนํ ์ ์์ต๋๋ค.**
- **๋ฐ์ด๋๋ฆฌ์์ rpath ๊ฒฝ๋ก ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฐพ๊ธฐ**: `otool -l </path/to/binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`
> [!NOTE] > **`@executable_path`**: **์ฃผ ์คํ ํ์ผ**์ด ํฌํจ๋ **๋๋ ํ ๋ฆฌ**์ **๊ฒฝ๋ก**์
๋๋ค.
>
> **`@loader_path`**: **๋ก๋ ๋ช
๋ น**์ด ํฌํจ๋ **Mach-O ๋ฐ์ด๋๋ฆฌ**๊ฐ ์๋ **๋๋ ํ ๋ฆฌ**์ **๊ฒฝ๋ก**์
๋๋ค.
>
> - ์คํ ํ์ผ์์ ์ฌ์ฉ๋ ๋, **`@loader_path`**๋ ์ฌ์ค์ **`@executable_path`**์ ๋์ผํฉ๋๋ค.
> - **dylib**์์ ์ฌ์ฉ๋ ๋, **`@loader_path`**๋ **dylib**์ **๊ฒฝ๋ก**๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ ์
์ฉํ์ฌ **๊ถํ์ ์์น์ํค๋ ๋ฐฉ๋ฒ**์ **๋ฃจํธ**์ ์ํด ์คํ๋๋ **์ ํ๋ฆฌ์ผ์ด์
**์ด ๊ณต๊ฒฉ์๊ฐ ์ฐ๊ธฐ ๊ถํ์ ๊ฐ์ง ํด๋์์ **๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐพ๋** ๋๋ฌธ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.
> [!TIP]
> ์ ํ๋ฆฌ์ผ์ด์
์์ **๋๋ฝ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ**๋ฅผ ์ฐพ๊ธฐ ์ํ ์ข์ **์ค์บ๋**๋ [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) ๋๋ [**CLI ๋ฒ์ **](https://github.com/pandazheng/DylibHijack)์
๋๋ค.\
> ์ด ๊ธฐ์ ์ ๋ํ **๊ธฐ์ ์ธ๋ถ์ ๋ณด๊ฐ ํฌํจ๋ ์ข์ ๋ณด๊ณ ์**๋ [**์ฌ๊ธฐ**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x)์์ ์ฐพ์ ์ ์์ต๋๋ค.
**์์**
<a class="content_ref" href="macos-dyld-hijacking-and-dyld_insert_libraries.md"><span class="content_ref_label">macOS Dyld Hijacking & DYLD_INSERT_LIBRARIES</span></a>
## Dlopen ํ์ด์ฌํน
> [!CAUTION]
> Dlopen ํ์ด์ฌํน ๊ณต๊ฒฉ์ ์ํํ๊ธฐ ์ํด์๋ **์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฒ์ฆ ์ ํ์ด ์ ์ฉ๋๋ค๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์**.
**`man dlopen`**์์:
- ๊ฒฝ๋ก์ **์ฌ๋์ ๋ฌธ์๊ฐ ํฌํจ๋์ง ์์ผ๋ฉด**(์ฆ, ๋จ์ํ ๋ฆฌํ ์ด๋ฆ์ธ ๊ฒฝ์ฐ) **dlopen()์ด ๊ฒ์์ ์ํํฉ๋๋ค**. **`$DYLD_LIBRARY_PATH`**๊ฐ ์์ ์ ์ค์ ๋์๋ค๋ฉด, dyld๋ ๋จผ์ **ํด๋น ๋๋ ํ ๋ฆฌ**๋ฅผ **์ฐพ์ต๋๋ค**. ๋ค์์ผ๋ก, ํธ์ถ๋ macho ํ์ผ์ด๋ ์ฃผ ์คํ ํ์ผ์ด **`LC_RPATH`**๋ฅผ ์ง์ ํ๋ฉด dyld๋ **ํด๋น ๋๋ ํ ๋ฆฌ**๋ฅผ **์ฐพ์ต๋๋ค**. ๋ค์์ผ๋ก, ํ๋ก์ธ์ค๊ฐ **์ ํ๋์ง ์์ ๊ฒฝ์ฐ**, dyld๋ **ํ์ฌ ์์
๋๋ ํ ๋ฆฌ**๋ฅผ ๊ฒ์ํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก, ์ค๋๋ ๋ฐ์ด๋๋ฆฌ์ ๊ฒฝ์ฐ dyld๋ ๋ช ๊ฐ์ง ๋์ฒด ๋ฐฉ๋ฒ์ ์๋ํฉ๋๋ค. **`$DYLD_FALLBACK_LIBRARY_PATH`**๊ฐ ์์ ์ ์ค์ ๋์๋ค๋ฉด dyld๋ **ํด๋น ๋๋ ํ ๋ฆฌ**๋ฅผ ๊ฒ์ํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด dyld๋ **`/usr/local/lib/`**(ํ๋ก์ธ์ค๊ฐ ์ ํ๋์ง ์์ ๊ฒฝ์ฐ)์์ ๊ฒ์ํ ํ **`/usr/lib/`**์์ ๊ฒ์ํฉ๋๋ค(์ด ์ ๋ณด๋ **`man dlopen`**์์ ๊ฐ์ ธ์จ ๊ฒ์
๋๋ค).
1. `$DYLD_LIBRARY_PATH`
2. `LC_RPATH`
3. `CWD`(์ ํ๋์ง ์์ ๊ฒฝ์ฐ)
4. `$DYLD_FALLBACK_LIBRARY_PATH`
5. `/usr/local/lib/` (์ ํ๋์ง ์์ ๊ฒฝ์ฐ)
6. `/usr/lib/`
> [!CAUTION]
> ์ด๋ฆ์ ์ฌ๋์๊ฐ ์์ผ๋ฉด ํ์ด์ฌํน์ ์ํํ ์ ์๋ ๋ฐฉ๋ฒ์ 2๊ฐ์ง์
๋๋ค:
>
> - **`LC_RPATH`**๊ฐ **์ฐ๊ธฐ ๊ฐ๋ฅ**ํ ๊ฒฝ์ฐ(ํ์ง๋ง ์๋ช
์ด ํ์ธ๋๋ฏ๋ก, ์ด๋ฅผ ์ํด์๋ ๋ฐ์ด๋๋ฆฌ๊ฐ ์ ํ๋์ง ์์์ผ ํฉ๋๋ค)
> - ๋ฐ์ด๋๋ฆฌ๊ฐ **์ ํ๋์ง ์์ ๊ฒฝ์ฐ**, CWD์์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ก๋ํ๊ฑฐ๋ ์ธ๊ธ๋ ํ๊ฒฝ ๋ณ์๋ฅผ ์
์ฉํ ์ ์์ต๋๋ค.
- ๊ฒฝ๋ก๊ฐ **ํ๋ ์์ํฌ** ๊ฒฝ๋ก์ฒ๋ผ ๋ณด์ผ ๊ฒฝ์ฐ(์: `/stuff/foo.framework/foo`), **`$DYLD_FRAMEWORK_PATH`**๊ฐ ์์ ์ ์ค์ ๋์๋ค๋ฉด dyld๋ ๋จผ์ ํด๋น ๋๋ ํ ๋ฆฌ์์ **ํ๋ ์์ํฌ ๋ถ๋ถ ๊ฒฝ๋ก**(์: `foo.framework/foo`)๋ฅผ ์ฐพ์ต๋๋ค. ๋ค์์ผ๋ก, dyld๋ **์ ๊ณต๋ ๊ฒฝ๋ก๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉ**ํฉ๋๋ค(์๋ ๊ฒฝ๋ก์ ๊ฒฝ์ฐ ํ์ฌ ์์
๋๋ ํ ๋ฆฌ๋ฅผ ์ฌ์ฉ). ๋ง์ง๋ง์ผ๋ก, ์ค๋๋ ๋ฐ์ด๋๋ฆฌ์ ๊ฒฝ์ฐ dyld๋ ๋ช ๊ฐ์ง ๋์ฒด ๋ฐฉ๋ฒ์ ์๋ํฉ๋๋ค. **`$DYLD_FALLBACK_FRAMEWORK_PATH`**๊ฐ ์์ ์ ์ค์ ๋์๋ค๋ฉด dyld๋ ํด๋น ๋๋ ํ ๋ฆฌ๋ฅผ ๊ฒ์ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด **`/Library/Frameworks`**(macOS์์ ํ๋ก์ธ์ค๊ฐ ์ ํ๋์ง ์์ ๊ฒฝ์ฐ)์์ ๊ฒ์ํ ํ **`/System/Library/Frameworks`**์์ ๊ฒ์ํฉ๋๋ค.
1. `$DYLD_FRAMEWORK_PATH`
2. ์ ๊ณต๋ ๊ฒฝ๋ก(์ ํ๋์ง ์์ ๊ฒฝ์ฐ ์๋ ๊ฒฝ๋ก์ ๋ํด ํ์ฌ ์์
๋๋ ํ ๋ฆฌ ์ฌ์ฉ)
3. `$DYLD_FALLBACK_FRAMEWORK_PATH`
4. `/Library/Frameworks` (์ ํ๋์ง ์์ ๊ฒฝ์ฐ)
5. `/System/Library/Frameworks`
> [!CAUTION]
> ํ๋ ์์ํฌ ๊ฒฝ๋ก์ธ ๊ฒฝ์ฐ, ํ์ด์ฌํนํ๋ ๋ฐฉ๋ฒ์:
>
> - ํ๋ก์ธ์ค๊ฐ **์ ํ๋์ง ์์ ๊ฒฝ์ฐ**, CWD์ ์๋ ๊ฒฝ๋ก๋ฅผ ์
์ฉํ์ฌ ์ธ๊ธ๋ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํฉ๋๋ค(๋ฌธ์์ ๋ช
์๋์ด ์์ง ์๋๋ผ๋ ํ๋ก์ธ์ค๊ฐ ์ ํ๋ ๊ฒฝ์ฐ DYLD_* ํ๊ฒฝ ๋ณ์๊ฐ ์ ๊ฑฐ๋ฉ๋๋ค).
- ๊ฒฝ๋ก์ **์ฌ๋์๊ฐ ํฌํจ๋์ด ์์ง๋ง ํ๋ ์์ํฌ ๊ฒฝ๋ก๊ฐ ์๋ ๊ฒฝ์ฐ**(์ฆ, dylib์ ๋ํ ์ ์ฒด ๊ฒฝ๋ก ๋๋ ๋ถ๋ถ ๊ฒฝ๋ก), dlopen()์ ๋จผ์ (์ค์ ๋ ๊ฒฝ์ฐ) **`$DYLD_LIBRARY_PATH`**์์ (๊ฒฝ๋ก์ ๋ฆฌํ ๋ถ๋ถ) ๊ฒ์ํฉ๋๋ค. ๋ค์์ผ๋ก, dyld๋ **์ ๊ณต๋ ๊ฒฝ๋ก๋ฅผ ์๋ํฉ๋๋ค**(์ ํ๋์ง ์์ ํ๋ก์ธ์ค์ ๊ฒฝ์ฐ ์๋ ๊ฒฝ๋ก์ ๋ํด ํ์ฌ ์์
๋๋ ํ ๋ฆฌ๋ฅผ ์ฌ์ฉ). ๋ง์ง๋ง์ผ๋ก, ์ค๋๋ ๋ฐ์ด๋๋ฆฌ์ ๊ฒฝ์ฐ dyld๋ ๋์ฒด ๋ฐฉ๋ฒ์ ์๋ํฉ๋๋ค. **`$DYLD_FALLBACK_LIBRARY_PATH`**๊ฐ ์์ ์ ์ค์ ๋์๋ค๋ฉด dyld๋ ํด๋น ๋๋ ํ ๋ฆฌ์์ ๊ฒ์ํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด dyld๋ **`/usr/local/lib/`**(ํ๋ก์ธ์ค๊ฐ ์ ํ๋์ง ์์ ๊ฒฝ์ฐ)์์ ๊ฒ์ํ ํ **`/usr/lib/`**์์ ๊ฒ์ํฉ๋๋ค.
1. `$DYLD_LIBRARY_PATH`
2. ์ ๊ณต๋ ๊ฒฝ๋ก(์ ํ๋์ง ์์ ๊ฒฝ์ฐ ์๋ ๊ฒฝ๋ก์ ๋ํด ํ์ฌ ์์
๋๋ ํ ๋ฆฌ ์ฌ์ฉ)
3. `$DYLD_FALLBACK_LIBRARY_PATH`
4. `/usr/local/lib/` (์ ํ๋์ง ์์ ๊ฒฝ์ฐ)
5. `/usr/lib/`
> [!CAUTION]
> ์ด๋ฆ์ ์ฌ๋์๊ฐ ํฌํจ๋๊ณ ํ๋ ์์ํฌ๊ฐ ์๋ ๊ฒฝ์ฐ, ํ์ด์ฌํนํ๋ ๋ฐฉ๋ฒ์:
>
> - ๋ฐ์ด๋๋ฆฌ๊ฐ **์ ํ๋์ง ์์ ๊ฒฝ์ฐ**, CWD ๋๋ `/usr/local/lib`์์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ก๋ํ๊ฑฐ๋ ์ธ๊ธ๋ ํ๊ฒฝ ๋ณ์๋ฅผ ์
์ฉํ ์ ์์ต๋๋ค.
> [!TIP]
> ์ฐธ๊ณ : **dlopen ๊ฒ์์ ์ ์ดํ๋** ๊ตฌ์ฑ ํ์ผ์ด **์์ต๋๋ค**.
>
> ์ฐธ๊ณ : ์ฃผ ์คํ ํ์ผ์ด **set\[ug]id ๋ฐ์ด๋๋ฆฌ์ด๊ฑฐ๋ ๊ถํ์ผ๋ก ์๋ช
๋ ๊ฒฝ์ฐ**, **๋ชจ๋ ํ๊ฒฝ ๋ณ์๋ ๋ฌด์๋๋ฉฐ**, ์ ์ฒด ๊ฒฝ๋ก๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค ([์์ธํ ์ ๋ณด๋ DYLD_INSERT_LIBRARIES ์ ํ ์ฌํญ ํ์ธ](macos-dyld-hijacking-and-dyld_insert_libraries.md#check-dyld_insert_librery-restrictions)).
>
> ์ฐธ๊ณ : Apple ํ๋ซํผ์ 32๋นํธ ๋ฐ 64๋นํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฒฐํฉํ๊ธฐ ์ํด "์ ๋๋ฒ์ค" ํ์ผ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ **๋ณ๋์ 32๋นํธ ๋ฐ 64๋นํธ ๊ฒ์ ๊ฒฝ๋ก๊ฐ ์์์ ์๋ฏธํฉ๋๋ค**.
>
> ์ฐธ๊ณ : Apple ํ๋ซํผ์์ ๋๋ถ๋ถ์ OS dylibs๋ **dyld ์บ์์ ๊ฒฐํฉ๋์ด** ์์ผ๋ฉฐ ๋์คํฌ์ ์กด์ฌํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ OS dylib๊ฐ ์กด์ฌํ๋์ง ์ฌ์ ํ์ธํ๊ธฐ ์ํด **`stat()`**๋ฅผ ํธ์ถํ๋ ๊ฒ์ **์๋ํ์ง ์์ต๋๋ค**. ๊ทธ๋ฌ๋ **`dlopen_preflight()`**๋ **`dlopen()`**๊ณผ ๋์ผํ ๋จ๊ณ๋ฅผ ์ฌ์ฉํ์ฌ ํธํ ๊ฐ๋ฅํ mach-o ํ์ผ์ ์ฐพ์ต๋๋ค.
**๊ฒฝ๋ก ํ์ธ**
๋ค์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ต์
์ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค:
```c
// gcc dlopentest.c -o dlopentest -Wl,-rpath,/tmp/test
#include <dlfcn.h>
#include <stdio.h>
int main(void)
{
void* handle;
fprintf("--- No slash ---\n");
handle = dlopen("just_name_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}
fprintf("--- Relative framework ---\n");
handle = dlopen("a/framework/rel_framework_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}
fprintf("--- Abs framework ---\n");
handle = dlopen("/a/abs/framework/abs_framework_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}
fprintf("--- Relative Path ---\n");
handle = dlopen("a/folder/rel_folder_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}
fprintf("--- Abs Path ---\n");
handle = dlopen("/a/abs/folder/abs_folder_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}
return 0;
}
์ปดํ์ผํ๊ณ ์คํํ๋ฉด ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด๋์์ ์ฑ๊ณต์ ์ผ๋ก ๊ฒ์๋์ง ์์๋์ง ๋ณผ ์ ์์ต๋๋ค. ๋ํ, FS ๋ก๊ทธ๋ฅผ ํํฐ๋งํ ์ ์์ต๋๋ค:
sudo fs_usage | grep "dlopentest"
์๋ ๊ฒฝ๋ก ํ์ด์ฌํน
ํน๊ถ ์ด์ง ํ์ผ/์ฑ(์: SUID ๋๋ ๊ฐ๋ ฅํ ๊ถํ์ ๊ฐ์ง ์ด์ง ํ์ผ)์ด ์๋ ๊ฒฝ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: @executable_path ๋๋ @loader_path ์ฌ์ฉ)๋ฅผ ๋ก๋ํ๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฒ์ฆ์ด ๋นํ์ฑํ๋ ๊ฒฝ์ฐ, ๊ณต๊ฒฉ์๊ฐ ์๋ ๊ฒฝ๋ก๋ก ๋ก๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ ํ ์ ์๋ ์์น๋ก ์ด์ง ํ์ผ์ ์ด๋์์ผ ํ๋ก์ธ์ค์ ์ฝ๋๋ฅผ ์ฃผ์
ํ๋ ๋ฐ ์
์ฉํ ์ ์์ต๋๋ค.
DYLD_* ๋ฐ LD_LIBRARY_PATH ํ๊ฒฝ ๋ณ์ ์ ๋ฆฌ
ํ์ผ dyld-dyld-832.7.1/src/dyld2.cpp์์ pruneEnvironmentVariables ํจ์๊ฐ ์์ผ๋ฉฐ, ์ด ํจ์๋ DYLD_ ๋ฐ **LD_LIBRARY_PATH=**๋ก ์์ํ๋ ๋ชจ๋ ํ๊ฒฝ ๋ณ์๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
๋ํ suid ๋ฐ sgid ์ด์ง ํ์ผ์ ๋ํด DYLD_FALLBACK_FRAMEWORK_PATH ๋ฐ DYLD_FALLBACK_LIBRARY_PATH ํ๊ฒฝ ๋ณ์๋ฅผ null๋ก ์ค์ ํฉ๋๋ค.
์ด ํจ์๋ OSX๋ฅผ ๋์์ผ๋ก ํ ๋ ๊ฐ์ ํ์ผ์ _main ํจ์์์ ํธ์ถ๋ฉ๋๋ค:
#if TARGET_OS_OSX
if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) {
pruneEnvironmentVariables(envp, &apple);
๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ๋ถ๋ฆฌ์ธ ํ๋๊ทธ๋ ์ฝ๋์ ๋์ผํ ํ์ผ์ ์ค์ ๋ฉ๋๋ค:
#if TARGET_OS_OSX
// support chrooting from old kernel
bool isRestricted = false;
bool libraryValidation = false;
// any processes with setuid or setgid bit set or with __RESTRICT segment is restricted
if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) {
isRestricted = true;
}
bool usingSIP = (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0);
uint32_t flags;
if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) {
// On OS X CS_RESTRICT means the program was signed with entitlements
if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP ) {
isRestricted = true;
}
// Library Validation loosens searching but requires everything to be code signed
if ( flags & CS_REQUIRE_LV ) {
isRestricted = false;
libraryValidation = true;
}
}
gLinkContext.allowAtPaths = !isRestricted;
gLinkContext.allowEnvVarsPrint = !isRestricted;
gLinkContext.allowEnvVarsPath = !isRestricted;
gLinkContext.allowEnvVarsSharedCache = !libraryValidation || !usingSIP;
gLinkContext.allowClassicFallbackPaths = !isRestricted;
gLinkContext.allowInsertFailures = false;
gLinkContext.allowInterposing = true;
์ฆ, ์ด์ง ํ์ผ์ด suid ๋๋ sgid์ด๊ฑฐ๋ ํค๋์ RESTRICT ์ธ๊ทธ๋จผํธ๊ฐ ์๊ฑฐ๋ CS_RESTRICT ํ๋๊ทธ๋ก ์๋ช
๋ ๊ฒฝ์ฐ, **!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache**๊ฐ true๊ฐ ๋๊ณ ํ๊ฒฝ ๋ณ์๋ ์ ๊ฑฐ๋ฉ๋๋ค.
CS_REQUIRE_LV๊ฐ true์ธ ๊ฒฝ์ฐ, ๋ณ์๋ ์ ๊ฑฐ๋์ง ์์ง๋ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฒ์ฆ์ ์๋ ์ด์ง ํ์ผ๊ณผ ๋์ผํ ์ธ์ฆ์๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
์ ํ ์ฌํญ ํ์ธ
SUID ๋ฐ SGID
# Make it owned by root and suid
sudo chown root hello
sudo chmod +s hello
# Insert the library
DYLD_INSERT_LIBRARIES=inject.dylib ./hello
# Remove suid
sudo chmod -s hello
Section __RESTRICT with segment __restrict
gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict
Hardened runtime
Keychain์์ ์ ์ธ์ฆ์๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์๋ช ํฉ๋๋ค:
# Apply runtime proetction
codesign -s <cert-name> --option=runtime ./hello
DYLD_INSERT_LIBRARIES=inject.dylib ./hello #Library won't be injected
# Apply library validation
codesign -f -s <cert-name> --option=library ./hello
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed #Will throw an error because signature of binary and library aren't signed by same cert (signs must be from a valid Apple-signed developer certificate)
# Sign it
## If the signature is from an unverified developer the injection will still work
## If it's from a verified developer, it won't
codesign -f -s <cert-name> inject.dylib
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed
# Apply CS_RESTRICT protection
codesign -f -s <cert-name> --option=restrict hello-signed
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work
Caution
0x0(none)ํ๋๊ทธ๋ก ์๋ช ๋ ๋ฐ์ด๋๋ฆฌ๊ฐ ์๋๋ผ๋, ์คํ ์ ๋์ ์ผ๋กCS_RESTRICTํ๋๊ทธ๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก ์ด ๊ธฐ์ ์ ๊ทธ๋ค์ ๋ํด ์๋ํ์ง ์์ต๋๋ค.ํ๋ก์ธ์ค์ ์ด ํ๋๊ทธ๊ฐ ์๋์ง ํ์ธํ๋ ค๋ฉด (get csops here):
csops -status <pid>๊ทธ๋ฐ ๋ค์ ํ๋๊ทธ 0x800์ด ํ์ฑํ๋์ด ์๋์ง ํ์ธํ์ญ์์ค.
References
- https://theevilbit.github.io/posts/dyld_insert_libraries_dylib_injection_in_macos_osx_deep_dive/
- *OS Internals, Volume I: User Mode. By Jonathan Levin
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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


