中间件安全/组件漏洞-IIS&Apache&Nginx漏洞
中间件安全/组件漏洞-IIS&Apache&Nginx漏洞
1.基础知识
1.1 Web中间件是什么
Web中间件可以理解为:
浏览器
↓
HTTP请求
↓
Web服务器 / 中间件
↓
静态文件 / 后端程序 / FastCGI / CGI / 应用服务
↓
返回响应常见的 Web 中间件有:
| 中间件 | 常见用途 | 常见漏洞类型 |
|---|---|---|
| IIS | Windows 平台 Web 服务 | 解析漏洞、短文件名泄露、WebDAV、认证绕过 |
| Apache HTTP Server | Linux/Windows 常见 Web 服务 | 目录遍历、路径穿越、CGI RCE、配置错误 |
| Nginx | 反向代理、静态资源、FastCGI转发 | 解析漏洞、alias目录穿越、CRLF注入、配置覆盖 |

- 说白了:*
IIS / Apache / Nginx 本身负责“接请求、找文件、转发给后端程序”。
如果路径解析、文件后缀判断、访问控制、HTTP方法控制出了问题,
就可能造成文件泄露、权限绕过、代码执行。2.IIS系列漏洞总结
2.1 IIS简介
IIS,全称 Internet Information Services,是微软 Windows Server 自带的 Web 服务组件。
常见部署环境:
Windows Server
↓
IIS
↓
ASP / ASP.NET / PHP
↓
网站业务IIS 典型攻击面:
1. ASP / ASP.NET 解析逻辑
2. WebDAV扩展
3. Windows 8.3短文件名机制
4. 认证目录访问控制
5. 老版本IIS解析兼容问题虽然现在 IIS 还在用,但已经不是主流 Web Server 了。和 Nginx、Apache 相比,它的公网网站占比明显低很多,更多出现在 Windows Server、ASP.NET、企业内网、政企/传统业务系统 里。
按 W3Techs 2026 年 5 月的数据,在“已知 Web Server 的网站”中:Nginx 约 32.7%,Apache 约 23.6%,Microsoft-IIS 约 3.3%。也就是说,公网网站层面 IIS 已经远低于 Nginx 和 Apache。
| Web Server | 2026年5月大致占比 | 当前地位 |
|---|---|---|
| Nginx | 32.7% | 当前最常见的 Web Server / 反向代理之一 |
| Apache | 23.6% | 老牌主流,仍大量存在 |
| Microsoft-IIS | 3.3% | 仍存在,但公网占比明显下降 |
| Cloudflare Server | 27.8% | CDN/WAF/边缘代理场景占比很高 |
W3Techs 的历史趋势也能看出 IIS 在持续下降:Microsoft-IIS 从 2025 年 5 月的 4.0%,下降到 2026 年 5 月的 3.3%。
不过要注意,“市场占比低”不代表“实战中遇不到”。IIS 在这些场景里还是比较常见:
1. Windows Server + ASP.NET / ASP.NET MVC / .NET Framework 老系统
2. 政企、医院、学校、制造业等传统信息系统
3. 内网 OA、ERP、CRM、门户系统
4. 早期部署的 .aspx / .asp 业务
5. 与 Active Directory、Windows 域环境深度绑定的系统现在公网网站中 IIS 的占比已经明显低于 Nginx 和 Apache,但在 Windows Server、ASP.NET、政企传统系统和企业内网环境中仍然经常出现,因此 IIS 相关漏洞仍然具有学习和实战价值。
对比记忆:
Nginx:现代互联网、反向代理、负载均衡、高并发场景多
Apache:老牌 Web Server,PHP/LAMP 历史存量多
IIS:Windows生态、ASP.NET、政企内网、传统业务系统多2.2 IIS 6.0 解析漏洞
2.2.1 漏洞简介
IIS 6.0 存在经典解析漏洞,主要有两种形式:
1. 目录解析漏洞
2. 文件名解析漏洞2.2.2 目录解析漏洞
错误形式:
/xxx.asp/1.jpg如果网站中存在一个目录:
xxx.asp/那么 IIS 6.0 可能会把该目录下的文件当作 ASP 脚本解析。
举例:
/wooyun.asp/1.jpg虽然 1.jpg 看起来是图片,但因为它位于 .asp 结尾的目录下,IIS 6.0 可能会按照 ASP 逻辑处理。
- 漏洞一句话理解*
IIS 6.0 会把.asp、.asa等特殊后缀目录下的文件当作脚本处理。
攻击链:
上传图片文件
↓
图片内容中包含脚本代码
↓
文件被放入 .asp 结尾目录
↓
访问 /xxx.asp/1.jpg
↓
IIS按ASP解析
↓
造成代码执行2.2.3 文件名解析漏洞
错误形式:
shell.asp;.jpgIIS 6.0 对分号 ; 后面的内容处理不严,可能只识别前半部分:
shell.asp所以:
shell.asp;.jpg看起来是 .jpg,实际可能被 IIS 当作 .asp 解析。
- 漏洞一句话理解*
IIS 6.0 在解析文件名时,可能忽略分号后面的内容,导致伪装成图片的 ASP 文件被执行。
2.2.4 防御建议
1. 不再使用IIS 6.0等老旧版本
2. 禁止用户控制上传目录名
3. 上传目录禁止脚本执行权限
4. 对上传文件做白名单校验
5. 文件重命名为随机名,去除用户可控后缀
6. 分离静态资源域名和脚本执行域名2.3 IIS WebDAV PUT任意文件写入
2.3.1 漏洞简介
WebDAV 是 HTTP 协议的扩展,允许客户端对服务器资源进行远程管理。
常见方法包括:
PUT
MOVE
COPY
DELETE
PROPFIND如果 IIS 开启 WebDAV,并且目录具有写入权限,攻击者可能通过 PUT 上传文件,再通过 MOVE 改名成可执行脚本。
2.3.2 漏洞成因
IIS启用WebDAV
↓
目录允许写入
↓
PUT上传普通文件
↓
MOVE重命名为脚本后缀
↓
访问脚本文件
↓
代码执行2.3.3 防御建议
1. 关闭WebDAV
2. 关闭Web目录写入权限
3. 禁止PUT、MOVE、DELETE等危险HTTP方法
4. 上传目录禁止脚本执行
5. 对WebDAV访问增加强认证和IP限制2.4 CVE-2017-7269 IIS 6.0 WebDAV远程代码执行
2.4.1 漏洞简介
CVE-2017-7269 是 IIS 6.0 WebDAV 服务中的远程代码执行漏洞。
- 编号:CVE-2017-7269
- 类型:缓冲区溢出 / 远程代码执行
- 影响组件:IIS 6.0 WebDAV
- 影响系统:Windows Server 2003 R2 + IIS 6.0
- 危害等级:高危 / 严重
NVD 对该漏洞的描述是:IIS 6.0 的 WebDAV 服务中 ScStoragePathFromUrl 函数存在缓冲区溢出,远程攻击者可通过以 If: <http:// 开头的长 Header 和 PROPFIND 请求触发任意代码执行。
2.4.2 漏洞成因
IIS 6.0启用WebDAV
↓
攻击者发送PROPFIND请求
↓
If头过长
↓
ScStoragePathFromUrl处理异常
↓
缓冲区溢出
↓
可能造成RCEMicrosoft 的安全公告也将 CVE-2017-7269 归类为 WebDAV 远程代码执行漏洞,说明 WebDAV 对内存对象处理不当可能导致攻击者运行任意代码。
2.4.3 防御建议
1. 停用Windows Server 2003 / IIS 6.0
2. 禁用WebDAV扩展
3. 阻断PROPFIND等不必要方法
4. 使用WAF/IPS拦截异常If Header
5. 迁移到受支持的Windows Server版本3.Apache HTTP Server漏洞总结
3.1 Apache简介
Apache HTTP Server,常简称 Apache 或 httpd,是 Apache 软件基金会维护的开源 Web 服务器。
常见用途:
1. 静态资源服务
2. PHP运行环境
3. CGI脚本执行
4. 反向代理
5. 目录访问控制常见攻击面:
1. 路径规范化
2. Alias配置
3. CGI执行
4. 目录遍历
5. .htaccess配置
6. 模块漏洞3.2 Apache目录遍历/目录浏览配置错误
3.2.1 漏洞简介
当 Apache 开启目录索引时,如果某目录下没有默认首页文件,例如:
index.html
index.phpApache 可能直接列出目录文件。
错误配置示例:
Options +Indexes有点类似使用python开临时服务器的效果
python3 -m http.server 80003.2.2 漏洞成因
目录没有首页文件
↓
Apache开启Indexes
↓
用户访问目录
↓
服务器返回文件列表
↓
敏感文件泄露3.2.3 风险
1. 泄露源码文件
2. 泄露备份文件
3. 泄露配置文件
4. 泄露压缩包
5. 辅助后续攻击常见敏感文件:
.bak
.zip
.tar.gz
.sql
.conf
.env3.2.4 防御建议
Options -Indexes并确保:
1. 目录下放置默认首页
2. 敏感文件不要放在Web根目录
3. 关闭目录浏览
4. 限制备份文件访问3.3 CVE-2021-41773 Apache路径穿越漏洞
3.3.1 漏洞简介
CVE-2021-41773 是 Apache HTTP Server 2.4.49 中的路径穿越和文件泄露漏洞。
- 编号:CVE-2021-41773
- 类型:路径穿越 / 文件读取 / 特定条件下RCE
- 影响版本:Apache HTTP Server 2.4.49
- 危害等级:Critical
Apache 官方说明:该漏洞源于 Apache 2.4.49 中路径规范化逻辑的变更,攻击者可利用路径穿越把 URL 映射到 Alias 等配置目录之外的文件;如果这些目录外文件没有受到默认 require all denied 保护,请求就可能成功;若同时启用 CGI,还可能导致远程代码执行。
3.3.2 漏洞成因
Apache 2.4.49路径规范化变更
↓
编码后的 . 被绕过
↓
路径穿越生效
↓
读取Web目录外文件
↓
如果CGI开启,则可能RCE- 说白了:*
正常情况下,Web服务器不应该让你访问:
/etc/passwd但漏洞版本 Apache 在处理编码路径时出了问题,导致攻击者可以通过特殊编码绕过路径限制。
3.3.3 漏洞复现
可以使用vulfocus来搭建环境
注册登录,搜索41773启动即可

启动完成给了环境地址

访问容器环境

payload:
//抓包,发送以下请求数据内容
GET /icons/.%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etc/passwd HTTP/1.1
...
它的核心意思是:
通过 /icons/ 这个可访问目录作为入口,
利用多层编码的 ../ 一层层跳出 Web 目录,
最后访问 Linux 系统文件 /etc/passwd。普通目录穿越一般长这样:
/icons/../../../../etc/passwd含义是:
/icons/ 当前可访问目录
../ 返回上一级
../ 再返回上一级
../ 再返回上一级
../ 再返回上一级
/etc/passwd 读取系统用户文件也就是:
从 /icons/ 目录一路往上跳,最后到 /etc/passwd- 为什么 payload 里不是直接写
../?*
因为 Apache 会对路径做安全检查。
如果直接请求:
/icons/../../../../etc/passwd服务器通常会识别出:
../然后拦截。
所以攻击者会把 . 编码,绕过检查。
%%32%65是什么?*
先拆开:
%%32%65可以理解成:
% + %32 + %65其中:
%32 = 字符 2
%65 = 字符 e所以:
%%32%65经过第一次解码后会变成:
%2e而:
%2e再次解码后就是:
.所以:
%%32%65本质上是对点号 . 做了“双重编码”。
- 那
%%32%65%%32%65是什么?*
%%32%65%%32%65可以拆成两个:
%%32%65 + %%32%65第一次解码后:
%2e%2e第二次解码后:
..所以:
%%32%65%%32%65最终等价于:
..- 为什么入口是
/icons/?*
Apache 默认配置里经常有类似:
Alias /icons/ "/usr/local/apache2/icons/"或者:
Alias /icons/ "/var/www/icons/"/icons/ 是一个通过 Alias 暴露出来的静态目录。
漏洞利用时,攻击者借助这个合法路径作为起点:
/icons/然后通过路径穿越:
../../../../跳出它原本应该访问的目录范围。
所以:
/icons/../../../../etc/passwd实际想访问的是:
/etc/passwd- 这个 payload 对应哪个漏洞?*
这个双重编码形式更典型地对应:
CVE-2021-42013它是:
CVE-2021-41773 的补丁绕过两个漏洞关系:
| 漏洞 | 影响版本 | 绕过方式 |
|---|---|---|
| CVE-2021-41773 | Apache 2.4.49 | 单层编码,如 .%2e/ |
| CVE-2021-42013 | Apache 2.4.50 | 双重编码,如 .%%32%65/ |
简单理解:
2.4.49:第一次修坏了路径规范化
2.4.50:补丁没修完整,双重编码还能绕
2.4.51:正式修复3.4 CVE-2021-42013 Apache路径穿越补丁绕过
3.4.1 漏洞简介
CVE-2021-42013 是 CVE-2021-41773 的补丁绕过漏洞。
- 编号:CVE-2021-42013
- 类型:路径穿越 / 文件读取 / 特定条件下RCE
- 影响版本:Apache HTTP Server 2.4.49、2.4.50
- 修复版本:2.4.51+
Apache 官方说明:2.4.50 对 CVE-2021-41773 的修复不完整,攻击者仍可利用路径穿越访问 Alias 类配置目录之外的文件;若 CGI 脚本也开启,可能导致远程代码执行。
3.4.2 两个漏洞区别
| 漏洞 | 影响版本 | 本质 |
|---|---|---|
| CVE-2021-41773 | Apache 2.4.49 | 路径规范化缺陷 |
| CVE-2021-42013 | Apache 2.4.49 / 2.4.50 | 41773补丁绕过 |
3.4.4 防御建议
1. 升级Apache到2.4.51或更高版本
2. 确保Web根目录外使用 Require all denied
3. 禁用不必要的CGI模块
4. 关闭目录浏览 Options -Indexes
5. 最小权限运行Apache进程
6. WAF拦截编码目录穿越路径安全配置示例:
<Directory />
Require all denied
</Directory>
<Directory "/var/www/html">
Require all granted
Options -Indexes
</Directory>3.5 CVE-2017-15715 文件解析漏洞(Apache HTTPD 换行解析漏洞)
3.5.1 漏洞简介
CVE-2017-15715 是 Apache HTTPD 的一个 文件名解析绕过漏洞,也常被叫做:
Apache HTTPD 换行解析漏洞
Apache FilesMatch 换行绕过漏洞
Apache 文件解析漏洞- 编号:CVE-2017-15715
- 类型:文件解析 / 后缀绕过
- 影响组件:Apache HTTP Server
- 影响版本:Apache HTTPD 2.4.0 - 2.4.29
- 修复版本:Apache HTTPD 2.4.33+
- 典型危害:绕过上传限制,使带特殊文件名的 PHP 文件被解析执行
Apache 官方漏洞说明中提到,<FilesMatch> 中的正则表达式可能会把 $ 匹配到恶意文件名中的换行符,而不是只匹配真正的文件名结尾;该问题影响 2.4.1 到 2.4.29,并在 2.4.33 中修复。
- 漏洞一句话理解*
Apache 在判断文件名是否以.php结尾时,可能把文件名中的换行符\x0A当成“结尾”,导致1.php\x0A这种文件也被当作 PHP 文件解析。
3.5.2 漏洞成因
很多 Apache + PHP 环境会用类似配置来告诉 Apache:
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>正常理解:
只有以 .php 结尾的文件
才交给 PHP 解析也就是:
1.php → 解析
1.jpg → 不解析
1.php.jpg → 不解析但在漏洞版本中,$ 这个正则结尾符存在问题。
在某些情况下:
1.php\x0A会被 Apache 判断为:
1.php因为:
\x0A = 换行符Apache 的 <FilesMatch \.php$> 可能把 $ 匹配到换行符之前的位置。
于是:
1.php\x0A也会命中:
<FilesMatch \.php$>最终被 PHP 解析。
所以:
1.php\x0A就可以绕过后缀检查。
- 核心问题:*
$ 本来应该匹配整个字符串的真正结尾
但漏洞版本中,它可能匹配到换行符前面3.5.3 漏洞复现
这里使用Vulhub搭建
https://github.com/vulhub/vulhub/blob/master/httpd/CVE-2017-15715/README.zh-cn.md

复现过程
首先,尝试上传一个名为 1.php 的文件,可以看到上传被安全检查拦截:

但是,如果我们在文件名 1.php 后面添加一个 \x0A(注意:必须是单独的 \x0A,而不是 \x0D\x0A),上传就会成功:
我们再次上传,使用bp 抓包,修改数据包的十六进制信息,找到此处,可以将0d修改为0a,或者不修改直接插入0a也可以,均可实现。修改完成后放包即可。

访问/1.php%0a,虽然该文件没有正确的 PHP 扩展名,但它会被成功解析为 PHP 文件。这证实了解析漏洞的存在:

3.5.4 POC拆解
文件名:
1.php%0A拆开:
1.php → 用来匹配 .php 后缀
%0A → 换行符Apache 解析逻辑:
用户访问 1.php%0A
↓
URL解码后变成 1.php\x0A
↓
<FilesMatch \.php$> 判断
↓
$ 错误匹配到换行符前
↓
认为文件名以 .php 结尾
↓
交给 PHP 解析正常安全预期应该是:
1.php\x0A 不等于 1.php但漏洞版本中会出现:
1.php\x0A 被当成 PHP 文件3.5.5 和普通文件上传绕过的区别
| 绕过方式 | 示例 | 原理 |
|---|---|---|
| 双后缀 | 1.php.jpg | 利用后端校验不严 |
| 大小写 | 1.pHp | 利用大小写匹配不严 |
| 空格绕过 | 1.php | 利用系统/程序处理差异 |
| 换行绕过 | 1.php%0A | 利用 Apache <FilesMatch> 对 $ 的解析缺陷 |
CVE-2017-15715 的关键不是上传校验本身,而是 Apache 对:
<FilesMatch \.php$>里的 $ 理解出了问题。
3.5.6 完整攻击链
发现目标使用 Apache 2.4.0 - 2.4.29
↓
网站存在文件上传功能
↓
上传 1.php\x0A 文件
↓
上传目录允许 PHP 解析
↓
访问 /upload/1.php%0A
↓
Apache 命中 <FilesMatch \.php$>
↓
PHP代码被执行
↓
造成代码执行风险3.5.10 防御建议
1. 升级 Apache HTTPD 到 2.4.33 或更高版本
2. 上传目录禁止 PHP / CGI / 脚本执行
3. 不要只依赖 FilesMatch 做安全边界
4. 文件上传后统一重命名,禁止用户控制文件名
5. 过滤文件名中的控制字符,例如 \x00、\x0A、\x0D
6. 使用白名单校验文件内容和扩展名
7. 将上传目录放到 Web 根目录之外安全配置示例:
<Directory "/var/www/html/upload">
php_admin_flag engine off
Options -ExecCGI
RemoveHandler .php .phtml .php3 .php4 .php5
RemoveType .php .phtml .php3 .php4 .php5
</Directory>更推荐的安全思路:
上传文件不直接落到 Web 可访问目录
↓
后端生成随机文件名
↓
只允许作为静态资源下载
↓
下载时通过程序读取并返回4.Nginx漏洞总结
4.1 Nginx简介
Nginx 是一款高性能 Web 服务器,也常作为:
1. 静态资源服务器
2. 反向代理
3. 负载均衡
4. FastCGI转发器
5. HTTP缓存服务器常见架构:
浏览器
↓
Nginx
↓
PHP-FPM / 后端服务 / 静态文件Nginx 本身通常不直接执行 PHP,而是把 PHP 请求转发给 PHP-FPM:
Nginx匹配.php
↓
设置SCRIPT_FILENAME
↓
转发给PHP-FPM
↓
PHP-FPM执行脚本所以 Nginx 相关漏洞很多不是“程序漏洞”,而是:
配置错误 + FastCGI解析差异4.2 Nginx解析漏洞
4.2.1 漏洞简介
Nginx 解析漏洞通常是配置错误造成的。
该漏洞与 Nginx、PHP 具体版本无关,属于用户配置不当造成的解析漏洞。
4.2.2 漏洞成因
常见错误配置:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}问题在于:
Nginx把某些特殊路径交给PHP-FPM
↓
PHP-FPM根据SCRIPT_FILENAME处理
↓
上传文件被当作PHP执行典型请求:
/uploadfiles/nginx.png/.php表面上访问的是:
nginx.png/.php但在错误配置下,PHP-FPM 可能把前面的 nginx.png 当作可执行脚本处理。
4.2.3 环境搭建
使用vulhub搭建,或者使用vulfocus在线搭建
https://github.com/vulhub/vulhub/blob/master/nginx/nginx_parsing_vulnerability/README.zh-cn.md
访问:
4.2.4 漏洞验证
正常访问图片:
http://125.77.172.32:28081/uploadfiles/nginx.png
追加 /.php:
http://125.77.172.32:28081/uploadfiles/nginx.png/.php如果图片内容中的 PHP 代码被解析,说明存在解析漏洞。

4.2.5 防御建议
1. 不允许上传目录执行PHP
2. PHP location中使用 try_files 校验真实文件
3. 设置 cgi.fix_pathinfo=0
4. 上传文件重命名,去除用户可控后缀
5. 上传目录放到Web根目录外cgi.fix_pathinfo=0 的作用是:禁止 PHP-FPM 在找不到精确脚本文件时,继续向前猜测可执行的 PHP 文件。
很多 PHP 环境中,历史上默认可能是:
cgi.fix_pathinfo=1意思是:
如果 SCRIPT_FILENAME 指向的文件不存在,
PHP-FPM 会尝试从路径中“向前找”一个真实存在的 PHP 文件来执行。举个例子。
假设服务器上真实存在一个文件:
/var/www/html/upload/1.jpg它内容里可能包含 PHP 代码。
用户访问:
/upload/1.jpg/1.phpNginx 可能把请求交给 PHP-FPM,并设置:
SCRIPT_FILENAME=/var/www/html/upload/1.jpg/1.php这个路径本身不存在。
如果:
cgi.fix_pathinfo=1PHP-FPM 可能会向前查找:
/var/www/html/upload/1.jpg/1.php 不存在
/var/www/html/upload/1.jpg 存在然后把:
/var/www/html/upload/1.jpg当作 PHP 脚本执行。
4.3 Nginx文件名逻辑漏洞 CVE-2013-4547
4.3.1 漏洞简介
CVE-2013-4547 是 Nginx 文件名解析逻辑漏洞。
- 编号:CVE-2013-4547
- 类型:文件名解析漏洞 / 权限绕过 / 特定条件下代码执行
- 影响版本:Nginx 0.8.41 到 1.4.3,以及 1.5.x 到 1.5.7
4.3.2 漏洞成因
错误配置:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}构造请求:
1.gif[0x20][0x00].php拆开看:
1.gif + 空格 + NUL字节 + .php作用:
| 部分 | 作用 |
|---|---|
1.gif | 真实存在的文件名,末尾有空格 |
[0x00] | NUL截断 |
.php | 让请求匹配 \.php$ 进入PHP location |
4.3.3 与Nginx解析漏洞的区别
区别可以一句话概括:
Nginx解析漏洞:主要是 Nginx + PHP-FPM 配置不当,导致非PHP文件被当成PHP执行。
CVE-2013-4547:是 Nginx 老版本自身的文件名解析逻辑漏洞,利用空格和NUL造成“正则匹配”和“真实文件名”不一致。4.3.3.1 漏洞性质不同
| 对比项 | Nginx解析漏洞 | CVE-2013-4547 |
|---|---|---|
| 本质 | 配置错误 | Nginx自身漏洞 |
| 是否有CVE | 通常没有固定CVE | 有,CVE-2013-4547 |
| 主要原因 | PHP-FPM 的 PATH_INFO 解析 + Nginx错误转发 | Nginx URI/文件名解析逻辑错误 |
| 是否依赖老版本Nginx | 不一定 | 是 |
是否依赖 cgi.fix_pathinfo | 经常依赖 | 不主要依赖 |
| 典型 payload | /1.jpg/.php | /1.gif[空格][NUL].php |
4.3.3.2 Nginx解析漏洞是什么
典型 payload:
/uploadfiles/1.jpg/.php真实文件:
/uploadfiles/1.jpg错误配置类似:
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}访问:
/uploadfiles/1.jpg/.phpNginx 看到 URI 里符合 PHP 匹配规则,就把请求交给 PHP-FPM。
PHP-FPM 收到:
SCRIPT_FILENAME=/var/www/html/uploadfiles/1.jpg/.php这个路径不存在。
如果 PHP 开启:
cgi.fix_pathinfo=1PHP-FPM 可能向前找真实存在的文件:
/var/www/html/uploadfiles/1.jpg/.php 不存在
/var/www/html/uploadfiles/1.jpg 存在于是把:
1.jpg当作 PHP 脚本执行。
所以它的核心链路是:
Nginx错误转发
↓
PHP-FPM向前猜文件
↓
图片文件被当PHP执行4.3.3.3 CVE-2013-4547是什么
典型 payload:
/uploadfiles/1.gif[0x20][0x00].php也就是:
/uploadfiles/1.gif 空格 NUL .php真实上传的文件名是:
1.gif 注意末尾有一个空格。
它的问题不是普通的 PATH_INFO,而是 Nginx 老版本对 URI 和文件名的处理出现了差异。
对 Nginx 的 location 正则来说:
1.gif[空格][NUL].php看起来能匹配:
location ~ \.php$ {
}因为后面有:
.php于是请求进入 PHP 解析逻辑。
但 Nginx 设置 SCRIPT_FILENAME 时,又可能把真实文件名识别成:
1.gif[空格]也就是:
1.gif 所以 PHP-FPM 最终处理的是这个带空格结尾的文件。
核心链路是:
上传 1.gif[空格]
↓
请求 1.gif[空格][NUL].php
↓
Nginx正则认为它是.php请求
↓
Nginx实际取文件名时认为它是 1.gif[空格]
↓
PHP-FPM解析 1.gif[空格]4.3.3.4 两个漏洞的 payload 为什么不一样
- Nginx解析漏洞*
/1.jpg/.php利用的是路径结构:
真实文件 / 伪造PHP路径重点是:
PATH_INFO也就是:
1.jpg 后面又接了 /.php- CVE-2013-4547*
/1.gif[0x20][0x00].php利用的是文件名特殊字符:
空格 + NUL字节重点是:
文件名解析差异不是通过 /xxx.php 这种 PATH_INFO 结构,而是通过:
Nginx看到的URI和:
Nginx最终解析出的真实文件名不一致。
4.3.3.5 是否依赖 cgi.fix_pathinfo
- Nginx解析漏洞*
通常和这个配置强相关:
cgi.fix_pathinfo=1如果改成:
cgi.fix_pathinfo=0并且 Nginx 配置了:
try_files $uri =404;那么:
/1.jpg/.php一般就不能被解析。
- CVE-2013-4547*
它的核心不是 PHP-FPM 向前猜文件,而是 Nginx 老版本错误设置了文件名。
所以:
cgi.fix_pathinfo=0不一定能从根本上解决 CVE-2013-4547。
根本修复方式是:
升级 Nginx 到安全版本同时加强:
过滤文件名中的空格、NUL、控制字符
上传目录禁止解析PHP4.3.4 环境搭建
使用vulhub搭建,或者使用vulfocus在线搭建
https://github.com/vulhub/vulhub/blob/master/nginx/CVE-2013-4547/README.zh-cn.md
访问:
注意这个环境如果访问上传文件一直404,可以改下docker compose文件
services:
nginx:
image: vulhub/nginx:1.4.2
volumes:
- ./nginx.conf:/usr/local/nginx/conf/nginx.conf
- ./index.php:/usr/local/nginx/html/index.php
- ./uploadfiles:/usr/local/nginx/html/uploadfiles
ports:
- "28082:80"
php:
image: vulhub/php:5.6-fpm
command:
- bash
- -c
- "mkdir -p /var/www/html/uploadfiles && chown -R www-data:www-data /var/www/html/uploadfiles && php-fpm"
volumes:
- ./index.php:/var/www/html/index.php
- ./www.conf:/usr/local/etc/php-fpm.d/zz-docker.conf
- ./uploadfiles:/var/www/html/uploadfiles4.3.5 漏洞验证
这个环境是黑名单验证,我们无法上传php后缀的文件

修改上传文件名:
2.gif 注意最后有一个空格。

访问:
http://125.77.172.32:28082/uploadfiles/2.gif[0x20][0x00].php这里需要抓包,然后在bp 抓的包的hex里手动加上00

即可发现PHP已被解析
4.3.6 利用过程
对Nginx正则来说:
1.gif 空格 NUL .php 以 .php 结尾
↓
可以进入 location ~ \.php$
对真实文件名来说:
NUL后面的 .php 被截断
↓
真实文件变成 1.gif空格完整攻击链:
上传带空格结尾的文件
↓
构造 1.gif[空格][NUL].php
↓
Nginx认为它是.php请求
↓
PHP-FPM实际拿到 1.gif[空格]
↓
文件内容被PHP解析4.3.7 防御建议
1. 升级Nginx到安全版本
2. 上传文件名去除尾随空格、控制字符、NUL字节
3. PHP location中使用 try_files $uri =404
4. 上传目录禁止PHP解析
5. 严格限制上传文件类型和内容4.4 Nginx配置错误漏洞
这里重点说一下Nginx alias目录穿越漏洞
4.4.1 漏洞简介
Nginx 使用 alias 做目录映射时,如果 location 没有以 / 结尾,可能导致目录穿越。
错误配置:
location /files {
alias /home/;
}原本目的:
/files/a.txt → /home/a.txt但实际可能出现:
/files../ → /home/../ → /因此,Nginx 在配置 alias 时,如果忘记加 /,将造成目录穿越漏洞;
示例 payload 为 http://your-ip:8081/files../,可穿越到根目录。
4.4.2 漏洞成因
location /files
↓
匹配 /files../
↓
alias /home/
↓
/files 被替换成 /home/
↓
/home/../
↓
穿越到上级目录4.4.3 正确配置
location /files/ {
alias /home/;
}核心区别:
错误:location /files
正确:location /files/4.4.4 防御建议
1. alias对应的location必须以/结尾
2. alias目标路径也建议以/结尾
3. 禁止autoindex
4. 对敏感目录增加访问控制
5. 避免将alias指向系统敏感目录安全配置:
location /files/ {
alias /home/;
autoindex off;
}5.IIS&Apache&Nginx漏洞对比总结
| 中间件 | 漏洞类型 | 典型漏洞 | 核心原因 |
|---|---|---|---|
| IIS | 解析漏洞 | IIS 6.0 .asp/xx.jpg、;解析 | 老版本解析规则缺陷 |
| IIS | 信息泄露 | 短文件名漏洞 | Windows 8.3短文件名机制 |
| IIS | 文件写入 | WebDAV PUT | WebDAV开启且目录可写 |
| IIS | RCE | CVE-2017-7269 | WebDAV缓冲区溢出 |
| Apache | 目录浏览 | Options +Indexes | 目录索引开启 |
| Apache | 路径穿越 | CVE-2021-41773 | 路径规范化缺陷 |
| Apache | 补丁绕过 | CVE-2021-42013 | 41773修复不完整 |
| Nginx | 解析漏洞 | xx.jpg/.php | FastCGI配置错误 |
| Nginx | 文件名逻辑漏洞 | CVE-2013-4547 | URI与文件名解析差异 |
| Nginx | 目录穿越 | alias忘记加 / | location匹配过宽 |
| Nginx | Header注入 | CRLF注入 | $uri解码后拼接响应头 |