通过json发送html代码_通过协议 FUZZ 的方法探测 IDS/防火墙检测规则的漏洞

本文为看雪论坛优秀文章

看雪论坛作者ID:fyb波

Fragscapy 是一个通过 Fuzz 经过防火墙发送的网络消息, 从而检测防火墙和IDS中的漏洞的工具。工具来源于开源项目,Amossys 的 Github 。

baaf6af9632829761cc7b7eec562ec86.gif

为啥叫"Fragscapy"

在Amossys,我们经常分析防火墙和IDS,测试它们的配置可能会很耗时。当然,已经开发了一些基本工具和脚本来自动化这些测试。

Fragscapy的目的是对这些工具进行改进。它用自动化,模块化,可扩展和高级的Python 3项目代替了它们。顾名思义,Fragscapy基于 Scapy 进行网络数据包处理。简而言之,Fragscapy是一种可以针对防火墙的保护进行连续测试的工具。它背后的原理实际上非常简单:

9494704c7897e71ab85dfd76e59e9b36.png

图 1: Fragscapy 的一般原理

Fragscapy的运行流程是:1. 启动将要与网络交互的应用程序(如果测试为基于HTTP的规则是wget,或者测试较低层的话是ping)。2. 拦截发出的数据包。3. 对数据包进行修改,这是流程中最重要的步骤,而这是fuzz(模糊测试)的真正定义所在。这么做的目的是使经过充分修改的数据包,可以绕过防火墙检查,但防火墙后面的服务仍然可以解析数据包。4. 发送修改后的数据包并等待响应。5. 重复第一步,但修改不同。

"修改"是什么呢?

那么,这个工具最有趣的部分发生在步骤3的修改中,其余的只是编排一下这些修改。那么,到底修改了哪些部分呢? 好吧,答案是“所有的一切” ...实际上,从技术上讲,修改是一个功能,它接收一个数据包列表并返回另一个数据包列表。在这之间,任何事情都可能发生:可以对数据包进行修改,延迟,丢弃,替换,切片,重新分组。工具中包含一些基本的修改,可以执行常规修改,例如:

  • 丢包(固定概率的随即包或者特定的包)
  • 延迟数据包
  • 过滤和重新排序数据包
  • 对IPv4和IPv6数据包进行分段(还有一些特殊的选项)
  • 分割TCP数据包
  • 修改数据包的任何字段

有关如何进行这些修改的更多详细信息,可以在fragscapy/modifications/:https://github.com/AMOSSYS/Fragscapy/tree/master/fragscapy/modifications查看Python代码。

如何使用这个很棒的工具?

示例1:如何发现Linux中未记录的行为对于第一个用法示例,我们来看一个简单的案例。假设我们有以下的设置,并且希望尝试访问服务器上的80端口和8080端口上的网页,但是有一个iptables防火墙阻止了我们对8080端口的请求。

1c28c17502cf9d9b76da739dcf363e16.png

图 2: 第一个示例的初始情况

配置 Fragscapy

现在,我们将通过 fuzz IPv6 片段来尝试绕过防火墙的安全性。为此,我们需要配置Fragscapy。一切都应通过以下方式配置:

  • JSON配置文件(用于测试行为)
  • 命令行选项(用于输出,日志)

因此,下面的JSON文件(ipv6_frag.json)定义了测试的3个方面:1. 要运行的命令:curl, 用来获取两个端口上的页面, 仅当在80端口上的网络页面可成功获取,比如防火墙完成了这个工作,最后以状态码0退出。2. 配置防火墙以便仅捕获特定的数据包:该工具无法猜测,因此默认情况下所有内容均被捕获。3. 要应用的修改列表:可以指定参数,并且INPUT和OUTPUT链上的修改可以不同。

{
  "cmd": "/usr/bin/curl -6 -f -m 1 http://www.example.com:80 -o results/http_{i}_{j}.html; e1=$?; /usr/bin/curl -6 -f -m 1 http://www.example.com:8080 -o results/alt_{i}_{j}.html; e2=$? if [ $e1 -eq 0 && $e2 -ne 0 ]; then return 0; else return 1; fi",
 
  "nfrules": [
    {"host": "www.example.com", "port": 80, "ipv4": false, "input_chain": false}
  ],
 
  "input": [
  ],
 
  "output": [
    {
      "mod_name": "ipv6_frag",
      "mod_opts": "range 10 3000 10"
    }
  ]
}

在这里,我们计划以10为步长,对所有数据包进行分段,其分段大小在10到3000字节之间。然后,剩下的就是通过运行以下命令来开始运行测试:

fragscapy start fragment.json 
  -o run/std/stdout_{i}_{j}.txt 
  -e run/std/stderr_{i}_{j}.txt 
  -W run/pcap/local_{i}_{j}.txt 
  -w run/pcap/remote_{i}_{j}.txt

这个命令有多个选项,以指定在何处输出有关每个测试的某些日志(标准输出和错误,数据包捕获)。

这样一来,我们可以轻松地详细检查在测试触发有趣行为的情况下发生的情况。{i}和{j}句式只是 python 格式的句式,它由测试编号和重复编号代替(在测试不确定的情况下,可以重复多次)。有关可用选项的更多信息,可以运行以下命令以获取每个可能参数的详细信息:

fragscapy --help
fragscapy start --help

令人惊讶的结果

有多种方法可以检查测试是否正确。首先,fragscapy start启动命令的输出显示基于命令的退出代码(0 意味着通过,其他就说明失败)的测试摘要。

100%|██████████████████████████████████████████████████████████████████|300/300
Results (300 tests done over 300 scenarios)
==================
Pass : 174
    n°0_0, n°127_0, n°128_0, n°129_0, n°130_0, n°131_0, n°132_0, n°133_0, ...
Fail : 126
    n°1_0, n°2_0, n°3_0, n°4_0, n°5_0, n°6_0, n°7_0, n°8_0, n°9_0, n°10_0, ...
Not Done : 0

好吧,这一切意味着什么?首先是一个进度条,用来说明测试过程中的进度。我们可以看到,这个配置总共要运行300个测试。之后的所有行仅在所有测试完成时显示。它包含3个部分:

  • 通过的测试数量(此处为174),然后是通过的第一个测试编号
  • 测试失败的次数(此处为126),然后是第一个失败的测试号码
  • 在测试中间中断的情况下未完成的测试数量(此处为0),然后是未完成的第一个测试编号(如果有的话)

因此,正如我们在小示例中看到的那样,有174个测试通过,这意味着,端口80上的页面被获取,而端口8080上的页面则没有。

但是,奇怪的是,在前126个案例中(碎片大小在10到1270之间),发生了一些事情。这就是我们在命令行中指定的日志的方便位置。通过查看results/output目录,我们可以发现端口8080上的页面从未被检索过(o/iptables完成了它的工作),但是端口80上的页面却在测试#1至#126中丢失了。发生了什么?让我们继续调查。在run/pcap/中,我们抓取到发生这种情况的数据包。短时间研究后发现,似乎以某种方式拒绝了1280字节以下的片段...这可能很奇怪。但是1280可能会提醒我们:这是IPv6数据包的下限大小,这可能不是一个巧合。是的,确实如此,经过几次搜索,似乎在Linux中引入了小于1280字节的拒绝片段,而没有任何文档或规范 "以避免不合理的情况”。这就是一切的来历:Linux内核删除了这些片段,但没有文档提及它。但是,由于兼容性问题 ,最近在Linux 5.0中对其进行了还原。好吧,这就是Fragscapy的使用方式:配置,运行测试,分析日志和结果。当然,在这样一个简单的示例中,我们没有揭示iptables的任何缺陷,但是我们揭示了iptables的奇怪行为。

示例2:断言对碎片的正确处理

现在,让我们更深入地使用Fragscapy进行恰当的测试。下面的示例来自真实例子,因此结果只能在此特定设备上复现。测试情况如下:

35c9d572f53b5eaa1778f69831021ec8.png

图 3: 实例的虚拟配置

我们将从“用户”区域 fuzz DMZ中的Web服务器。Web应用程序防火墙已配置,因此我们不应发送具有给定参数的请求。让我们运行大量测试,看看会发生什么:fragment_ipv4.json

{
  "cmd": "/usr/bin/curl -f -m 1 http://www.example.com/index.html?azerty -o results/{i}_{j}.html",
 
  "nfrules": [
    {"host": "www.example.com", "port": 80, "ipv6": false, "input_chain": false}
  ],
 
  "input": [
  ],
 
  "output": [
    {
      "mod_name": "ipv4_frag",
      "mod_opts": "range 1 1000"
    },
    {
      "mod_name": "drop_proba",
      "mod_opts": "seq_float 0.1 0.2 0.3 0.4 0.5",
      "optional": true
    },
    {
      "mod_name": "duplicate",
      "mod_opts": "seq_str first last random",
      "optional": true
    },
    {
      "mod_name": "reorder",
      "mod_opts": "seq_str reverse random",
      "optional": true
    }
  ]
}

segment_tcp.json

{
  "cmd": "/usr/bin/curl -f -m 1 http://www.example.com/index.html?azerty -o results/{i}_{j}.html",
 
  "nfrules": [
    {"host": "www.example.com", "port": 80, "input_chain": false}
  ],
 
  "input": [
  ],
 
  "output": [
    {
      "mod_name": "tcp_segment",
      "mod_opts": "range 1 1000"
    },
    {
      "mod_name": "drop_proba",
      "mod_opts": "seq_float 0.1 0.2 0.3 0.4 0.5",
      "optional": true
    },
    {
      "mod_name": "duplicate",
      "mod_opts": "seq_str first last random",
      "optional": true
    },
    {
      "mod_name": "reorder",
      "mod_opts": "seq_str reverse random",
      "optional": true
    }
  ]
}
fragscapy start fragment_ipv4.json segment_tcp.json 
  -o run/std/stdout_{i}_{j}.txt 
  -e run/std/stderr_{i}_{j}.txt 
  -W run/pcap/local_{i}_{j}.txt 
  -w run/pcap/remote_{i}_{j}.txt 
  --append

因此,基本上,我们运行Fragscapy是为了在请求带有参数azerty(事实上这不可能)来获取获取index.html 。但是,我们还在许多不同的配置中处理 IPv4 片段 和TCP分段。运行144k 大小的测试需要经历数个小时,结果非常有趣:

100%|██████████████████████████████████████████████████████████████|72000|72000
Results (666000 tests done over 72000 scenarios)
==================
Pass : 0
 
Fail : 666000
    n°0_0, n°1_0, n°2_0, n°2_1, n°2_2, n°2_3, n°2_4, n°2_5, n°2_6, n°2_7, ...
Not Done : 0
 
100%|██████████████████████████████████████████████████████████████|72000|72000
Results (666000 tests done over 72000 scenarios)
==================
Pass : 98
    n°0_0, n°1_0, n°2_0, n°2_1, n°2_2, n°2_3, n°2_4, n°2_5, n°2_6, n°2_7, ...
Fail : 665987
    n°22_5, n°23_3, n°25_5, n°32_1, n°32_6, n°33_8, n°34_1, n°35_6, n°35_7, ...
Not Done : 0

好的,这里有很多结果。上半部分显示了IPv4分段的结果。没什么奇怪的,一切都失败了,这意味着防火墙阻止了数据包,或者通过的数据包对Web服务器来说毫无意义。

但是,TCP分段的下半部分,显示一些测试设法成功检索了该网页。实际上,在查看了result/目录后,防火墙似乎无法很好地处理从1到46的分段,并且没有触发阻塞规则,而Web服务器可以完美地重建数据并响应请求。因此,是的,这是对于这个特定的防火墙的结果:可以使用小型分段通过防火墙传输有效数据。这是产品分析的结果之一:它不能正确地确保承诺的保护措施。旁注:防火墙允许某些错误构造的数据包通过(Web服务器无法理解)的情况是合理的,但实际上并不意味着 Fragscapy可以检测到。

尽管这显然是一个容易被利用的安全问题,但Fragscapy 有一个更高层次的解释:该协议在仍然有效的同时,是否正确地绕过了防火墙?但是,可以想象这样一个场景,防火墙的两边都有一个客户端和服务器,使用格式错误的数据包。

Fragscapy的测试命令可以从客户端发送数据,并检查在服务器端接收和解释的内容(就像攻击者可以窃取数据一样)。由于Fragscapy不会解释命令的含义,因此对它没有任何影响:这是一条命令,无论它做了什么。

示例3:劫持Fragscapy获得有趣的东西

让我们用最后一个有趣的例子来演示 Fragscapy 还能做些什么。我们现在知道,它可以用于对安全产品进行测试,并断言其一致性,但是同样的机制也可以用于其他目的。

我们将配置Fragscapy 使其看起来像 HTTP 代理,但不是 HTTP 代理。这实际上非常简单,您只需要使用以下配置文件启动 Fragscapy:

{
  "cmd": "while true; do sleep 1; done",
 
  "nfrules": [
    {"port": 80, "output_chain": false},
    {"port": 8080, "input_chain": false}
  ],
 
  "input": [
    {
      "mod_name": "field",
      "mod_opts": ["TCP", "sport", 8080]
    },
    {
      "mod_name": "field",
      "mod_opts": ["TCP", "chksum", "none"]
    }
  ],
 
  "output": [
    {
      "mod_name": "field",
      "mod_opts": ["TCP", "dport", 80]
    },
    {
      "mod_name": "field",
      "mod_opts": ["TCP", "chksum", "none"]
    }
  ]
}

这个配置有什么作用呢?这只是一个无限循环命令,因此它实际上不会运行任何测试。

它拦截所有从8080 端口输出并进入80 端口的数据包。然后,它修改端口8080上的传出数据包,使它们进入端口80,并对传入数据包执行相反的操作。要对其进行测试,请启动Fragscapy(无需在此处保存输出结果和数据包捕获):

fragscapy start http_proxy.json

就是如此,现在所有网站都可以通过8080 端口而不是80 端口进行访问,至少对于使用HTTP的浏览器和本地工具来说是这样的。

您可以访问 http://www.example.com:8080,它之所以起作用,是因为您实际上是在端口80上发送数据包的。原文链接:https://blog.amossys.fr/author/mael-kervella.html

b27663e6bbf643d2ee309e3c01e3f393.gif

- End -

看雪ID:fyb波

https://bbs.pediy.com/user-726271.htm

*本文由看雪翻译小组 fyb波 编译,由看雪翻译小组 sudozhange 校对

推荐文章++++

* 内存dump 获得基于Unity3d的游戏相关代码

* AS 3.0.1 编写 Xposed 插件入门记录

* Linux内核驱动调试遇到的一些坑以及解决方法(新手必看指南)

* 记一起 kthroltlds 挖矿蠕虫变种分析

* Metasploit后门以及跨平台后门生成

163b3a08a26577ed22e75661b5a270c0.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值