buuctf-[HCTF 2018]WarmUp1

考察知识点:

代码审计
本地文件包含漏洞

根据前端源代码得到提示

访问source.php

代码审计

class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];

定义了一个名为emmm的类,在该类中有一个静态方法checkFile用于检查要包含的文件是否在白名单中,白名单是一个关联数组$whitelist,其中包含了允许包含的文件的键值对。在代码中,允许包含的文件有"source"=>"source.php"和"hint"=>"hint.php"。

if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

checkFile方法首先检查传入的$page参数是否为字符串类型,如果不是或者未设置,将输出"you can't see it"并返回false。

 if (in_array($page, $whitelist)) {
                return true;
            }

接下来,它检查传入的$page是否直接在白名单中存在,如果存在,返回true。

 $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );

然后它会对\$page参数进行一系列处理:首先使用mb\_strpos函数找到\$page中第一个问号的位置,然后使用mb\_substr函数将问号之前的部分作为\$\_page进行处理。

注意:这个mb_strpos函数嵌套在了mb_substr函数中,准确说并不叫嵌套,而是将返回值作为了它的一个参数。

说明:符号点 '.' 是 PHP 中的字符串连接运算符,它用于将两个字符串连接在一起,形成一个更长的字符串。在这里,它将 $page 变量的值和一个问号字符 '?' 连接在一起,形成一个新的字符串,在这个新的字符串中查找问号是否存在,那么很明显肯定能找到。

也就是说 in_array() 函数的第三个参数length肯定为正数,又因为in_array() 函数的第二个参数start为0,因此会在字符串中的第一个字符处开始按照length长度进行截取,重新赋值给page。

如果看到这里你没有明白,那么看完后面三个函数的详细介绍你就懂了

下面是关于 substr()、strpos() 和in_array()函数的详细介绍和用法:

(mb_strpos和strpos,substr和mb_substr在功能上几乎没什么区别)

strpos(string,find,start)函数:

返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。注意: 字符串位置是从 0 开始,不是从 1 开始。

mb\_substr(str,start,length,encoding) 函数:

返回字符串的一部分,对于substr() 函数,它只针对英文字符, 而mb\_substr()对于中文也适用。

in_array(search,array,type)函数

if (in_array($_page, $whitelist)) {
                return true;
            }

之后再次检查传入的$page是否直接在白名单中存在

$_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

将\$\_page进行URL解码,并重复之前的处理步骤,如果\$\_page在白名单中存在,返回true。

如果上述条件都不满足,则输出"you can't see it"并返回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\" />";
    }

检查$_REQUEST['file']是否存在且为字符串类型,并调用emmm::checkFile方法进行检查。如果返回值为true,则通过include语句包含$_REQUEST['file']指定的文件并终止程序执行,否则输出一个图片标签。

先尝试包含hint.php

source.php?file=hint.php

回显成功,flag在ffffllllaaaagggg 注意:我们始终是在source.php页面下进行的传参操作,目的是利用include函数将flag文件包含出来,不要被这里的白名单搞混了。 让我们来分析一下传入这个东西后,php代码是如何进行判断的: 传入file=hint.php,首先检查'hint.php'是否是一个字符串,它是字符串,条件通过; 检查'hint.php'是否在白名单中(白名单包括hint.php和source.php),在,继续执行后面的代码; 对'hint.php'执行mb_substr函数,但是函数内一个参数是来自另一个函数mb_strpos的返回值,因此我们先看mb_strpos函数,使用.进行字符连接,即连接了一个问号字符 '?',得到hint.php? 然后查找'?'在字符串'hint.php?'中第一次出现的位置,从0开始算,返回8,即length=8 接下来我们执行mb_substr函数,即 mb_substr('hint.php',0,8) 从字符串中的第一个字符处开始,返回8个字符,其实还是返回的hint.php; 然后对返回的内容进行url解码,重复执行上面的检查和截取操作。 我们只需要传入一个在白名单内的文件名(source.php或者hint.php),并添加上问号,这样可以保证每次找去用于检查的内容都在白名单,返回true。 构造payload:

source.php?file=hint.php?/../../../../ffffllllaaaagggg

​flag{6272ede4-e873-4782-8259-6fb7ada8469c}

[HCTF 2018]WarmUp是一个CTF比赛题目,其中涉及到一个叫做emmm的类。这个类中有一个名为checkFile的方法。checkFile方法的作用是对传入的$page参数进行检查。在方法中,首先判断$page是否存在并且是字符串类型,如果不满足条件,则输出"you can't see it"并返回false。接着,将$page与白名单数组$whitelist进行匹配,如果匹配成功,则返回true。如果没有匹配成功,则继续进行下一步操作。 下一步操作中,先对$page进行一次截取操作,截取到第一个问号之前的部分,将截取结果赋值给$_page。然后再次对$_page进行白名单匹配,如果匹配成功,则返回true。如果匹配不成功,则对$_page进行二次URL解码,并再次进行一次截取操作,将结果赋值给$_page。最后再次对$_page进行白名单匹配,如果匹配成功,则输出"sdf you can't see it"并返回true。如果都不满足条件,则输出"you can't see it"并返回false。 这个题目的前身是一个cve漏洞(phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613))。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [[HCTF 2018]WarmUp](https://blog.csdn.net/m0_62709637/article/details/125022518)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值