[HCTF 2018]WarmUp1

正式写ctf第一天,第一道题打开就是这张笑脸。

检查源代码,发现注释中有source.php的提示

查看source.php文件,是php源代码

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

            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'])
        && 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函数的检查

  • checkFile函数中有三个if条件,其中一个if通过就可以返回true

  • 要构造的payload中肯定要包含flag文件名,因此不可能通过第一个if。第二个if要求截取从参数的开头到参数第一次出现?的位置的字符串,并且能够通过白名单。第三个if还要求对url进行解码,解码并截取字符串后要通过白名单

查看白名单中的hint.php文件,构造payload为?file=hint.php

提示flag在ffffllllaaaagggg文件中

接下来我们构造包含ffffllllaaaagggg文件的payload。

  1. linux中目录可以携带?,我们可以通过第二个if条件,我们以hint.php为目录,寻找ffffllllaaaagggg的路径,依次添加../,

payload构造为?file=hint.php?/../../../../ffffllllaaaagggg,实际上ffffllllaaaagggg就提示我们要穿透四次

  1. windows中目录不可以携带?,所以我们绕过第三个if条件,对?进行两次url编码为%253,payload构造为?file=hint.php%253/../../../../ffffllllaaaagggg。

就可以看到flag了。

flag{c2c61acd-93aa-4224-ab71-86d30917f406}

涉及知识点:

  • mb_substr() 函数返回字符串的一部分,之前我们学过 substr() 函数,它只针对英文字符,如果要分割的中文文字则需要使用 mb_substr()。

mb_strpos —查找字符串在另一个字符串中首次出现的位置。

$page . '?'意味着会自动在我们上传的参数后面加一个?,这两个函数一起的作用是在字符串中截取从第一个位置开始到整个字符串中第一次出现?的位置的字符串。

  • 为什么要对url二次编码?

应用服务器会对传进来的url进行一次url解码,所以如果代码中有urldecode()函数,便会对url进行二次解码,因此我们输入url时要进行二次编码而不是一次编码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值