這題目寫起來很有趣,反斜線看到時覺得好像有問題,卻過一小時後才去確認有沒有問題,前面都在找其他的洞,非常失策
[正文]
題目有給 source code
| 1 | <?php | 
Analysis
- 觀察 source code,發現在最後會用 system 去執行 - file $file1 $file2,且- $file1,- $file2的內容會被雙引號包住來防止 injection,如果可以繞過 WAF 和雙引號,就可以控制 system 的內容!
- 觀察 WAF,可以發現在 preg_match 的 regular expression 中有反斜線的漏洞 - 7 
 8
 9
 10
 11
 12- // WAF 
 if(preg_match("/\'|\"|;|,|\`|\*|\\|\n|\t|\r|\xA0|\{|\}|\(|\)|<|\&[^\d]|@|\||ls|cat|sh|flag|find|grep|echo|w/is", $file1))
 $file1 = "";
 if(preg_match("/\'|\"|;|,|\`|\*|\\|\n|\t|\r|\xA0|\{|\}|\(|\)|<|\&[^\d]|@|\||ls|cat|sh|flag|find|grep|echo|w/is", $file2))
 $file2 = "";- 可以看到反斜線的 escape 為 - \\,但是在 php 中要 escape 反斜線要四個- \\\\,這個錯誤會引發後面的- \n也會出錯,- \\|\n在 string escape 變成- \|\n,導致在 preg_match 中要- |\n才會被 match 到。這樣就可以使用 反斜線 和 換行符號!- Escape backslash in PHP- 根據 PHP Manual 的說明,PHP 在建構 string 時會先 escape 反斜線一次,所以要表示一個反斜線,會變成 - \\,在 preg_match 中 pattern 又會在 escape,所以會變成- \\\\才能成功過濾反斜線。
Payload
知道可以使用反斜線和換行符號,那可以嘗試使用反斜線去 escape 雙引號,換行符號 (%0a) 來讓 system 以為有兩行命令
| $file1 = \ | 
換行符號
這裡使用 %0a 當換行符號,主要是因為傳資料的時候會經過 http,會被 urlencode,%0a 就是 url 中的urlencode 換行符號,另外就是 %0a 本來就不會被 preg_match 批配到換行字元。
WAF pattern 的後半段有 ls|cat|sh|flag|find|grep|echo|w,這些簡單地用 $3 來 bypass 就好,例如 ls ==> l$3s
| http://final.kaibro.tw:10002/ | 
FLAG: FLAG{e4sy_w4f_byp4s5_0h_y4_XD__}