Talk to a Security Expert Now: (800) 721-9177

DoS-ing over Dial-Up

DoS, or Denial of Service attacks, are nothing new.  The main idea behind a DoS attack is to exhaust a devices resources (be it HTTP, some database backend, or any other form of  ‘service’) until it can’t respond to legitimate requests anymore. Typically, this is done from an application or link-saturation aspect, although it can be much more than that. Taking a sledgehammer to the A/C unit that serves a data center is pretty messy – but technically it is still a DoS attack.

The most popular form of DoS (i.e. the ones you read about in the paper) is link saturation. The plan is to send a massive amount of requests to a server, much more than it normally receives, in order to saturate either the server or its link. This requires LOTS of computers – usually sent from a botnet of some sort. When Amazon got hit with a DoS attack back in 2000, they had this to say about the amount of traffic:

“We had 800M bit/sec hit the site, which equals eight times our capacity. On average, our site runs at only 30% capacity, which gives you an idea of how unprecedented this traffic hit was.”

That is a downright amazing amount of traffic. To sustain that type of a DoS attack, you would need your own botnet. You would need thousands and thousands of computers on fast connections. The computers would have to be spread across the internet so they didn’t saturate the connection to the target site. This would have to be a huge, collaborative effort in the works for weeks. Recently, a new method of DoS-ing Apache HTTP servers has emerged that can take down a site with as little as 11.6Kb/s worth of traffic. That’s slow enough to be launched from a dial-up connection.

The idea has been around for a while, but just recently a tool has been developed to launch the attack. The tool works by exhausting Apache processes.  Apache comes configured to only allow a certain number of processes (default install is 256) and not answer any more requests when that limit is hit. What this tool does is send the first part of a request header. While Apache waits for the rest of the header, one of those 256 processes it taken up.  The tool, Slowloris, will send the partial header to the web server a few hundred times to hog the connection pool.  By default, Apache will wait up to 5 minutes for those connections to complete.  Once the tool has taken up all the available connections – the Apache server will not serve any new requests.

Lets dig in.  Here, I ran the tool against a test web server:

[email protected]:~$ perl slowloris.pl -dns webdev

Welcome to Slowloris – the low bandwidth, yet greedy and poisonous HTTP client

Defaulting to port 80.
Defaulting to a 5 second tcp connection timeout.
Defaulting to a 100 second re-try timeout.
Defaulting to 1000 connections.
Multithreading enabled.
Connecting to webdev:80 every 100 seconds with 1000 sockets:
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Building sockets.
Sending data.
Current stats:    Slowloris has now sent 658 packets successfully.
This thread now sleeping for 100 seconds…

Sending data.
Current stats:    Slowloris has now sent 1059 packets successfully.
This thread now sleeping for 100 seconds…

Sending data.
Current stats:    Slowloris has now sent 1283 packets successfully.
This thread now sleeping for 100 seconds…

As you can see, the tool makes 1000 requests every 100 seconds, more than enough to saturate our default Apache settings of 256 connections every 5 minutes.  While this tool is running, the Apache server is completely unresponsive to any new requests.  If someone is already at the site when this attack is launched, their connection will stay active until they request a new process.  At this point, its a race condition between a legitimate browsing session and the Slowloris tool, one that Slowloris will always eventually win.

Another interesting point is that this type of attack doesn’t create any errors in the logs until the attack is over.  Since the connections never complete – Apache never writes any of it to its logs.  Once the attack is over, multiple 404 errors will pop up – but its a little too late at that point.  First, I saw this in Apache’s error logs:

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

This shows us that Slowloris was able to hog all the connections to the Apache server.  Then, we see hundreds of these entries in access.log:

[error] [client 10.0.0.45] request failed: error reading the headers
[error] [client 10.0.0.45] request failed: error reading the headers
[error] [client 10.0.0.45] request failed: error reading the headers
[error] [client 10.0.0.45] request failed: error reading the headers
[error] [client 10.0.0.45] request failed: error reading the headers
[error] [client 10.0.0.45] request failed: error reading the headers
[error] [client 10.0.0.45] request failed: error reading the headers

This happens because Apache only got the first part of the request headers, and never saw the complete header.  The following is all the 404 errors the tool generates:

“GET / HTTP/1.1” 400 351 “-” “Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)”
“GET / HTTP/1.1” 400 351 “-” “Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)”
“GET / HTTP/1.1” 400 351 “-” “Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)”
“GET / HTTP/1.1” 400 351 “-” “Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)”

This all happens well into the attack.  It looks like you could keep a server down for quite a while before connections get reset and Apache writes anything to the logs.

I’ve seen some discussion about changing the connection timeouts on Apache from 300 seconds (our default 5 minutes) to something a little quicker – like 10 seconds.  This way, Slowloris can only hog a connection for 10 seconds until it resets.  Even so, limiting the timeouts to 10 seconds does little to stop the attack.  Anyone with an average speed cable connection could still DoS a vulnerable Apache site.  I’ve seen reports that with Apache timeouts set as low as 5 seconds, it still only takes less than 50kb/s of traffic to bring a site down.

If you have a good baseline on your web servers and know the limits of expected traffic – there is a quick and dirty fix for this.  This fix assumes that the attack comes from the same source-ip.  The following iptables rule limits the amount of connections from the same source to 20 connections.

iptables -A INPUT -p tcp –dport 80 -m connlimit –connlimit-above 20 -j REJECT –reject-with tcp-reset

With this in place, Slowloris can only take up 20 connections per source ip, leaving the other connections open for legitimate users.  Now we see Slowloris only sends 35 packets to the web server vs the ~1000 it could do before:

Building sockets.
Sending data.
Current stats:    Slowloris has now sent 35 packets successfully.
This thread now sleeping for 100 seconds…

While this is in no way a long-term fix, it takes the edge of a little.  I’ve also heard of people having success with mod_limitipconn, mod_evasive and accf_http, so they might be worth investigating as well.  Good Luck!

Leave a Reply

Your email address will not be published. Required fields are marked *