扫描器报出 Apache RCE 时,最容易做错的是直接按产品名升级,或者把扫描器里出现的几个 CVE 合并成一个漏洞。处理顺序是:定位真正运行中的 httpd 二进制,按 CVE 分流,核对模块和网络入口,先收口暴露,再升级,最后复测所有节点。
尤其不能把 CVE-2026-119618 与 CVE-2026-23918 混为一谈。现有热点材料只能确认报道指向 CVE-2026-119618;对 CVE-2026-23918 的受影响版本、模块和触发过程有具体描述的是另一份二手资料。实际处置时,应从 Apache 官方漏洞页和 CVE 记录补齐前者的版本边界与首个修复版本。在无法排除影响时,先把节点移出公网入口或限制来源,再升级到不早于官方首个修复版本的 Apache 稳定版。所给 Apache 官方页面当前将 2.4.71 列为 2.4.x 稳定分支的可用版本,但它在 2026-11-11 发布,发稿当天仍应重新核对发布页和变更日志。
先确认扫描对象
先找到真正对外提供服务的 Apache HTTP Server 二进制,不要只看响应中的 Server: Apache。这个响应头可以由代理添加、修改或删除;扫描器也可能把位于反向代理后的 Apache、Tomcat 或其他 Web 服务混在一起。Apache Tomcat 属于 Servlet 容器,与 Apache httpd 不是同一种产品,不能套用相同的版本判断和升级方案。
Linux 上可以从进程表开始,再沿着 /proc 找到实际执行文件:
ps -eo pid,user,comm,args | grep -E '[h]ttpd|[a]pache2'
readlink -f /proc/<PID>/exe
/proc/<PID>/exe -v
把 <PID> 替换为上一步找到的实际进程号。httpd 可能来自源码安装、/usr/sbin、发行版工具目录或容器镜像,PATH 中的命令不一定就是正在监听端口的二进制,核对版本和模块时不能只看 PATH 中的命令。
Debian、Ubuntu 常见命令名是 apache2ctl,其他发行版多使用 httpd 或 apachectl:
httpd -v
httpd -M | grep -E 'http2_module|proxy_uwsgi_module'
httpd -t
Debian、Ubuntu 可改用:
apache2ctl -v
apache2ctl -M
apache2ctl -t
httpd -M 或 apache2ctl -M 反映的是当前配置加载的模块,适合确认 mod_http2、mod_proxy_uwsgi 是否存在,但不能代替协议协商和监听端口检查。httpd -t 用来检查配置语法,也不代表服务已经成功启动或业务路由正常。
还要把运行方式与安装来源对上。下列命令按系统选择其一执行:
dpkg-query -W -f='${Package}\t${Version}\n' apache2 apache2-bin
rpm -q httpd
apk info -a apache2
Debian 系的 apache2 元包和真正包含二进制的 apache2-bin 可能不是同一个版本。发行版也可能在旧的上游版本号上回补安全补丁,因此不能仅凭软件包版本中的 2.4.x 与上游版本号直接比较,还要查看发行版安全公告和回补说明。
容器环境则要把宿主机端口与容器内进程一起看:
docker ps --no-trunc --format 'table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Ports}}'
docker inspect <容器名或ID> --format '{{.Image}} {{.Path}} {{json .Args}}'
docker exec <容器名或ID> httpd -v
如果容器内没有 httpd 命令,不能据此判断没有 Apache,需要继续检查镜像的软件包、启动参数和可执行文件。扫描器命中的也可能是已经退出但尚未清理的旧容器,这一步应保留容器 ID、镜像 ID 和启动时间。
把漏洞编号分开
同一台 Apache 可以同时命中新旧漏洞,但不同编号的产品、模块、版本范围和触发条件不能互相借用。下表按现有材料区分已确认信息和待官方确认的信息:正式发布前,应使用 Apache 官方漏洞公告和 CVE 记录补齐 CVE-2026-119618 的受影响范围、首个修复版本、模块及触发条件,不能把 CVE-2026-23918 的数字移植过去。
| 编号 | 已知受影响范围 | 已知修复信息 | 触发条件 | 处理方式 |
|---|---|---|---|---|
CVE-2026-119618 |
热点报道对象是 Apache HTTP Server;现有材料没有给出可核实的官方版本区间 | 首个修复版本须以 Apache 官方公告和 CVE 记录为准;当前稳定版 2.4.71 可作为升级候选,但须确认变更日志已包含修复 | 现有材料不足以确认,不能套用另一漏洞的模块和利用条件 | 命中后保持工单开启,按官方记录核对版本并升级,不因版本字段未知而直接关闭 |
CVE-2026-23918 |
二手资料称影响 Apache HTTP Server 2.4.66 | 同一资料称修复版本为 2.4.67 及以上 | 位于 mod_http2 流清理逻辑的双重释放;资料称无需认证即可触发,但实现 RCE 仍有额外条件 |
作为独立漏洞核对 mod_http2、HTTP/2 链路和崩溃日志,并以 Apache 官方公告复核 |
CVE-2020-11984 |
Apache HTTP Server 2.4.32 至 2.4.44 | 所给资料没有列出首个修复版本,应查对应官方公告 | 位于 mod_proxy_uwsgi,攻击者发送特制请求时可能造成信息泄露或潜在 RCE |
只用于历史告警分流,不能移植到新漏洞 |
CNVD-2024-36388 |
Apache HTTP Server 大于等于 2.4.0 且小于等于 2.4.59 | 资料只说明厂商已发布修复程序,没有给出可直接引用的版本号 | 攻击者可在配置允许的目录中执行脚本 | 单独检查允许执行脚本的目录,不推测它与其他 CVE 的别名关系 |
这张表用于按漏洞编号分流告警。扫描器仍然命中,可能是旧容器仍运行 2.4.59,也可能是受 CVE-2026-23918 影响的节点仍运行 2.4.66,还可能是负载均衡器仍在把流量送往这些节点。即使主节点已经升级,扫描器也会继续命中旧实例、代理后端或缓存结果。
升级目标也不应统一写成“2.4.67 以上”。2.4.67 这个下限来自资料对 CVE-2026-23918 的描述,不是 CVE-2026-119618 的修复依据。对每个编号分别取官方首个修复版本,再选择不更旧的稳定版。Apache 2.2 已结束生命周期,不会继续获得补丁和安全更新,应规划迁移到 2.4.x。
确认模块和入口
模块存在、协议可达和网络入口可达是三个不同条件。模块已经加载,不代表客户端一定能使用它;客户端能使用 HTTP/2,也不代表 HTTP/2 请求一定能够绕过代理到达源站。
对明确涉及 HTTP/2 的告警,先看 mod_http2 是否加载,再验证 TLS 端口是否通过 ALPN 协商 h2:
openssl s_client -connect <自有测试域名>:443 -servername <自有测试域名> -alpn h2 </dev/null
随后从有权测试的位置发起实际请求:
curl --http2 -sS -o /dev/null -w '%{http_version}\n' https://<自有测试域名>/
对于明确配置了明文 HTTP/2,也就是 h2c 的监听地址,可以使用:
curl --http2-prior-knowledge -sS -o /dev/null -w '%{http_version}\n' http://<h2c测试地址>/
不要把 --http2-prior-knowledge 用来探测普通 HTTP/1.1 服务,也不要把未启用 h2c 的 80 端口误判为 HTTP/2 入口。
代理链路要分两种情况。若客户端到负载均衡器使用 HTTP/2,但负载均衡器以 HTTP/1.1 回源,客户端的 HTTP/2 请求不会原样到达 Apache;若代理也以 HTTP/2 回源,则源站的 mod_http2 仍在暴露面上。需要同时查看负载均衡器、CDN、反向代理和源站的协议配置。
mod_proxy_uwsgi 则只对应 CVE-2020-11984 的历史排查。对于引用该编号的告警,应确认模块是否加载、哪些 ProxyPass 路由会进入它,以及这些路由是否可从外部访问;它与 CVE-2026-23918 的 HTTP/2 流清理问题不是同一条攻击路径。
网络层不能只检查 80 和 443:
sudo ss -lntp
sudo ss -6 -lntp
还要核对备用端口、管理接口、IPv6 监听、容器发布端口,以及负载均衡器到源站的链路。还要确认源站能否绕过代理直接访问:如果源站 IP 允许公网直连,攻击者可以绕过负载均衡器和 WAF,直接访问旧版本节点。
日志也要分层看。普通访问日志未必记录 HTTP/2 帧序列,单纯搜索请求路径通常找不到 CVE-2026-23918 的触发痕迹。应同时检查 Apache 错误日志、崩溃记录、系统 core dump 和代理侧访问日志,并确认日志是否覆盖了对应时间窗口。
先限制暴露再升级
如果版本、模块和入口三个条件都指向可能受影响,应先减少攻击面,再等待维护窗口。按发布版流程修复比临时改配置更稳妥;时间不允许时,至少应把风险节点从负载均衡池摘除,或通过安全组、防火墙和反向代理访问控制限制来源地址。
如果业务允许,可以在配置管理中移除相关模块加载或关闭对应协议入口。这个动作会影响依赖 HTTP/2 的客户端、代理性能和服务间调用,变更前应确认客户端是否支持回退,以及上游代理是否仍会向源站发送 HTTP/2。WAF 和访问控制只能作为临时缓解,不能代替漏洞修复。
升级前应保存当前配置、模块清单、编译参数、二进制摘要和版本:
httpd -V
httpd -M
httpd -t
sha256sum "$(readlink -f /proc/<PID>/exe)"
这些记录既用于升级失败时对照,也用于证明升级前后的实际二进制已经变化。回滚节点必须继续留在受限网络内,不能因为升级失败就重新暴露到公网。
选对版本完成升级
使用发行版软件包时,优先安装对应发行版厂商发布的安全更新。厂商可能在旧的上游版本分支上回补补丁,因此判断依据应是软件包公告、仓库版本和变更说明,而不是简单比较数字大小。
Debian、Ubuntu 的升级路径通常类似:
sudo apt-get update
sudo apt-get install --only-upgrade apache2
sudo apache2ctl configtest
sudo systemctl restart apache2
RHEL 系通常类似:
sudo dnf upgrade httpd
sudo httpd -t
sudo systemctl restart httpd
这两组命令不能混用,发行版还需要确认服务名称、软件仓库和模块包是否同步更新。升级后应再次检查实际运行的二进制:
httpd -v
httpd -M
httpd -t
源码安装时,应从 Apache 官方发布页取得源码、签名和校验值,并保留现有编译参数及需要的模块:
./config.status --config
tar -xzf httpd-<官方修复版本>.tar.gz
cd httpd-<官方修复版本>
./configure <沿用现有必要参数>
make -j"$(nproc)"
sudo make install
<沿用现有必要参数> 不是可执行占位符,必须根据旧源码目录的 config.status、模块列表和安装路径补全。直接套用发行版的 ./configure 参数可能漏掉认证、代理、日志或缓存相关模块。
容器部署不能只重启旧容器。重启不会替换镜像中的 httpd,需要更新基础镜像或 Dockerfile 中的固定版本、重新构建并重新创建容器:
docker build --pull --no-cache -t registry.internal/httpd:fixed .
docker push registry.internal/httpd:fixed
docker compose pull
docker compose up -d --force-recreate
实际使用 pull 还是 build,取决于镜像发布流程。构建时应在 Dockerfile 中固定经过官方公告确认的版本或镜像摘要,不能继续引用浮动标签。
集群环境应先升级一个测试节点,完成配置、业务和回源检查,再逐批替换其他节点。滚动更新期间要禁止负载均衡器把流量发给旧节点,否则扫描器会在升级尚未结束时持续命中。
如果服务启动失败,先运行配置检查,再处理端口占用。Address already in use 表示对应的端口或 IP 已被其他服务占用,不是 RCE 已经成功的证据。可以这样定位:
sudo ss -ntlp 'sport = 80'
sudo ss -ntlp 'sport = 443'
如果使用了自定义模块,还要确认它们是否针对目标 Apache 版本重新编译。旧模块与新 httpd 的二进制接口不兼容时,即使进程能够启动,代理、认证、缓存等功能也可能异常。
Apache 官方页面还说明,在 OpenSSL 1.1.1 环境中提供 TLS 1.3 需要 Apache HTTP Server 2.4.43 或更高版本。这属于升级兼容性约束,不能代替漏洞版本判断。
查清是否留下后门
补丁只能阻止后续利用,不能自动删除已经上传的脚本、建立的持久化账户或窃取的凭据。如果扫描器告警曾持续命中,或者在异常时间窗口内出现过 HTTP/2 请求,应把升级和入侵排查作为两件并行的事。
针对 CVE-2026-23918,二手资料描述的典型路径是客户端发送 HEADERS 后立即发送 RST_STREAM,使同一个流被重复加入清理队列并重复销毁内存。排查时重点查找 double free、段错误、apr_pool_destroy 和异常退出。按实际日志路径搜索:
grep -Ein 'segfault|double free|apr_pool_destroy' /var/log/httpd/error_log
Debian、Ubuntu 常见路径是 /var/log/apache2/error.log,应替换成实际位置。使用 systemd 且启用了 core dump 管理时,还可以检查:
coredumpctl list httpd
coredumpctl info httpd
这些命令没有输出并不代表没有利用,只能说明当前日志或转储中没有对应记录。HTTP/2 帧级异常也可能只出现在代理日志或上游抓包中,普通 Apache 访问日志未必保留足够信息。
针对 CNVD-2024-36388,重点检查配置允许执行脚本的目录中是否出现来源异常的新文件:
find <允许脚本目录> -xdev -type f -mtime -30 -ls
随后还要检查异常子进程、监听端口、计划任务、systemd 启动项、SSH authorized keys、应用凭据和代理后端。发现可疑文件或进程后,先保存日志、进程信息、网络连接和磁盘快照,再隔离节点、轮换凭据或从可信镜像重建,不能只覆盖 Apache 二进制后继续运行。
对于 CVE-2026-119618,不能把 CVE-2026-23918 的双重释放特征直接当成它的入侵指标。应依据官方公告列出的触发条件和检测特征进行关联,再结合通用的进程、文件和凭据检查判断是否留下持久化。
升级后重新验证
升级后应检查每个实际接收流量的实例,而不是发布清单上的主机名。逐节点记录运行中二进制的版本、加载模块和监听端口:
/proc/<PID>/exe -v
/proc/<PID>/exe -M
sudo ss -lntp
容器还要核对镜像 ID、仓库摘要、启动时间和实际创建时间:
docker inspect <容器名或ID> --format '{{.Image}} {{.Path}} {{json .Args}}'
docker image inspect <镜像名或ID> --format '{{.Id}} {{json .RepoDigests}}'
从授权测试位置分别访问负载均衡地址和源站地址,确认预期协议路径:
curl --http2 -sS -o /dev/null -w '%{http_version}\n' https://<负载均衡测试域名>/
curl --http2 -sS -o /dev/null -w '%{http_version}\n' https://<源站测试域名>/
源站测试应从外部网络执行。如果源站能够被直接访问,应先修正防火墙、安全组或监听地址,再判断客户端到源站这一段是否真正完成切换。代理在边缘终止 HTTP/2、但以 HTTP/2 回源时,还要在代理侧验证回源协议,不能只测公网入口。
复测时建议保留下面这些记录:
| 节点或入口 | 实际运行版本 | 软件包或镜像摘要 | 加载模块 | 监听端口 | 代理与回源链路 | 协议测试结果 | 复测时间 | 异常处置结果 |
|---|---|---|---|---|---|---|---|---|
扫描器仍然命中同一 CVE 时,先确认它访问的是不是已升级节点,再核对扫描器的产品指纹和 CVE 映射。只有当公网入口、负载均衡后端和容器实例都运行在不早于官方首个修复版本的 Apache 上,没有旧实例继续接收流量、源站无法被绕过,并且复测不再命中该编号时,这个漏洞工单才具备关闭条件。












暂无评论内容