ユーザー名前空間
Reading time: 13 minutes
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を提出してハッキングトリックを共有してください。
基本情報
ユーザー名前空間は、ユーザーおよびグループIDマッピングの隔離を提供するLinuxカーネルの機能であり、各ユーザー名前空間が独自のユーザーおよびグループIDのセットを持つことを可能にします。この隔離により、異なるユーザー名前空間で実行されているプロセスは、同じユーザーおよびグループIDを数値的に共有していても、異なる特権と所有権を持つことができます。
ユーザー名前空間は、各コンテナが独自の独立したユーザーおよびグループIDのセットを持つべきコンテナ化に特に便利であり、コンテナとホストシステム間のセキュリティと隔離を向上させます。
仕組み:
- 新しいユーザー名前空間が作成されると、空のユーザーおよびグループIDマッピングのセットから始まります。これは、新しいユーザー名前空間で実行されるプロセスが名前空間の外で特権を持たないことを意味します。
- IDマッピングは、新しい名前空間のユーザーおよびグループIDと親(またはホスト)名前空間のIDとの間で確立できます。これにより、新しい名前空間のプロセスが親名前空間のユーザーおよびグループIDに対応する特権と所有権を持つことができます。ただし、IDマッピングは特定の範囲やIDのサブセットに制限でき、プロセスに付与される特権を細かく制御できます。
- ユーザー名前空間内では、プロセスは名前空間内の操作に対して完全なルート特権(UID 0)を持つことができますが、名前空間の外では制限された特権を持ちます。これにより、コンテナはホストシステム上で完全なルート特権を持たずに、自身の名前空間内でルートのような機能を持って実行できます。
- プロセスは、
setns()
システムコールを使用して名前空間間を移動したり、unshare()
またはclone()
システムコールをCLONE_NEWUSER
フラグと共に使用して新しい名前空間を作成したりできます。プロセスが新しい名前空間に移動するか、新しい名前空間を作成すると、その名前空間に関連付けられたユーザーおよびグループIDマッピングを使用し始めます。
ラボ:
異なる名前空間を作成する
CLI
sudo unshare -U [--mount-proc] /bin/bash
新しいインスタンスの /proc
ファイルシステムを --mount-proc
パラメータを使用してマウントすることで、新しいマウントネームスペースがそのネームスペースに特有のプロセス情報の正確で隔離されたビューを持つことを保証します。
エラー: bash: fork: メモリを割り当てることができません
unshare
が -f
オプションなしで実行されると、Linux が新しい PID (プロセス ID) ネームスペースを処理する方法のためにエラーが発生します。重要な詳細と解決策は以下の通りです:
- 問題の説明:
- Linux カーネルはプロセスが
unshare
システムコールを使用して新しいネームスペースを作成することを許可します。しかし、新しい PID ネームスペースの作成を開始するプロセス(「unshare」プロセスと呼ばれる)は新しいネームスペースに入らず、その子プロセスのみが入ります。 %unshare -p /bin/bash%
を実行すると、unshare
と同じプロセスで/bin/bash
が開始されます。その結果、/bin/bash
とその子プロセスは元の PID ネームスペースに存在します。- 新しいネームスペース内の
/bin/bash
の最初の子プロセスは PID 1 になります。このプロセスが終了すると、他にプロセスがない場合、PID 1 は孤児プロセスを引き取る特別な役割を持っているため、ネームスペースのクリーンアップがトリガーされます。Linux カーネルはそのネームスペース内での PID 割り当てを無効にします。
- 結果:
- 新しいネームスペース内での PID 1 の終了は
PIDNS_HASH_ADDING
フラグのクリーンアップを引き起こします。これにより、新しいプロセスを作成する際にalloc_pid
関数が新しい PID を割り当てることに失敗し、「メモリを割り当てることができません」というエラーが発生します。
- 解決策:
- この問題は、
unshare
に-f
オプションを使用することで解決できます。このオプションは、unshare
が新しい PID ネームスペースを作成した後に新しいプロセスをフォークします。 %unshare -fp /bin/bash%
を実行すると、unshare
コマンド自体が新しいネームスペース内で PID 1 になります。これにより、/bin/bash
とその子プロセスはこの新しいネームスペース内に安全に収容され、PID 1 の早期終了を防ぎ、通常の PID 割り当てを可能にします。
unshare
が -f
フラグで実行されることを保証することで、新しい PID ネームスペースが正しく維持され、/bin/bash
とそのサブプロセスがメモリ割り当てエラーに遭遇することなく動作できるようになります。
Docker
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
ユーザー名前空間を使用するには、Dockerデーモンを --userns-remap=default
で起動する必要があります(Ubuntu 14.04では、/etc/default/docker
を変更し、その後 sudo service docker restart
を実行することで行えます)
プロセスがどの名前空間にいるかを確認する
ls -l /proc/self/ns/user
lrwxrwxrwx 1 root root 0 Apr 4 20:57 /proc/self/ns/user -> 'user:[4026531837]'
Dockerコンテナからユーザーマップを確認することができます:
cat /proc/self/uid_map
0 0 4294967295 --> Root is root in host
0 231072 65536 --> Root is 231072 userid in host
ホストから次のように:
cat /proc/<pid>/uid_map
すべてのユーザー名前空間を見つける
sudo find /proc -maxdepth 3 -type l -name user -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name user -exec ls -l {} \; 2>/dev/null | grep <ns-number>
ユーザー名前空間に入る
nsenter -U TARGET_PID --pid /bin/bash
また、ルートでなければ他のプロセスの名前空間に入ることはできません。そして、ディスクリプタがそれを指していない限り(例えば /proc/self/ns/user
)、他の名前空間に入ることはできません。
新しいユーザー名前空間を作成する(マッピング付き)
unshare -U [--map-user=<uid>|<name>] [--map-group=<gid>|<name>] [--map-root-user] [--map-current-user]
# Container
sudo unshare -U /bin/bash
nobody@ip-172-31-28-169:/home/ubuntu$ #Check how the user is nobody
# From the host
ps -ef | grep bash # The user inside the host is still root, not nobody
root 27756 27755 0 21:11 pts/10 00:00:00 /bin/bash
Recovering Capabilities
ユーザー名前空間の場合、新しいユーザー名前空間が作成されると、その名前空間に入るプロセスには完全な権限のセットが付与されます。これらの権限により、プロセスはファイルシステムのマウント、デバイスの作成、ファイルの所有権の変更などの特権操作を実行できますが、そのユーザー名前空間のコンテキスト内でのみ実行できます。
例えば、ユーザー名前空間内でCAP_SYS_ADMIN
権限を持っている場合、ファイルシステムのマウントなど、この権限を通常必要とする操作を実行できますが、あなたのユーザー名前空間のコンテキスト内でのみです。この権限を使用して実行する操作は、ホストシステムや他の名前空間には影響しません。
warning
したがって、新しいユーザー名前空間内に新しいプロセスを取得することがすべての権限を戻すことになります(CapEff: 000001ffffffffff)としても、実際には名前空間に関連するもののみを使用できます(例えばマウント)が、すべての権限を使用できるわけではありません。したがって、これだけではDockerコンテナから脱出するには不十分です。
# There are the syscalls that are filtered after changing User namespace with:
unshare -UmCpf bash
Probando: 0x067 . . . Error
Probando: 0x070 . . . Error
Probando: 0x074 . . . Error
Probando: 0x09b . . . Error
Probando: 0x0a3 . . . Error
Probando: 0x0a4 . . . Error
Probando: 0x0a7 . . . Error
Probando: 0x0a8 . . . Error
Probando: 0x0aa . . . Error
Probando: 0x0ab . . . Error
Probando: 0x0af . . . Error
Probando: 0x0b0 . . . Error
Probando: 0x0f6 . . . Error
Probando: 0x12c . . . Error
Probando: 0x130 . . . Error
Probando: 0x139 . . . Error
Probando: 0x140 . . . Error
Probando: 0x141 . . . Error
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を提出してハッキングトリックを共有してください。