PID 名前空間
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
PID (Process IDentifier) 名前空間は、Linux カーネルの機能で、プロセスのグループに他の名前空間の PID とは別の一意の PID セットを持たせることでプロセスの分離を提供します。これは、プロセス分離がセキュリティやリソース管理に不可欠なコンテナ化で特に有用です。
新しい PID 名前空間が作成されると、その名前空間内の最初のプロセスには PID 1 が割り当てられます。このプロセスは新しい名前空間の “init” プロセスとなり、その名前空間内の他のプロセスを管理する役割を担います。名前空間内で作成される各プロセスは、その名前空間内で一意の PID を持ち、これらの PID は他の名前空間の PID とは独立しています。
PID 名前空間内のプロセスの観点からは、同じ名前空間内のプロセスだけを参照できます。他の名前空間のプロセスを認識せず、従来のプロセス管理ツール(例: kill, wait など)を使って相互作用することはできません。これにより、プロセス同士が干渉するのを防ぐための分離が提供されます。
仕組み:
- 新しいプロセスが作成されると(例:
clone()システムコールを使用して)、プロセスは新しいまたは既存の PID 名前空間に割り当てられることがあります。 新しい名前空間が作成された場合、そのプロセスはその名前空間の “init” プロセスになります。 - kernel は親名前空間(すなわち新しい名前空間が作成された元の名前空間)における対応する PID と新しい名前空間内の PID との間の マッピング を維持します。このマッピングにより、kernel が必要に応じて PID を翻訳できるようになります(例えば異なる名前空間間でプロセス間シグナルを送る場合など)。
- PID 名前空間内のプロセスは同じ名前空間内の他のプロセスのみを参照・操作できます。他の名前空間のプロセスを認識せず、各プロセスの PID はその名前空間内で一意です。
- PID 名前空間が破棄されると(例: その名前空間の “init” プロセスが終了したとき)、その名前空間内のすべてのプロセスは終了されます。これにより、名前空間に関連するすべてのリソースが適切にクリーンアップされます。
ラボ:
異なる名前空間の作成
CLI
sudo unshare -pf --mount-proc /bin/bash
Error: bash: fork: Cannot allocate memory
-f オプションなしで unshare を実行すると、Linux が新しい PID (Process ID) 名前空間を扱う方法によりエラーが発生します。以下に主要な点と解決策を示します。
- Problem Explanation:
- Linux カーネルは
unshareシステムコールでプロセスが新しい名前空間を作成することを許可します。しかし、新しい PID 名前空間の作成を開始したプロセス(ここでは「unshare」プロセスと呼ぶ)はその新しい名前空間に入らず、その子プロセスのみが入ります。 %unshare -p /bin/bash%を実行すると/bin/bashはunshareと同じプロセスで起動します。したがって/bin/bashとその子プロセスは元の PID 名前空間にいます。- 新しい名前空間内で
/bin/bashの最初の子プロセスが PID 1 になります。このプロセスが終了すると、PID 1 は孤児プロセスの引き取りなど特別な役割を持つため、他にプロセスがなければ名前空間のクリーンアップが起こります。その結果、Linux カーネルはその名前空間での PID 割り当てを無効にします。
- Consequence:
- 新しい名前空間で PID 1 が終了すると
PIDNS_HASH_ADDINGフラグがクリアされます。そのためalloc_pid関数は新しいプロセスのために PID を割り当てられず、“Cannot allocate memory” エラーが発生します。
- Solution:
- この問題は
unshareに-fオプションを付けることで解決できます。これによりunshareは新しい PID 名前空間を作成した後に fork して新しいプロセスを生成します。 %unshare -fp /bin/bash%を実行すると、unshare自身が新しい名前空間内の PID 1 になります。これにより/bin/bashとその子プロセスは新しい名前空間内に安全に収容され、PID 1 の早期終了を防ぎ、通常の PID 割り当てが行えるようになります。
unshare を -f フラグ付きで実行することで、新しい PID 名前空間が正しく維持され、/bin/bash とそのサブプロセスはメモリ割り当てエラーに遭遇することなく動作できます。
--mount-proc パラメータを使って /proc ファイルシステムの新しいインスタンスをマウントすることで、新しいマウント名前空間はその名前空間に特有のプロセス情報に対する正確で独立したビューを持つことが保証されます。
Docker
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
プロセスがどの namespace にいるかを確認する
ls -l /proc/self/ns/pid
lrwxrwxrwx 1 root root 0 Apr 3 18:45 /proc/self/ns/pid -> 'pid:[4026532412]'
すべての PID ネームスペースを見つける
sudo find /proc -maxdepth 3 -type l -name pid -exec readlink {} \; 2>/dev/null | sort -u
初期(デフォルト)の PID namespace からの root ユーザーは、新しい PID namespace 内のプロセスであってもすべてのプロセスを見ることができる点に注意してください。そのため、すべての PID namespaces を見ることができます。
PID namespace 内に入る
nsenter -t TARGET_PID --pid /bin/bash
When you enter inside a PID namespace from the default namespace, you will still be able to see all the processes. And the process from that PID ns will be able to see the new bash on the PID ns.
また、他のプロセスの PID namespace に入れるのは root の場合のみです。そして、descriptor(例: /proc/self/ns/pid)を指すものがないと他の namespace に入ることはできません。
最近の悪用メモ
CVE-2025-31133: maskedPaths を悪用してホスト PID に到達する
runc ≤1.2.7 は、container images または runc exec ワークロードを制御する攻撃者が、ランタイムが敏感な procfs エントリをマスクする直前にコンテナ側の /dev/null を置き換えることを許していました。レースが成功すると、/dev/null は任意のホストパス(例えば /proc/sys/kernel/core_pattern)を指すシンボリックリンクに変えられ、結果として新しいコンテナの PID namespace は自分の namespace を出ていないにもかかわらずホスト全体の procfs 設定に対する読み書きアクセスを突然継承してしまいます。core_pattern や /proc/sysrq-trigger が書き込み可能になると、coredump を生成するか SysRq をトリガーすることで、ホストの PID namespace 上でコード実行やサービス拒否を引き起こせます。
実践的なワークフロー:
- ホストのパスを指すリンクで
/dev/nullを置き換える OCI bundle を作成する(ln -sf /proc/sys/kernel/core_pattern rootfs/dev/null)。 - 修正が入る前にコンテナを起動して、runc がそのリンク上にホストの procfs ターゲットを bind-mount するようにする。
- コンテナ namespace 内で、公開された procfs ファイルに書き込み(例:
core_patternを reverse shell helper を指すように設定)し、任意のプロセスをクラッシュさせてホストカーネルにあなたのヘルパーを PID 1 コンテキストで実行させる。
起動前にバンドルが適切なファイルをマスキングしているかどうかを素早く監査できます:
jq '.linux.maskedPaths' config.json | tr -d '"'
ランタイムが期待するマスキングエントリを欠いている(または /dev/null が消失したためスキップしている)場合、そのコンテナはホストの PID が見えてしまう可能性があるものとして扱ってください。
insject による Namespace 注入
NCC Group の insject は LD_PRELOAD ペイロードとしてロードされ、ターゲットプログラムの後期(デフォルトは main)にフックして execve() の後に一連の setns() 呼び出しを行います。これにより、ランタイムが 初期化後 にホスト(または別のコンテナ)から被害者の PID namespace にアタッチでき、コンテナのファイルシステムにバイナリをコピーすることなく /proc/<pid> のビューを保持できます。insject は PID namespace への参加を fork するまで遅らせることができるため、1 つのスレッドをホスト namespace(CAP_SYS_PTRACE を持たせたまま)に残し、別のスレッドをターゲットの PID namespace で実行させることで、強力なデバッグや攻撃用プリミティブを作り出せます。
使用例:
sudo insject -S -p $(pidof containerd-shim) -- bash -lc 'readlink /proc/self/ns/pid && ps -ef'
namespace injection を悪用または防御する際の主な注意点:
-S/--strictを使用して、スレッドが既に存在するか namespace joins が失敗した場合にinsjectを中止させてください。さもなければ、一部移行されたスレッドがホストとコンテナの PID スペースにまたがったままになる可能性があります。- 書き込み可能なホストのファイルディスクリプタをまだ保持しているツールを、mount namespace に参加しないままアタッチしてはいけません — さもなければ、PID namespace 内の任意のプロセスがあなたのヘルパーを ptrace し、それらのディスクリプタを再利用してホストのリソースを改ざんすることができます。
参考
- https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory
- container escape via “masked path” abuse due to mount race conditions (GitHub Security Advisory)
- Tool Release – insject: A Linux Namespace Injector (NCC Group)
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks

