之前wooyun上經常也看到一些bypass的方法,如利用mysql的特性bypass web程序的防注入函數,又例如直接構造繞過防注入的正則等等。最近在編寫IPS特征的時候,發現在一些其他的角度上可以做到繞過IPS防護,下面就將這些另外的角度做一個總結。在描述的時候涉及到一些網絡層面的基礎知識,這里不單獨敘述,在利用姿勢里面強調。
Ps.此處說明,方法不代表能bypass掉所有的IPS。
做過IPS測試的選手應該都會聽到過這樣一句話,廠商在保證檢測率90%的條件下,性能是多少。這里所說的性能一般是性能測試中涉及的新建,并發,吞吐等等指標。此處不敘述這些指標。
從上面可以看出IPS的檢測效果和性能是有一個平衡關系的。先來描述一些基本概念,第一個概念是數據流和會話的概念:
在網絡基礎中有五元組的概念,即為源地址,目的地址,源端口,目的端口以及協議號,五元組相同即認為是一條同樣的會話,當你在瀏覽器中訪問www.wooyun.org的時候,打開wireshark抓包工具抓包,然后follow下這一條stream可以發現如下內容。這也就是所描述的會話和流。
IPS中一般是通過會話,流來進行檢測的。如何來通過會話來檢測呢,這里有第二個概念需要了解,第二個概念為重組:
為什么要重組,一個以太網包的最大長度為1518字節,譬如我們這時候發送一個大附件出去,此時就會把數據分成多個數據包發送出去,數據包在internet上轉發的時候會被路由轉發,在整個internet中轉發的時候會出現亂序,導致有些數據包先到IPS設備,有些數據包后到IPS設備,此時就需要IPS將發送的數據包,完整的組合起來。因為組合起來之后才可以方便后面的數據分析,提取內容。如下圖所示:
現在問題就來了,如果對于每條數據流的所有內容都做檢測應該就沒問題了,但是每條數據流的所有內容都進行檢測,肯定所耗費的資源也就越多,應該大部分廠商不會檢測數據流的所有包。因此就會出現個問題,到底檢測多大的大小呢?在處理這個問題的時候有些使用的是包數,有些使用的是流大小的方法。但是這都會導致所說的一個問題,就是性能優化導致的bypass。如下圖所示:
在該數據流中,前面多個包如20個包沒有發現特征,20個包之后的內容不再做ips檢測,這樣后面的包里的特征就沒有受到IPS引擎的檢測。
利用:
例如我們在繞過bypass的時候,人為的將get方式提交改為post方式提交,同時在提交的時候,添加大量的填充數據,如使用post的方式,上傳一個大的文件,雖然這部分填充數據不會被服務器端所處理,但是在通過IPS設備的時候就會被解析處理,有可能就bypass掉了ips的檢測。
Ips規則即為經常說到的ips特征,見到過的很多IPS特征都是根據不同協議來分的,如http,smtp,pop3,tcp,udp等等,每一種協議下又可以有不同的內容,如http協議下可以有cookie,header,msgbody等等。
這些特征都會被以一種算法加載到內存中,然后等到數據流解析完畢之后,進行匹配。因此這里又涉及到了一個基礎概念:協議解析。
協議解析為啥?即將上面重組過后的信息,提取相應的內容賦值給協議變量。打個比方,如http協議,在重組完成之后肯定會出現http標準的內容,http的cookie,header,method等等,因此IPS會根據標準的內容解析,然后將解析的內容賦值給類似http_cookie,http_method的變量。有了這些變量就可以對數據流進行IPS特征匹配了。效果如下圖所示:
解析出來各種http的相關內容,當然不同的協議解析出來的內容不相同,有的可能是smtp,tcp等等。
但是在這個過程中,如果程序員處理的不好,就會出現IPS bypass的情況。
舉個例子,例如某漏洞的特征為search{xxxx},特征利用正則編寫,需要匹配search{},括號內容隨意,此時,攻擊者提交search{sada%00},這樣在協議解析的時候出來的結果是search{sada,不會匹配到后面的}符號,導致了bypass。
url編碼繞過IPS規則同樣存在可能性。
在IPS中對于同一種協議可能有多種協議變量,如HTTP中可能有沒有url_decode的協議變量和進行了url_decode的協議變量,如果沒有正確使用也會導致IPS規則繞過。
瀏覽器在發送數據包的時候,會對url進行編碼,而且不同瀏覽器的編碼還不相同,例如chrome對于單引號編碼為%27,但是IE瀏覽器對于單引號不做編碼,同時瀏覽器對于英文字符都不做編碼的。
之前碰到了一個例子,在IPS規則中,書寫特征的人員使用了未解碼的協議變量書寫特征,如特征為包含search關鍵字,此時我們可以這樣bypass規則,將search書寫為%73earch,這樣當數據包經過IPS設備的時候,內容未作解碼還是為%73earch,未匹配上規則,而到服務器端時候,被解碼為search。
因此這里說,在做web測試的時候,盡量編碼一些英文字符提交,可能會有驚喜。
http常用請求方式有GET和POST兩種方式,POST提交的時候又常見的有www/urlencode的方式和multipart的方式,后者常常用于文件上傳。 查看一些CMS的源碼,經常會發現有類似的代碼,如下代碼摘抄自dedecms:
#!php
if (!defined('DEDEREQUEST'))
{
//檢查和注冊外部提交的變量
foreach($_REQUEST as $_k=>$_v)
{
if( strlen($_k)>0 && preg_match('/^(cfg_|GLOBALS)/',$_k) )
{
exit('Request var not allow!');
}
}
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}
}
可以看出無論get提交,cookie提交,post提交對于web服務器端,其實效果是一樣的,但是對于IPS就不一樣了。在我接觸的不同的IPS中,對于不同http請求部分,擁有不同的協議變量,同時不同的協議變量也有解碼和未解碼之分。
舉例,如dedecms中的一個漏洞,uploadsafe.inc.php界面的錯誤過濾導致recommend.php頁面可以sql注入。網上給出的POC通常是一個url,直接粘貼到瀏覽器,即可以獲取到了管理員賬號密碼,因此一些IPS規則通常就直接書寫了一個httpurl解碼的規則。
很容易此處更換一下提交方式,使用post的方式,無論是urlencode的方式還是form-data的方式,均可以繞過該規則。
此處如果發現post方式被過濾了,此處對于post的內容進行編碼,然后再提交,仍然存在可以繞過的可能。
因此各位在編寫payload的時候盡量使用編碼過的post方式提交,成功的概率大一點。
Ps.之前wooyun上看見有提交二進制文件混淆繞過的,此處暫時沒有想到為什么。
1:對于host以及useraget的修改 一般不要使用默認的useragent,如使用一些自定義或則模擬瀏覽器的http-header字段。如那些sqlmap的特征可能就是針對于useragent做的文章。
2:字符混淆 盡量不使用網上公開的poc,針對于一些payload中可控的部分做字符混淆,使用字符填充等等。
3:漏洞利用方式 例如之前報過dedecms的recommend的注入漏洞,該漏洞是因為uploadsafe.inc.php界面導致的,其實利用頁面還有flink.php等等,網上利用的最多recommend的poc,因此使用flink.php的頁面可能就繞過了dedecms ips特征的防御,又如牛B的dedesql.class.php的變量覆蓋漏洞,網上大多poc是基于download.php的,其實erraddsave.php等其他頁面也是可以利用的,使用一些非主流POC的利用頁面,也是可以bypass掉ips特征的。 一般的IPS特征都與基于一個頁面來寫特征,避免誤報的。
IPS和WAF網絡攻擊的防護設備,往往為了自身的一些如性能的提升,而放棄了一些功能,例如我見過有些IPS規則在編寫的時候不支持正則表達式。可能就是正則表達式匹配的時候會大大的影響性能。由于這些功能上的放棄,必然導致各種各樣規則的bypass,作為用戶既需要這些防護設備,同時也需要做好自身網絡安全的提升,如服務器的補丁,相關服務器的實時監控等等。