跳转到帖子

Apache CVE-2021-41773 路径穿越:授权验证、配置边界与修复复测

精选回复

发布于

一、漏洞背景与适用范围

CVE-2021-41773 是 Apache HTTP Server 2.4.49 中的路径规范化缺陷。特定编码路径可以绕过预期的目录边界;当目标文件所在目录没有被访问控制拒绝时,可能导致 Web 目录之外的文件被读取。在额外满足 CGI 配置条件时,风险还可能扩大,但本文只验证文件读取边界,不进行命令执行测试。

版本判断要特别注意:该漏洞针对 2.4.49;2.4.50 的修复不完整,对应后续 CVE-2021-42013,不能把升级到 2.4.50 当作完整修复。2.4.51 修复了这两个历史问题,但生产环境应升级到发行版当前维护的安全版本,而不是停留在这个历史版本。

二、具体场景与授权边界

假设待测站点将 URL 路径 /assets/ 映射到 /var/www/assets/。测试目标是确认请求能否越出这个文件系统目录,读取管理员预先放置的无敏感内容标记文件。

  • 只对明确授权的主机、端口和虚拟主机发起请求。
  • 标记文件使用随机内容,不读取口令、私钥或业务配置。
  • 记录测试时间、源 IP、响应状态和唯一标记,方便关联日志。
  • 不为了复现而放宽生产环境权限;需要调整配置时,应在隔离副本中进行。

三、问题定位:先查实际进程与配置

不要只看响应头中的 Server 字段。反向代理可能隐藏版本,发行版也可能回移安全补丁。应以实际运行的二进制、软件包安全公告和生效配置为准。以下命令在不同发行版上可能需要替换为 apache2ctl:

httpd -v
httpd -V
apachectl -t
apachectl -S
apachectl -M

# Debian / Ubuntu:核对安装包版本
 dpkg-query -W apache2 apache2-bin

# RHEL 系:核对安装包版本
 rpm -q httpd

httpd -V 可帮助确定配置根目录和主配置文件;apachectl -S 用于确认目标 Host 实际落在哪个虚拟主机。容器环境应在对应容器内检查,避免把宿主机版本误当成服务版本。

重点排查 Alias、ScriptAlias、Directory、Require 和 CGI 相关设置。下面的配置仅用于解释风险条件,不应直接部署:

# 危险配置示意:文件系统根目录被广泛放行
<Directory />
    Require all granted
</Directory>

Alias /assets/ /var/www/assets/
<Directory /var/www/assets>
    Require all granted
</Directory>

这里需要区分两个边界:Alias 决定 URL 映射到哪里,Directory 决定文件系统位置是否允许访问。路径规范化出现缺陷后,如果目录外的访问又被宽泛授权,穿越请求才可能获得目标内容。存在 Alias 本身并不等于存在可利用漏洞。

四、技术分析:为什么普通请求看不出来

正常情况下,路径中的父目录引用应在安全检查前完成规范化。该漏洞涉及编码字符的处理顺序,类似 .%2e 的路径段能够在受影响版本中产生非预期的父目录语义。

测试工具也会影响结果:客户端、代理或 WAF 可能提前规范化、解码或拦截路径。因此 curl 验证时使用 --path-as-is,避免客户端先改写请求。但它只能控制 curl 自身,不能保证中间链路不修改请求。

五、操作步骤:使用受控标记文件验证

由资产管理员在目标服务器创建测试文件。该文件位于 Alias 目录之外,内容无敏感信息,并允许 Web 服务账户读取。测试结束后删除。

# 在目标服务器执行;标记值应为本次测试独有
sudo install -d -m 0755 /srv/vuln-canary
printf '%s\n' 'audit-41773-7f3c2d91' | sudo tee /srv/vuln-canary/probe.txt
sudo chmod 0644 /srv/vuln-canary/probe.txt

以下假定 /assets/ 确实映射到 /var/www/assets/。三个父目录段用于从该目录返回文件系统根目录,再访问受控文件。实际映射不同,目录层级也需要重新计算,不能机械套用。

# 用授权测试地址替换示例域名;保留状态、响应头及响应体
curl --path-as-is --connect-timeout 5 --max-time 10 \
  -H 'X-Audit-ID: audit-41773-7f3c2d91' \
  -D baseline.headers -o baseline.body \
  '

curl --path-as-is --connect-timeout 5 --max-time 10 \
  -H 'X-Audit-ID: audit-41773-7f3c2d91' \
  -D traversal.headers -o traversal.body \
  '

cat traversal.headers
grep -Fx 'audit-41773-7f3c2d91' traversal.body

判断成功的依据是响应体出现完整、唯一的标记内容,而不是单纯返回 HTTP 200。统一错误页、登录页和前端路由都可能返回 200。建议在同一次测试中确认:标记文件没有通过其他正常路由公开,基线请求也没有返回相同内容。

403、404 或空响应不能单独证明版本已经修复。需要继续排查虚拟主机是否匹配、Alias 是否生效、目录层级是否正确、文件权限与 SELinux/AppArmor 是否阻止读取,以及请求是否在代理层被拦截。不得为得到阳性结果而关闭生产环境防护。

六、日志留痕与证据关联

在 Apache 实际配置的访问日志和错误日志中,按测试时间、源地址及路径片段检索。日志路径由 CustomLog 和 ErrorLog 决定,不一定使用发行版默认位置:

grep -Ei '(%2e|vuln-canary|7f3c2d91)' /var/log/apache2/access.log
 grep -Ei '(denied|vuln-canary|7f3c2d91)' /var/log/apache2/error.log

默认访问日志通常不会记录自定义请求头。若需要记录测试编号,可在变更审批后增加专用日志格式:

LogFormat "%h %t \"%r\" %>s %b audit=%{X-Audit-ID}i" audit
CustomLog logs/audit_access.log audit

该请求头只能辅助关联,不能作为可信身份凭据。经过代理时,还应对照边缘日志与后端日志;边缘节点拒绝请求,只能说明该入口当时被阻断,不能替代后端漏洞修复。

七、修复建议与复测标准

  • 升级到供应商当前维护的安全版本,并确认旧工作进程已退出;只替换磁盘上的二进制不代表运行实例已更新。
  • 恢复文件系统默认拒绝,只对实际需要发布的目录授权。修改前核对现有配置合并关系,避免影响正常业务。
  • 清理无业务用途的 Alias、ScriptAlias 和 CGI 配置,避免静态资源目录同时具备脚本执行能力。
  • 将服务账户权限限制在必要范围,保留 SELinux/AppArmor 等额外边界。
  • WAF 规则可作为临时缓解,但不能代替升级和目录权限修复。
# 访问控制收敛示例,需结合现有配置调整
<Directory />
    AllowOverride None
    Require all denied
</Directory>

<Directory /var/www/assets>
    AllowOverride None
    Options -Indexes -ExecCGI
    Require all granted
</Directory>

# 校验通过后,再按维护流程重载或重启
apachectl -t

复测必须同时满足:正常资源仍可访问;原穿越请求无法取得标记内容;运行版本与供应商修复状态一致;直连源站等其他授权入口也经过检查。最后删除标记文件,保留必要的响应与日志证据。

八、总结

这条漏洞记录的核心不是记住一段编码路径,而是确认“受影响实现、路径映射、目录授权和可读取文件”是否形成完整链路。报告应明确区分版本风险、已验证的越界读取,以及尚未验证的更高影响,避免把一次状态码变化直接写成远程代码执行。

漏洞验证与修复流程示意图
漏洞成因、验证条件与修复闭环示意
服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意

复测时建议把“版本已修复”和“被配置挡住”分开记录。CVE-2021-41773 影响上游 Apache HTTP Server 2.4.49;2.4.50 的修复不完整,对应 CVE-2021-42013。不要把升级到 2.4.50 当作闭环,应升级到发行版提供的受支持修复版本,并核对软件包公告,不能只看响应头里的版本号。

配置排查重点是 Alias、ScriptAlias 的映射目标,以及目标目录实际继承的授权规则:

apachectl -t
apachectl -S
apachectl -M | grep -E 'alias|cgi|cgid'
# 路径按发行版调整;还要检查 Include 引入的配置
grep -RniE 'Alias|ScriptAlias|<Directory|Require|AllowOverride' \
  /etc/apache2 /etc/httpd 2>/dev/null

正常情况下根目录应保持默认拒绝,只对必要的站点目录放行;不要为了“复现成功”在生产环境放宽授权:

<Directory />
    AllowOverride None
    Require all denied
</Directory>

在明确授权的隔离环境,可以用无敏感内容的标记文件验证边界:假设现有测试映射为 /probe/ → /srv/httpd-check/public/,把唯一标记写到它的父目录,而不是读取系统文件:

printf 'boundary-check-7c92\n' > /srv/httpd-check/marker.txt

curl --path-as-is -i \
  '

--path-as-is 是为了避免客户端提前规范化路径。收到标记内容才是越界读取的直接证据;403/404 只能说明这条请求没读到,不能单独证明修复成功。应同时核对实际命中的虚拟主机、后端访问/错误日志,并分别检查代理入口和受控直连后端,排除 WAF 或代理代为拦截。这个单编码用例也不足以覆盖 CVE-2021-42013。

另外,路径穿越不等于必然能执行命令:RCE 还取决于 CGI 模块、处理器和目录配置。修复验收没必要执行系统命令,用标记文件验证边界,再确认正常静态资源和业务路由没有回归即可。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。

SiteMap HACKHAT © 2026 All rights reserved.