您现在的位置是:首页 > 唯美句子

征服web第一站-BUUCTF Warmup

作者:胡椒时间:2024-04-17 15:58:35分类:唯美句子

简介  文章浏览阅读982次,点赞17次,收藏24次。小白全流程解读代码和自己的思路,欢迎大家一起学习和批评指正。

点击全文阅读

小白全流程解读代码和自己的思路,欢迎大家一起学习和批评指正。

一、开局展示

开局一张图,作为一星的web题,我感觉应该不会考图片隐写,这偏离了web题的初衷了。先看看源代码、

二、源代码展示

源代码中没有直接写flag,看到中间body'中有标注source.php,想到这个php文件应该是破题的关键,也没有什么链接可以直接跳转到这个php文件,考虑是不是url里的子路径。添加试了一下,果然能访问,看一看这个代码情况。

 三、代码解读

<?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中截止第一个问号之间的内容
                $_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\" />";
    }  
?>

1.直接把核心代码贴出来,先把代码分成两块来读。上面一块是定义了一个emmm的类,下面从  if (! empty($_REQUEST['file'])是对前段接收的file的值做了个判断,然后把值传入的emmm类中的checkFile方法中。

2.先解读下面的代码,直接以注释的形式解读。

    if (! empty($_REQUEST['file'])    //对传入的file的值做了个判断,是否为空
        && is_string($_REQUEST['file'])  //并且是否为字符串
        && emmm::checkFile($_REQUEST['file'])  //传入类中的checkFile方法,看返回值是否为真
    ) {
        include $_REQUEST['file'];    //上述返回都为真后,执行include方法,考虑是文件的任意读取
        exit;
    } else {  //为假则是输出刚才的笑脸的图
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

由此总结,首先我们需要一个file参数,?file=,传入的值不能为空,得为字符串,然后看看checkFile函数是怎么判断的。

3.解读emmm类的代码

class emmm
    {
        public static function checkFile(&$page) //file传入由page接受
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //定义了一个白名单数组
            if (! isset($page) || !is_string($page)) { //做判断,page是否为空,是否为字符串
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;//判断传入的page是否是在白名单内,是的直接返回ture,这里我们做了个测试,?file=source.php,直接返回了source.php的代码file=hint.php,则跳出flag not here, and flag in ffffllllaaaagggg,证明flag在ffffllllaaaagggg这个文件里,我要读取的就是这个文件。
            }

            $_page = mb_substr(   
                $page,
                0,
                mb_strpos($page . '?', '?')
            );//这是做了个file传入的值做了分割,从初始位开始,mb_strpos($page . '?', '?')中,$page . '?'是直接在fule传入的值末尾加个?,字符串的拼接,然后方法的返回值是$page中初始位到第一个出现?的地方,有几位。因为末尾有个?,所以这个函数返回有两种结果,比如file传入的值是abc.php,没有问号,拼接后就是abc.php?,返回的分割后的值就是abc.php,如果file传入的值是abc.php?source=flag,这个URL完整的应该是XXXXX?file=abc.php?source=flag,那么file的值中已经有问好了,他就会从file的初始位截去到第一个问号,也就是abc.php,赋值给$_page
            if (in_array($_page, $whitelist)) {
                return true; 
            } //再次判断$page是否在白名单内

            $_page = urldecode($page);  对page进行url解码
            );
            $_page = mb_substr( //重复刚才的操作
                $_page,
                0,
                mb_strpos($_page . '?', '?')   
            if (in_array($_page, $whitelist)) { //在进行白名单校验
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

四、poc尝试

首先我们需要一个值是fule,及xxxx?file=,一直file的值中到一个问号之间必须为白名单的值,所以file后至少是?file=source.php或?file=hint.php,那我们的poc就是XXXX?file=source.php。一直flag在ffffllllaaaagggg文件,一般都是向上级补录遍历该文件,也就是../../../../ffffllllaaaagggg,那么把这个加进URL呢,结合方法中对第一个问号的截断判断,poc可以写成file=hint.php?../../../../../../../../ffffllllaaaagggg,那么截断下来的_page就是hint.php,可以绕过白名单,而后传入include方法的路径就是hint.php?../../../../../../../../ffffllllaaaagggg,由于在url中在没有被&分割的情况下,会从第一个?开始解读一系列的参数名和参数值,因此在URL中添加了第二个问号及其后面的内容时,服务器会将这部分内容作为查询字符串的一部分进行处理,而不是作为路径的一部分。所以,它不会影响路径的读取或目录遍历攻击。这样就获得了flag。

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句