[HCTF 2018]WarmUp 1——文件上传漏洞

                       [HCTF 2018]WarmUp 1


前言

       个人观点,若有误请指教


解题思路及步骤

  • 由于点开后只是一个表情包,所以查看html源码,发现一个提示
    在这里插入图片描述
    在这里插入图片描述

  • 根据提示访问source.php文件,正式开始代码审计环节
    在这里插入图片描述

<?php
	//打印代码,之所以能在浏览器看到php源码就因为这个
    highlight_file(__FILE__);
    class emmm
    {
    
    
    	//&为引用,即在函数修改会改变外面的,但在这里应该没用,因为是通过这个$_REQUEST['file']传参的,而不是一个变量名。
    	//另一个证明没用的是如果有用,那还怎么文件包含????
        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是在同一目录下的,因为在include(路径),路径是一致的。
            if (in_array($page, $whitelist)) {
    
    
                return true;
            }
			
			//mb_substr截取函数(字符串,开始位置,截取长度)
			//mb_strpos()函数返回被查找的字符串在另一字符串中首次出现的位置(下标从0开始)
			//如果$page的值有?,则字符串只剩下在?之前的字符,若无则截取整个$page
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
			
			//第二次检测传进来的值是否匹配白名单列表$whitelist 如果有则为真
            if (in_array($_page, $whitelist)) {
    
    
                return true;
            }

			//对$page中的url编码字符进行解码,如%23变成#
            $_page = urldecode($page);
			
			//再进行一次上面的操作
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );

			//第三次检测传进来的值是否匹配白名单列表$whitelist 如果有则为真
            if (in_array($_page, $whitelist)) {
    
    
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }
	
	//empty函数判断file值是否为空,is_string判断file值是否为字符串(通过$_REQUEST获得的会默认加引号的),调用checkFile函数来进行最后判断。
	//即其关键在于传了文件包含漏洞的payload之后,还使checkFile返回真。
    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\" />";
    }  
?>

通过代码审计,我们可以发现checkFile返回真的地方一共有三处,但对于上传payload可以利用的地方只有最后两处。(第一处用不了,因为file就等于hint.php,这样叫payload?)

  • 访问hint.php,获得提示
    在这里插入图片描述

  • payload环节
    ①对于第二个返回真的地方,我们可以注入file=hint.php?/…/…/…/…/…/…/…/…/ffffllllaaaagggg
    在这里插入图片描述
    注:在第二处判断之前先进行截取了?之前的字符串,即在此之后的$page等于hint.php。


    ②对于第三个返回真的地方,我们可以注入file=hint.php%253f/…/…/…/…/…/…/…/…/ffffllllaaaagggg
    在这里插入图片描述
    注:一般情况下,在地址栏中一些字符需要用url编码进行输入(如想在地址栏中输入#则需要输入%23),而在后台服务器中会自动进行解码,获得原始的字符。而在这道题中的代码会自己再进行一次解码。但payload想返回真就需要有问号,那么我们可以对问号进行两次编码。
    在这里插入图片描述


总结

  • 在解这道题时只能做到出现flag not here, and flag in ffffllllaaaagggg字眼,对于文件上传漏洞极其不熟,而且在代码审计时对函数的返回真的情况出现了误解。o(╥﹏╥)o

  • 为什么hint.php?/…/…/…/…/…/…/…/…/ffffllllaaaagggg就可以访问到ffffllllaaaagggg文件?
    include 函数把hint.php? 当成一个文件夹(不论你是否真实存在,include函数都认为它有) ,然后在进行一层一层地返回上级。
    该题的include函数会先进到hint.php文件夹(实际上不存在)中再一层层的返回。
    注:来自https://blog.csdn.net/FY10033/article/details/119950878

猜你喜欢

转载自blog.csdn.net/weixin_46962006/article/details/121788865