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信息

关键数据结构

  1. 共享内存结构(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数组索引
};
  1. prefork_child_bucket结构:
struct prefork_child_bucket {
    ap_pod_t *pod;
    ap_listen_rec *listeners;
    apr_proc_mutex_t *mutex;  // 关键指针
};
  1. 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;
    // ...
};
  1. 函数表结构:
struct apr_proc_mutex_unix_lock_methods_t {
    // ...
    apr_status_t (*child_init)(apr_proc_mutex_t **, apr_pool_t *, const char *);  // 目标函数指针
    // ...
};

漏洞原理

  1. 恶意worker可以修改共享内存中的bucket索引,使其指向攻击者控制的结构
  2. 当Apache优雅重启时,主进程会:
    • 杀死原有worker
    • 使用被篡改的bucket索引访问all_buckets数组
    • 调用mutex->meth->child_init()函数
  3. 由于没有边界检查,攻击者可控制该函数调用链,最终以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. 构造恶意结构

在共享内存中构造以下链式结构:

  1. 伪造的prefork_child_bucket结构
  2. 指向伪造的apr_proc_mutex_t结构
  3. 伪造的apr_proc_mutex_unix_lock_methods_t函数表
  4. child_init指针指向目标函数(zend_object_std_dtor)

4. 喷射共享内存

由于all_buckets地址在重启后会变化,需要在SHM中广泛布置恶意结构:

  • 利用多个worker的process_score结构
  • 为每个worker设置不同的bucket索引,覆盖更多可能的内存区域

5. 等待触发

  • 等待logrotate在6:25触发优雅重启
  • 重启过程中漏洞自动触发,执行恶意代码

利用成功率提升技巧

  1. 增加worker数量:更多worker意味着更高的成功率
  2. 广泛的内存喷射:覆盖更多可能的内存地址
  3. 多次尝试:失败后可等待下次重启自动重试
  4. 结构重叠:将zend_object和apr_proc_mutex_t结构重叠布置

漏洞时间线

  • 2019-02-22:漏洞发现并报告
  • 2019-02-25:Apache确认漏洞
  • 2019-03-07:补丁开发完成
  • 2019-04-01:Apache 2.4.39发布,修复漏洞

防御措施

  1. 升级到Apache HTTP Server 2.4.39或更高版本
  2. 限制PHP模块的功能
  3. 使用权限分离,将worker进程以非特权用户运行
  4. 监控共享内存的异常修改

教学总结

CVE-2019-0211是一个典型的条件竞争漏洞,结合了:

  1. 共享内存操作缺乏边界检查
  2. 权限管理不当
  3. 优雅重启机制的设计缺陷

通过精心构造的内存布局和利用PHP的UAF漏洞,攻击者可以实现可靠的本地提权。这个案例展示了现代服务器软件中复杂漏洞的利用方式,强调了安全开发中边界检查和权限控制的重要性。

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) : prefork_ child_ bucket结构 : apr_ proc_ mutex_ t结构 : 函数表结构 : 漏洞原理 恶意worker可以修改共享内存中的bucket索引,使其指向攻击者控制的结构 当Apache优雅重启时,主进程会: 杀死原有worker 使用被篡改的bucket索引访问all_ buckets数组 调用 mutex->meth->child_init() 函数 由于没有边界检查,攻击者可控制该函数调用链,最终以root权限执行任意代码 漏洞利用步骤 1. 获取worker进程的R/W访问权限 使用PHP UAF漏洞(CVE-2019-6977或其他0day)来读写内存: 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漏洞,攻击者可以实现可靠的本地提权。这个案例展示了现代服务器软件中复杂漏洞的利用方式,强调了安全开发中边界检查和权限控制的重要性。