User Namespace

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)

HackTricksをサポートする

基本情報

ユーザー名前空間は、ユーザーおよびグループIDマッピングの隔離を提供するLinuxカーネルの機能であり、各ユーザー名前空間が独自のユーザーおよびグループIDのセットを持つことを可能にします。この隔離により、異なるユーザー名前空間で実行されるプロセスは、同じユーザーおよびグループIDを数値的に共有していても、異なる特権と所有権を持つことができます

ユーザー名前空間は、各コンテナが独自の独立したユーザーおよびグループIDのセットを持つべきコンテナ化に特に役立ち、コンテナとホストシステム間のセキュリティと隔離を向上させます。

仕組み:

  1. 新しいユーザー名前空間が作成されると、空のユーザーおよびグループIDマッピングのセットから始まります。これは、新しいユーザー名前空間で実行されるプロセスが名前空間の外で特権を持たないことを意味します

  2. 新しい名前空間のユーザーおよびグループIDと親(またはホスト)名前空間のIDとの間にIDマッピングを確立できます。これにより、新しい名前空間のプロセスが親名前空間のユーザーおよびグループIDに対応する特権と所有権を持つことができます。ただし、IDマッピングは特定の範囲やIDのサブセットに制限でき、名前空間内のプロセスに付与される特権を細かく制御できます。

  3. ユーザー名前空間内では、プロセスは名前空間内の操作に対して完全なルート特権(UID 0)を持つことができますが、名前空間の外では制限された特権を持ちます。これにより、コンテナはホストシステム上で完全なルート特権を持たずに、自身の名前空間内でルートのような機能を持って実行できます

  4. プロセスはsetns()システムコールを使用して名前空間間を移動したり、unshare()またはclone()システムコールを使用してCLONE_NEWUSERフラグで新しい名前空間を作成したりできます。プロセスが新しい名前空間に移動するか、新しい名前空間を作成すると、その名前空間に関連付けられたユーザーおよびグループIDマッピングを使用し始めます。

ラボ:

異なる名前空間を作成する

CLI

sudo unshare -U [--mount-proc] /bin/bash

新しいインスタンスの /proc ファイルシステムを --mount-proc パラメータを使用してマウントすることで、新しいマウント名前空間がその名前空間に特有のプロセス情報の 正確で隔離されたビュー を持つことを保証します。

エラー: bash: fork: メモリを割り当てることができません

unshare-f オプションなしで実行されると、Linux が新しい PID (プロセス ID) 名前空間を処理する方法のためにエラーが発生します。重要な詳細と解決策は以下の通りです:

  1. 問題の説明

  • Linux カーネルは、プロセスが unshare システムコールを使用して新しい名前空間を作成することを許可します。しかし、新しい PID 名前空間の作成を開始するプロセス(「unshare」プロセスと呼ばれる)は新しい名前空間に入らず、その子プロセスのみが入ります。

  • %unshare -p /bin/bash% を実行すると、unshare と同じプロセスで /bin/bash が開始されます。その結果、/bin/bash とその子プロセスは元の PID 名前空間に存在します。

  • 新しい名前空間内の /bin/bash の最初の子プロセスは PID 1 になります。このプロセスが終了すると、他にプロセスがない場合、孤児プロセスを引き取る特別な役割を持つ PID 1 により名前空間のクリーンアップがトリガーされます。Linux カーネルはその名前空間での PID 割り当てを無効にします。

  1. 結果

  • 新しい名前空間内の PID 1 の終了は PIDNS_HASH_ADDING フラグのクリーンアップを引き起こします。これにより、新しいプロセスを作成する際に alloc_pid 関数が新しい PID を割り当てることに失敗し、「メモリを割り当てることができません」というエラーが発生します。

  1. 解決策

  • この問題は、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権限を持っている場合、ファイルシステムのマウントなど、この権限を通常必要とする操作を実行できますが、あなたのユーザー名前空間のコンテキスト内でのみです。この権限を使用して実行する操作は、ホストシステムや他の名前空間には影響しません。

したがって、新しいユーザー名前空間内に新しいプロセスを取得することがすべての権限を取り戻すことになります(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

<div data-gb-custom-block data-tag="hint" data-style='success'>

Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)

<details>

<summary>Support HackTricks</summary>

* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>

</div>

hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</div>

</details>

</div>

</details>

</div>

</details>

</div>

</details>

</div>

</details>

</div>

Last updated