Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
xspawn — launchdのプライベートXPCインターフェースを介してmacOSプログラムをexecせずに起動し、EDRにlaunchdが親プロセスとして記録させます。ワンショット、KeepAlive、およびplistベースのジョブに対応しています。 | Kitploit
ツール/GitHubGitHub/cenobyte-vincit/xspawn
永続化メカニズムIDS/IPS回避ポストエクスプロイトレッドチーミング敵対的攻撃
GitHubcenobyte-vincit/xspawn

xspawn

launchdのプライベートXPCインターフェースを介してmacOSプログラムをexecせずに起動し、EDRにlaunchdが親プロセスとして記録させます。ワンショット、KeepAlive、およびplistベースのジョブに対応しています。

リポジトリを見る
351ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

xspawn

xspawn は macOS 上で launchd を通じてプログラムを起動し、そのプログラム自体を exec することはありません。目的は、EDR が親としてこのツールや呼び出し元シェルではなく launchd を記録することです。

作者: cenobyte [email protected] 2026

https://github.com/cenobyte-vincit/xspawn

概要

xspawn は xpc_pipe_create_from_port(bootstrap_port) を開き、launchctl が使用するのと同じ非公開 XPC パイプである _xpc_pipe_interface_routine を通じてプログラムの実行をブートストラップし、プログラム自体を exec することはありません。

  • ルートは拒否されます。他UIDモードはありません。
  • 1回の呼び出しで1つのジョブを送信または削除します。
  • クライアントが /bin/launchctl を exec することはありません。

要件

ランタイムホスト

  • gui/<uid> セッションを備えた macOS (Darwin)

ビルドホスト

  • Xcode Command Line Tools または Xcode を備えた macOS (Darwin)
  • C17 コンパイラ(cc)
  • make
  • 開発用の cppcheck(brew install cppcheck)

ビルド

make

使い方

xspawn oneshot -l <label> [-o <stdout>] [-e <stderr>] [--] <program> [args...]
xspawn submit  -l <label> [-o <stdout>] [-e <stderr>] [--] <program> [args...]
xspawn remove  -l <label>
xspawn load    -p <plist>
サブコマンドライフサイクル
oneshotワンショット(RunAtLoad + LaunchOnlyOnce)
submitKeepAlive
load呼び出し元所有の plist をそのまま使用
removeラベル指定でアンロード

ワンショット(RunAtLoad + LaunchOnlyOnce。0 はスリープなし):

./xspawn oneshot -l com.example.once -- /tmp/helloworld 0

-- の後の引数は ProgramArguments です。これにはインラインコード(python3 -c、perl -e)も含まれます。CrowdStrike Falcon for macOS は完全な CommandLine を記録するため、インタプリタを使うインラインコードの使用は控えめにしてください。

./xspawn oneshot -l com.example.py -o /tmp/py.out -- \
	/usr/bin/python3 -c "print('hello world')"

KeepAlive ジョブ。launchctl submit と同じライフサイクルです。60 秒スリープするので、CrowdStrike Falcon for macOS と launchctl print はプロセスをまだ確認できます:

./xspawn submit -l com.example.svc \
	-o /tmp/out.log -e /tmp/err.log -- /tmp/helloworld 60

launchctl print で確認します(検証専用。このクライアントはこれを呼び出しません):

launchctl print gui/$(id -u)/com.example.svc

成功すると、type = LaunchAgent(Submitted ではない)、絶対パスとしての program、そして state = running または一時的な xpcproxy が表示されます。Submitted は、ジョブがブートストラップ経路を取らなかったことを意味します。

テストジョブを後始末する:

./xspawn remove -l com.example.svc

呼び出し元所有の plist をロードします(応答後も削除されません):

./xspawn load -p /tmp/job.plist

<program> は絶対パスでなければなりません。launchd は $PATH を検索しません。

load -p には .plist で終わる絶対パスが必要です。

-o / -e は相対パスでもかまいません。plist に書き込まれる前に、カレントワーキングディレクトリからの相対パスとして解決されます。-o と -e を省略した場合は /dev/null になります。

oneshot と submit は、一時 plist を書き込む前に gui と user(ディスクリプタ 708)でラベルを調べます。使用済みラベルの場合は label already loaded で終了し、標準出力には何も出力しません。このチェックは、失敗する運命にある 800 が $TMPDIR/XXXXXX/XXXXXX.plist を書き込んだり(DFIR の成果物。CrowdStrike Falcon はパスを ASEPFilePath に保持します)、ジョブ辞書の XML コピーを出力したりしないためにあります。空きラベルの場合は、一時パスを出力し、次にその XML を出力してから 800 を送信します。load -p は、ファイルの Label に対して同じ占有チェックを実行し、その後、呼び出し元パスと XML を出力します。一時ディレクトリはすべての終了時に削除されます。remove はラベル指定です。

終了コード

コード意味
0ブートストラップまたはブートアウト XPC が成功
1使用法エラー、無効なラベル、ルート、または launchd/XPC による拒否

検証

ビルドホスト(make とテストツリー。多くの場合 gui セッションと同じ場所にあります)。これらのチェックはクリーンなランタイムの証明ではありません:

make
make test
make test-unit
make test-functional
./xspawn oneshot -l com.example.once -- /tmp/helloworld 0

制限事項

  • 同一ユーザーの gui/<uid> のみ。ルートは拒否されます。他UIDを対象にしません。
  • 一時的:再起動やログアウトをまたいで永続しません。
  • 非公開 XPC のロード定数とブートアウト定数は macOS 26.6.1 build 25G76 に固定されています。sw_vers -buildVersion が変わった場合は固定をやり直してください(ARCHITECTURE.md 参照)。
  • 一時 plist は $TMPDIR/XXXXXX/XXXXXX.plist です($TMPDIR は絶対パスである必要があり、それ以外は /tmp)。ディレクトリはすべての終了時に削除されます。使用済みラベルでは、そのファイルは決して作成されません。
  • CrowdStrike Falcon for macOS は、ProcessRollup2 イベントの Auto-Start Extensibility Point フィールド(ASEPFilePath)に一時 plist のパスを記録します。プロセスの親は launchd のままです。
  • 単体の xspawn の実行は、このクライアントとして可視です。つまり、シェル履歴と、このバイナリに対する EDR プロセスイベントです。CrowdStrike Falcon for macOS は完全な CommandLine を記録します。これにはプログラムのパスとその引数が含まれます。そのイメージと argv が特徴的になる場合は、クライアントを他のツールに組み込んでください。埋め込んでも、ASEPFilePath や launchd.log のブートストラップ行は削除されません(ARCHITECTURE.md の Parentage を参照)。
  • launchd はまた、スポーンを /private/var/log/com.apple.xpc.launchd/launchd.log に記録します(ARCHITECTURE.md の Parentage を参照)。
  • 手書きの plist に XPCService キーを入れないでください。xpcproxy がフォークし、CrowdStrike Falcon for macOS は親を xpcproxy として記録します。

非公開 XPC プロトコル

launchd は Mach ブートストラップサーバーです。このクライアントは公開 XPC(xpc_connection_create)を使用しません。継承された bootstrap_port 上で xpc_pipe_create_from_port(bootstrap_port, 4) を使って非公開の libxpc パイプを開き、_xpc_pipe_interface_routine を送信します。これらのシンボルは libxpc にあり、SDK ヘッダーにはありません。

ルーチン ID はディスクリプタ引数であり、リクエスト辞書のキーではありません。macOS 26.6.1 build 25G76 では、ロードはディスクリプタ 800、ブートアウトは 801 です。インターフェースフラグは 6 です。gui/<uid> セッションが必要です。継承されたポートが gui launchd ドメインになるのは Aqua ログインセッション内だけであり、このクライアントは handle = uid を持つ type 8 のみを送信します。

ロード(800)は XPC 辞書です。ジョブ定義はメッセージ本文にはありません。

handle   uid (uint64)
type     8 (gui)
paths    [absolute .plist]
by-cli   true

launchd はパスを stat し、plist を解析し、それから xpcproxy を posix_spawn します。xpcproxy は同じ PID 内でプログラムを exec します。成功の条件は、パイプ戻り値 0、xpc-fault なし、error 0、bootstrap-error 0 です。

ブートアウト(801)はラベル指定です:handle、type 8、name、no-einprogress、wait。plist はありません。

このチャネルは先行技術です。Jonathan Levin(launjctl、2015年。Mac OS X and iOS Internals Vol. 1)は、launchctl が非公開の XPC パイプを介して launchd と通信することを示し、dict キー type、handle、subsystem、routine、name を持つ xpc_pipe_create_from_port / xpc_pipe_routine を文書化しました。Patrick Wardle(The Art of Mac Malware Vol. 2)は、後続の送信エントリとして _xpc_pipe_interface_routine を文書化しました。Csaba Fitzl と Brandon Dalton(OBTS)は、同じ dict ファミリーとドメインタイプコード(gui は 8)をマッピングしました。公開スニペットはすでに xpc_pipe_create_from_port(bootstrap_port, 4) を使用していました。

これらの解説はプロトコルのクラスを説明しています。それらは、実際に動作する 25G76 のロード定数を提供していません。Levin の2015年のキャプチャでは、subsystem と routine を辞書内に置き、xpc_pipe_routine を使用していました。25G76 では、これらのキーは存在しません。launchctl bootstrap は、ルーチン ID をディスクリプタ引数として _xpc_pipe_interface_routine に到達します。launchctl の arm64e 静的解析は依然として古い dict 経路のように見え、ロード ID として 703 を示唆します。実機での x86_64 lldb と arm64 クライアントの実行は、どちらもそれらのキーなしで 800 / 801 を使用します。このクライアントは、両方のスライスでその単一の形状を提供します。

レジスタダンプ、lldb の再固定レシピ、および親子関係フィールドのメモは ARCHITECTURE.md にあります。

関連項目

  • ARCHITECTURE.md:スポーンパス、親子関係、実配線、再固定
  • AGENTS.md:ビルドホストとターゲット
ツールをダウンロード