一、漏洞基本信息
- 影响版本:phpMyAdmin 4.8.0、4.8.1
- 漏洞类型:任意文件包含漏洞
- CVE 编号:CVE-2018-12613
- 危害等级:高危,可读取服务器任意文件,在特定条件下可 getshell
二、漏洞根源
漏洞存在于 phpMyAdmin 根目录index.php的请求路由逻辑中:
- 程序通过
$_REQUEST['target']参数动态加载页面 - 为了防止非法访问,设计了
Core::checkPageValidity()白名单检查函数 - 该函数存在致命缺陷:会对输入参数进行额外的一次 URL 解码,然后截取第一个问号之前的部分进行白名单检查
- 只要检查通过,就会直接执行
include $_REQUEST['target'],没有任何进一步的过滤
三、核心利用原理
1. 两次 URL 编码绕过白名单
这是整个漏洞最关键的利用技巧:
- 浏览器 / 服务器会自动对 URL 进行一次解码
- 代码中又会执行一次
urldecode() - 因此需要对问号
?进行两次 URL 编码(?→%3f→%253f) - 两次解码后还原为问号,函数截取问号前的白名单文件(如
db_sql.php)通过检查 - 最终执行
include时使用的是完整的原始路径
2. 目录穿越读取任意文件
- 利用
../向上遍历目录,访问服务器文件系统中的任意文件 - 操作系统内核会自动忽略根目录之后多余的
../,因此写 8-10 个../可以兼容所有部署环境 - 典型目标:
/etc/passwd、/flag、网站源代码文件等
四、漏洞利用通用 Payload 结构
plaintext
/phpmyadmin/index.php?target=[白名单文件]%253f/[N个../][目标文件路径]
- 白名单文件:
db_sql.php、db_datadict.php、db_export.php等 - N:通常取 8-10,确保能回溯到系统根目录
- 目标文件路径:要读取的文件的绝对路径或相对路径
五、漏洞限制与边界
- open_basedir 限制:如果 PHP 配置了
open_basedir,单纯的目录穿越会失效,需要使用专门的绕过技巧 - 数据库权限限制:低权限数据库用户无法通过修改全局变量(如
general_log)的方式写 shell - PHP 版本限制:该漏洞不依赖特定 PHP 版本,只要 phpMyAdmin 版本符合即可利用
六、漏洞本质与启示
- 这是一个典型的输入验证不充分导致的漏洞
- 白名单机制本身是安全的,但实现过程中的微小疏忽(多余的解码操作)会导致完全被绕过
- 路径解析过程中的层级差异(URL 路径与文件系统路径不一致)是很多 Web 漏洞的根源
- 多写
../永远是 CTF 中文件包含漏洞的最佳实践,兼容性最强且绝对无害