mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 20:53:37 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
f100364187
commit
d4fac87507
2 changed files with 191 additions and 119 deletions
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요!</summary>
|
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로**부터 **히어로**까지 AWS 해킹을 배우세요!</summary>
|
||||||
|
|
||||||
HackTricks를 지원하는 다른 방법:
|
HackTricks를 지원하는 다른 방법:
|
||||||
|
|
||||||
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
* **회사를 HackTricks에서 광고**하거나 **PDF로 HackTricks 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구입하세요
|
* [**공식 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) 컬렉션
|
* [**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)를 **팔로우**하세요.
|
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소로 **PR 제출**을 통해 여러분의 해킹 기술을 공유하세요.
|
* **HackTricks** 및 **HackTricks Cloud** github 저장소로 PR을 제출하여 **해킹 트릭을 공유**하세요.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ HackTricks를 지원하는 다른 방법:
|
||||||
|
|
||||||
### 기본 정보
|
### 기본 정보
|
||||||
|
|
||||||
Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하며, 각 작업은 **여러 스레드**를 포함할 수 있습니다. 이러한 **작업과 스레드는 1:1로 POSIX 프로세스와 스레드에 매핑**됩니다.
|
Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하며, 각 작업에는 **여러 스레드**가 포함될 수 있습니다. 이러한 **작업 및 스레드는 1:1로 POSIX 프로세스 및 스레드에 매핑**됩니다.
|
||||||
|
|
||||||
작업 간 통신은 Mach Inter-Process Communication (IPC)을 통해 발생하며, 일방향 통신 채널을 활용합니다. **메시지는 포트 간에 전송**되며, 이는 커널에서 관리되는 **메시지 큐와 유사한 역할**을 합니다.
|
작업 간 통신은 Mach Inter-Process Communication (IPC)을 통해 발생하며, **일방향 통신 채널**을 활용합니다. **메시지는 포트 간에 전송**되며, 이는 커널에서 관리되는 **메시지 큐**와 같은 역할을 합니다.
|
||||||
|
|
||||||
**포트**는 Mach IPC의 **기본 요소**입니다. 메시지를 **보내고 받는 데 사용**할 수 있습니다.
|
**포트**는 Mach IPC의 **기본 요소**입니다. 메시지를 **보내고 받는 데 사용**할 수 있습니다.
|
||||||
|
|
||||||
|
@ -32,18 +32,18 @@ Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하
|
||||||
|
|
||||||
작업이 수행할 수 있는 작업을 정의하는 포트 권한은 이 통신에 중요합니다. 가능한 **포트 권한**은 ([여기에서 정의된 내용](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
|
작업이 수행할 수 있는 작업을 정의하는 포트 권한은 이 통신에 중요합니다. 가능한 **포트 권한**은 ([여기에서 정의된 내용](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
|
||||||
|
|
||||||
* **수신 권한**은 포트로 전송된 메시지를 수신할 수 있게 합니다. Mach 포트는 MPSC (다중 생산자, 단일 소비자) 큐이므로 전체 시스템에서 각 포트에 대해 **하나의 수신 권한만** 있을 수 있습니다 (여러 프로세스가 하나의 파이프의 읽기 끝에 대한 파일 디스크립터를 모두 보유할 수 있는 파이프와는 달리).
|
* **수신 권한**은 포트로 보낸 메시지를 수신할 수 있게 합니다. Mach 포트는 MPSC (다중 생산자, 단일 소비자) 큐이므로 전체 시스템에서 각 포트에 대해 **하나의 수신 권한만 있을 수** 있습니다 (여러 프로세스가 하나의 파이프의 읽기 끝에 대한 파일 디스크립터를 모두 보유할 수 있는 파이프와는 달리).
|
||||||
* **수신 권한을 가진 작업**은 메시지를 수신하고 **보내기 권한을 생성**할 수 있으며, 처음에는 **자체 작업만이 포트에 대한 수신 권한**을 가지고 있었습니다.
|
* **수신 권한을 가진 작업**은 메시지를 수신하고 **보내기 권한을 생성**할 수 있으며, 처음에는 **자체 작업만 수신 권한을 가집니다**.
|
||||||
* 수신 권한의 소유자가 **죽거나 종료**하면 **보내기 권한이 무용지물이 됩니다 (데드 네임).**
|
* 수신 권한의 소유자가 **죽거나 종료**하면 **보내기 권한이 무용지물이 됩니다(데드 네임).**
|
||||||
* **보내기 권한**은 포트로 메시지를 보낼 수 있게 합니다.
|
* **보내기 권한**은 포트로 메시지를 보낼 수 있게 합니다.
|
||||||
* 보내기 권한은 **복제**될 수 있어서 보내기 권한을 가진 작업이 권한을 복제하고 **제3 작업에게 부여**할 수 있습니다.
|
* 보내기 권한은 **복제**될 수 있어서 보내기 권한을 가진 작업이 권한을 복제하고 **제3의 작업에게 부여**할 수 있습니다.
|
||||||
* **포트 권한**은 Mac 메시지를 통해 **전달**될 수도 있습니다.
|
* **포트 권한**은 Mac 메시지를 통해 **전달**될 수도 있습니다.
|
||||||
* **한 번 보내기 권한**은 포트로 한 번의 메시지를 보낼 수 있고 그 후 사라집니다.
|
* **한 번 보내기 권한**은 포트로 한 번의 메시지를 보낼 수 있고 그 후 사라집니다.
|
||||||
* 이 권한은 **복제**될 수 없지만 **이동**될 수 있습니다.
|
* 이 권한은 **복제**될 수 없지만 **이동**될 수 있습니다.
|
||||||
* **포트 세트 권한**은 단일 포트가 아닌 _포트 세트_를 나타냅니다. 포트 세트에서 메시지를 디큐하는 것은 그 포트가 포함하는 포트 중 하나에서 메시지를 디큐합니다. 포트 세트는 Unix의 `select`/`poll`/`epoll`/`kqueue`와 매우 유사하게 여러 포트에서 동시에 수신할 수 있습니다.
|
* **포트 집합 권한**은 단일 포트가 아닌 _포트 세트_를 나타냅니다. 포트 세트에서 메시지를 디큐하는 것은 그 포트가 포함하는 포트 중 하나에서 메시지를 디큐합니다. 포트 세트는 Unix의 `select`/`poll`/`epoll`/`kqueue`와 매우 유사하게 여러 포트에서 동시에 수신할 수 있습니다.
|
||||||
* **데드 네임**은 실제 포트 권한이 아니라 단순히 자리 표시자입니다. 포트가 파괴되면 포트에 대한 모든 기존 포트 권한이 데드 네임으로 변합니다.
|
* **데드 네임**은 실제 포트 권한이 아니라 단순히 자리 표시자입니다. 포트가 파괴되면 포트에 대한 모든 기존 포트 권한이 데드 네임으로 변합니다.
|
||||||
|
|
||||||
**작업은 SEND 권한을 다른 작업에게 전달**하여 다시 메시지를 보낼 수 있게 합니다. **SEND 권한은 복제**될 수 있어서 작업이 권한을 복제하고 **제3 작업에게 권한을 부여**할 수 있습니다. 이는 **부트스트랩 서버**라는 중간 프로세스와 결합되어 작업 간 효과적인 통신을 가능하게 합니다.
|
**작업은 SEND 권한을 다른 작업에게 전달**하여 메시지를 다시 보낼 수 있습니다. **SEND 권한은 복제**될 수 있기 때문에 작업은 권한을 복제하고 **제3의 작업에게 권한을 부여**할 수 있습니다. 이는 **부트스트랩 서버**라는 중간 프로세스와 결합되어 작업 간 효과적인 통신을 가능케 합니다.
|
||||||
|
|
||||||
### 파일 포트
|
### 파일 포트
|
||||||
|
|
||||||
|
@ -53,29 +53,29 @@ Mach는 **작업**을 **리소스 공유의 가장 작은 단위**로 사용하
|
||||||
|
|
||||||
이전에 언급했듯이 Mach 메시지를 사용하여 권한을 보낼 수 있지만, 이미 Mach 메시지를 보낼 권한이 없는 경우 **권한을 보낼 수 없습니다**. 그렇다면 첫 번째 통신은 어떻게 설정됩니까?
|
이전에 언급했듯이 Mach 메시지를 사용하여 권한을 보낼 수 있지만, 이미 Mach 메시지를 보낼 권한이 없는 경우 **권한을 보낼 수 없습니다**. 그렇다면 첫 번째 통신은 어떻게 설정됩니까?
|
||||||
|
|
||||||
이를 위해 **부트스트랩 서버**(**mac의 launchd**)가 관여되며, **누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있으므로**, 다른 프로세스에게 메시지를 보낼 권한을 요청할 수 있습니다:
|
이를 위해 **부트스트랩 서버**(mac의 **launchd**)가 관여됩니다. **누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있으므로**, 다른 프로세스에 메시지를 보낼 권한을 요청할 수 있습니다:
|
||||||
|
|
||||||
1. 작업 **A**는 **새 포트**를 생성하여 **그것에 대한 수신 권한**을 얻습니다.
|
1. 작업 **A**는 **새 포트**를 생성하여 **그것에 대한 수신 권한**을 얻습니다.
|
||||||
2. 수신 권한을 보유한 작업 **A**는 **포트에 대한 SEND 권한을 생성**합니다.
|
2. 수신 권한의 소유자인 작업 **A**는 **포트에 대한 SEND 권한을 생성**합니다.
|
||||||
3. 작업 **A**는 **부트스트랩 서버**와 **연결**을 설정하고, 처음에 생성한 포트에 대한 **SEND 권한을 부트스트랩 서버에 보냅니다**.
|
3. 작업 **A**는 **부트스트랩 서버**와 **연결**을 설정하고, 처음에 생성한 포트에 대한 **SEND 권한을 부트스트랩 서버에 보냅니다**.
|
||||||
* 누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있습니다.
|
* 누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있습니다.
|
||||||
4. 작업 A는 부트스트랩 서버에 `bootstrap_register` 메시지를 보내 **주어진 포트를 `com.apple.taska`와 같은 이름과 연결**합니다.
|
4. 작업 A는 부트스트랩 서버에 `bootstrap_register` 메시지를 보내 **`com.apple.taska`**와 같은 이름으로 주어진 포트를 **연결**합니다.
|
||||||
5. 작업 **B**는 **부트스트랩 서버**와 상호 작용하여 서비스 이름에 대한 부트스트랩 **조회를 실행**합니다 (`bootstrap_lookup`). 따라서 부트스트랩 서버가 응답하려면 작업 B는 조회 메시지 내에서 **이전에 생성한 포트에 대한 SEND 권한을 부트스트랩 서버에 보냅니다**. 조회가 성공하면 부트스트랩 서버는 작업 A로부터 받은 SEND 권한을 **복제**하고 **작업 B에게 전송**합니다.
|
5. 작업 **B**는 서비스 이름에 대한 부트스트랩 **룩업**을 실행하기 위해 **부트스트랩 서버**와 상호 작용합니다(`bootstrap_lookup`). 따라서 부트스트랩 서버가 응답하려면 작업 B는 룩업 메시지 내에서 이전에 생성한 **포트에 대한 SEND 권한을 부트스트랩 서버에 보냅니다**. 룩업이 성공하면 부트스트랩 서버는 작업 A로부터 받은 SEND 권한을 **복제**하고 **작업 B에게 전송**합니다.
|
||||||
* 누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있습니다.
|
* 누구나 부트스트랩 서버에 SEND 권한을 얻을 수 있습니다.
|
||||||
6. 이 SEND 권한으로 **작업 B**는 **작업 A에게 메시지를 보낼 수 있습니다**.
|
6. 이 SEND 권한으로 **작업 B**는 **작업 A에게 메시지를 보낼 수 있습니다**.
|
||||||
7. 양방향 통신을 위해 일반적으로 작업 **B**는 **수신** 권한과 **보내기** 권한이 있는 새 포트를 생성하고 **보내기 권한을 작업 A에게 주어서 작업 B에게 메시지를 보낼 수 있게 합니다** (양방향 통신).
|
7. 양방향 통신을 위해 일반적으로 작업 **B**는 **수신** 권한과 **보내기** 권한이 있는 새 포트를 생성하고 **보내기 권한을 작업 A에게 제공**하여 작업 B에게 메시지를 보낼 수 있게 합니다.
|
||||||
|
|
||||||
부트스트랩 서버는 작업이 주장한 서비스 이름을 인증할 수 없습니다. 이는 **작업**이 잠재적으로 **시스템 작업을 가장할 수 있음**을 의미합니다. 예를 들어 권한 서비스 이름을 가장하고 모든 요청을 승인할 수 있습니다.
|
부트스트랩 서버는 작업이 주장하는 서비스 이름을 인증할 수 없습니다. 이는 **작업**이 잠재적으로 **시스템 작업을 가장할 수 있음**을 의미합니다. 즉, 권한 서비스 이름을 가장하고 모든 요청을 승인할 수 있습니다.
|
||||||
|
|
||||||
그런 다음 Apple은 시스템 제공 서비스의 이름을 안전한 구성 파일에 저장합니다. 이 파일은 SIP로 보호된 디렉토리인 `/System/Library/LaunchDaemons` 및 `/System/Library/LaunchAgents`에 있습니다. 각 서비스 이름 옆에는 **관련된 이진 파일도 저장**됩니다. 부트스트랩 서버는 이러한 서비스 이름 각각에 대한 **수신 권한을 생성하고 보유**합니다.
|
그런 다음, Apple은 **시스템 제공 서비스의 이름**을 안전한 구성 파일에 저장합니다. 이 파일은 **SIP로 보호된** 디렉토리인 `/System/Library/LaunchDaemons` 및 `/System/Library/LaunchAgents`에 있습니다. 각 서비스 이름 옆에는 **관련된 이진 파일도 저장**됩니다. 부트스트랩 서버는 이러한 서비스 이름 각각에 대한 **수신 권한을 생성하고 보유**합니다.
|
||||||
|
|
||||||
이러한 사전 정의된 서비스의 경우 **조회 프로세스가 약간 다릅니다**. 서비스 이름을 조회할 때, launchd는 서비스를 동적으로 시작합니다. 새로운 워크플로우는 다음과 같습니다:
|
이러한 사전 정의된 서비스에 대해서는 **룩업 프로세스가 약간 다릅니다**. 서비스 이름을 찾을 때, launchd는 서비스를 동적으로 시작합니다. 새로운 워크플로우는 다음과 같습니다:
|
||||||
|
|
||||||
* 작업 **B**는 서비스 이름에 대한 부트스트랩 **조회**를 시작합니다.
|
* 작업 **B**는 서비스 이름에 대한 부트스트랩 **룩업**을 시작합니다.
|
||||||
* **launchd**는 작업이 실행 중인지 확인하고 실행 중이 아니면 **시작**합니다.
|
* **launchd**는 작업이 실행 중인지 확인하고 실행 중이 아니면 **시작**합니다.
|
||||||
* 작업 **A** (서비스)는 **부트스트랩 체크인**(`bootstrap_check_in()`)을 수행합니다. 여기서 **부트스트랩** 서버는 SEND 권한을 생성하고 보유하며 **수신 권한을 작업 A에게 전송**합니다.
|
* 작업 **A**(서비스)는 **부트스트랩 체크인**(`bootstrap_check_in()`)을 수행합니다. 여기서 **부트스트랩** 서버는 SEND 권한을 생성하고 보유하며 **수신 권한을 작업 A에게 전송**합니다.
|
||||||
* launchd는 **SEND 권한을 복제하고 작업 B에게 전송**합니다.
|
* launchd는 **SEND 권한을 복제하고 작업 B에게 전송**합니다.
|
||||||
* 작업 **B**는 **수신** 권한과 **보내기** 권한이 있는 새 포트를 생성하고 **보내기 권한을 작업 A**에게 주어서 작업 B에게 메시지를 보낼 수 있게 합니다 (양방향 통신).
|
* 작업 **B**는 **수신** 권한과 **보내기** 권한이 있는 새 포트를 생성하고 **보내기 권한을 작업 A**(svc)에게 제공하여 작업 B에게 메시지를 보낼 수 있게 합니다.
|
||||||
|
|
||||||
그러나 이 프로세스는 사전 정의된 시스템 작업에만 적용됩니다. 비시스템 작업은 여전히 처음에 설명한 대로 작동하며, 이는 가장할 수 있는 가능성을 열어둘 수 있습니다.
|
그러나 이 프로세스는 사전 정의된 시스템 작업에만 적용됩니다. 비시스템 작업은 여전히 처음에 설명한 대로 작동하며, 이는 가장할 수 있는 가능성을 열어둘 수 있습니다.
|
||||||
|
|
||||||
|
@ -97,17 +97,17 @@ mach_port_name_t msgh_voucher_port;
|
||||||
mach_msg_id_t msgh_id;
|
mach_msg_id_t msgh_id;
|
||||||
} mach_msg_header_t;
|
} mach_msg_header_t;
|
||||||
```
|
```
|
||||||
프로세스가 _**수신 권한**_을 가지고 있으면 Mach 포트에서 메시지를 수신할 수 있습니다. 반대로 **보내는 쪽**은 _**보내기**_ 또는 _**한 번 보내기 권한**_을 부여받습니다. 한 번 보내기 권한은 한 번의 메시지를 보낸 후에 무효화됩니다.
|
프로세스가 _**수신 권한**_을 가지고 있으면 Mach 포트에서 메시지를 수신할 수 있습니다. 반대로 **보내는 쪽(sender)**은 _**송신 권한**_ 또는 _**일회용 송신 권한**_을 부여받습니다. 일회용 송신 권한은 한 번의 메시지를 보낸 후에 무효화됩니다.
|
||||||
|
|
||||||
초기 필드 **`msgh_bits`**는 비트맵입니다:
|
초기 필드 **`msgh_bits`**는 비트맵입니다:
|
||||||
|
|
||||||
* 첫 번째 비트(가장 중요함)는 메시지가 복잡함을 나타내는 데 사용됩니다(자세한 내용은 아래 참조)
|
* 첫 번째 비트(가장 중요함)는 메시지가 복잡함을 나타내는 데 사용됩니다(자세한 내용은 아래 참조)
|
||||||
* 3번째와 4번째는 커널에 의해 사용됩니다
|
* 3번째와 4번째는 커널에서 사용됩니다
|
||||||
* 2번 바이트의 **가장 낮은 5개 비트**는 **바우처**(key/value 조합을 보내는 또 다른 유형의 포트)에 사용할 수 있습니다.
|
* 두 번째 바이트의 **가장 낮은 5개 비트**는 **바우처(voucher)**에 사용될 수 있습니다: 키/값 조합을 보내는 또 다른 유형의 포트입니다.
|
||||||
* 3번 바이트의 **가장 낮은 5개 비트**는 **로컬 포트**에 사용할 수 있습니다.
|
* 세 번째 바이트의 **가장 낮은 5개 비트**는 **로컬 포트**에 사용될 수 있습니다.
|
||||||
* 4번 바이트의 **가장 낮은 5개 비트**는 **원격 포트**에 사용할 수 있습니다.
|
* 네 번째 바이트의 **가장 낮은 5개 비트**는 **원격 포트**에 사용될 수 있습니다.
|
||||||
|
|
||||||
바우처, 로컬 및 원격 포트에 지정할 수 있는 유형은 [**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
|
```c
|
||||||
#define MACH_MSG_TYPE_MOVE_RECEIVE 16 /* Must hold receive right */
|
#define MACH_MSG_TYPE_MOVE_RECEIVE 16 /* Must hold receive right */
|
||||||
#define MACH_MSG_TYPE_MOVE_SEND 17 /* Must hold send right(s) */
|
#define MACH_MSG_TYPE_MOVE_SEND 17 /* Must hold send right(s) */
|
||||||
|
@ -120,9 +120,9 @@ mach_msg_id_t msgh_id;
|
||||||
#define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */
|
#define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */
|
||||||
#define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26 /* must hold sendonce right */
|
#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" %}
|
{% 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`), **일반적으로 서로 다른 포트가 생성**되어 양방향 통신을 생성하는 방법에 대해 이전에 설명한 대로 사용됩니다.
|
||||||
|
@ -130,22 +130,22 @@ mach_msg_id_t msgh_id;
|
||||||
|
|
||||||
메시지 헤더의 다른 필드는 다음과 같습니다:
|
메시지 헤더의 다른 필드는 다음과 같습니다:
|
||||||
|
|
||||||
* `msgh_size`: 전체 패킷의 크기.
|
- `msgh_size`: 전체 패킷의 크기.
|
||||||
* `msgh_remote_port`: 이 메시지가 전송된 포트.
|
- `msgh_remote_port`: 이 메시지가 전송된 포트.
|
||||||
* `msgh_voucher_port`: [mach 바우처](https://robert.sesek.com/2023/6/mach\_vouchers.html).
|
- `msgh_voucher_port`: [mach 바우처](https://robert.sesek.com/2023/6/mach\_vouchers.html).
|
||||||
* `msgh_id`: 이 메시지의 ID로, 수신자에 의해 해석됩니다.
|
- `msgh_id`: 이 메시지의 ID로, 수신자에 의해 해석됩니다.
|
||||||
|
|
||||||
{% hint style="danger" %}
|
{% hint style="danger" %}
|
||||||
**mach 메시지는 `mach 포트`를 통해 전송**되며, 이는 mach 커널에 내장된 **단일 수신자**, **다중 송신자** 통신 채널입니다. **여러 프로세스**가 mach 포트로 **메시지를 보낼** 수 있지만 언제든지 **단일 프로세스만** 읽을 수 있습니다.
|
**mach 메시지는 `mach 포트`를 통해 전송**되며, 이는 mach 커널에 내장된 **단일 수신자**, **다중 송신자** 통신 채널입니다. **여러 프로세스**가 mach 포트로 **메시지를 보낼** 수 있지만 언제든지 **단일 프로세스만** 읽을 수 있습니다.
|
||||||
{% endhint %}
|
{% 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
|
```c
|
||||||
|
@ -167,12 +167,12 @@ mach_msg_descriptor_type_t type : 8;
|
||||||
### 32비트에서는 모든 디스크립터가 12B이며 디스크립터 유형은 11번째에 있습니다. 64비트에서는 크기가 다양합니다.
|
### 32비트에서는 모든 디스크립터가 12B이며 디스크립터 유형은 11번째에 있습니다. 64비트에서는 크기가 다양합니다.
|
||||||
|
|
||||||
{% hint style="danger" %}
|
{% hint style="danger" %}
|
||||||
커널은 다른 작업으로 디스크립터를 복사하지만 먼저 **커널 메모리에 복사본을 생성**합니다. 이 "Feng Shui" 기술은 여러 악용으로 **커널이 자신의 메모리에 데이터를 복사**하도록 만들어 프로세스가 자신에게 디스크립터를 보낼 수 있게 합니다. 그런 다음 프로세스는 메시지를 수신할 수 있습니다 (커널이 이를 해제합니다).
|
커널은 다른 작업으로 디스크립터를 복사하지만 먼저 **커널 메모리에 복사본을 생성**합니다. 이 "Feng Shui" 기술은 여러 악용으로 커널이 데이터를 자체 메모리에 복사하도록 만들어 프로세스가 자신에게 디스크립터를 보낼 수 있게 합니다. 그런 다음 프로세스는 메시지를 수신할 수 있습니다 (커널이 이를 해제합니다).
|
||||||
|
|
||||||
취약한 프로세스로 **포트 권한을 보낼 수도** 있으며, 포트 권한은 프로세스에 나타날 것입니다 (그가 처리하고 있지 않더라도).
|
취약한 프로세스로 **포트 권한을 보낼 수도 있으며**, 포트 권한은 프로세스에 나타날 것입니다 (그가 처리하지 않더라도).
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
### Mac Ports APIs
|
### Mac Ports API
|
||||||
|
|
||||||
포트는 작업 네임스페이스에 연결되므로 포트를 생성하거나 검색하려면 작업 네임스페이스도 쿼리됩니다 (`mach/mach_port.h`에서 자세히 설명):
|
포트는 작업 네임스페이스에 연결되므로 포트를 생성하거나 검색하려면 작업 네임스페이스도 쿼리됩니다 (`mach/mach_port.h`에서 자세히 설명):
|
||||||
|
|
||||||
|
@ -183,15 +183,15 @@ mach_msg_descriptor_type_t type : 8;
|
||||||
* `mach_port_type`: 이름에 대한 작업의 권한 가져오기
|
* `mach_port_type`: 이름에 대한 작업의 권한 가져오기
|
||||||
* `mach_port_rename`: 포트의 이름 바꾸기 (FD의 dup2와 유사)
|
* `mach_port_rename`: 포트의 이름 바꾸기 (FD의 dup2와 유사)
|
||||||
* `mach_port_allocate`: 새로운 RECEIVE, PORT\_SET 또는 DEAD\_NAME 할당
|
* `mach_port_allocate`: 새로운 RECEIVE, PORT\_SET 또는 DEAD\_NAME 할당
|
||||||
* `mach_port_insert_right`: 수신할 수 있는 포트에 새 권한 생성
|
* `mach_port_insert_right`: 수신 권한이 있는 포트에 새 권한 생성
|
||||||
* `mach_port_...`
|
* `mach_port_...`
|
||||||
* **`mach_msg`** | **`mach_msg_overwrite`**: **mach 메시지를 보내고 받는** 데 사용되는 함수입니다. 덮어쓰기 버전은 메시지 수신을 위한 다른 버퍼를 지정할 수 있게 합니다 (다른 버전은 그냥 재사용합니다).
|
* **`mach_msg`** | **`mach_msg_overwrite`**: **mach 메시지를 보내고 받는** 데 사용되는 함수입니다. 덮어쓰기 버전은 메시지 수신을 위한 다른 버퍼를 지정할 수 있습니다 (다른 버전은 그냥 재사용합니다).
|
||||||
|
|
||||||
### Debug mach\_msg
|
### 디버그 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
|
<pre class="language-armasm"><code class="lang-armasm"><strong>(lldb) b mach_msg
|
||||||
</strong>Breakpoint 1: where = libsystem_kernel.dylib`mach_msg, address = 0x00000001803f6c20
|
</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&) const::$_0::operator()() const + 168
|
frame #9: 0x0000000181a1d5c8 dyld`invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const::$_0::operator()() const + 168
|
||||||
</code></pre>
|
</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
|
```c
|
||||||
__WATCHOS_PROHIBITED __TVOS_PROHIBITED
|
__WATCHOS_PROHIBITED __TVOS_PROHIBITED
|
||||||
extern mach_msg_return_t mach_msg(
|
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)
|
x5 = 0x0000000000000000 ;mach_msg_timeout_t (timeout)
|
||||||
x6 = 0x0000000000000000 ;mach_port_name_t (notify)
|
x6 = 0x0000000000000000 ;mach_port_name_t (notify)
|
||||||
```
|
```
|
||||||
첫 번째 인수를 확인하여 메시지 헤더를 검사하십시오.
|
첫 번째 인수를 확인하여 메시지 헤더를 검사하십시오:
|
||||||
```armasm
|
```armasm
|
||||||
(lldb) x/6w $x0
|
(lldb) x/6w $x0
|
||||||
0x124e04ce8: 0x00131513 0x00000388 0x00000807 0x00001f03
|
0x124e04ce8: 0x00131513 0x00000388 0x00000807 0x00001f03
|
||||||
|
@ -256,7 +256,7 @@ x6 = 0x0000000000000000 ;mach_port_name_t (notify)
|
||||||
; 0x00000b07 -> mach_port_name_t (msgh_voucher_port)
|
; 0x00000b07 -> mach_port_name_t (msgh_voucher_port)
|
||||||
; 0x40000322 -> mach_msg_id_t (msgh_id)
|
; 0x40000322 -> mach_msg_id_t (msgh_id)
|
||||||
```
|
```
|
||||||
그 유형의 `mach_msg_bits_t`는 응답을 허용하기 위해 매우 일반적입니다.
|
그 유형의 `mach_msg_bits_t`는 응답을 허용하는 데 매우 일반적입니다.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,16 +285,18 @@ name ipc-object rights flags boost reqs recv send sonce oref q
|
||||||
[...]
|
[...]
|
||||||
```
|
```
|
||||||
**이름**은 포트에 지정된 기본 이름입니다 (첫 3바이트에서 **증가**하는 방법을 확인하십시오). **`ipc-object`**는 포트의 **가려진** 고유 **식별자**입니다.\
|
**이름**은 포트에 지정된 기본 이름입니다 (첫 3바이트에서 **증가**하는 방법을 확인하십시오). **`ipc-object`**는 포트의 **가려진** 고유 **식별자**입니다.\
|
||||||
또한 **`send`** 권한만 있는 포트는 해당 소유자를 **식별**하는 방법을 주목하십시오 (포트 이름 + pid).\
|
또한 **`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
|
procesp 1 ports
|
||||||
```
|
```
|
||||||
|
iOS에서 이 도구를 설치하려면 [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)에서 다운로드할 수 있습니다.
|
||||||
|
|
||||||
### 코드 예시
|
### 코드 예시
|
||||||
|
|
||||||
**sender**가 포트를 할당하고 `org.darlinghq.example`라는 이름에 대한 **send right**를 생성하여 **부트스트랩 서버**로 보내는 방법에 주목하십시오. 수신자는 해당 이름에 대한 **send right**를 요청하고 이를 사용하여 **메시지를 보내는** 방법을 사용했습니다.
|
**sender**가 포트를 할당하고 `org.darlinghq.example` 이름에 대한 **send right**를 생성하여 이를 **부트스트랩 서버**에 보낸 것에 주목하십시오. 수신자는 해당 이름에 대한 **send right**를 요청하고 이를 사용하여 **메시지를 보냈습니다**.
|
||||||
|
|
||||||
{% tabs %}
|
{% tabs %}
|
||||||
{% tab title="receiver.c" %}
|
{% tab title="receiver.c" %}
|
||||||
|
@ -365,7 +367,31 @@ printf("Text: %s, number: %d\n", message.some_text, message.some_number);
|
||||||
```
|
```
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="sender.c" %}sender.c 파일{% endtab %}
|
{% tab title="sender.c" %}
|
||||||
|
## macOS Inter-Process Communication (IPC)
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
{% endtab %}
|
||||||
```c
|
```c
|
||||||
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
|
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
|
||||||
// gcc sender.c -o sender
|
// gcc sender.c -o sender
|
||||||
|
@ -422,20 +448,20 @@ printf("Sent a message\n");
|
||||||
|
|
||||||
### 특권 포트
|
### 특권 포트
|
||||||
|
|
||||||
* **호스트 포트**: 프로세스가이 포트에 대한 **Send** 권한을 갖고 있으면 **시스템에 대한 정보**를 얻을 수 있습니다 (예 : `host_processor_info`).
|
* **호스트 포트**: 프로세스가 이 포트에 대한 **Send** 권한을 가지고 있으면 **시스템에 대한 정보**를 얻을 수 있습니다 (예: `host_processor_info`).
|
||||||
* **호스트 priv 포트**: 이 포트에 대한 **Send** 권한이있는 프로세스는 커널 확장 프로그램을로드하는 것과 같은 **특권 작업**을 수행 할 수 있습니다. **이 권한을 얻으려면 루트 여야합니다**.
|
* **호스트 특권 포트**: 이 포트에 대한 **Send** 권한을 가진 프로세스는 커널 익스텐션을 로드하는 등 **특권 작업**을 수행할 수 있습니다. 이 권한을 얻으려면 **프로세스가 루트여야** 합니다.
|
||||||
* 또한 **`kext_request`** API를 호출하려면 다른 엔타이틀먼트 **`com.apple.private.kext*`**가 필요하며이는 Apple 이진 파일에만 제공됩니다.
|
* 또한 **`kext_request`** API를 호출하려면 다른 엔타이틀먼트 **`com.apple.private.kext*`**가 필요하며, 이는 Apple 이진 파일에만 부여됩니다.
|
||||||
* **작업 이름 포트**: _작업 포트_의 특권이없는 버전입니다. 작업을 참조하지만 제어하지는 않습니다. 이를 통해 사용할 수있는 유일한 것은 `task_info()`입니다.
|
* **태스크 이름 포트**: _태스크 포트_의 특권이 없는 버전입니다. 태스크를 참조하지만 제어할 수는 없습니다. 이를 통해 사용할 수 있는 유일한 것은 `task_info()`입니다.
|
||||||
* **작업 포트** (또는 커널 포트)**:**이 포트에 대한 Send 권한이있으면 작업을 제어 할 수 있습니다 (메모리 읽기 / 쓰기, 스레드 생성 등).
|
* **태스크 포트** (또는 커널 포트)**:** 이 포트에 대한 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 이진 파일에서도 특별한 경우로 태스크는 새로운 태스크 포트를 받습니다). 태스크를 생성하고 해당 포트를 가져오는 유일한 방법은 `fork()`를 수행하는 동안 ["포트 스왑 댄스"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html)를 수행하는 것입니다.
|
||||||
* 이 포트에 액세스하는 제한 사항 (바이너리 `AppleMobileFileIntegrity`의 `macos_task_policy`에서):
|
* 이 포트에 액세스하는 제한 사항은 (`AppleMobileFileIntegrity` 바이너리의 `macos_task_policy`에서):
|
||||||
* 앱에 **`com.apple.security.get-task-allow` 엔틀리먼트**가있는 경우 **동일한 사용자의 프로세스가 작업 포트에 액세스** 할 수 있습니다 (주로 디버깅을위한 Xcode에서 추가). **노타리제이션** 프로세스는 프로덕션 릴리스에 대해 허용하지 않습니다.
|
* 앱이 **`com.apple.security.get-task-allow` 엔타이틀먼트**를 가지고 있으면 **동일한 사용자의 프로세스가** 태스크 포트에 액세스할 수 있습니다 (주로 디버깅을 위해 Xcode에서 추가됨). **노타리제이션** 프로세스는 프로덕션 릴리스에서 이를 허용하지 않습니다.
|
||||||
* **`com.apple.system-task-ports`** 엔틀리먼트가있는 앱은 커널을 제외한 **모든** 프로세스의 **작업 포트를 얻을 수 있습니다**. 이전 버전에서는 **`task_for_pid-allow`**라고 불렸습니다. 이것은 Apple 애플리케이션에만 부여됩니다.
|
* **`com.apple.system-task-ports`** 엔타이틀먼트가 있는 앱은 커널을 제외한 **모든** 프로세스의 **태스크 포트를 얻을 수 있습니다**. 이전 버전에서는 **`task_for_pid-allow`**로 불렸습니다. 이 권한은 Apple 애플리케이션에만 부여됩니다.
|
||||||
* **루트는** **하드닝 된** 런타임으로 컴파일되지 않은 응용 프로그램의 작업 포트에 액세스 할 수 있습니다 (Apple에서 제공하지 않음).
|
* **루트는** **하드닝된** 런타임으로 컴파일되지 않은 애플리케이션의 **태스크 포트에 액세스**할 수 있습니다 (Apple에서 제공되지 않음).
|
||||||
|
|
||||||
### 작업 포트를 통한 스레드 내 셸코드 삽입
|
### 태스크 포트를 통한 스레드 내 쉘코드 삽입
|
||||||
|
|
||||||
다음 위치에서 셸코드를 가져올 수 있습니다:
|
다음에서 쉘코드를 가져올 수 있습니다:
|
||||||
|
|
||||||
{% content-ref url="../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md" %}
|
{% 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)
|
[arm64-basic-assembly.md](../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md)
|
||||||
|
@ -471,7 +497,33 @@ return 0;
|
||||||
```
|
```
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="entitlements.plist" %}엔터틀먼트.plist{% endtab %}
|
{% tab title="entitlements.plist" %}
|
||||||
|
|
||||||
|
## entitlements.plist
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### 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)
|
||||||
|
|
||||||
|
{% endtab %}
|
||||||
```xml
|
```xml
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
@ -686,17 +738,26 @@ return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
</details>
|
</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.
|
||||||
```bash
|
```bash
|
||||||
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
|
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
|
||||||
./inject <pi or string>
|
./inject <pi or string>
|
||||||
```
|
```
|
||||||
### 태스크 포트를 통한 스레드 내 Dylib 삽입
|
### 태스크 포트를 통한 스레드 내 Dylib 주입
|
||||||
|
|
||||||
macOS에서 **스레드**는 **Mach**를 통해 조작되거나 **posix `pthread` api**를 사용하여 조작될 수 있습니다. 이전 삽입에서 생성된 스레드는 Mach api를 사용하여 생성되었기 때문에 **posix 호환성이 없습니다**.
|
macOS에서 **스레드**는 **Mach**를 통해 조작되거나 **posix `pthread` api**를 사용하여 조작될 수 있습니다. 이전 주입에서 생성된 스레드는 Mach api를 사용하여 생성되었기 때문에 **posix 호환성이 없습니다**.
|
||||||
|
|
||||||
**간단한 쉘코드를 삽입**하여 명령을 실행하는 것이 가능했던 이유는 **posix 호환성이 필요하지 않았기 때문**이며, Mach와만 작동해도 충분했습니다. **더 복잡한 삽입**을 위해서는 **스레드**가 **posix 호환**되어야 합니다.
|
**단순한 셸코드를 주입**하여 명령을 실행하는 것이 가능했던 이유는 **posix 호환성이 필요하지 않았기** 때문입니다. **더 복잡한 주입**을 하려면 **스레드**가 또한 **posix 호환성이 있어야** 합니다.
|
||||||
|
|
||||||
따라서 **스레드를 개선**하기 위해 **`pthread_create_from_mach_thread`**를 호출하여 **유효한 pthread를 생성**해야 합니다. 그런 다음, 이 새로운 pthread는 **시스템에서 dylib를 로드**하기 위해 **dlopen을 호출**할 수 있으므로 다른 작업을 수행하기 위해 새로운 쉘코드를 작성하는 대신 사용자 정의 라이브러리를 로드할 수 있습니다.
|
따라서 **스레드를 개선**하기 위해 **`pthread_create_from_mach_thread`**를 호출하여 **유효한 pthread를 생성**해야 합니다. 그런 다음, 이 새로운 pthread는 시스템에서 **dylib를 로드**하기 위해 **dlopen을 호출**할 수 있으므로 다른 작업을 수행하기 위해 새로운 셸코드를 작성하는 대신 사용자 지정 라이브러리를 로드할 수 있습니다.
|
||||||
|
|
||||||
예를 들어 **로그를 생성하고 해당 로그를 수신할 수 있는 라이브러리**가 있는 (예:):
|
예를 들어 **로그를 생성하고 해당 로그를 수신할 수 있는 라이브러리**가 있는 (예:):
|
||||||
|
|
||||||
|
@ -987,19 +1048,7 @@ fprintf(stderr,"Dylib를 찾을 수 없음\n");
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
#### Types of macOS IPC
|
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.
|
||||||
|
|
||||||
1. **Mach Messages**: Low-level messaging system used by macOS for inter-process communication.
|
|
||||||
2. **XPC**: Apple's high-level inter-process communication technology used for communication between processes.
|
|
||||||
3. **Distributed Objects**: Apple's legacy inter-process communication technology that allows objects to be used by multiple processes.
|
|
||||||
|
|
||||||
#### macOS IPC Abuse Techniques
|
|
||||||
|
|
||||||
1. **Impersonating XPC Services**: Attacker can impersonate XPC services to gain unauthorized access to sensitive functionalities.
|
|
||||||
2. **Mach Message Injection**: Attacker can inject malicious Mach messages to manipulate target processes.
|
|
||||||
3. **Distributed Objects Abuse**: Attacker can abuse Distributed Objects to perform privilege escalation or gain unauthorized access.
|
|
||||||
|
|
||||||
By understanding the intricacies of macOS IPC mechanisms, security researchers can discover and mitigate potential security vulnerabilities effectively.
|
|
||||||
```bash
|
```bash
|
||||||
gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
|
gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
|
||||||
./inject <pid-of-mysleep> </path/to/lib.dylib>
|
./inject <pid-of-mysleep> </path/to/lib.dylib>
|
||||||
|
@ -1016,9 +1065,9 @@ gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
|
||||||
|
|
||||||
### 기본 정보
|
### 기본 정보
|
||||||
|
|
||||||
XPC는 macOS 및 iOS에서 **프로세스 간 통신**을 위한 프레임워크인 XNU( macOS에서 사용되는 커널) Inter-Process Communication의 약자입니다. XPC는 시스템 내에서 **다른 프로세스 간에 안전하고 비동기적인 메소드 호출을 가능하게 하는 메커니즘**을 제공합니다. 이는 Apple의 보안 패러다임의 일부로, **권한이 분리된 응용 프로그램을 생성**할 수 있게 하며, 각 **구성 요소**가 **필요한 권한만 가지고** 작업을 수행하도록 함으로써, 침해된 프로세스로부터의 잠재적인 피해를 제한합니다.
|
XPC는 macOS 및 iOS에서 **프로세스 간 통신**을 위한 XNU( macOS에서 사용되는 커널) 인터프로세스 통신을 나타냅니다. XPC는 시스템 내의 **다른 프로세스 간에 안전한 비동기 메소드 호출을 수행하는 메커니즘**을 제공합니다. 이는 Apple의 보안 패러다임의 일부로, **권한이 분리된 응용 프로그램을 생성**할 수 있게 하며, 각 **구성 요소**가 **수행해야 하는 권한만 가지고** 작동하도록 함으로써, 침해된 프로세스로부터의 잠재적인 피해를 제한합니다.
|
||||||
|
|
||||||
이 **통신이 작동하는 방식** 및 **취약할 수 있는 방법**에 대한 자세한 정보는 확인하세요:
|
이 **통신이 작동하는 방식** 및 **취약할 수 있는 방법**에 대한 자세한 정보는 다음을 확인하십시오:
|
||||||
|
|
||||||
{% content-ref url="macos-xpc/" %}
|
{% content-ref url="macos-xpc/" %}
|
||||||
[macos-xpc](macos-xpc/)
|
[macos-xpc](macos-xpc/)
|
||||||
|
@ -1026,9 +1075,11 @@ XPC는 macOS 및 iOS에서 **프로세스 간 통신**을 위한 프레임워크
|
||||||
|
|
||||||
## MIG - Mach Interface Generator
|
## MIG - Mach Interface Generator
|
||||||
|
|
||||||
MIG는 Mach IPC의 프로세스를 **간단화하는 데 사용되는 코드 생성을 간소화**하기 위해 만들어졌습니다. 기본적으로 주어진 정의로 서버와 클라이언트가 통신할 수 있도록 **필요한 코드를 생성**합니다. 생성된 코드가 어색해도, 개발자는 그것을 가져와서 그 코드가 이전보다 훨씬 간단해질 것입니다.
|
MIG는 Mach IPC 코드 생성 과정을 **간소화**하기 위해 만들어졌습니다. 이는 RPC 프로그래밍에 대부분의 작업이 동일한 작업을 필요로 하기 때문입니다(인수 패킹, 메시지 전송, 서버에서 데이터 언패킹...).
|
||||||
|
|
||||||
자세한 정보는 확인하세요:
|
MIG는 기본적으로 서버와 클라이언트가 주어진 정의(IDL -인터페이스 정의 언어-)로 통신할 수 있도록 **필요한 코드를 생성**합니다. 생성된 코드가 어색해도, 개발자는 그것을 가져와서 이전보다 훨씬 간단한 코드를 작성할 수 있습니다.
|
||||||
|
|
||||||
|
자세한 정보는 다음을 확인하십시오:
|
||||||
|
|
||||||
{% content-ref url="macos-mig-mach-interface-generator.md" %}
|
{% content-ref url="macos-mig-mach-interface-generator.md" %}
|
||||||
[macos-mig-mach-interface-generator.md](macos-mig-mach-interface-generator.md)
|
[macos-mig-mach-interface-generator.md](macos-mig-mach-interface-generator.md)
|
||||||
|
@ -1048,10 +1099,10 @@ MIG는 Mach IPC의 프로세스를 **간단화하는 데 사용되는 코드 생
|
||||||
|
|
||||||
HackTricks를 지원하는 다른 방법:
|
HackTricks를 지원하는 다른 방법:
|
||||||
|
|
||||||
* **회사를 HackTricks에서 홍보**하거나 **PDF 형식의 HackTricks 다운로드**를 원하시면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
* **회사를 HackTricks에 광고**하거나 **PDF 형식의 HackTricks를 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
* [**공식 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) 컬렉션
|
* [**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)를 **팔로우**하세요.
|
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||||
* **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
|
* **해킹 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하세요.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
|
@ -2,23 +2,42 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 제로부터 전문가까지 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>에서 <strong>제로부터 영웅까지 AWS 해킹 배우기</strong>!</summary>
|
||||||
|
|
||||||
HackTricks를 지원하는 다른 방법:
|
다른 HackTricks 지원 방법:
|
||||||
|
|
||||||
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드**하고 싶다면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
- **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
- [**공식 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) 컬렉션
|
- [**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)를 **팔로우**하세요.
|
- **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
|
- **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 요령을 공유**하세요.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
MIG는 Mach IPC 코드 생성 프로세스를 **간단화**하기 위해 만들어졌습니다. 기본적으로 주어진 정의와 통신하기 위해 서버와 클라이언트가 필요로 하는 코드를 **생성**합니다. 생성된 코드가 어색해 보이더라도, 개발자는 그것을 가져와서 이전보다 훨씬 간단한 코드를 작성할 수 있습니다.
|
## 기본 정보
|
||||||
|
|
||||||
|
MIG는 **Mach IPC 코드 생성 과정을 간소화**하기 위해 만들어졌습니다. 기본적으로 서버와 클라이언트가 주어진 정의와 통신할 수 있도록 **필요한 코드를 생성**합니다. 생성된 코드가 어색해 보이더라도, 개발자는 그냥 가져와서 이전보다 훨씬 간단한 코드를 작성할 수 있습니다.
|
||||||
|
|
||||||
|
이 정의는 인터페이스 정의 언어(IDL)를 사용하여 `.defs` 확장자로 지정됩니다.
|
||||||
|
|
||||||
|
이러한 정의에는 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`: 응답을 기대
|
||||||
|
|
||||||
### 예시
|
### 예시
|
||||||
|
|
||||||
아주 간단한 함수를 가진 정의 파일을 생성합니다:
|
아주 간단한 함수가 있는 정의 파일을 만듭니다:
|
||||||
|
|
||||||
{% code title="myipc.defs" %}
|
{% code title="myipc.defs" %}
|
||||||
```cpp
|
```cpp
|
||||||
|
@ -37,11 +56,13 @@ n2 : uint32_t);
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
|
||||||
이제 mig를 사용하여 서버 및 클라이언트 코드를 생성하여 서로 통신하고 Subtract 함수를 호출할 수 있도록합니다:
|
첫 번째 **인수는 바인딩할 포트**이며 MIG는 **자동으로 응답 포트를 처리**할 것입니다 (`mig_get_reply_port()`를 클라이언트 코드에서 호출하지 않는 한). 게다가 **작업의 ID**는 지정된 서브시스템 ID부터 시작하는 **연속적**일 것입니다 (따라서 작업이 폐기되면 삭제되고 `skip`이 사용되어 여전히 해당 ID를 사용합니다).
|
||||||
|
|
||||||
|
이제 MIG를 사용하여 서버 및 클라이언트 코드를 생성하여 서로 통신하고 Subtract 함수를 호출할 수 있도록 합니다:
|
||||||
```bash
|
```bash
|
||||||
mig -header myipcUser.h -sheader myipcServer.h myipc.defs
|
mig -header myipcUser.h -sheader myipcServer.h myipc.defs
|
||||||
```
|
```
|
||||||
현재 디렉토리에 여러 새 파일이 생성됩니다.
|
현재 디렉토리에 여러 개의 새 파일이 생성됩니다.
|
||||||
|
|
||||||
**`myipcServer.c`** 및 **`myipcServer.h`** 파일에는 기본적으로 수신된 메시지 ID에 따라 호출할 함수를 정의하는 **`SERVERPREFmyipc_subsystem`** 구조체의 선언과 정의가 포함되어 있습니다 (시작 번호로 500을 지정했습니다):
|
**`myipcServer.c`** 및 **`myipcServer.h`** 파일에는 기본적으로 수신된 메시지 ID에 따라 호출할 함수를 정의하는 **`SERVERPREFmyipc_subsystem`** 구조체의 선언과 정의가 포함되어 있습니다 (시작 번호로 500을 지정했습니다):
|
||||||
|
|
||||||
|
@ -64,7 +85,7 @@ myipc_server_routine,
|
||||||
```
|
```
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="myipcServer.h" %}서버 코드를 작성하고 IPC를 통해 클라이언트로부터 요청을 수신하는 방법을 보여줍니다. 이 코드는 MIG를 사용하여 서버 및 클라이언트 간 통신을 처리합니다. 이 예제에서는 `myipc.defs` 파일에 정의된 MIG 함수를 구현합니다.{% endtab %}
|
{% tab title="myipcServer.h" %}서버 코드를 작성하고 IPC를 통해 클라이언트로부터 요청을 수신하는 방법을 보여줍니다. 이 코드는 MIG를 사용하여 IPC를 처리하는 방법을 보여줍니다. 이 예제에서는 `myipc.defs` 파일에 정의된 MIG 함수를 구현합니다. 이 파일은 MIG 컴파일러에 의해 생성됩니다. 서버는 클라이언트로부터 요청을 수신하고 해당 요청에 응답합니다. 이 코드는 macOS에서 IPC를 구현하는 방법을 보여줍니다. {% endtab %}
|
||||||
```c
|
```c
|
||||||
/* Description of this subsystem, for use in direct RPC */
|
/* Description of this subsystem, for use in direct RPC */
|
||||||
extern const struct SERVERPREFmyipc_subsystem {
|
extern const struct SERVERPREFmyipc_subsystem {
|
||||||
|
@ -80,7 +101,7 @@ routine[1];
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
{% endtabs %}
|
{% endtabs %}
|
||||||
|
|
||||||
이전 구조체를 기반으로 **`myipc_server_routine`** 함수는 **메시지 ID**를 받고 호출할 적절한 함수를 반환합니다:
|
이전 구조체를 기반으로 **`myipc_server_routine`** 함수는 **메시지 ID**를 받아 적절한 함수를 호출하여 반환합니다:
|
||||||
```c
|
```c
|
||||||
mig_external mig_routine_t myipc_server_routine
|
mig_external mig_routine_t myipc_server_routine
|
||||||
(mach_msg_header_t *InHeadP)
|
(mach_msg_header_t *InHeadP)
|
||||||
|
@ -104,7 +125,7 @@ return SERVERPREFmyipc_subsystem.routine[msgh_id].stub_routine;
|
||||||
{ "Subtract", 500 }
|
{ "Subtract", 500 }
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
마지막으로, 서버가 작동하도록 하는 데 중요한 기능 중 하나인 **`myipc_server`**는 실제로 수신된 id에 관련된 함수를 **호출**하는 함수입니다:
|
마지막으로, 서버가 작동하도록 하는 데 중요한 기능 중 하나는 **`myipc_server`**일 것입니다. 이 함수는 실제로 받은 ID에 관련된 함수를 **호출**할 것입니다:
|
||||||
|
|
||||||
<pre class="language-c"><code class="lang-c">mig_external boolean_t myipc_server
|
<pre class="language-c"><code class="lang-c">mig_external boolean_t myipc_server
|
||||||
(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
|
(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
|
||||||
|
@ -121,7 +142,7 @@ mig_routine_t routine;
|
||||||
|
|
||||||
OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0);
|
OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0);
|
||||||
OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port;
|
OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port;
|
||||||
/* 최소 크기: 다르면 routine()이 업데이트함 */
|
/* 최소 크기: 다르면 routine()이 업데이트할 것 */
|
||||||
OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
|
OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
|
||||||
OutHeadP->msgh_local_port = MACH_PORT_NULL;
|
OutHeadP->msgh_local_port = MACH_PORT_NULL;
|
||||||
OutHeadP->msgh_id = InHeadP->msgh_id + 100;
|
OutHeadP->msgh_id = InHeadP->msgh_id + 100;
|
||||||
|
@ -140,7 +161,7 @@ return FALSE;
|
||||||
|
|
||||||
이전에 강조된 줄을 확인하여 ID에 의해 호출할 함수에 액세스합니다.
|
이전에 강조된 줄을 확인하여 ID에 의해 호출할 함수에 액세스합니다.
|
||||||
|
|
||||||
다음은 서버와 클라이언트를 만드는 코드이며, 클라이언트는 서버에서 함수를 호출할 수 있습니다. 서버에서 Subtract 함수를 호출하는 간단한 **서버** 및 **클라이언트** 코드가 있습니다:
|
다음은 서버와 클라이언트를 만드는 코드이며, 클라이언트는 서버에서 함수를 호출할 수 있습니다. Subtract:
|
||||||
|
|
||||||
{% tabs %}
|
{% tabs %}
|
||||||
{% tab title="myipc_server.c" %}
|
{% tab title="myipc_server.c" %}
|
||||||
|
@ -176,7 +197,7 @@ mach_msg_server(myipc_server, sizeof(union __RequestUnion__SERVERPREFmyipc_subsy
|
||||||
```
|
```
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="myipc_client.c" %}번역{% endtab %}
|
{% tab title="myipc_client.c" %}번역된 텍스트가 여기에 들어갑니다.
|
||||||
```c
|
```c
|
||||||
// gcc myipc_client.c myipcUser.c -o myipc_client
|
// gcc myipc_client.c myipcUser.c -o myipc_client
|
||||||
|
|
||||||
|
@ -203,16 +224,16 @@ USERPREFSubtract(port, 40, 2);
|
||||||
```
|
```
|
||||||
### 이진 분석
|
### 이진 분석
|
||||||
|
|
||||||
많은 이진 파일이 이제 MIG를 사용하여 mach 포트를 노출시키기 때문에, **MIG가 사용된 것을 식별하는 방법**과 각 메시지 ID마다 MIG가 실행하는 **함수를 식별하는 것**을 알아보는 것이 흥미로울 것입니다.
|
많은 이진 파일이 이제 MIG를 사용하여 mach 포트를 노출하는데, **MIG가 사용되었는지 식별하는 방법**과 각 메시지 ID별로 **MIG가 실행하는 함수**를 알아내는 것이 흥미로울 수 있습니다.
|
||||||
|
|
||||||
[**jtool2**](../../macos-apps-inspecting-debugging-and-fuzzing/#jtool2)는 Mach-O 이진 파일에서 MIG 정보를 구문 분석하여 메시지 ID를 나타내고 실행할 함수를 식별할 수 있습니다:
|
[**jtool2**](../../macos-apps-inspecting-debugging-and-fuzzing/#jtool2)는 Mach-O 이진 파일에서 MIG 정보를 구문 분석하여 메시지 ID를 나타내고 실행할 함수를 식별할 수 있습니다:
|
||||||
```bash
|
```bash
|
||||||
jtool2 -d __DATA.__const myipc_server | grep MIG
|
jtool2 -d __DATA.__const myipc_server | grep MIG
|
||||||
```
|
```
|
||||||
이전에 **수신된 메시지 ID에 따라 올바른 함수를 호출하는 함수**는 `myipc_server`라고 언급되었습니다. 그러나 일반적으로 이진 파일의 심볼(함수 이름 없음)을 가지고 있지 않으므로, **디컴파일된 내용을 확인하는 것이 흥미로울 것**입니다. 이 함수의 코드는 항상 매우 유사할 것입니다(노출된 함수와 독립적입니다):
|
이전에 **수신된 메시지 ID에 따라 올바른 함수를 호출하는 함수**는 `myipc_server`라고 언급되었습니다. 그러나 보통 이진 파일의 심볼(함수 이름 없음)을 가지고 있지 않기 때문에, **디컴파일된 내용을 확인하는 것이 흥미로울 것**입니다. 이 함수의 코드는 항상 매우 유사할 것입니다(이 함수의 코드는 노출된 함수와 독립적입니다):
|
||||||
|
|
||||||
{% tabs %}
|
{% tabs %}
|
||||||
{% tab title="디컴파일된 myipc_server 1" %}
|
{% tab title="myipc_server 디컴파일 1" %}
|
||||||
<pre class="language-c"><code class="lang-c">int _myipc_server(int arg0, int arg1) {
|
<pre class="language-c"><code class="lang-c">int _myipc_server(int arg0, int arg1) {
|
||||||
var_10 = arg0;
|
var_10 = arg0;
|
||||||
var_18 = arg1;
|
var_18 = arg1;
|
||||||
|
@ -226,7 +247,7 @@ var_18 = arg1;
|
||||||
if (*(int32_t *)(var_10 + 0x14) <= 0x1f4 && *(int32_t *)(var_10 + 0x14) >= 0x1f4) {
|
if (*(int32_t *)(var_10 + 0x14) <= 0x1f4 && *(int32_t *)(var_10 + 0x14) >= 0x1f4) {
|
||||||
rax = *(int32_t *)(var_10 + 0x14);
|
rax = *(int32_t *)(var_10 + 0x14);
|
||||||
// 이 함수를 식별하는 데 도움이 되는 sign_extend_64 호출
|
// 이 함수를 식별하는 데 도움이 되는 sign_extend_64 호출
|
||||||
// 이는 호출해야 하는 호출 지점의 포인터를 rax에 저장합니다
|
// 이는 호출해야 하는 호출 포인터를 rax에 저장합니다
|
||||||
// 주소 0x100004040(함수 주소 배열)의 사용 확인
|
// 주소 0x100004040(함수 주소 배열)의 사용 확인
|
||||||
// 0x1f4 = 500(시작 ID)
|
// 0x1f4 = 500(시작 ID)
|
||||||
<strong> rax = *(sign_extend_64(rax - 0x1f4) * 0x28 + 0x100004040);
|
<strong> rax = *(sign_extend_64(rax - 0x1f4) * 0x28 + 0x100004040);
|
||||||
|
@ -254,8 +275,8 @@ return rax;
|
||||||
</code></pre>
|
</code></pre>
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="디컴파일된 myipc_server 2" %}
|
{% tab title="myipc_server 디컴파일 2" %}
|
||||||
다른 Hopper 무료 버전에서 동일한 함수가 디컴파일된 것입니다:
|
다른 Hopper 무료 버전에서 동일한 함수가 디컴파일된 내용입니다:
|
||||||
|
|
||||||
<pre class="language-c"><code class="lang-c">int _myipc_server(int arg0, int arg1) {
|
<pre class="language-c"><code class="lang-c">int _myipc_server(int arg0, int arg1) {
|
||||||
r31 = r31 - 0x40;
|
r31 = r31 - 0x40;
|
||||||
|
@ -306,7 +327,7 @@ r8 = 0x1;
|
||||||
var_4 = 0x0;
|
var_4 = 0x0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 함수가 있는 곳으로 호출하는 계산된 주소 호출
|
// 함수가 있는 주소를 호출하는 호출
|
||||||
<strong> (var_20)(var_10, var_18);
|
<strong> (var_20)(var_10, var_18);
|
||||||
</strong> var_4 = 0x1;
|
</strong> var_4 = 0x1;
|
||||||
}
|
}
|
||||||
|
@ -330,13 +351,13 @@ return r0;
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
{% endtabs %}
|
{% endtabs %}
|
||||||
|
|
||||||
실제로 **`0x100004000`** 함수로 이동하면 **`routine_descriptor`** 구조체 배열을 찾을 수 있습니다. 구조체의 첫 번째 요소는 **함수가 구현된 주소**이며, **구조체는 0x28 바이트**를 차지하므로 각 0x28 바이트(바이트 0부터 시작)에서 8바이트를 얻을 수 있고, 이것이 **호출될 함수의 주소**가 됩니다:
|
실제로 **`0x100004000` 함수**로 이동하면 **`routine_descriptor`** 구조체 배열을 찾을 수 있습니다. 구조체의 첫 번째 요소는 **함수가 구현된 주소**이며, **구조체는 0x28 바이트**를 차지하므로 각 0x28 바이트(바이트 0부터 시작)마다 8바이트를 얻을 수 있고, 그것이 **호출될 함수의 주소**가 됩니다:
|
||||||
|
|
||||||
<figure><img src="../../../../.gitbook/assets/image (35).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../../.gitbook/assets/image (35).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
<figure><img src="../../../../.gitbook/assets/image (36).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../../.gitbook/assets/image (36).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
이 데이터는 [**이 Hopper 스크립트를 사용하여**](https://github.com/knightsc/hopper/blob/master/scripts/MIG%20Detect.py) 추출할 수 있습니다.
|
이 데이터는 [**이 Hopper 스크립트**](https://github.com/knightsc/hopper/blob/master/scripts/MIG%20Detect.py)를 사용하여 추출할 수 있습니다.
|
||||||
* **HackTricks** 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks) GitHub 저장소에 PR을 제출하여 해킹 기법을 공유하세요.
|
* **HackTricks** 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 저장소에 PR을 제출하여 해킹 기법을 공유하세요.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
Loading…
Reference in a new issue