> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md).

# User Namespace

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter**上关注我们 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 基本信息

用户命名空间是Linux内核的一个功能，**提供用户和组ID映射的隔离**，允许每个用户命名空间拥有**自己的用户和组ID集合**。这种隔离使得在不同用户命名空间中运行的进程可以**拥有不同的特权和所有权**，即使它们在数字上共享相同的用户和组ID。

用户命名空间在容器化中特别有用，每个容器应该有自己独立的用户和组ID集合，从而在容器和主机系统之间实现更好的安全性和隔离。

### 工作原理：

1. 创建新用户命名空间时，它**从一个空的用户和组ID映射集开始**。这意味着在新用户命名空间中运行的任何进程**最初在命名空间外部没有特权**。
2. 可以在新命名空间和父（或主机）命名空间之间建立ID映射。这**允许新命名空间中的进程具有与父命名空间中的用户和组ID相对应的特权和所有权**。但是，ID映射可以限制为特定范围和ID子集，从而对在新命名空间中的进程授予的特权进行精细控制。
3. 在用户命名空间内，**进程可以拥有完整的根特权（UID 0）用于命名空间内的操作**，同时在命名空间外部具有有限特权。这允许**容器在其自己的命名空间中以类似根用户的能力运行，而不会在主机系统上具有完整的根特权**。
4. 进程可以使用`setns()`系统调用在命名空间之间移动，或者使用带有`CLONE_NEWUSER`标志的`unshare()`或`clone()`系统调用创建新命名空间。当进程移动到新命名空间或创建一个时，它将开始使用与该命名空间关联的用户和组ID映射。

## 实验：

### 创建不同的命名空间

#### 命令行界面

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

通过使用参数`--mount-proc`挂载`/proc`文件系统的新实例，确保新的挂载命名空间具有**准确且独立的进程信息视图，特定于该命名空间**。

<details>

<summary>错误：bash: fork: 无法分配内存</summary>

当执行`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分配。

2. **后果**：

* 在新命名空间中，PID 1的退出导致`PIDNS_HASH_ADDING`标志的清除。这会导致`alloc_pid`函数在创建新进程时无法分配新的PID，从而产生“无法分配内存”错误。

3. **解决方案**：

* 可以通过在`unshare`中使用`-f`选项来解决此问题。此选项使`unshare`在创建新PID命名空间后fork一个新进程。
* 执行`%unshare -fp /bin/bash%`确保`unshare`命令本身成为新命名空间中的PID 1。然后，`/bin/bash`及其子进程安全地包含在此新命名空间中，防止PID 1过早退出，并允许正常的PID分配。

通过确保`unshare`使用`-f`标志运行，新的PID命名空间得以正确维护，使`/bin/bash`及其子进程能够正常运行，避免遇到内存分配错误。

</details>

#### Docker

```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
```

要使用用户命名空间，Docker 守护程序需要使用 **`--userns-remap=default`** 启动（在 Ubuntu 14.04 中，可以通过修改 `/etc/default/docker` 然后执行 `sudo service docker restart` 来完成）

### 检查您的进程位于哪个命名空间

```bash
ls -l /proc/self/ns/user
lrwxrwxrwx 1 root root 0 Apr  4 20:57 /proc/self/ns/user -> 'user:[4026531837]'
```

可以使用以下命令检查 Docker 容器中的用户映射：

```bash
cat /proc/self/uid_map
0          0 4294967295  --> Root is root in host
0     231072      65536  --> Root is 231072 userid in host
```

或者从主机执行：

```bash
cat /proc/<pid>/uid_map
```

### 查找所有用户命名空间

{% code overflow="wrap" %}

```bash
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>
```

{% endcode %}

### 进入用户命名空间

```bash
nsenter -U TARGET_PID --pid /bin/bash
```

另外，只有**作为root用户**才能**进入另一个进程命名空间**。而且，**没有指向它的描述符**（比如`/proc/self/ns/user`），你**无法进入**其他命名空间。

### 创建新的用户命名空间（带映射）

{% code overflow="wrap" %}

```bash
unshare -U [--map-user=<uid>|<name>] [--map-group=<gid>|<name>] [--map-root-user] [--map-current-user]
```

{% endcode %}

```bash
# 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
```

### 恢复权限

在用户命名空间的情况下，**当创建一个新的用户命名空间时，进入该命名空间的进程将在该命名空间内被授予完整的权限集**。这些权限允许进程执行特权操作，如**挂载文件系统**、创建设备或更改文件所有权，但**仅限于其用户命名空间的上下文**。

例如，当您在用户命名空间中拥有`CAP_SYS_ADMIN`权限时，您可以执行通常需要此权限的操作，比如挂载文件系统，但仅限于您的用户命名空间的上下文。您使用此权限执行的任何操作都不会影响主机系统或其他命名空间。

{% hint style="warning" %}
因此，即使在新的用户命名空间中获得一个新进程**将使您恢复所有权限**（CapEff: 000001ffffffffff），实际上您**只能使用与命名空间相关的权限**（例如挂载），而不是所有权限。因此，仅凭这一点是不足以逃离 Docker 容器的。
{% endhint %}

\`\`\`bash # 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 Probando: 0x143 . . . Error

```
## 参考资料
* [https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory](https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory)

<details>

<summary><strong>从零开始学习AWS黑客技术</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。 

</details>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
