你真的在“裸奔”式黑客攻击吗?
我最近遇到了一次有趣的经历,提醒我要始终“信任但验证”。让我为你铺垫一下场景。作为一名渗透测试员和IT安全顾问,我拥有相当庞大的网络和家庭实验室设置。就我而言,这包括一根光纤线路和一个相关的/28 IPv4网络块。天哪,为什么我们还没有采用IPv6!!!但我跑题了。
我的一位优秀的Black Hills同事(Sally)要求我启动一个KALI Linux镜像,用于使用MASSCAN进行一些面向客户的扫描活动。供你参考,MASSCAN的GitHub链接在此:https://github.com/robertdavidgraham/masscan。
这个工具绝对棒极了。它实际上能够在六分钟内以每秒一千万个数据包的速度扫描整个互联网。
我的互联网服务提供商(在他们的智慧中)为我提供了一个Adtran 3140路由器作为服务安装的一部分。Adtran通过以太网连接到我的路由器网关,并向上游连接到一个光纤桥接设备。
挑战来了……一旦MASSCAN启动,Adtran路由器立即开始大量丢包。大多数信息安全顾问可能会说这可能是带宽问题。嗯,绝对不是,因为扫描配置仅为每秒400个数据包或更少。我怀疑这实际上是一个连接状态跟踪问题。
为什么我这么想?好吧,让我们看看目标:在非常短的时间内扫描数百个IP地址的65535个TCP端口。如果边界设备正在跟踪连接状态,假设我们只有100个IP地址被并行扫描,那么我们需要在毫秒内跟踪655,230个TCP连接状态。
我打电话给ISP说:“嘿,伙计们,你们能给我一个直接以太网连接到我的路由器设备吗?”。令我惊讶的是,他们说“可以”!我想,“嘿,酷,现在消费者垃圾没了,让我们摇滚吧。”所以我打电话给Sally,直接说我们修好了,“让它以1000 pps的速度运行。”
接下来发生了什么?我的Linux路由器不幸死亡,路由器核心的系统CPU时间达到100%,数据包开始大量丢失。让我退一步。你可能在想“嘿,Joff,你的盒子应该只是桥接公开可路由的盒子,这到底有多难?”嗯,是的,如果ISP不要求我路由交付给我的公共IP空间,情况就会是这样,但现在我有了以太网连接,我的工作就是充当路由器,而不仅仅是为RFC1918内部网络。
真相?嗯,我的Linux系统正在路由流量,因为ISP实际上将我视为我的/28的最后一个路由器跳。嘿,没什么大不了的,我可以处理,因为我可以在我的iptables配置中设置一些IP转发规则,应该没问题。
这是一个场景。想象你的公共WAN IP地址是1.2.3.4,你很幸运,你的ISP正在将一个255.2.2.0/28的IP地址块路由到这个IP地址。那是什么意思?嗯,任何指向255.2.2.0/28的数据包都将到达1.2.3.4。
那么你的配置是什么样的?像这样: 接口: Eth0: 1.2.3.4/24(或ISP给你的任何掩码) Eth1: 255.2.2.1/28
是的,你还需要在内核中设置IP转发,这样所有到达255.1.2.3的数据包都会被转发,对吧?好吧,这很酷,但你是安全人员,所以你设置你的防火墙网关来做其他很酷的事情,比如为一些内部网段执行网络地址转换(NAT),并且你还有出口过滤!
作为你这样的极客,你有一个4接口系统,不仅能够在Eth1上托管公共IP(DMZ)段,你内部还有几个网络,比如: Eth2: 192.168.100.1/24 Eth3: 192.168.200.1/24
所以我们现在自我感觉良好,因为我们构建了一个路由网络,但我们的防火墙规则需要制定。在Linux世界中,这一切都将发生在iptables的“FORWARD”链中。让我们想象一下,我们想将所有流量转发到我们的DMZ,只允许选定的流量从内部流向外部。我在这里使用“选定”相当自由,因为下面的规则允许所有TCP/UDP流量流动。但真正的重点是我们想使用“nf_conntrack”模块跟踪连接状态,该模块是iptables Linux内核实现的一部分。
一个合适的规则集如下(注意这是“iptables-save”格式):
DMZ流量
-A FORWARD -i eth0 -o eth1 -d 255.2.2.0/28 -j ACCEPT
-A FORWARD -i eth1 -o eth0 -s 255.2.2.0/28 -j ACCEPT
内部到外部流量
-A FORWARD -s 192.168.0.0/16 -p tcp -j ACCEPT
-A FORWARD -s 192.168.0.0/16 -p udp -j ACCEPT
-A FORWARD -m state –state RELATED,ESTABLISHED -j ACCEPT
直观上,你会认为上述规则集完全覆盖了你,一切都会很美好。是的,这绝对正确,直到你从255.2.2.1/28网段的DMZ启动那个“MASSCAN”。
猜猜怎么着,伙计们?由于你想勤奋地跟踪来自内部网段的连接状态,你的DMZ接口也不能幸免。但等等,你说!!?我在配置中放了规则,让它毫无阻碍地通过。别这么快,Obi-Wan,状态跟踪无论如何都适用,因为你告诉iptables这么做!!
好吧,所以“MASSCAN”启动,突然你的连接状态表从可能几百个连接(嘿,我有孩子)增加到超过五十万,你的Linux NAT/防火墙盒子就倒下了。
我是如何验证发生了什么的?我使用了Linux命令“conntrack”,它显示了状态表本身。基本上,如果流条目数字非常大(成千上万),那么发生的连接跟踪比我想要的要多。
conntrack -L
… 省略内容 …
conntrack v1.4.3 (conntrack-tools): 310 flow entries have been shown.
解决方案是什么?这里有几个想法。一个是我们不应该跟踪转发连接的状态。话虽如此,你真的想只在配置的外部->内部部分允许短暂的TCP/UDP端口打开吗?我不这么认为,Kemosabe。
正确的答案,在我看来,是iptables的一个可爱功能,允许你调整“raw”表,使得一些连接永远不会被跟踪!
所以你可能需要这样做: *raw -A PREROUTING -i eth1 -s 255.2.2.0/28 ! -d 255.2.2.0/28 -j NOTRACK
简而言之,规则说如果某些东西从你的网络的DMZ(公开可路由)段进入你的基于家庭的Linux路由器,并且数据包目的地是更大的互联网,那么忘记跟踪连接状态!换句话说,短路iptables的剩余逻辑,只转发数据包。
正如你可能想象的,我在帮助Sally的 quest 中研究并实现了非常类似的东西,果然,它像冠军一样工作。
所以在一天之内,我实现了:
从ISP直接以太网连接 更快乐的网络性能 更快乐的孩子,和更快乐的爸爸 获胜的扫描仪性能!
前进并获利,记住始终“保持冷静,裸奔黑客。”