[RoarCTF 2019]Easy Calc-3.23BUUCTF練習day5(2)
解題過程
查看源碼
發現calc.php頁面,訪問一下
分析代碼
首先獲取$_GET['num']
的值并賦給變量$str
。然后定義了一個黑名單數組$blacklist
,包含了一系列被禁止的字符或轉義字符,如空格、制表符、換行符、單引號、雙引號、反引號、方括號、美元符號、反斜杠和脫字符號
接下來是一個foreach循環,遍歷黑名單中的每一個元素。對于每個被禁止的字符$blackitem
,使用preg_match
函數和正則表達式來檢查$str
中是否包含該字符。正則表達式中的/m
修飾符表示多行模式,如果發現任何黑名單中的字符存在,就會調用die("what are you want to do?");
終止腳本執行,并顯示提示信息
如果通過了所有黑名單檢查,最后一行代碼是eval('echo '.$str.';');
,這里將輸入的$str
拼接到echo
語句中,并通過eval()
函數執行
思路
通過多次嘗試,發現一輸入字符,就會被禁止訪問
而輸入數字,卻可以正常回顯
那么想起剛剛查看源碼信息卻沒有使用的waf防火墻,應該是waf的原因不能輸入字符
用于我們需要輸入字符構造命令,所以必須想要繞過waf
PHP字符串解析特性繞過WAF
PHP需要將所有參數轉換為有效變量名,因此在解析查詢字符串時,它會做兩件事:1,刪除空白字符;2,將某些字符轉換為下劃線(包括空格)
因為num不可以傳入字母,但是我們在num參數之前添加一個空格(? num=),這樣在PHP的語言特性下會默認刪除這個空格,但是WAF會因為這個空格導致檢測不到num這個參數,最終導致WAF被繞過。
繞過了waf,那么就剩下構造payload找出flag了
在此過程中需要三個函數
- scandir()列出 參數目錄 中的文件和目錄,從而找到flag在哪里
- var_dump()輸出一個或多個表達式的結構信息,包括表達式的類型與值(反正輸出的信息很詳細)
- file_get_contents()輸出文件的具體內容,把整個文件讀入一個字符串中,確實也可以用include()函數繞過
步驟
在剛剛的代碼中知道過濾了/(反斜杠)需要使用chr繞過(chr是什么?chr()里頭是1-255的整數數字,其是對應ascii碼值。也就是說chr(47)也就是等價于 /)
payload是? num=var_dump(scandir(chr(47)))
列出根目錄下所有信息
找到flag的具體名稱f1agg
payload是? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
也就是?num=var_dump(file_get_concents(/f1agg))其中.是PHP中的字符拼接符號,目的將/f1agg拼接起來