Fork me on GitHub

phpmyadmin远程文件包含漏洞

phpmyadmin 这个漏洞可以说是由于太过细心而导致的,这也证实了安全永远在路上

这个本地文件包含的漏洞确实挺巧妙地,分析一下:

漏洞利用分析

在GitHub上找了一下phpmyadmin的源码,不过话说我还不知带phpmyadmin怎么安装,之后研究一下

index.php

看到这串代码if判断很多,主要是最后一个判断

1
2
3
4
5
6
7
8
9
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;
}

注意preg_match('/^index/', $_REQUEST['target'])是判断是不是以index开头,如果是就返回true,但是由于!所以就不能以index开头,类似这种判断不要被绕晕了

Core::checkPageValidity检查,问题就出在这,方法定义在443行

黑名单如下

1
2
3
$target_blacklist = array (
'import.php', 'export.php'
);

方法具体如下:

1
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
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;
}

如果我们两个词URL编码。即%253f 浏览器传送之后变成%3f此时前两次if都不会进去,最后一次先urldecode,那么就变成了? 这时候是可以绕过的。

之所以要两次编码,直接用一个”?”不也可以绕过吗。

会导致这样的问题不能包含成功,具体为什么我也不是很清楚

hctf2018

这篇文章已经讲的很详细了,这里写一下hctf2018的一道热身题,当时都还没仔细想过是一个已经存在的CVE

题目源码:

1
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
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;
}
echo "you can't see it";
return false;
}
}

if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>

题目要绕过不算难,但是有一个地方很重要

这是我在本地调试的目录:

调试的时候我使用了如下payload

http://localhost/audit/warmup.php?file=source.php%253f/../flag.php

此时能够成功绕过

就在这种情况下,文件包含也是成功的!

根据题目提示flag在某个位置,其实这里靠猜了,因为只能用../这样的来回到上一级目录

参考

phpmyadmin4.8.1远程文件包含漏洞
phpmyadmin4.8.1后台getshell

phpMyAdmin 4.8.x 本地文件包含漏洞利用

突然还发现一个可以复现很多漏洞的地方 https://www.vulnspy.com/phpmyadmin-4.8.1/

github地址: https://github.com/vulnspy/phpmyadmin-4.8.1