hacktricks/linux-hardening/privilege-escalation/euid-ruid-suid.md

204 lines
9.8 KiB
Markdown
Raw Normal View History

2022-05-31 22:22:36 +00:00
# euid, ruid, suid
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-05-31 22:22:36 +00:00
* 如果您在**网络安全公司**工作,想在**HackTricks**中看到您的**公司广告**,或者想要获取**PEASS的最新版本或下载HackTricks的PDF**?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* 获取[**官方PEASS & HackTricks周边商品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**telegram群组**](https://t.me/peass)或在**Twitter**上**关注**我[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向[hacktricks仓库](https://github.com/carlospolop/hacktricks)和[hacktricks-cloud仓库](https://github.com/carlospolop/hacktricks-cloud)提交PR来分享您的黑客技巧**。
2022-05-31 22:22:36 +00:00
</details>
### 用户身份变量
2022-05-31 22:22:36 +00:00
- **`ruid`**: **真实用户ID**表示启动进程的用户。
- **`euid`**: 作为**有效用户ID**,它代表系统用来确定进程权限的用户身份。通常,`euid`与`ruid`相同除非执行SetUID二进制文件时`euid`会承担文件所有者的身份,从而授予特定的操作权限。
- **`suid`**: **保存的用户ID**在高权限进程通常以root身份运行需要临时放弃其权限以执行某些任务然后再重新获得其最初的提升状态时至关重要。
2022-05-31 22:22:36 +00:00
#### 重要说明
非root操作的进程只能将其`euid`修改为当前的`ruid`、`euid`或`suid`。
2022-05-31 22:22:36 +00:00
### 理解set*uid函数
2022-05-31 22:22:36 +00:00
- **`setuid`**: 与最初的假设相反,`setuid`主要修改的是`euid`而不是`ruid`。具体来说,对于有权限的进程,它会将`ruid`、`euid`和`suid`与指定的用户通常是root对齐由于覆盖了`suid`这些ID因此变得固定。更多详细信息可以在[setuid手册页](https://man7.org/linux/man-pages/man2/setuid.2.html)中找到。
- **`setreuid`** 和 **`setresuid`**: 这些函数允许对`ruid`、`euid`和`suid`进行微妙的调整。然而它们的能力取决于进程的权限级别。对于非root进程修改限于`ruid`、`euid`和`suid`的当前值。相比之下root进程或具有`CAP_SETUID`能力的进程可以为这些ID分配任意值。更多信息可以从[setresuid手册页](https://man7.org/linux/man-pages/man2/setresuid.2.html)和[setreuid手册页](https://man7.org/linux/man-pages/man2/setreuid.2.html)中获得。
2022-05-31 22:22:36 +00:00
这些功能的设计不是作为安全机制而是为了促进预期的操作流程例如当程序通过改变其有效用户ID来采用另一个用户的身份时。
2022-05-31 22:22:36 +00:00
值得注意的是,虽然`setuid`可能是提升到root权限的常用方法因为它将所有ID对齐到root但区分这些函数对于理解和操纵不同场景中的用户ID行为至关重要。
2022-05-31 22:22:36 +00:00
### Linux中的程序执行机制
2022-05-31 22:22:36 +00:00
#### **`execve` 系统调用**
- **功能**: `execve`通过第一个参数确定程序,并启动它。它接受两个数组参数,`argv`用于参数,`envp`用于环境。
- **行为**: 它保留调用者的内存空间,但刷新堆栈、堆和数据段。程序的代码被新程序替换。
- **用户ID保留**:
- `ruid`、`euid`和补充组ID保持不变。
- 如果新程序设置了SetUID位`euid`可能会有细微变化。
- 执行后,`suid`从`euid`更新。
- **文档**: 更多详细信息可以在[`execve`手册页](https://man7.org/linux/man-pages/man2/execve.2.html)中找到。
2022-05-31 22:22:36 +00:00
#### **`system` 函数**
- **功能**: 与`execve`不同,`system`使用`fork`创建子进程,并使用`execl`在该子进程中执行命令。
- **命令执行**: 通过`sh`执行命令,使用`execl("/bin/sh", "sh", "-c", command, (char *) NULL);`。
- **行为**: 由于`execl`是`execve`的一种形式,它以类似的方式操作,但在新子进程的上下文中。
- **文档**: 更多洞见可以从[`system`手册页](https://man7.org/linux/man-pages/man3/system.3.html)中获得。
2022-05-31 22:22:36 +00:00
#### **带有SUID的`bash`和`sh`的行为**
- **`bash`**:
- 有一个`-p`选项,影响`euid`和`ruid`的处理方式。
- 没有`-p`时,如果`euid`和`ruid`最初不同,`bash`会将`euid`设置为`ruid`。
- 使用`-p`时,保留初始`euid`。
- 更多细节可以在[`bash`手册页](https://linux.die.net/man/1/bash)中找到。
- **`sh`**:
- 没有类似于`bash`中的`-p`机制。
- 关于用户ID的行为没有明确提及除了在`-i`选项下,强调保持`euid`和`ruid`的相等。
- 额外信息可以在[`sh`手册页](https://man7.org/linux/man-pages/man1/sh.1p.html)中找到。
2022-05-31 22:22:36 +00:00
这些机制在操作上各不相同为执行和转换程序提供了多样化的选择具有在如何管理和保留用户ID方面的特定细微差别。
2022-05-31 22:22:36 +00:00
### 测试执行中的用户ID行为
2022-05-31 22:22:36 +00:00
示例取自https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail更多信息请查看该网站
2022-05-31 22:22:36 +00:00
#### 案例1结合`setuid`和`system`使用
2022-05-31 22:22:36 +00:00
**目标**: 理解结合`system`和作为`sh`的`bash`时`setuid`的效果。
2022-05-31 22:22:36 +00:00
**C代码**:
2022-05-31 22:22:36 +00:00
```c
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
2023-08-03 19:12:22 +00:00
setuid(1000);
system("id");
return 0;
2022-05-31 22:22:36 +00:00
}
```
**编译和权限:**
2022-05-31 22:22:36 +00:00
```bash
oxdf@hacky$ gcc a.c -o /mnt/nfsshare/a;
oxdf@hacky$ chmod 4755 /mnt/nfsshare/a
```
2022-05-31 22:22:36 +00:00
```bash
bash-4.2$ $ ./a
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
```
**分析:**
2022-05-31 22:22:36 +00:00
* `ruid``euid` 分别以 99 (nobody) 和 1000 (frank) 开始。
* `setuid` 将两者都对齐到 1000。
* `system` 通过从 sh 到 bash 的符号链接执行 `/bin/bash -c id`
* `bash`,如果没有 `-p`,会调整 `euid` 以匹配 `ruid`,导致两者都变为 99 (nobody)。
2022-05-31 22:22:36 +00:00
#### 案例 2: 使用 setreuid 与 system
2022-05-31 22:22:36 +00:00
**C 代码**:
2022-05-31 22:22:36 +00:00
```c
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
2023-08-03 19:12:22 +00:00
setreuid(1000, 1000);
system("id");
return 0;
2022-05-31 22:22:36 +00:00
}
```
**编译和权限:**
```bash
2022-05-31 22:22:36 +00:00
oxdf@hacky$ gcc b.c -o /mnt/nfsshare/b; chmod 4755 /mnt/nfsshare/b
```
**执行和结果:**
```bash
2022-05-31 22:22:36 +00:00
bash-4.2$ $ ./b
uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
```
**分析:**
2022-05-31 22:22:36 +00:00
* `setreuid` 将 ruid 和 euid 都设置为 1000。
* `system` 调用 bash由于用户 ID 相等bash 保持这些 ID有效地作为 frank 操作。
2022-05-31 22:22:36 +00:00
#### 案例 3结合 setuid 与 execve 使用
目标:探索 setuid 与 execve 之间的交互。
```bash
2022-05-31 22:22:36 +00:00
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
2023-08-03 19:12:22 +00:00
setuid(1000);
execve("/usr/bin/id", NULL, NULL);
return 0;
2022-05-31 22:22:36 +00:00
}
```
**执行和结果:**
```bash
2022-05-31 22:22:36 +00:00
bash-4.2$ $ ./c
uid=99(nobody) gid=99(nobody) euid=1000(frank) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
```
**分析:**
2022-05-31 22:22:36 +00:00
* `ruid` 保持为 99但 euid 被设置为 1000符合 setuid 的效果。
**C 代码示例 2调用 Bash**
```bash
2022-05-31 22:22:36 +00:00
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
2023-08-03 19:12:22 +00:00
setuid(1000);
execve("/bin/bash", NULL, NULL);
return 0;
2022-05-31 22:22:36 +00:00
}
```
**执行和结果:**
```bash
2022-05-31 22:22:36 +00:00
bash-4.2$ $ ./d
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
```
**分析:**
2022-05-31 22:22:36 +00:00
* 尽管 `setuid``euid` 设置为1000但由于缺少 `-p``bash` 将 euid 重置为 `ruid` (99)。
```bash
2022-05-31 22:22:36 +00:00
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
2023-08-03 19:12:22 +00:00
char *const paramList[10] = {"/bin/bash", "-p", NULL};
setuid(1000);
execve(paramList[0], paramList, NULL);
return 0;
2022-05-31 22:22:36 +00:00
}
```
**执行和结果:**
```bash
2022-05-31 22:22:36 +00:00
bash-4.2$ $ ./e
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) euid=100
2022-05-31 22:22:36 +00:00
```
# 参考资料
* [https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail](https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail)
2022-05-31 22:22:36 +00:00
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-05-31 22:22:36 +00:00
* 如果你在一家**网络安全公司**工作,想在**HackTricks**上看到你的**公司广告**,或者想要获取**PEASS最新版本或下载HackTricks的PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs**](https://opensea.io/collection/the-peass-family)收藏。
* 获取[**官方PEASS & HackTricks商品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**telegram群组**](https://t.me/peass)或在**Twitter**上**关注**我[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向[hacktricks仓库](https://github.com/carlospolop/hacktricks)和[hacktricks-cloud仓库](https://github.com/carlospolop/hacktricks-cloud)提交PR来分享你的黑客技巧。**
2022-05-31 22:22:36 +00:00
</details>