進入正題,隨著安全意思增強,各企業對自己的網站也更加注重安全性。但很多web應用因為老舊,或貪圖方便想以最小代價保證應用安全,就只僅僅給服務器安裝waf。
本次從協議層面繞過waf實驗用sql注入演示,但不限于實際應用時測試sql注入(命令執行,代碼執行,文件上傳等測試都通用)。
原理
先給服務器發送payload數據包,使得waf無法識別出payload,當apache,tomcat等web容器能正常解析其內容。如圖一所示
實驗環境
本機win10+xampp+某狗web應用防火墻最新版。為方便演示,存在sql注入的腳本中使用$_REQUEST["id"]來接收get,或者post提交的數據。
waf配置為攔截url和post的and ?or 注入,如圖二所示。
發送get請求或利用hackbar插件發送post請求payload均被攔截,如圖三。
利用pipline繞過[該方法經測試會被某狗攔截]
原理:
http協議是由tcp協議封裝而來,當瀏覽器發起一個http請求時,瀏覽器先和服務器建立起連接tcp連接,然后發送http數據包(即我們用burpsuite截獲的數據),其中包含了一個Connection字段,一般值為close,apache等容器根據這個字段決定是保持該tcp連接或是斷開。
當發送的內容太大,超過一個http包容量,需要分多次發送時,值會變成keep-alive,即本次發起的http請求所建立的tcp連接不斷開,直到所發送內容結束Connection為close為止。
1. 關閉burp的Repeater的Content-Length自動更新,如圖四所示,點擊紅圈的Repeater在下拉選項中取消update Content-Length選中。這一步至關重要!!!
2. burp截獲post提交
id=1 and 1=1,顯示被waf攔截如圖五所示。
3. 復制圖五中的數據包黏貼到
id=1 and 1=1,后面如圖六所示。
4. 接著修改第一個數據包的數據部分,即將
id=1+and+1%3D1
修改為正常內容id=1,再將數據包的Content-Length的值設置為修改后的【id=1】的字符長度即4,最后將Connection字段值設為keep-alive。提交后如圖七所示,會返回兩個響應包,分別對應兩個請求。
注意:從結果看,第一個正常數據包返回了正確內容,第二個包含有效載荷的數據包被某狗waf攔截,說明兩數據包都能到達服務器,在面對其他waf時有可能可以繞過。無論如何這仍是一種可學習了解的繞過方法,且可以和接下來的方法進行組合使用繞過。
利用分塊編碼傳輸繞過[該方法可繞某狗]
原理:
在頭部加入 Transfer-Encoding: chunked 之后,就代表這個報文采用了分塊編碼。這時,post請求報文中的數據部分需要改為用一系列分塊來傳輸每個分塊包含十六進制的長度值和數據,長度值獨占一行,長度不包括它結尾的,也不包括分塊數據結尾的,且最后需要用0獨占一行表示結束。
1. 開啟上個實驗中已關閉的content-length自動更新。給post請求包加入Transfer-Encoding: chunked后,將數據部分id=1 and 1=1進行分塊編碼(注意長度值必須為十六進制數),每一塊里長度值獨占一行,數據占一行如圖八所示。
2.將上面圖八數據包的
id=1 and 1=1
改為
id=1 and 1=2
?即將圖八中所標的第4塊的1改為2。如圖九所示沒有返回數據,payload生效。
注意:分塊編碼傳輸需要將關鍵字and,or,select ,union等關鍵字拆開編碼,不然仍然會被waf攔截。編碼過程中長度需包括空格的長度。最后用0表示編碼結束,并在0后空兩行表示數據包結束,不然點擊提交按鈕后會看到一直處于waiting狀態。
利用協議未覆蓋進行繞過[同樣會被某狗攔截]
原理:
HTTP頭里的Content-Type一般有application/x-www-form-urlencoded,multipart/form-data,text/plain三種,其中multipart/form-data表示數據被編碼為一條消息,頁上的每個控件對應消息中的一個部分。所以,當waf沒有規則匹配該協議傳輸的數據時可被繞過。
1.將頭部Content-Type改為multipart/form-data; boundary=69 ? 然后設置分割符內的Content-Disposition的name為要傳參數的名稱。數據部分則放在分割結束符上一行。
由于是正常數據提交,所以從圖十可知數據是能被apache容器正確解析的,嘗試1 and 1=1也會被某狗waf攔截,但如果其他waf沒有規則攔截這種方式提交的數據包,那么同樣能繞過。
2.一般繞waf往往需要多種方式結合使用,如圖十的示例中,只需將數據部分1 and 1=1用一個小數點"."當作連接符即1.and 1=1就可以起到繞過作用。當然,這只是用小數點當連接符所起的作用而已。
分塊編碼+協議未覆蓋組合繞過
1.在協議未覆蓋的數據包中加入Transfer-Encoding: chunked ,然后將數據部分全部進行分塊編碼,如圖十二所示(數據部分為1 and 1=1)。
注意:第2塊,第3塊,第7塊,和第8塊。
第2塊中需要滿足
長度值空行Content-Disposition: name="id"空行
這種形式,且長度值要將兩個空行的長度計算在內(空行長度為2)。
第3塊,即數據開始部分需滿足
長度值 空行數據
形式,且需將空行計算在內。
第7塊即分割邊界結束部分,需滿足
長度值空行分割結束符空行
形式,且計算空行長度在內。
第8塊需滿足
0 ?空行空行
形式。如果不同時滿足這四塊的形式要求,payload將不會生效。
結語:
以上是在http協議層面繞過waf,因為比較通用,所以理論上可以用于平時滲透時的方方面面,如命令執行,代碼注入,sql注入等測試。雖然本文中只有分塊編碼真正做到了繞過某狗,但其他兩種方法在其他waf繞過中可能仍然可用,而且可與其他繞過方法結合使用,甚至像四中一樣相互組合使用