basename();绕过目前就碰到两道题 :
NSS——[鹤城杯 2021]EasyP
BUU——[Zer0pts2020]Can you guess it
以NSS这道为例,先放个源码。
<?php
include 'utils.php';
if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if ($guess === $secret) {
$message = 'Congratulations! The flag is: ' . $flag;
} else {
$message = 'Wrong. Try Again';
}
}
if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("hacker :)");
}
if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
exit("hacker :)");
}
if (isset($_GET['show_source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}else{
show_source(__FILE__);
}
?>
很多人有疑问为什么/utils.php/哈哈?show[source
不可以,非要前面加一个index.php,payload是/index.php/utils.php/哈哈?shouw[source
才行,/utils.php/哈哈?show[source
确实可以绕过上述种种限制,但如果你的payload是/utils.php/哈哈?show[source
,那么访问的就不再是index.php,也就不再运行index.php的代码逻辑,那么payload是否能绕过又有何意义?而前面加一个index.php可以让我们访问的仍然是index.php,至于这个为什么,因为$_SERVER[‘PHP_SELF’]会获取我们当前执行脚本的文件名,并且PHP在根据URI解析到对应文件后会忽略掉URL中多余的部分,即只要index.php页面存在,如下两种URL均访问的是index.php而不受untils.php的影响。
/index.php
/index.php/untils.php