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

This commit is contained in:
Translator 2024-05-06 23:55:08 +00:00
parent d4fac87507
commit 33fa716bde
2 changed files with 215 additions and 177 deletions

View file

@ -2,15 +2,15 @@
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로**부터 **히어로**까지 AWS 해킹을 배우세요!</summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅이 될 때까지 AWS 해킹을 배우세요** <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고**하거나 **PDF로 HackTricks 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* **회사를 HackTricks에서 광고하거나 PDF로 HackTricks 다운로드**하려면 [**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을 제출하여 **해킹 트릭을 공유**하세요.
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소로 **PR을 제출**하여 해킹 트릭을 공유하세요.
</details>
@ -18,13 +18,13 @@ HackTricks를 지원하는 다른 방법:
### 기본 정보
Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하며, 각 작업에는 **여러 스레드**가 포함될 수 있습니다. 이러한 **작업 및 스레드는 1:1로 POSIX 프로세스 및 스레드에 매핑**됩니다.
Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하며, 각 작업에는 **여러 스레드**가 포함될 수 있습니다. 이러한 **작업과 스레드는 1:1로 POSIX 프로세스와 스레드에 매핑**됩니다.
작업 간 통신은 Mach Inter-Process Communication (IPC)을 통해 발생하며, **일방향 통신 채널**을 활용합니다. **메시지는 포트 간에 전송**되며, 이는 커널에서 관리되는 **메시지 큐**와 같은 역할을 합니다.
작업 간 통신은 Mach Inter-Process Communication (IPC)을 통해 발생하며, **메시지는 포트 간에 전송**되며, 이는 커널에서 관리되는 **메시지 큐**와 유사하게 작동합니다.
**포트**는 Mach IPC의 **기본 요소**입니다. 메시지를 **보내고 받는 데 사용**할 수 있습니다.
**포트**는 Mach IPC의 **기본** 요소입니다. 메시지를 **보내고 받는 데 사용**할 수 있습니다.
각 프로세스에는 **IPC 테이블**이 있으며, 거기에는 **프로세스의 mach 포트**를 찾을 수 있습니다. mach 포트의 이름은 실제로 숫자(커널 객체에 대한 포인터)입니다.
각 프로세스에는 **IPC 테이블**이 있으며, 여기에는 **프로세스의 mach 포트**를 찾을 수 있습니다. Mach 포트의 이름은 실제로 숫자(커널 객체에 대한 포인터)입니다.
프로세스는 또한 **다른 작업에게 일부 권한을 가진 포트 이름을 보낼 수 있으며**, 커널은 이를 **다른 작업의 IPC 테이블에 등록**합니다.
@ -32,52 +32,52 @@ Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하
작업이 수행할 수 있는 작업을 정의하는 포트 권한은 이 통신에 중요합니다. 가능한 **포트 권한**은 ([여기에서 정의된 내용](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
* **수신 권한**은 포트로 보낸 메시지를 수신할 수 있게 합니다. Mach 포트는 MPSC (다중 생산자, 단일 소비자) 큐이므로 전체 시스템에서 각 포트에 대해 **하나의 수신 권한만 있을 수** 있습니다 (여러 프로세스가 하나의 파이프의 읽기 끝에 대한 파일 디스크립터를 모두 보유할 수 있는 파이프와는 달리).
* **수신 권한을 가진 작업**은 메시지를 수신하고 **보내기 권한을 생성**할 수 있으며, 처음에는 **자체 작업만 수신 권한을 가집니다**.
* 수신 권한의 소유자가 **죽거나 종료**하면 **보내기 권한이 무용지물이 됩니다(데드 네임).**
* **보내기 권한**은 포트로 메시지를 보낼 수 있게 합니다.
* 보내기 권한은 **복제**될 수 있어서 보내기 권한을 가진 작업이 권한을 복제하고 **제3 작업에게 부여**할 수 있습니다.
* **수신 권한**은 포트로 보낸 메시지를 수신할 수 있게 합니다. Mach 포트는 MPSC (다중 생산자, 단일 소비자) 큐이므로 전체 시스템에서 각 포트에 대해 **하나의 수신 권한만** 있을 수 있습니다 (여러 프로세스가 하나의 파이프의 읽기 끝에 대한 파일 기술자를 모두 보유할 수 있는 파이프와는 달리).
* **수신 권한을 가진 작업**은 메시지를 수신하고 **보낼 수 있는 송신 권한을 생성**할 수 있습니다. 처음에는 **자체 작업이 수신 권한을 가집니다**.
* 수신 권한의 소유자가 **죽거나 종료**하면 **송신 권한이 무용지물이 됩니다(데드 네임).**
* **송신 권한**은 포트로 메시지를 보낼 수 있게 합니다.
* 송신 권한은 **복제**될 수 있어 송신 권한을 가진 작업이 권한을 복제하고 **제3 작업에게 부여**할 수 있습니다.
* **포트 권한**은 Mac 메시지를 통해 **전달**될 수도 있습니다.
* **한 번 보내기 권한**은 포트로 한 번의 메시지를 보낼 수 있고 그 후 사라집니다.
* **한 번 송신 권한**은 포트로 한 번 메시지를 보낼 수 있고 그 후 사라집니다.
* 이 권한은 **복제**될 수 없지만 **이동**될 수 있습니다.
* **포트 집합 권한**은 단일 포트가 아닌 _포트 세트_를 나타냅니다. 포트 세트에서 메시지를 디큐하는 것은 그 포트가 포함하는 포트 중 하나에서 메시지를 디큐합니다. 포트 세트는 Unix의 `select`/`poll`/`epoll`/`kqueue`와 매우 유사하게 여러 포트에서 동시에 수신할 수 있습니다.
* **데드 네임**은 실제 포트 권한이 아니라 단순히 자리 표시자입니다. 포트가 파괴되면 포트에 대한 모든 기존 포트 권한이 데드 네임으로 변니다.
* **포트 세트 권한**은 단일 포트가 아닌 _포트 세트_를 나타냅니다. 포트 세트에서 메시지를 디큐하는 것은 해당 포트 중 하나에서 메시지를 디큐합니다. 포트 세트는 Unix의 `select`/`poll`/`epoll`/`kqueue`와 매우 유사하게 여러 포트에서 동시에 수신할 수 있습니다.
* **데드 네임**은 실제 포트 권한이 아니라 단순히 자리 표시자입니다. 포트가 파괴되면 포트에 대한 모든 기존 포트 권한이 데드 네임으로 변환됩니다.
**작업은 SEND 권한을 다른 작업에게 전달**하여 메시지를 다시 보낼 수 있습니다. **SEND 권한은 복제**될 수 있기 때문에 작업은 권한을 복제하고 **제3의 작업에게 권한을 부여**할 수 있습니다. 이는 **부트스트랩 서버**라는 중간 프로세스와 결합되어 작업 간 효과적인 통신을 가능케 합니다.
**작업은 다른 작업에게 송신 권한을 전달**하여 메시지를 다시 보낼 수 있습니다. **송신 권한은 복제**될 수 있어 작업이 권한을 복제하고 **제3 작업에게 권한을 부여**할 수 있습니다. 이는 **부트스트랩 서버**라는 중간 프로세스와 결합되어 작업 간 효과적인 통신을 가능케 합니다.
### 파일 포트
파일 포트를 사용하면 Mac 포트(맥 포트 권한 사용)에 파일 디스크립터를 캡슐화할 수 있습니다. 주어진 FD를 사용하여 `fileport_makeport`를 사용하여 `fileport`를 만들고 `fileport_makefd`를 사용하여 fileport에서 FD를 만들 수 있습니다.
파일 포트를 사용하면 Mac 포트(맥 포트 권한 사용)에 파일 기술자를 캡슐화할 수 있습니다. 주어진 FD를 사용하여 `fileport_makeport`를 사용하여 `fileport`를 만들고 `fileport_makefd`를 사용하여 fileport에서 FD를 만들 수 있습니다.
### 통신 설정
이전에 언급했듯이 Mach 메시지를 사용하여 권한을 보낼 수 있지만, 이미 Mach 메시지를 보낼 권한이 없는 경우 **권한을 보낼 수 없습니다**. 그렇다면 첫 번째 통신은 어떻게 설정됩니까?
이를 위해 **부트스트랩 서버**(mac의 **launchd**)가 관여됩니다. **누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있으므로**, 다른 프로세스에 메시지를 보낼 권한을 요청할 수 있습니다:
이를 위해 **부트스트랩 서버**(mac의 **launchd**)가 관여되며, **누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있으므로**, 다른 프로세스에 메시지를 보낼 권한을 요청할 수 있습니다:
1. 작업 **A**는 **새 포트**를 생성하여 **그것에 대한 수신 권한**을 얻습니다.
2. 수신 권한의 소유자인 작업 **A**는 **포트에 대한 SEND 권한을 생성**합니다.
3. 작업 **A**는 **부트스트랩 서버**와 **연결**을 설정하고, 처음에 생성한 포트에 대한 **SEND 권한을 부트스트랩 서버에 보냅니다**.
2. 수신 권한의 소유자인 작업 **A**는 **포트에 대한 송신 권한을 생성**합니다.
3. 작업 **A**는 **부트스트랩 서버**와 **연결**을 설정하고, 처음에 생성한 포트에 대한 **송신 권한을 부트스트랩 서버에 보냅니다**.
* 누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있습니다.
4. 작업 A는 부트스트랩 서버에 `bootstrap_register` 메시지를 보내 **`com.apple.taska`**와 같은 이름으로 주어진 포트를 **연결**합니다.
5. 작업 **B**는 서비스 이름에 대한 부트스트랩 **룩업**을 실행하기 위해 **부트스트랩 서버**와 상호 작용합니다(`bootstrap_lookup`). 따라서 부트스트랩 서버가 응답하려면 작업 B는 룩업 메시지 내에서 이전에 생성한 **포트에 대한 SEND 권한을 부트스트랩 서버에 보냅니다**. 룩업이 성공하면 부트스트랩 서버는 작업 A로부터 받은 SEND 권한을 **복제**하고 **작업 B에게 전송**합니다.
4. 작업 A는 부트스트랩 서버에 `bootstrap_register` 메시지를 보내 **주어진 포트를 `com.apple.taska`와 같은 이름과 연결**합니다.
5. 작업 **B**는 서비스 이름에 대한 부트스트랩 **룩업을 실행**하기 위해 **부트스트랩 서버**와 상호 작용합니다(`bootstrap_lookup`). 따라서 부트스트랩 서버가 응답하려면 작업 B는 룩업 메시지 내에서 이전에 생성한 **포트에 대한 SEND 권한을 부트스트랩 서버에 보냅니다**. 룩업이 성공하면 **서버는 Task A로부터 받은 SEND 권한을 복제**하고 **Task B로 전송**합니다.
* 누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있습니다.
6. 이 SEND 권한으로 **작업 B**는 **작업 A에게 메시지를 보낼 수 있습니다**.
7. 양방향 통신을 위해 일반적으로 작업 **B**는 **수신** 권한과 **보내기** 권한이 있는 새 포트를 생성하고 **보내기 권한을 작업 A에게 제공**하여 작업 B에게 메시지를 보낼 수 있게 합니다.
7. 양방향 통신을 위해 일반적으로 작업 **B**는 **수신** 권한과 **송신** 권한이 있는 새 포트를 생성하고 **송신 권한을 Task A에게 제공**하여 Task B에게 메시지를 보낼 수 있도록 합니다.
부트스트랩 서버는 작업이 주장하는 서비스 이름을 인증할 수 없습니다. 이는 **작업**이 잠재적으로 **시스템 작업을 가장할 수 있음**을 의미합니다. 즉, 권한 서비스 이름을 가장하고 모든 요청을 승인할 수 있습니다.
부트스트랩 서버는 작업이 주장한 서비스 이름을 인증할 수 없습니다. 이는 **작업**이 잠재적으로 **모든 시스템 작업을 흉내 낼 수 있음**을 의미합니다. 예를 들어 권한 서비스 이름을 거짓으로 주장하고 모든 요청을 승인할 수 있습니다.
그런 다음, Apple은 **시스템 제공 서비스의 이름**을 안전한 구성 파일에 저장합니다. 이 파일은 **SIP로 보호된** 디렉토리인 `/System/Library/LaunchDaemons``/System/Library/LaunchAgents`에 있습니다. 각 서비스 이름 옆에는 **관련된 이진 파일도 저장**됩니다. 부트스트랩 서버는 이러한 서비스 이름 각각에 대한 **수신 권한을 생성하고 보유**합니다.
그런 다음 Apple은 시스템 제공 서비스의 **이름을 안전한 구성 파일**에 저장합니다. 이 파일은 **SIP로 보호된** 디렉토리인 `/System/Library/LaunchDaemons``/System/Library/LaunchAgents`에 있습니다. 각 서비스 이름 옆에는 **관련된 이진 파일도 저장**됩니다. 부트스트랩 서버는 이러한 서비스 이름 각각에 대한 **수신 권한을 생성하고 보유**합니다.
이러한 사전 정의된 서비스에 대해서는 **룩업 프로세스가 약간 다릅니다**. 서비스 이름을 찾을 때, launchd는 서비스를 동적으로 시작합니다. 새로운 워크플로우는 다음과 같습니다:
이러한 사전 정의된 서비스의 경우 **룩업 프로세스가 약간 다릅니다**. 서비스 이름을 찾을 때, launchd는 서비스를 동적으로 시작합니다. 새로운 워크플로우는 다음과 같습니다:
* 작업 **B**는 서비스 이름에 대한 부트스트랩 **룩업**을 시작합니다.
* **launchd**는 작업이 실행 중인지 확인하고 실행 중이 아니면 **시작**합니다.
* 작업 **A**(서비스)는 **부트스트랩 체크인**(`bootstrap_check_in()`)을 수행합니다. 여기서 **부트스트랩** 서버는 SEND 권한을 생성하고 보유하며 **수신 권한을 작업 A에게 전**합니다.
* launchd는 **SEND 권한을 복제하고 작업 B에게 전송**합니다.
* 작업 **B**는 **수신** 권한과 **보내기** 권한이 있는 새 포트를 생성하고 **보내기 권한을 작업 A**(svc)에게 제공하여 작업 B에게 메시지를 보낼 수 있게 합니다.
* 작업 **A**(서비스)는 **부트스트랩 체크인**(`bootstrap_check_in()`)을 수행합니다. 여기서 **부트스트랩** 서버는 SEND 권한을 생성하고 보유하며 **수신 권한을 작업 A에게 전**합니다.
* launchd는 **SEND 권한을 복제하고 Task B에게 전송**합니다.
* 작업 **B**는 **수신** 권한과 **송신** 권한이 있는 새 포트를 생성하고 **송신 권한을 Task A**(svc)에게 제공하여 Task B에게 메시지를 보낼 수 있도록 합니다.
그러나 이 프로세스는 사전 정의된 시스템 작업에만 적용됩니다. 비시스템 작업은 여전히 처음에 설명한 대로 작동하며, 이는 가장할 수 있는 가능성을 열어둘 수 있습니다.
그러나 이 프로세스는 사전 정의된 시스템 작업에만 적용됩니다. 비시스템 작업은 여전히 처음에 설명한 대로 작동하며, 이는 흉내 낼 수 있도록 허용할 수 있습니다.
{% hint style="danger" %}
따라서 launchd가 절대로 충돌해서는 안 되며, 그렇게 되면 전체 시스템이 충돌합니다.
@ -86,7 +86,7 @@ Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하
[더 많은 정보는 여기에서 찾을 수 있습니다](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
`mach_msg` 함수는 본질적으로 시스템 호출로, Mach 메시지를 보내고 받기 위해 사용됩니다. 이 함수는 보내려는 메시지를 초기 인수로 필요로 합니다. 이 메시지는 `mach_msg_header_t` 구조체로 시작해야 합니다. 그 뒤에 실제 메시지 내용이 이어집니다. 이 구조체는 다음과 같이 정의됩니다:
`mach_msg` 함수는 본질적으로 시스템 호출로, Mach 메시지를 보내고 받는 데 사용됩니다. 이 함수는 보내려는 메시지를 초기 인수로 필요로 합니다. 이 메시지는 반드시 `mach_msg_header_t` 구조체로 시작해야 합니다. 그 뒤에 실제 메시지 내용이 이어집니다. 이 구조체는 다음과 같이 정의됩니다:
```c
typedef struct {
mach_msg_bits_t msgh_bits;
@ -97,15 +97,15 @@ mach_port_name_t msgh_voucher_port;
mach_msg_id_t msgh_id;
} mach_msg_header_t;
```
프로세스가 _**수신 권한**_을 가지고 있으면 Mach 포트에서 메시지를 수신할 수 있습니다. 반대로 **보내는 쪽(sender)**은 _**송신 권한**_ 또는 _**일회용 송신 권한**_을 부여받습니다. 일회용 송신 권한은 한 번의 메시지를 보낸 후에 무효화됩니다.
프로세스가 _**수신 권한**_을 보유하면 Mach 포트에서 메시지를 수신할 수 있습니다. 반면에 **보내는 쪽(sender)**은 _**송신 권한**_ 또는 _**일회용 송신 권한**_을 부여받습니다. 일회용 송신 권한은 한 번의 메시지를 보낸 후에 무효화됩니다.
초기 필드 **`msgh_bits`**는 비트맵입니다:
* 첫 번째 비트(가장 중요함)는 메시지가 복잡함을 나타내는 데 사용됩니다(자세한 내용은 아래 참조)
* 3번째와 4번째는 커널에서 사용됩니다
* 두 번째 바이트의 **가장 낮은 5개 비트**는 **바우처(voucher)**에 사용될 수 있습니다: 키/값 조합을 보내는 또 다른 유형의 포트입니다.
* 세 번째 바이트의 **가장 낮은 5개 비트**는 **로컬 포트**에 사용될 수 있습니다.
* 네 번째 바이트의 **가장 낮은 5개 비트**는 **원격 포트**에 사용될 수 있습니다.
* 3번째와 4번째 비트는 커널에 의해 사용됩니다
* 2번 바이트의 **가장 낮은 5개 비트**는 **바우처(voucher)**에 사용될 수 있습니다: 키/값 조합을 보내는 또 다른 유형의 포트
* 3번 바이트의 **가장 낮은 5개 비트**는 **로컬 포트**에 사용될 수 있습니다
* 4번 바이트의 **가장 낮은 5개 비트**는 **원격 포트**에 사용될 수 있습니다
바우처, 로컬 및 원격 포트에 지정할 수 있는 유형은 다음과 같습니다([**mach/message.h**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html) 참조):
```c
@ -120,12 +120,12 @@ mach_msg_id_t msgh_id;
#define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */
#define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26 /* must hold sendonce right */
```
예를 들어, `MACH_MSG_TYPE_MAKE_SEND_ONCE`는 이 포트를 위해 파생 및 전송해야 하는 **한 번만 보내기 권한**을 나타내는 데 사용될 수 있습니다. 수신자가 이 메시지에 대답할 수 없도록 하려면 `MACH_PORT_NULL`을 지정할 수 있습니다.
예를 들어, `MACH_MSG_TYPE_MAKE_SEND_ONCE`는 이 포트를 위해 파생 및 전송되어야 하는 **한 번만 보내기** **권한**을 나타내는 데 사용될 수 있습니다. 또한 수신자가 응답을 보낼 수 없도록 하려면 `MACH_PORT_NULL`을 지정할 수 있습니다.
쉬운 **양방향 통신**을 달성하기 위해 프로세스는 메시지 **헤더**에서 _응답 포트_ (**`msgh_local_port`**로 불리는 mach 포트)를 지정할 수 있습니다. 메시지의 **수신자**는 이 메시지에 대한 응답을 보낼 수 있습니다.
쉬운 **양방향 통신**을 위해 프로세스는 메시지 헤더의 **_응답 포트_**(**`msgh_local_port`**)라고 불리는 mach **포트**를 지정할 수 있으며, 메시지의 **수신자**는 이 메시지에 대한 응답을 보낼 수 있습니다.
{% hint style="success" %}
이러한 종류의 양방향 통신은 응답을 기대하는 XPC 메시지에서 사용되며 (`xpc_connection_send_message_with_reply` 및 `xpc_connection_send_message_with_reply_sync`), **일반적으로 서로 다른 포트가 생성**되어 양방향 통신을 생성하는 방법에 대해 이전에 설명한 대로 사용됩니다.
이러한 종류의 양방향 통신은 XPC 메시지에서 사용되며, 응답을 예상하는 메시지(`xpc_connection_send_message_with_reply` 및 `xpc_connection_send_message_with_reply_sync`)에서 사용됩니다. 그러나 일반적으로 양방향 통신을 생성하려면 이전에 설명한 대로 **다른 포트가 생성**됩니다.
{% endhint %}
메시지 헤더의 다른 필드는 다음과 같습니다:
@ -139,15 +139,15 @@ mach_msg_id_t msgh_id;
**mach 메시지는 `mach 포트`를 통해 전송**되며, 이는 mach 커널에 내장된 **단일 수신자**, **다중 송신자** 통신 채널입니다. **여러 프로세스**가 mach 포트로 **메시지를 보낼** 수 있지만 언제든지 **단일 프로세스만** 읽을 수 있습니다.
{% endhint %}
그런 다음 메시지는 **`mach_msg_header_t`** 헤더, **바디**, 그리고 **트레일러** (있는 경우)로 구성되며, 이에 대한 응답 권한을 부여할 수 있습니다. 이러한 경우, 커널은 메시지를 한 작업에서 다른 작업으로 전달하기만 하면 됩니다.
그런 다음 메시지는 **`mach_msg_header_t`** 헤더, **본문** 및 **트레일러**(있는 경우)로 구성되며, 응답 권한을 부여할 수 있습니다. 이러한 경우, 커널은 메시지를 한 작업에서 다른 작업으로 전달하기만 하면 됩니다.
**트레일러**는 **커널에 의해 메시지에 추가된 정보**(사용자가 설정할 수 없음) 메시지 수신 시 `MACH_RCV_TRAILER_<trailer_opt>` 플래그로 요청할 수 있습니다 (요청할 수 있는 다양한 정보가 있음).
**트레일러**는 **커널에 의해 메시지에 추가된 정보**입니다(사용자가 설정할 수 없음) 메시지 수신 시 `MACH_RCV_TRAILER_<trailer_opt>` 플래그로 요청할 수 있습니다(요청할 수 있는 다양한 정보가 있음).
#### 복잡한 메시지
그러나 커널이 수신자에게 추가 포트 권한을 전달하거나 메모리를 공유하는 등 **더 복잡한** 메시지도 있습니다. 이러한 경우, 헤더 `msgh_bits`의 가장 상위 비트가 설정됩니다.
그러나 커널이 수신자에게 이러한 객체를 전송해야 하는 추가 포트 권한이나 메모리 공유와 같은 더 **복잡한** 메시지도 있습니다. 이러한 경우 헤더 `msgh_bits`의 가장 상위 비트가 설정됩니다.
전달할 수 있는 가능한 디스크립터는 [**`mach/message.h`**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html)에서 정의되어 있습니다.
전달할 가능한 기술자는 [**`mach/message.h`**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html)에서 정의됩니다:
```c
#define MACH_MSG_PORT_DESCRIPTOR 0
#define MACH_MSG_OOL_DESCRIPTOR 1
@ -167,12 +167,12 @@ mach_msg_descriptor_type_t type : 8;
### 32비트에서는 모든 디스크립터가 12B이며 디스크립터 유형은 11번째에 있습니다. 64비트에서는 크기가 다양합니다.
{% hint style="danger" %}
커널은 다른 작업으로 디스크립터를 복사하지만 먼저 **커널 메모리에 복사본을 생성**합니다. 이 "Feng Shui" 기술은 여러 악용으로 커널이 데이터를 자체 메모리에 복사하도록 만들어 프로세스가 자신에게 디스크립터를 보낼 수 있게 합니다. 그런 다음 프로세스는 메시지를 수신할 수 있습니다 (커널이 를 해제합니다).
커널은 먼저 **커널 메모리에 복사본을 생성** 한 다음 한 작업에서 다른 작업으로 디스크립터를 복사합니다. 이 "펑 수이" 기술은 여러 악용으로 알려져 있으며 **커널이 데이터를 메모리에 복사**하여 프로세스가 자신에게 디스크립터를 보낼 수 있게 합니다. 그런 다음 프로세스는 메시지를 수신할 수 있습니다 (커널이 메모리를 해제합니다).
취약한 프로세스**포트 권한을 보낼 수도 있으며**, 포트 권한은 프로세스에 나타날 것입니다 (그가 처리하지 않더라도).
취약한 프로세스**포트 권한을 보낼 수도** 있으며 포트 권한은 프로세스에 나타날 것입니다 (그가 처리하지 않더라도).
{% endhint %}
### Mac Ports API
### Mac Ports APIs
포트는 작업 네임스페이스에 연결되므로 포트를 생성하거나 검색하려면 작업 네임스페이스도 쿼리됩니다 (`mach/mach_port.h`에서 자세히 설명):
@ -183,15 +183,15 @@ mach_msg_descriptor_type_t type : 8;
* `mach_port_type`: 이름에 대한 작업의 권한 가져오기
* `mach_port_rename`: 포트의 이름 바꾸기 (FD의 dup2와 유사)
* `mach_port_allocate`: 새로운 RECEIVE, PORT\_SET 또는 DEAD\_NAME 할당
* `mach_port_insert_right`: 수신 권한이 있는 포트에 새 권한 생성
* `mach_port_insert_right`: 수신할 수 있는 포트에 새 권한 생성
* `mach_port_...`
* **`mach_msg`** | **`mach_msg_overwrite`**: **mach 메시지를 보내고 받는** 데 사용되는 함수입니다. 덮어쓰기 버전은 메시지 수신을 위한 다른 버퍼를 지정할 수 있니다 (다른 버전은 그냥 재사용합니다).
* **`mach_msg`** | **`mach_msg_overwrite`**: **mach 메시지를 보내고 받는 데 사용되는 함수**입니다. 덮어쓰기 버전은 메시지 수신을 위한 다른 버퍼를 지정할 수 있게 합니다 (다른 버전은 그냥 재사용합니다).
### 디버그 mach\_msg
### Debug mach\_msg
함수 **`mach_msg`**와 **`mach_msg_overwrite`**는 메시지를 보내고 받는 데 사용되는 함수이므로 이러한 함수에 중단점을 설정하면 보낸 메시지 받은 메시지를 검사할 수 있습니다.
**`mach_msg`** 및 **`mach_msg_overwrite`** 함수는 메시지를 보내고 받는 데 사용되는 함수이므로 이러한 함수에 중단점을 설정하면 보낸 메시지 받은 메시지를 검사할 수 있습니다.
예를 들어 디버깅할 수 있는 모든 응용 프로그램을 시작하면 **`libSystem.B`를 로드**할 것이므로 이 함수를 사용할 것입니다.
예를 들어 디버깅할 수 있는 모든 응용 프로그램을 시작하면 이 함수를 사용할 **`libSystem.B`가 로드**됩니다.
<pre class="language-armasm"><code class="lang-armasm"><strong>(lldb) b mach_msg
</strong>Breakpoint 1: where = libsystem_kernel.dylib`mach_msg, address = 0x00000001803f6c20
@ -220,7 +220,7 @@ frame #8: 0x000000018e59e6ac libSystem.B.dylib`libSystem_initializer + 236
frame #9: 0x0000000181a1d5c8 dyld`invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&#x26;) const::$_0::operator()() const + 168
</code></pre>
**`mach_msg`**의 인수를 얻으려면 레지스터를 확인하십시오. 이러한 이 인수입니다 ([mach/message.h](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html) 참조):
**`mach_msg`**의 인수를 얻으려면 레지스터를 확인하십시오. 이것이 인수입니다 ([mach/message.h](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html) 참조):
```c
__WATCHOS_PROHIBITED __TVOS_PROHIBITED
extern mach_msg_return_t mach_msg(
@ -243,7 +243,7 @@ x4 = 0x0000000000001f03 ;mach_port_name_t (rcv_name)
x5 = 0x0000000000000000 ;mach_msg_timeout_t (timeout)
x6 = 0x0000000000000000 ;mach_port_name_t (notify)
```
첫 번째 인수를 확인하여 메시지 헤더를 검사하십시오:
첫 번째 인수를 확인하여 메시지 헤더를 검사하십시오.
```armasm
(lldb) x/6w $x0
0x124e04ce8: 0x00131513 0x00000388 0x00000807 0x00001f03
@ -256,11 +256,11 @@ x6 = 0x0000000000000000 ;mach_port_name_t (notify)
; 0x00000b07 -> mach_port_name_t (msgh_voucher_port)
; 0x40000322 -> mach_msg_id_t (msgh_id)
```
그 유형의 `mach_msg_bits_t`는 응답을 허용하는 데 매우 일반적입니다.
그 유형의 `mach_msg_bits_t`는 응답을 허용하기 위해 매우 일반적입니다.
### 포트
### 포트 열거하기
```bash
lsmp -p <pid>
@ -286,9 +286,9 @@ name ipc-object rights flags boost reqs recv send sonce oref q
```
**이름**은 포트에 지정된 기본 이름입니다 (첫 3바이트에서 **증가**하는 방법을 확인하십시오). **`ipc-object`**는 포트의 **가려진** 고유 **식별자**입니다.\
또한 **`send`** 권한만 있는 포트는 해당 소유자를 **식별**하는 데 사용됨을 주목하십시오 (포트 이름 + pid).\
또한 **`+`**를 사용하여 **동일한 포트에 연결된 다른 작업**을 나타내는 것에 유의하십시오.
또한 **`+`**를 사용하여 **동일한 포트에 연결된 다른 작업을 나타내는** 방법에 주목하십시오.
또한 [**procesxp**](https://www.newosxbook.com/tools/procexp.html)를 사용하여 **등록된 서비스 이름**도 볼 수 있습니다 (SIP가 비활성화된 경우 `com.apple.system-task-port`가 필요함).
또한 [**procesxp**](https://www.newosxbook.com/tools/procexp.html)를 사용하여 **등록된 서비스 이름**도 볼 수 있습니다 (SIP가 비활성화되어 있어 `com.apple.system-task-port`가 필요한 경우):
```
procesp 1 ports
```
@ -296,7 +296,7 @@ iOS에서 이 도구를 설치하려면 [http://newosxbook.com/tools/binpack64-2
### 코드 예시
**sender**가 포트를 할당하고 `org.darlinghq.example` 이름에 대한 **send right**를 생성하여 이를 **부트스트랩 서버**에 보낸 것에 주목하십시오. 수신자는 해당 이름에 대한 **send right**를 요청하고 이를 사용하여 **메시지를 보냈습니다**.
**sender**가 포트를 할당하고 `org.darlinghq.example` 이름에 대한 **send right**를 생성하여 이를 **부트스트랩 서버**에 보낼 때, 수신자는 해당 이름에 대한 **send right**를 요청하고 이를 사용하여 **메시지를 보내는 방법**을 요청했음을 주목하세요.
{% tabs %}
{% tab title="receiver.c" %}
@ -368,29 +368,27 @@ printf("Text: %s, number: %d\n", message.some_text, message.some_number);
{% endtab %}
{% tab title="sender.c" %}
## macOS Inter-Process Communication (IPC)
## sender.c
### Overview
sender.c는 수신자 프로세스에 메시지를 보내는 프로세스입니다.
In macOS, Inter-Process Communication (IPC) mechanisms are used for communication between processes. This can be abused by malicious actors to escalate privileges or perform other unauthorized actions.
### 사용법
### Techniques
```bash
gcc sender.c -o sender
./sender
```
1. **Mach Ports**: Mach ports are a fundamental IPC mechanism in macOS. They can be used for inter-process communication and are a common target for privilege escalation attacks.
### 동작
2. **XPC Services**: XPC services allow processes to communicate with each other. By abusing XPC services, an attacker can potentially escalate privileges.
1. 메시지 큐를 생성합니다.
2. 메시지를 작성하고 메시지 큐에 보냅니다.
3. 메시지 큐를 삭제합니다.
3. **Distributed Objects**: Distributed objects are another IPC mechanism that can be abused for privilege escalation.
### 주의사항
### Mitigation
To mitigate the risks associated with IPC abuse, follow these best practices:
- **Use Code Signing**: Ensure that all processes involved in IPC are properly code signed to prevent unauthorized processes from communicating.
- **Implement Sandboxing**: Utilize sandboxing to restrict the capabilities of processes and limit the potential impact of IPC abuse.
- **Monitor IPC Activity**: Regularly monitor IPC activity to detect any suspicious behavior or unauthorized communication between processes.
By following these mitigation strategies, you can enhance the security of your macOS system against IPC abuse.
- 이 코드는 macOS에서만 동작합니다.
- IPC(Inter-Process Communication)를 이해하고 있는 것이 도움이 됩니다.
{% endtab %}
```c
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
@ -448,20 +446,20 @@ printf("Sent a message\n");
### 특권 포트
* **호스트 포트**: 프로세스가 이 포트에 대한 **Send** 권한을 가지고 있으면 **시스템에 대한 정보**를 얻을 수 있습니다 (예: `host_processor_info`).
* **호스트 포트**: 프로세스가 이 포트에 대한 **Send** 권한을 가지면 **시스템에 대한 정보**를 얻을 수 있습니다 (예: `host_processor_info`).
* **호스트 특권 포트**: 이 포트에 대한 **Send** 권한을 가진 프로세스는 커널 익스텐션을 로드하는 등 **특권 작업**을 수행할 수 있습니다. 이 권한을 얻으려면 **프로세스가 루트여야** 합니다.
* 또한 **`kext_request`** API를 호출하려면 다른 엔타이틀먼트 **`com.apple.private.kext*`**가 필요하며, 이는 Apple 이진 파일에만 부여됩니다.
* **태스크 이름 포트**: _태스크 포트_의 권이 없는 버전입니다. 태스크를 참조하지만 제어할 수는 없습니다. 이를 통해 사용할 수 있는 유일한 것은 `task_info()`입니다.
* **태스크 이름 포트**: _태스크 포트_의 권이 없는 버전입니다. 태스크를 참조하지만 제어할 수는 없습니다. 이를 통해 사용 가능한 것은 `task_info()`입니다.
* **태스크 포트** (또는 커널 포트)**:** 이 포트에 대한 Send 권한이 있으면 태스크를 제어할 수 있습니다 (메모리 읽기/쓰기, 스레드 생성 등).
* 호출하면 `mach_task_self()` 호출자 태스크에 대한 이 포트의 **이름을 가져올 수** 있습니다. 이 포트는 **`exec()`**를 통해만 **상속**됩니다. `fork()`로 생성된 새로운 태스크는 새로운 태스크 포트를 받습니다 (`exec()` 후 suid 이진 파일에서도 특별한 경우로 태스크는 새로운 태스크 포트를 받습니다). 태스크를 생성하고 해당 포트를 가져오는 유일한 방법은 `fork()`를 수행하는 동안 ["포트 스왑 댄스"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html)를 수행하는 것입니다.
* 호출 `mach_task_self()`하여 호출자 태스크에 대한 이 포트의 **이름을 가져옵니다**. 이 포트는 **`exec()`**를 통해만 **상속**됩니다. `fork()`로 생성된 새 태스크는 새 태스크 포트를 받습니다 (`exec()` 후 suid 이진 파일에서도 특별한 경우로 태스크는 `exec()` 후에도 새 태스크 포트를 받습니다). 태스크를 생성하고 해당 포트를 가져오는 유일한 방법은 `fork()`를 수행하는 동안 ["포트 스왑 댄스"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html)를 수행하는 것입니다.
* 이 포트에 액세스하는 제한 사항은 (`AppleMobileFileIntegrity` 바이너리의 `macos_task_policy`에서):
* 앱이 **`com.apple.security.get-task-allow` 엔타이틀먼트**를 가지고 있으면 **동일한 사용자의 프로세스가** 태스크 포트에 액세스할 수 있습니다 (주로 디버깅을 위해 Xcode에서 추가됨). **노타리제이션** 프로세스는 프로덕션 릴리스에서 이를 허용하지 않습니다.
* **`com.apple.system-task-ports`** 엔타이틀먼트가 있는 앱은 커널을 제외한 **모든** 프로세스의 **태스크 포트를 얻을 수 있습니다**. 이전 버전에서는 **`task_for_pid-allow`**로 불렸습니다. 이 권한은 Apple 애플리케이션에만 부여됩니다.
* 앱이 **`com.apple.security.get-task-allow` 엔타이틀먼트**를 가지고 있으면 **동일한 사용자의 프로세스가 태스크 포트에 액세스**할 수 있습니다 (주로 디버깅을 위해 Xcode에서 추가됨). **노타리제이션** 프로세스는 프로덕션 릴리스에서 이를 허용하지 않습니다.
* **`com.apple.system-task-ports` 엔타이틀먼트**가 있는 앱은 커널을 제외한 **모든** 프로세스의 **태스크 포트를 얻을 수** 있습니다. 이전 버전에서는 **`task_for_pid-allow`**로 불렸습니다. 이 권한은 Apple 애플리케이션에만 부여됩니다.
* **루트는** **하드닝된** 런타임으로 컴파일되지 않은 애플리케이션의 **태스크 포트에 액세스**할 수 있습니다 (Apple에서 제공되지 않음).
### 태스크 포트를 통한 스레드 내 쉘코드 삽입
### 태스크 포트를 통한 스코드 삽입
다음에서 코드를 가져올 수 있습니다:
다음에서 스렬코드를 가져올 수 있습니다:
{% content-ref url="../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md" %}
[arm64-basic-assembly.md](../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md)
@ -503,25 +501,36 @@ return 0;
### Description
The `entitlements.plist` file contains a list of entitlements that define the capabilities and permissions of a macOS application. These entitlements determine what actions the application can perform and what resources it can access on the system.
The `entitlements.plist` file contains a list of entitlements that define the capabilities and permissions of a macOS application. These entitlements determine what actions the application is allowed to perform on the system.
### Location
The `entitlements.plist` file is typically located within the application bundle of a macOS application.
### Usage
Developers can specify various entitlements in the `entitlements.plist` file to request specific permissions from the system, such as access to certain resources or the ability to perform privileged operations.
### Example
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
```
In this example, the entitlements.plist file specifies that the application has permission to read and write user-selected files and to act as a network client.
### Impact
If an attacker can modify the `entitlements.plist` file of a vulnerable application, they may be able to escalate privileges, bypass security restrictions, or perform unauthorized actions on the system.
### Detection
Monitor changes to the `entitlements.plist` file, especially unexpected modifications or additions. Regularly check the file's permissions and integrity to detect any unauthorized alterations.
### Mitigation
- Apply the principle of least privilege when defining entitlements for an application.
- Encrypt and sign the `entitlements.plist` file to prevent unauthorized modifications.
- Regularly audit and review the entitlements assigned to applications to ensure they are necessary and appropriate.
### References
- [Apple Developer Documentation: Entitlement Key Reference](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Introduction/Introduction.html)
Improperly configured entitlements in the `entitlements.plist` file can lead to privilege escalation and security vulnerabilities in macOS applications. It is essential to carefully review and restrict entitlements to minimize the risk of abuse.
{% endtab %}
```xml
@ -536,7 +545,7 @@ Monitor changes to the `entitlements.plist` file, especially unexpected modifica
{% endtab %}
{% endtabs %}
이전 프로그램을 **컴파일**하고 동일한 사용자로 코드를 주입할 수 있도록 **엔타이틀먼트**를 추가하십시오 (그렇지 않으면 **sudo**를 사용해야 합니다).
이전 프로그램을 **컴파일**하고 동일한 사용자로 코드를 주입할 수 있도록 **엔타이틀먼트**를 추가합니다 (그렇지 않으면 **sudo**를 사용해야 함).
<details>
@ -737,16 +746,7 @@ inject(pid);
return 0;
}
```
</details>
<details>
<summary>macOS IPC (Inter-Process Communication)</summary>
### macOS IPC (Inter-Process Communication)
Inter-process communication (IPC) is a set of methods for the exchange of data among multiple threads in one or more processes. macOS provides several IPC mechanisms that can be abused by attackers to escalate privileges or perform other malicious activities. Understanding how IPC works on macOS is crucial for both offensive and defensive security research.
In this section, we will explore various macOS IPC mechanisms, their security implications, and potential abuse scenarios. By gaining insights into IPC, security professionals can better protect macOS systems from potential attacks leveraging IPC vulnerabilities.
</details>
```bash
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
./inject <pi or string>
@ -755,11 +755,11 @@ gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
macOS에서 **스레드**는 **Mach**를 통해 조작되거나 **posix `pthread` api**를 사용하여 조작될 수 있습니다. 이전 주입에서 생성된 스레드는 Mach api를 사용하여 생성되었기 때문에 **posix 호환성이 없습니다**.
**단순한 셸코드를 주입**하여 명령을 실행하는 것이 가능했던 이유는 **posix 호환성이 필요하지 않았기** 때문입니다. **더 복잡한 주입**을 하려면 **스레드**가 또한 **posix 호환성이 있어야** 합니다.
**단순한 셸코드를 주입**하여 명령을 실행하는 것이 가능했던 이유는 **posix 호환성이 필요하지 않았기** 때문입니다. **더 복잡한 주입**을 위해서는 **스레드**가 또한 **posix 호환성이 있어야** 합니다.
따라서 **스레드를 개선**하기 위해 **`pthread_create_from_mach_thread`**를 호출하여 **유효한 pthread를 생성**해야 합니다. 그런 다음, 이 새로운 pthread는 시스템에서 **dylib를 로드**하기 위해 **dlopen을 호출**할 수 있으므로 다른 작업을 수행하기 위해 새로운 셸코드를 작성하는 대신 사용자 지정 라이브러리를 로드할 수 있습니다.
따라서, **스레드를 개선**하기 위해 **`pthread_create_from_mach_thread`**를 호출하여 **유효한 pthread를 생성**해야 합니다. 그런 다음, 이 새로운 pthread는 **시스템에서 dylib를 로드**하기 위해 **dlopen을 호출**할 수 있으므로 다른 작업을 수행하기 위해 새로운 셸코드를 작성하는 대신 사용자 지정 라이브러리를 로드할 수 있습니다.
예를 들어 **로그를 생성하고 해당 로그를 수신할 수 있는 라이브러리**가 있는 (예:):
예를 들어 **로그를 생성하고 그 후에 해당 로그를 수신할 수 있는** (예:):
{% content-ref url="../macos-library-injection/macos-dyld-hijacking-and-dyld_insert_libraries.md" %}
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](../macos-library-injection/macos-dyld-hijacking-and-dyld\_insert_libraries.md)
@ -993,7 +993,7 @@ thread_act_t remoteThread;
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
remoteStack64 += (STACK_SIZE / 2); // 실제 스택
//remoteStack64 -= 8; // 16의 배수 정렬 필요
//remoteStack64 -= 8; // 16의 배수 정렬 필요
const char* p = (const char*) remoteCode64;
@ -1039,16 +1039,7 @@ fprintf(stderr,"Dylib를 찾을 수 없음\n");
}
```
</details>
<details>
<summary>macOS IPC (Inter-Process Communication)</summary>
### macOS IPC (Inter-Process Communication)
Inter-process communication (IPC) is a set of methods for the exchange of data among multiple threads in one or more processes. macOS provides several IPC mechanisms that can be abused by attackers to escalate privileges or perform other malicious activities. Understanding how IPC works on macOS is crucial for both offensive and defensive security research.
In this section, we will explore various macOS IPC mechanisms, their security implications, and potential abuse scenarios. By gaining insights into IPC, security professionals can better protect macOS systems from potential attacks leveraging IPC vulnerabilities.
</details>
```bash
gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
./inject <pid-of-mysleep> </path/to/lib.dylib>
@ -1065,9 +1056,9 @@ gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
### 기본 정보
XPC는 macOS 및 iOS에서 **프로세스 간 통신**을 위한 XNU( macOS에서 사용되는 커널) 인터프로세스 통신을 나타냅니다. XPC는 시스템 내의 **다른 프로세스 간에 안전한 비동기 메소드 호출을 수행하는 메커니즘**을 제공합니다. 이는 Apple의 보안 패러다임의 일부로, **권한이 분리된 응용 프로그램을 생성**할 수 있게 하며, 각 **구성 요소**가 **수행해야 하는 권한만 가지고** 작동하도록 함으로써, 침해된 프로세스로부터의 잠재적인 피해를 제한합니다.
XPC는 macOS 및 iOS에서 **프로세스 간 통신**을 위한 프레임워크인 XNU( macOS에서 사용되는 커널) Inter-Process Communication의 약자입니다. XPC는 시스템 내에서 **다른 프로세스 간 안전한 비동기 메소드 호출 메커니즘**을 제공합니다. 이는 Apple의 보안 패러다임의 일부로, **권한이 분리된 응용 프로그램을 생성**할 수 있게 하며, 각 **구성 요소**가 **필요한 권한만으로 작동**하도록 하여, 침해된 프로세스로부터의 잠재적인 피해를 제한합니다.
**통신이 작동하는 방식** 및 **취약할 수 있는 방법**에 대한 자세한 정보는 다음을 확인하십시오:
**통신이 작동하는 방식** 및 **취약할 수 있는 방법**에 대한 자세한 정보는 확인하세요:
{% content-ref url="macos-xpc/" %}
[macos-xpc](macos-xpc/)
@ -1075,11 +1066,11 @@ XPC는 macOS 및 iOS에서 **프로세스 간 통신**을 위한 XNU( macOS에
## MIG - Mach Interface Generator
MIG는 Mach IPC 코드 생성 과정을 **간소화**하기 위해 만들어졌습니다. 이는 RPC 프로그래밍에 대부분의 작업이 동일한 작업을 필요로 하기 때문입니다(인수 패킹, 메시지 전송, 서버에서 데이터 언패킹...).
MIG는 Mach IPC 코드 생성 과정을 **간단화**하기 위해 만들어졌습니다. 이는 RPC 프로그래밍에 대한 많은 작업이 동일한 작업(인수 패킹, 메시지 전송, 서버에서 데이터 언패킹...)을 포함하기 때문입니다.
MIG는 기본적으로 서버와 클라이언트가 주어진 정의(IDL -인터페이스 정의 언어-)로 통신할 수 있도록 **필요한 코드를 생성**합니다. 생성된 코드가 어색해도, 개발자는 그것을 가져와서 이전보다 훨씬 간단한 코드를 작성할 수 있습니다.
MIG는 기본적으로 서버와 클라이언트가 주어진 정의(IDL - Interface Definition Language-)로 통신할 수 있도록 **필요한 코드를 생성**합니다. 생성된 코드가 어색하더라도, 개발자는 그것을 가져와서 그 코드가 이전보다 훨씬 간단해질 것입니다.
자세한 정보는 다음을 확인하십시오:
자세한 정보는 확인하세요:
{% content-ref url="macos-mig-mach-interface-generator.md" %}
[macos-mig-mach-interface-generator.md](macos-mig-mach-interface-generator.md)
@ -1092,17 +1083,18 @@ MIG는 기본적으로 서버와 클라이언트가 주어진 정의(IDL -인터
* [https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a](https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a)
* [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
* [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
* [\*OS Internals, Volume I, User Mode, Jonathan Levin](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X)
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로부터 AWS 해킹을 전문가로 배우세요!</summary>
<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에 광고**하거나 **PDF 형식의 HackTricks를 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구하세요
* **회사를 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) 컬렉션
* 💬 [**디스코드 그룹**](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을 제출하세요.
* **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>

View file

@ -2,38 +2,38 @@
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>에서 <strong>제로부터 영웅까지 AWS 해킹 배우기</strong>!</summary>
<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에 광고되길 원하거나 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을 제출하여 **해킹 요령을 공유**하세요.
* **회사가 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) 컬렉션
* **💬 [**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>
## 기본 정보
MIG는 **Mach IPC 코드 생성 과정을 간소화**하기 위해 만들어졌습니다. 기본적으로 서버와 클라이언트가 주어진 정의와 통신할 수 있도록 **필요한 코드를 생성**합니다. 생성된 코드가 어색해 보이더라도, 개발자는 그냥 가져와서 이전보다 훨씬 간단한 코드를 작성할 수 있습니다.
MIG는 Mach IPC 코드 생성 과정을 **간단화**하기 위해 만들어졌습니다. 기본적으로 서버와 클라이언트가 주어진 정의와 통신하기 위해 필요한 코드를 **생성**합니다. 생성된 코드가 어색해 보이더라도 개발자는 그냥 가져와서 이전보다 훨씬 간단한 코드를 작성할 수 있습니다.
정의는 인터페이스 정의 언어(IDL)를 사용하여 `.defs` 확장자 지정됩니다.
정의는 인터페이스 정의 언어(IDL)를 사용하여 `.defs` 확장자를 사용하여 지정됩니다.
이러한 정의에는 5개 섹션이 있습니다:
이러한 정의에는 5개 섹션이 있습니다:
- **서브시스템 선언**: 서브시스템 키워드는 **이름**과 **ID**를 나타내는 데 사용됩니다. 또한 서버가 커널에서 실행야 하는 경우 **`KernelServer`**로 표시할 수도 있습니다.
- **포함 및 임포트**: MIG는 C-프리프로세서를 사용하므로 임포트를 사용할 수 있습니다. 또한 사용자 또는 서버 생성 코드에 대해 `uimport``simport`를 사용할 수 있습니다.
- **유형 선언**: 데이터 유형을 정의할 수 있지만 일반적으로 `mach_types.defs``std_types.defs`를 가져올 것입니다. 사용자 정의 유형의 경우 일부 구문을 사용할 수 있습니다:
- \[i`n/out]tran: 수신 또는 송신 메시지에서 번역해야 하는 함수
- `c[user/server]type`: 다른 C 유형에 매핑
- `destructor`: 유형이 해제될 때 이 함수를 호출
- **작업**: 이들은 RPC 메서드의 정의입니다. 5가지 다른 유형이 있습니다:
- `routine`: 응답을 기대
- `simpleroutine`: 응답을 기대하지 않음
- `procedure`: 응답을 기대
- `simpleprocedure`: 응답을 기대하지 않음
- `function`: 응답을 기대
* **서브시스템 선언**: 서브시스템 키워드는 **이름**과 **ID**를 나타내는 데 사용됩니다. 또한 서버가 커널에서 실행되어야 하는 경우 **`KernelServer`**로 표시할 수도 있습니다.
* **포함 및 가져오기**: MIG는 C-프리프로세서를 사용하므로 가져오기를 사용할 수 있습니다. 또한 사용자 또는 서버 생성 코드에 대해 `uimport``simport`를 사용할 수 있습니다.
* **유형 선언**: 데이터 유형을 정의할 수 있지만 일반적으로 `mach_types.defs``std_types.defs`를 가져올 것입니다. 사용자 정의 유형의 경우 일부 구문을 사용할 수 있습니다:
* \[i`n/out]tran`: 수신 또는 송신 메시지에서 번역해야 하는 함수
* `c[user/server]type`: 다른 C 유형에 매핑
* `destructor`: 유형이 해제될 때 이 함수를 호출합니다.
* **작업**: 이들은 RPC 메서드의 정의입니다. 5가지 다른 유형이 있습니다:
* `routine`: 응답을 기대합니다
* `simpleroutine`: 응답을 기대하지 않습니다
* `procedure`: 응답을 기대합니다
* `simpleprocedure`: 응답을 기대하지 않습니다
* `function`: 응답을 기대합니다
### 예시
@ -56,15 +56,20 @@ n2 : uint32_t);
```
{% endcode %}
첫 번째 **인수는 바인딩할 포트**이며 MIG는 **자동으로 응답 포트를 처리**할 것입니다 (`mig_get_reply_port()`를 클라이언트 코드에서 호출하지 않는 한). 게다가 **작업의 ID**는 지정된 서브시스템 ID부터 시작하는 **연속적**일 것입니다 (따라서 작업이 폐기되면 삭제되고 `skip`이 사용되어 여전히 해당 ID를 사용합니다).
첫 번째 **인수는 바인딩할 포트**이며 MIG는 **자동으로 응답 포트를 처리**합니다 (클라이언트 코드에서 `mig_get_reply_port()`를 호출하지 않는 한). 또한 **작업의 ID**는 지정된 서브시스템 ID부터 시작하는 **연속적**일 것입니다 (따라서 작업이 폐기되면 삭제되고 `skip`이 사용되어 여전히 해당 ID를 사용합니다).
이제 MIG를 사용하여 서버 및 클라이언트 코드를 생성하여 서로 통신하고 Subtract 함수를 호출할 수 있도록 합니다:
이제 MIG를 사용하여 서로 통신할 수 있는 서버 및 클라이언트 코드를 생성하여 Subtract 함수를 호출하십시오:
```bash
mig -header myipcUser.h -sheader myipcServer.h myipc.defs
```
현재 디렉토리에 여러 개의 새 파일이 생성됩니다.
**`myipcServer.c`** 및 **`myipcServer.h`** 파일에는 기본적으로 수신된 메시지 ID에 따라 호출할 함수를 정의하는 **`SERVERPREFmyipc_subsystem`** 구조체의 선언과 정의가 포함되어 있습니다 (시작 번호로 500을 지정했습니다):
{% hint style="success" %}
시스템에서 더 복잡한 예제를 찾을 수 있습니다: `mdfind mach_port.defs`\
그리고 파일이 있는 폴더에서 다음과 같이 컴파일할 수 있습니다: `mig -DLIBSYSCALL_INTERFACE mach_ports.defs`
{% endhint %}
**`myipcServer.c`** 및 **`myipcServer.h`** 파일에서는 **`SERVERPREFmyipc_subsystem`** 구조체의 선언과 정의를 찾을 수 있습니다. 이 구조체는 기본적으로 수신된 메시지 ID에 따라 호출할 함수를 정의합니다 (시작 번호로 500을 지정했습니다):
{% tabs %}
{% tab title="myipcServer.c" %}
@ -85,7 +90,7 @@ myipc_server_routine,
```
{% endtab %}
{% tab title="myipcServer.h" %}서버 코드를 작성하고 IPC를 통해 클라이언트로부터 요청을 수신하는 방법을 보여줍니다. 이 코드는 MIG를 사용하여 IPC를 처리하는 방법을 보여줍니다. 이 예제에서는 `myipc.defs` 파일에 정의된 MIG 함수를 구현합니다. 이 파일은 MIG 컴파일러에 의해 생성됩니다. 서버는 클라이언트로부터 요청을 수신하고 해당 요청에 응답합니다. 이 코드는 macOS에서 IPC를 구현하는 방법을 보여줍니다. {% endtab %}
{% tab title="myipcServer.h" %}서버 코드를 작성하고 IPC를 통해 클라이언트로부터 요청을 수신하는 방법을 보여줍니다. 이 코드는 MIG를 사용하여 Mach RPC를 구현합니다. 클라이언트가 요청을 보내면 서버는 해당 요청을 처리하고 결과를 반환합니다. 이를 통해 프로세스 간 통신을 구현할 수 있습니다.{% endtab %}
```c
/* Description of this subsystem, for use in direct RPC */
extern const struct SERVERPREFmyipc_subsystem {
@ -101,7 +106,7 @@ routine[1];
{% endtab %}
{% endtabs %}
이전 구조를 기반으로 **`myipc_server_routine`** 함수는 **메시지 ID**를 받아 적절한 함수를 호출하여 반환합니다:
이전 구조를 기반으로 **`myipc_server_routine`** 함수는 **메시지 ID**를 받아 적절한 호출할 함수를 반환합니다:
```c
mig_external mig_routine_t myipc_server_routine
(mach_msg_header_t *InHeadP)
@ -118,14 +123,16 @@ return SERVERPREFmyipc_subsystem.routine[msgh_id].stub_routine;
```
이 예제에서는 정의된 함수가 하나뿐이지만, 더 많은 함수를 정의했다면 이들은 **`SERVERPREFmyipc_subsystem`** 배열 내에 있었을 것이며, 첫 번째 함수는 **500** ID에 할당되었을 것이고, 두 번째 함수는 **501** ID에 할당되었을 것입니다...
실제로 이 관계를 **`myipcServer.h`**의 **`subsystem_to_name_map_myipc`** 구조체에서 식별하는 것이 가능합니다:
함수가 **reply**를 보내기를 기대한다면, 함수 `mig_internal kern_return_t __MIG_check__Reply__<name>`도 존재했을 것입니다.
실제로 이 관계를 **`myipcServer.h`**의 **`subsystem_to_name_map_myipc`** 구조체에서 확인할 수 있습니다 (**다른 파일에서는 **`subsystem_to_name_map_***`**):
```c
#ifndef subsystem_to_name_map_myipc
#define subsystem_to_name_map_myipc \
{ "Subtract", 500 }
#endif
```
마지막으로, 서버가 작동하도록 하는 데 중요한 기능 중 하나**`myipc_server`**일 것입니다. 이 함수는 실제로 받은 ID에 관련된 함수를 **호출**할 것입니다:
마지막으로, 서버가 작동하도록 하는 데 중요한 기능 중 하나**`myipc_server`**가 있습니다. 이 함수는 실제로 받은 ID에 관련된 함수를 **호출**할 것입니다:
<pre class="language-c"><code class="lang-c">mig_external boolean_t myipc_server
(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
@ -142,7 +149,7 @@ mig_routine_t routine;
OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0);
OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port;
/* 최소 크기: 다르면 routine()이 업데이트할 것 */
/* 최소 크기: 다르면 routine()에서 업데이트 */
OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
OutHeadP->msgh_local_port = MACH_PORT_NULL;
OutHeadP->msgh_id = InHeadP->msgh_id + 100;
@ -159,9 +166,9 @@ return FALSE;
}
</code></pre>
이전에 강조된 줄을 확인하여 ID에 의해 호출할 함수에 액세스합니다.
이전에 강조된 줄을 확인하여 ID에 따라 호출할 함수에 액세스합니다.
다음은 서버와 클라이언트를 만드는 코드이며, 클라이언트는 서버에서 함수를 호출할 수 있습니다. Subtract:
다음은 서버와 클라이언트를 만들기 위한 코드이며, 클라이언트는 서버에서 함수를 호출할 수 있습니다. 서버에서 Subtract 함수를 호출하는 간단한 **서버****클라이언트** 코드는 다음과 같습니다:
{% tabs %}
{% tab title="myipc_server.c" %}
@ -197,7 +204,7 @@ mach_msg_server(myipc_server, sizeof(union __RequestUnion__SERVERPREFmyipc_subsy
```
{% endtab %}
{% tab title="myipc_client.c" %}번역된 텍스트가 여기에 들어갑니다.
{% tab title="myipc_client.c" %}클라이언트 코드는 서버와 통신하기 위해 `mach_msg()` 함수를 사용합니다. 이 함수는 MIG 생성 코드에서 자동으로 생성된 함수를 호출하는 데 사용됩니다. 클라이언트는 서버에 메시지를 보내고 응답을 받기 위해 이 함수를 사용합니다. 이 코드는 클라이언트 측의 IPC 동작을 보여줍니다.{% endtab %}
```c
// gcc myipc_client.c myipcUser.c -o myipc_client
@ -222,15 +229,36 @@ printf("Port right name %d\n", port);
USERPREFSubtract(port, 40, 2);
}
```
### 이진 분석
{% endtab %}
{% endtabs %}
많은 이진 파일이 이제 MIG를 사용하여 mach 포트를 노출하는데, **MIG가 사용되었는지 식별하는 방법**과 각 메시지 ID별로 **MIG가 실행하는 함수**를 알아내는 것이 흥미로울 수 있습니다.
### NDR\_record
NDR\_record은 `libsystem_kernel.dylib`에 의해 내보내어지며, 시스템에 대해 중립적인 데이터로 변환할 수 있게 해주는 구조체입니다. MIG는 서로 다른 시스템 간에 사용되도록 고안되었기 때문에 동일한 기계에서만 사용되는 것이 아닙니다.
이는 `_NDR_record`가 이진 파일에서 종속성으로 발견된다면 (`jtool2 -S <binary> | grep NDR` 또는 `nm`), 해당 이진 파일이 MIG 클라이언트 또는 서버임을 의미합니다.
또한 **MIG 서버**는 디스패치 테이블을 `__DATA.__const`에 가지고 있습니다 (또는 macOS 커널의 `__CONST.__constdata` 및 다른 \*OS 커널의 `__DATA_CONST.__const`에 있음). 이는 **`jtool2`**를 사용하여 덤프할 수 있습니다.
그리고 **MIG 클라이언트**는 `__mach_msg`로 서버에게 보내기 위해 `__NDR_record`를 사용할 것입니다.
## 이진 분석
### jtool
많은 바이너리가 이제 MIG를 노출하기 위해 mach 포트를 사용하므로, MIG가 사용되었는지 **식별하는 방법**과 각 메시지 ID마다 MIG가 실행하는 **함수를 식별하는 것**을 알아보는 것이 흥미로울 것입니다.
[**jtool2**](../../macos-apps-inspecting-debugging-and-fuzzing/#jtool2)는 Mach-O 이진 파일에서 MIG 정보를 구문 분석하여 메시지 ID를 나타내고 실행할 함수를 식별할 수 있습니다:
```bash
jtool2 -d __DATA.__const myipc_server | grep MIG
```
이전에 **수신된 메시지 ID에 따라 올바른 함수를 호출하는 함수**는 `myipc_server`라고 언급되었습니다. 그러나 보통 이진 파일의 심볼(함수 이름 없음)을 가지고 있지 않기 때문에, **디컴파일된 내용을 확인하는 것이 흥미로울 것**입니다. 이 함수의 코드는 항상 매우 유사할 것입니다(이 함수의 코드는 노출된 함수와 독립적입니다):
게다가, MIG 함수는 호출되는 실제 함수의 래퍼일 뿐이므로, 해당 함수의 어셈블리를 가져와 BL을 찾으면 호출되는 실제 함수를 찾을 수도 있습니다:
```bash
jtool2 -d __DATA.__const myipc_server | grep BL
```
### 어셈블리
이전에 **수신된 메시지 ID에 따라 올바른 함수를 호출하는 함수**는 `myipc_server`라고 언급되었습니다. 그러나 보통 이진 파일의 심볼(함수 이름 없음)을 가지고 있지 않기 때문에, 이 함수가 어떻게 디컴파일된 것처럼 보이는지 **확인하는 것이 흥미로울 것**입니다. (이 함수의 코드는 노출된 함수와 독립적이기 때문에 항상 매우 유사할 것입니다):
{% tabs %}
{% tab title="myipc_server 디컴파일 1" %}
@ -247,12 +275,12 @@ var_18 = arg1;
if (*(int32_t *)(var_10 + 0x14) &#x3C;= 0x1f4 &#x26;&#x26; *(int32_t *)(var_10 + 0x14) >= 0x1f4) {
rax = *(int32_t *)(var_10 + 0x14);
// 이 함수를 식별하는 데 도움이 되는 sign_extend_64 호출
// 이는 호출해야 하는 호출 포인터를 rax에 저장합니다
// 이는 호출해야 하는 호출 지점의 포인터를 rax에 저장
// 주소 0x100004040(함수 주소 배열)의 사용 확인
// 0x1f4 = 500(시작 ID)
// 0x1f4 = 500 (시작 ID)
<strong> rax = *(sign_extend_64(rax - 0x1f4) * 0x28 + 0x100004040);
</strong> var_20 = rax;
// if - else, if는 false를 반환하고 else는 올바른 함수를 호출하고 true를 반환합니다
// if - else, if는 false를 반환하고 else는 올바른 함수를 호출하고 true를 반환
<strong> if (rax == 0x0) {
</strong> *(var_18 + 0x18) = **_NDR_record;
*(int32_t *)(var_18 + 0x20) = 0xfffffffffffffed1;
@ -276,7 +304,7 @@ return rax;
{% endtab %}
{% tab title="myipc_server 디컴파일 2" %}
다른 Hopper 무료 버전에서 동일한 함수가 디컴파일된 내용입니다:
다른 Hopper 무료 버전에서 디컴파일된 동일한 함수입니다:
<pre class="language-c"><code class="lang-c">int _myipc_server(int arg0, int arg1) {
r31 = r31 - 0x40;
@ -308,7 +336,7 @@ r8 = 0x1;
}
if ((r8 &#x26; 0x1) == 0x0) {
r8 = *(int32_t *)(var_10 + 0x14);
// 0x1f4 = 500(시작 ID)
// 0x1f4 = 500 (시작 ID)
<strong> r8 = r8 - 0x1f4;
</strong> asm { smaddl x8, w8, w9, x10 };
r8 = *(r8 + 0x8);
@ -327,7 +355,7 @@ r8 = 0x1;
var_4 = 0x0;
}
else {
// 함수가 있는 주소를 호출하는 호출
// 함수가 있어야 하계산된 주소 호출
<strong> (var_20)(var_10, var_18);
</strong> var_4 = 0x1;
}
@ -357,7 +385,25 @@ return r0;
<figure><img src="../../../../.gitbook/assets/image (36).png" alt=""><figcaption></figcaption></figure>
이 데이터는 [**이 Hopper 스크립트**](https://github.com/knightsc/hopper/blob/master/scripts/MIG%20Detect.py)를 사용하여 추출할 수 있습니다.
* **HackTricks** 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 저장소에 PR을 제출하여 해킹 기법을 공유하세요.
이 데이터는 [**이 Hopper 스크립트를 사용하여**](https://github.com/knightsc/hopper/blob/master/scripts/MIG%20Detect.py) 추출할 수 있습니다.
### 디버그
MIG에 의해 생성된 코드는 또한 `kernel_debug`를 호출하여 진입 및 종료에 대한 작업 로그를 생성합니다. **`trace`** 또는 **`kdv`**를 사용하여 이를 확인할 수 있습니다: `kdv all | grep MIG`
## 참고 자료
* [\*OS Internals, Volume I, User Mode, Jonathan Levin](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X)
<details>
<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에 광고되길 원하거나** **PDF 형식의 HackTricks를 다운로드하고 싶다면** [**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) 컬렉션
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>