点击Source,去看一下.
开始审计.
<?php
// 包含配置文件,其中定义了FLAG常量
include 'config.php'; // 检查当前请求的脚本路径是否以'config.php/'结尾(不区分大小写,且'/'可以是0个或多个)
// 如果匹配,则退出并显示一条消息,防止直接访问包含敏感信息的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 :)");
} // 如果URL中存在'source' GET参数
if (isset($_GET['source'])) { // 使用basename函数获取当前脚本的基本名称(即去除任何路径信息),并高亮显示其源代码 // 这可能导致信息泄露,因为攻击者可以看到部分源代码 highlight_file(basename($_SERVER['PHP_SELF'])); exit(); // 在显示源代码后退出
} // 生成一个随机的64字节秘密,并将其转换为十六进制字符串
$secret = bin2hex(random_bytes(64)); // 如果POST请求中包含了'guess'参数
if (isset($_POST['guess'])) { // 将'guess'参数的值转换为字符串 $guess = (string) $_POST['guess']; // 使用hash_equals函数比较猜测和秘密(防止时间攻击) if (hash_equals($secret, $guess)) { // 如果猜测正确,显示FLAG $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)) { ?> <!-- 如果设置了$message变量,则显示它 --> <p><?= $message ?></p>
<?php } ?> <!-- 提供一个表单,允许用户通过POST请求提交他们的猜测 --> <form action="index.php" method="POST"> <input type="text" name="guess"> <input type="submit"> </form> </body>
</html>
这部分就不用想了,他每次出现的数字是随机的.
看看上面的.
一个正则表达式,一个highlight_file(basename($SERVER["PHP_SELF"])).
知识点 :
basename漏洞,basename可以匹配到可见字符,但是无法匹配不可见字符
示例:
书接上回,我们可以通过 highlight_file(config.php)来读取flag.
而basename($SERVER["PHP_SELF"]) <=>config.php的实现就用上面的basename漏洞来实现
同时我要还需要绕过正则表达式.
我们通过分析'/config\.php\/*$/i',
可知正则表达式匹配条件为:
以 config.php 结尾,后面跟着零个或多个斜杠,且不区分大小写
所以我们在后面+点东西就可以绕过了,而+的东西就是不可见字符.
示例
理论成立开始实操
拿到flag,游戏结束~