zoukankan      html  css  js  c++  java
  • warm_up

    warm_up

    本来想着倒头睡觉的,但是万分愧疚,觉得得再做个题才行,于是点开了这道warm up

    先谈谈感受吧,(自己还是懂的太少了),这种用到CVE的题,需要理解的知识点不是单一的,而且要有很缜密的思维,可以说是需要很多的经验积累的。加油吧!

    看题,打开是个滑稽标签

    1

    f12看源码,提示有source.php,代码:

    <?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\" />";
        } 
     ?> flag not here, and flag in ffffllllaaaagggg
    

    得安排时间学学代码审计的姿势了

    提示代码在ffffllllaaaagggg中

    看题,想要访问传入的file需要满足几个条件:

    • file非空
    • file是string
    • emmm::checkFile返回true
      • (checkFile返回true的条件)file能通过in_array()检验

    前两个条件没有问题,但第三个没有思路,仔细看了两边代码,去查了下in_array()和mb_substr()

    mb_substr ( string $str , int $start [, int $length = NULL [, string $encoding = mb_internal_encoding() ]] ) : string

    根据字符数执行一个多字节安全的 substr() 操作。 位置是从 str 的开始位置进行计数。 第一个字符的位置是 0。第二个字符的位置是 1,以此类推。

    in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) : bool

    在array中查询needle,有则返回true。如果没有设置 strict ,那么比较时只会比较值,不会比较类型。

    补充:in_array()函数的弱类型比较利用:

    <?php
    
    // Example array
    
    $array = array(
      'egg' => true,
      'cheese' => false,
      'hair' => 765,
      'goblins' => null,
      'ogres' => 'no ogres allowed in this array'
    );
    
    // Loose checking -- return values are in comments
    
    // First three make sense, last four do not
    
    in_array(null, $array); // true
    in_array(false, $array); // true
    in_array(765, $array); // true
    in_array(763, $array); // true
    in_array('egg', $array); // true
    in_array('hhh', $array); // true
    in_array(array(), $array); // true
    
    // Strict checking
    
    in_array(null, $array, true); // true
    in_array(false, $array, true); // true
    in_array(765, $array, true); // true
    in_array(763, $array, true); // false
    in_array('egg', $array, true); // false
    in_array('hhh', $array, true); // false
    in_array(array(), $array, true); // false
    
    ?>
    

    回到题目中,想尝试下in_array()弱类型的漏洞,但无法构造有效的payload,只好放弃,另寻他路。

    搜索到一位前辈的wp,记录了解题思路和要点(感谢),也提到了这是CVE-2018-12613

    下面是我在读过wp之后的结题思路:

    bypass重点在checkFile函数,看函数的代码

    • 检测page的类型必须是set或者string
    • 传入page后,把page和白名单对比,如果在白名单里就直接返回true,不在则进入下一步,因为要访问ffffllllaaaagggg
    • 提取page里第一个问号前的字符串并拿来和白名单对比
    • urldecode,然后重复上一步的操作
    • 前边没有返回的话,最后会返回false

    这里有个前置的知识点:

    传入的参数(比如这里的hint.php)后边加上(可以是两次urlencode)任意字符和目录,那么服务器会把这个参数当作目录处理

    例如:include 'x.x/../../../../../1.txt';,php会将include_path常量与该路径组合起来,即path = include_path.'x.x/../../../../../1.txt',然后去访问该文件,判断其是否存在,这个机制给予了我们实现目录穿越的机会。(x为除过截止字符、目录分隔符、系统不允许的空白字符之外的任意字符)

    两次urlencode的原因是,服务器接收到数据包后会自动decode一次

    既然有了访问目录的法子,就来想下怎么绕过检测函数呢?

    这里刚好有问号,而检测函数里会截取file参数里问号之前的内容和白名单比对,所以两次urlencode的问号(一次被服务器decode,一次等函数中的decode)刚好符合情况。

    函数中:

    • 第一次白名单没过
    • 提取的字符串等于本身(没有变化)
    • urldecode,让file里出现了问号
    • 提取了file中问号前的字符并与白名单比对,到这里就可以构造payload了

    payload :

    • ?file=hint.php%253f/../../../../../../ffffllllaaaagggg(最后一次比对时返回true)
    • ?file=hint.php?/../../../../../../ffffllllaaaagggg(第一次比对时返回true)

    自己的基础真的还差很多,肝!

  • 相关阅读:
    利用正则表达式去掉html代码
    TYPE='application/xshockwaveflash'
    SQL存储过程事务和优化方法(包括查询方式语句结合)
    C#中Bitmap类实现对图像操作的一些方法
    回首往事,碩果累累,展望未來,信心滿懷。
    此方法用于确认用户输入的不是恶意信息
    js去除字符串中的空格
    SQLServer存储过程中的简单事务处理
    SQL 2000中行加入序号用法
    C#中将byte数组转换为8bit灰度图像
  • 原文地址:https://www.cnblogs.com/R3col/p/12452513.html
Copyright © 2011-2022 走看看