[HCTF 2018]WarmUp

1、靶场首页

首页是一个滑稽.jpg,打开源码可以看到有个source.php

 

2、查看source.php(部分已进行注释)

<?php
    highlight_file(__FILE__);  #对文件进行语法高亮显示
    class emmm                 #定义emmm类
    {
        public static function checkFile(&$page)  #将传入参数赋值给$page
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; #声明$whitelist数组
            if (! isset($page) || !is_string($page)) {        #如果$page不存在或者不为字符串
                echo "you can't see it";                      #打印"you can't see it"
                return false;                                 #返回false
            }

            if (in_array($page, $whitelist)) {       #如果$whitelist数组存在$page变量
                return true;                         #返回true
            }

            $_page = mb_substr(         # mb_substr() 返回字符串的一部分
                $page,
                0,
                mb_strpos($page . '?', '?') # mb_strpos()查找字符串在另一个字符串中首次出现的位置 
            );
            if (in_array($_page, $whitelist)) {   #如果$whitelist数组存在$_page变量
                return true;                      #返回true
            }

            $_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;
        }
    }

    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\" />";
    }  
?>

可以看到有个hint.php

 

3、/hint.php

提示:flag在 ffffllllaaaagggg 里面

 

4、接着回去对source.php进行一个代码的审计

if (! empty($_REQUEST['file'])     # $_REQUEST['file']值非空
        && is_string($_REQUEST['file'])   # $_REQUEST['file']值为字符串
        && emmm::checkFile($_REQUEST['file'])   # $_REQUEST['file']通过checkfile校验
    ) {
        include $_REQUEST['file'];   # $_REQUEST['file']文件包含
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";   # 打印滑稽.jpg
    }  

可以看出如果 file值为非空且为字符串,可以通过emmm类的checkFile函数过滤,就执行文件包含,否则就打印滑稽表情。而需要被包含的文件就是hint.php提示的ffffllllaaaagggg。

 

5、回去查看emmm类下的checkfile函数

class emmm                 #定义emmm类
    {
        public static function checkFile(&$page)  #将传入参数赋值给$page
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; #声明$whitelist数组
            if (! isset($page) || !is_string($page)) {     #如果$page不存在或者不为字符串
                echo "you can't see it";                   #打印"you can't see it"
                return false;                              #返回false
            }

            if (in_array($page, $whitelist)) {        #如果$whitelist数组存在$page变量
                return true;                          #返回true
            }

            $_page = mb_substr(    # mb_substr() 返回字符串的一部分
                $page,
                0,
                mb_strpos($page . '?', '?')  # mb_strpos()查找字符串在另一个字符串中首次出现的位置 
            );
            if (in_array($_page, $whitelist)) {   #如果$whitelist数组存在$_page变量
                return true;                      #返回true
            }

            $_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;
        }
    }

 可以看到函数内一共有4个if。

  • 第一个if检验$page是否为字符串,否则返回false
  • 第二个if判断$whitelist数组中是否存在$page,存在则返回true
  • 第三个if判断$_page(即截取 $page . '?' '?' 前部分得到的变量)是否存在于$whitelist数组中(即值为hint.php或source.php),存在则返回true
  • 第四个if判断$_page(即url解码后再进行截取后得到的变量)是否存在于$whitelist数组中(即值为hint.php或source.php),存在则返回true

如果4个if语句均为返回值,则返回false。

有3个if语句可以返回true,可以从中寻找利用点。

  • 第二个if直接判断$page,不可利用
  • 第三个语句截取'?'前部分,由于?后部分被解析为get方式提交的参数,也不可利用
  • 第四个if语句先进行url解码再截取。

因此我们可以将 ? 经过两次url编码。在服务器端(浏览器)提取参数时解码一次,checkFile函数中解码一次后,仍会解码为,即可通过第四个if校验。

? 经过一次url编码为 %3f ,两次为 %253f

由于不知道ffffllllaaaagggg文件存放的具体位置,所以依次增加../即可拿到flag。

 

6、payload

http://xxxx:xxxx/source.php?file=source.php%253f../../../../../ffffllllaaaagggg

 

posted @ 2021-11-10 13:54  kinyoobi  阅读(148)  评论(0编辑  收藏  举报