<?php include 'utils.php'; if (isset($_POST['guess'])) { $guess = (string) $_POST['guess']; if ($guess $secret) { $message = 'Congratulations! The fla ...
<?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__); } ?>
這個題目出現了$_SERVER['PHP_SELF']
這個是你調用的腳本的路徑
比如說這個題目它的值就是/index.php
如果你訪問的是
http://1.14.71.254:28189/index.php/utils.php
那麼它的值就會是/index.php/utils.php
而$_SEVER['REQUEST_URL']
它的值這個時候和$_SERVER['PHP_SELF']的值是一樣的,
區別在於,如果你用get傳參的時候$_SEVER['REQUEST_URL']是會加上那個參數的,而$_SERVER['PHP_SELF']不會。
然後是basename這個函數。
這個函數是返回最後面一個/後面的名字。
這個函數有一個可以利用的地方就是,如果傳入的參數中出現了非ascii字元則會把它給丟棄。
最後是講繞過正則
if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){ exit("hacker :)"); }
這個正則的繞過方法就是利用特性來繞過,可以用
[
(空格)
+
.
上面那幾個字元任何一個都行,都可以被處理成_
if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) { exit("hacker :)"); }
這個正則是匹配末尾有沒有utils.php/
繞過辦法很簡單
因為後面要調用basename,所以可以利用中文來繞過,中文不屬於ascii編碼中的,所以可以payload