【服务器特性】结合服务器/CMS:解析漏洞实战
前言
在前面几期中,我们学习了如何绕过前端、黑白名单、MIME 以及文件头校验。有些读者可能会问:
"如果后端的白名单校验极其严密,我们只能上传纯粹的
.jpg或.png图片,且没有文件包含漏洞,那图片马不就彻底成了摆设吗?"答案是:不一定!
很多时候,代码写得没问题,但Web 服务器(Apache / Nginx / IIS)本身的解析机制或配置缺陷,会强行把正常后缀的图片当成脚本去执行。今天我们就来盘点三大主流 Web 服务器的解析漏洞!

💡 1. 什么是解析漏洞?
简单来说,解析漏洞(Parsing Vulnerability) 不是由于应用程序(PHP/Java 代码)写错产生的,而是因为 Web 服务器在处理特定文件名格式、畸形请求或特殊路径时,产生了逻辑判断失误 ,将原本安全的文件(如 .jpg、.txt)送交给了脚本解释器(如 php-cgi)去运行。
[用户请求] ──► /upload/avatar.jpg/1.php
│
(服务器解析机制缺陷)
▼
[误认为这是 PHP 脚本并强制运行!]
🛠️ 2. Apache 解析漏洞
Apache 服务器在历史上出现过两种最经典的解析缺陷。
缺陷一:多后缀未知扩展名解析漏洞(从右往左解析)
📌 原理剖析
Apache 在处理含有多个后缀的文件(如 webshell.php.gif.a.b)时,遵循 "从右往左" 的识别规则:
- 先看最右侧的
.b,Apache 不认识这个扩展名; - 往左看
.a,依然不认识; - 继续往左看
.gif,认识,但发现再往左还有.php; - 如果 Apache 配置了处理 PHP 的句柄,它会忽略后面所有不认识的扩展名 ,直接将整个文件当成
PHP代码来解析!
🛠️ 实战利用 (upload-labs Pass-04 衍生)
- 目标网站后端采用白名单或黑名单限制,但允许上传多个后缀。
- 将一句话木马文件命名为:
webshell.php.7z或webshell.php.jpeg.abc。 - 后端校验时:看见后缀是
.7z或.abc(不在黑名单中),准许上传。 - 访问时:直接访问
[http://target.com/upload/webshell.php.7z](http://target.com/upload/webshell.php.7z),Apache 会自动将其识别并按 PHP 运行!
缺陷二:换行符绕过漏洞(CVE-2017-15715)
📌 原理剖析
在 Apache 2.4.0 ~ 2.4.29 版本中,如果在配置文件中使用了正则匹配来防止上传脚本文件(例如 <FilesMatch "\.php$">),正则表达式中的 $ 默认匹配字符串末尾,但也匹配换行符 \n(十六进制 0x0a)前面的位置。
🛠️ 实战利用
- 准备文件名
webshell.php。 - 在 Burp Suite 的 Hex(十六进制)视图中,在文件名末尾添加一个
0x0a字节,变成webshell.php\n。 - 后端正则表达式校验:
\.php$匹配成功,放行上传。 - Apache 保存文件并解析时,能正常识别并以 PHP 方式执行。
⚡ 3. Nginx 解析漏洞(畸形路径解析)
Nginx 本身的解析漏洞非常少,但在常见的 Nginx + PHP-FPM 组合配置中,极易因为配置不当引发严重的畸形路径解析漏洞。
📌 原理剖析(cgi.fix_pathinfo 机制)
在 PHP 的配置文件 php.ini 中,存在一个默认开启的配置项:
ini
cgi.fix_pathinfo = 1
这个配置项的作用是:当请求的文件路径不存在时,PHP 会顺着路径向上递归寻找真正存在的文件。
当用户请求路径:[http://target.com/upload/avatar.jpg/1.php](http://target.com/upload/avatar.jpg/1.php)
- Nginx 看到请求以
.php结尾,便把请求转交给后端的 PHP-FPM 处理。 - PHP-FPM 去找
1.php,发现磁盘上根本没有这个文件! - 因为
cgi.fix_pathinfo=1开着,PHP-FPM 开始"向上剥离"路径,发现/upload/avatar.jpg是真实存在的。 - PHP-FPM 就会把
avatar.jpg当作 PHP 文件执行 ,并将/1.php作为PATH_INFO传给脚本。
🛠️ 实战利用
- 制作一个合法的图片马
avatar.jpg并成功上传到服务器。 - 假设获得的图片地址为:
[http://target.com/upload/avatar.jpg](http://target.com/upload/avatar.jpg)。 - 在图片 URL 后面人为追加斜杠和任意
.php文件名:
[http://target.com/upload/avatar.jpg/x.php](http://target.com/upload/avatar.jpg/x.php) - 页面返回木马执行结果,成功获取服务器控制权!
🏛️ 4. IIS 解析漏洞
微软的 IIS(Internet Information Services)在 6.0 和 7.x 版本中也曾暴露过极具代表性的解析缺陷。
缺陷一:IIS 6.0 目录解析与分号截断漏洞
1. 目录解析漏洞
- 现象 :当服务器上存在名为
*.asp的文件夹时,该目录下的所有文件(哪怕是.jpg、.txt)都会被 IIS 强制当作 ASP 脚本来解析。 - 利用 :创建或上传文件到目录
/blog.asp/logo.jpg,访问该logo.jpg即会执行里面的 ASP 代码。
2. 分号截断漏洞(;)
- 现象 :IIS 6.0 在处理文件名时,如果文件名中包含分号
;,它会忽略分号后面的内容。 - 利用 :上传文件名改为
webshell.asp;.jpg。 - 黑/白名单 :检查后缀看最右侧,认为是
.jpg,放行。 - IIS 6.0 解析 :截断分号后面的内容,直接当成
webshell.asp执行。
缺陷二:IIS 7.0 / 7.5 解析漏洞
与 Nginx 类似,IIS 7.0/7.5 在 FastCGI 模式下运行 PHP 时,如果配置不当,同样会触发与上述 Nginx 类似的 cgi.fix_pathinfo 畸形路径解析漏洞。
- 利用方式 :在成功上传的图片后追加
/.php(如[http://target.com/shell.png/.php](http://target.com/shell.png/.php))。
🔍 5. 源码剖析与正确防御
解析漏洞的根源在于系统环境与容器配置缺陷。想要彻底根除,需要针对不同的中间件进行强化配置。
防御 1:配置 Nginx / PHP-FPM 禁绝畸形解析
方案 A:彻底关闭 PHP 的路径修复(推荐)
修改 php.ini 文件:
ini
cgi.fix_pathinfo = 0
方案 B:Nginx 检查文件物理存在性
在 Nginx 配置文件中加入条件判断,如果物理文件不存在,直接返回 404,不传递给 PHP-FPM:
nginx
location ~ \.php$ {
# 如果文件物理不存在,直接 404
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
防御 2:正确配置 Apache 模块
针对 Apache 多后缀解析,不要在 httpd.conf 中使用以下模糊配置:
apache
# ❌ 错误配置:会将所有文件名包含 .php 的文件都交给 PHP 处理
AddHandler application/x-httpd-php .php
应该使用严密的正则匹配:
apache
# ✅ 正确配置:精确匹配以 .php 结尾的文件
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
防御 3:终极解法------禁止上传目录执行脚本
无论中间件有什么漏洞,只要存储上传文件的目录根本不允许运行脚本,攻击者就只能眼睁睁看着图片马失效。
例如在 Nginx 中禁止 /uploads/ 目录运行任何 PHP 脚本:
nginx
location ~ ^/uploads/.*\.php$ {
deny all;
}
📝 6. 本章总结卡片
| Web 服务器 | 漏洞类型 | 触发条件 / 请求形式 | 防御核心 |
|---|---|---|---|
| Apache | 多后缀解析 | shell.php.jpeg.abc(从右往左识别未识别后缀) |
精确匹配 \.php$,禁用模糊 AddHandler |
| Apache | 换行符绕过 (CVE-2017-15715) | shell.php%0a(匹配换行符) |
升级 Apache 版本,严格正则限制 |
| Nginx / IIS 7.x | 畸形路径解析 | shell.png/x.php(依赖 cgi.fix_pathinfo=1) |
设置 cgi.fix_pathinfo=0 或配置 try_files |
| IIS 6.0 | 目录 / 分号解析 | /folder.asp/x.jpg 或 x.asp;.jpg |
升级老旧 IIS 系统,关闭废弃解析规则 |