CARPE (DIEM): CVE-2019-0211 Apache Root Privilege Escalation
字数 1691 2025-08-29 08:32:09
Apache HTTP Server 本地提权漏洞(CVE-2019-0211)深度分析与利用教学
漏洞概述
CVE-2019-0211是Apache HTTP Server中的一个本地提权漏洞,影响版本从2.4.17(2015年10月9日发布)到2.4.38(2019年4月1日发布)。该漏洞允许低权限用户(如www-data)提升至root权限,主要通过数组越界访问导致的任意函数调用实现。
漏洞背景
受影响的模块
- mod_prefork
- mod_worker
- mod_event
触发条件
当Apache正常重新启动(apache2ctl graceful)时触发漏洞。在标准Linux配置中,logrotate程序每天6:25会自动运行重启命令来重置日志文件句柄。
技术细节分析
Apache MPM prefork架构
- 主服务器进程以root权限运行
- 管理单线程、低权限(www-data)的工作进程池
- 使用共享内存区域(SHM)即scoreboard来存储worker信息
关键数据结构
- 共享内存结构(scoreboard):
struct process_score {
pid_t pid;
ap_generation_t generation;
char quiescing;
char not_accepting;
apr_uint32_t connections;
apr_uint32_t write_completion;
apr_uint32_t lingering_close;
apr_uint32_t keep_alive;
apr_uint32_t suspended;
int bucket; // 关键字段 - 用于all_buckets数组索引
};
- prefork_child_bucket结构:
struct prefork_child_bucket {
ap_pod_t *pod;
ap_listen_rec *listeners;
apr_proc_mutex_t *mutex; // 关键指针
};
- apr_proc_mutex_t结构:
struct apr_proc_mutex_t {
apr_pool_t *pool;
const apr_proc_mutex_unix_lock_methods_t *meth; // 关键函数表指针
int curr_locked;
char *fname;
// ...
};
- 函数表结构:
struct apr_proc_mutex_unix_lock_methods_t {
// ...
apr_status_t (*child_init)(apr_proc_mutex_t **, apr_pool_t *, const char *); // 目标函数指针
// ...
};
漏洞原理
- 恶意worker可以修改共享内存中的bucket索引,使其指向攻击者控制的结构
- 当Apache优雅重启时,主进程会:
- 杀死原有worker
- 使用被篡改的bucket索引访问all_buckets数组
- 调用
mutex->meth->child_init()函数
- 由于没有边界检查,攻击者可控制该函数调用链,最终以root权限执行任意代码
漏洞利用步骤
1. 获取worker进程的R/W访问权限
使用PHP UAF漏洞(CVE-2019-6977或其他0day)来读写内存:
class X extends DateInterval implements JsonSerializable {
public function jsonSerialize() {
global $y, $p;
unset($y[0]);
$p = $this->y;
return $this;
}
}
function get_aslr() {
global $p, $y;
$p = 0;
$y = [new X('PT1S')];
json_encode([1234 => &$y]);
return $p;
}
2. 定位关键内存区域
- 共享内存区域:通过
/proc/self/maps查找rw-s区域 - all_buckets数组:通过匹配已知结构在内存中搜索
- PHP堆布局:利用zend_string结构扩展读写范围
3. 构造恶意结构
在共享内存中构造以下链式结构:
- 伪造的
prefork_child_bucket结构 - 指向伪造的
apr_proc_mutex_t结构 - 伪造的
apr_proc_mutex_unix_lock_methods_t函数表 - 将
child_init指针指向目标函数(zend_object_std_dtor)
4. 喷射共享内存
由于all_buckets地址在重启后会变化,需要在SHM中广泛布置恶意结构:
- 利用多个worker的process_score结构
- 为每个worker设置不同的bucket索引,覆盖更多可能的内存区域
5. 等待触发
- 等待logrotate在6:25触发优雅重启
- 重启过程中漏洞自动触发,执行恶意代码
利用成功率提升技巧
- 增加worker数量:更多worker意味着更高的成功率
- 广泛的内存喷射:覆盖更多可能的内存地址
- 多次尝试:失败后可等待下次重启自动重试
- 结构重叠:将zend_object和apr_proc_mutex_t结构重叠布置
漏洞时间线
- 2019-02-22:漏洞发现并报告
- 2019-02-25:Apache确认漏洞
- 2019-03-07:补丁开发完成
- 2019-04-01:Apache 2.4.39发布,修复漏洞
防御措施
- 升级到Apache HTTP Server 2.4.39或更高版本
- 限制PHP模块的功能
- 使用权限分离,将worker进程以非特权用户运行
- 监控共享内存的异常修改
教学总结
CVE-2019-0211是一个典型的条件竞争漏洞,结合了:
- 共享内存操作缺乏边界检查
- 权限管理不当
- 优雅重启机制的设计缺陷
通过精心构造的内存布局和利用PHP的UAF漏洞,攻击者可以实现可靠的本地提权。这个案例展示了现代服务器软件中复杂漏洞的利用方式,强调了安全开发中边界检查和权限控制的重要性。