the recent OWASP AppSec DC presentation on Slow HTTP POST DoS attacks, the issue of web server platform DoS concerns have reached a new high. Notice that I said, web server platform and not web application code. The attack scenario raised by slow HTTP POST attack is related to web server software (Apache, IIS, SunONE, etc...) and can not be directly mitigated by the application code. In the blog post, we will highlight the two main varieties of slow HTTP attacks - slow request headers and slow request bodies. We will then provide some new mitigation options for the Apache web server platform with ModSecurity.
Network DoS vs. Layer-7 DoS
Whereas network level DoS attacks aim to flood your pipe with lower-level OSI traffic (SYN packets, etc...), web application layer DoS attacks can often be achieved with much less traffic. The point here is that the amount of traffic which can often cause an HTTP DoS condition is often much less than what a network level device would identify as anomalous and therefore would not report on it as they would with traditional network level botnet DDoS attacks.
Layer-7 Connection Consumption Attacks
Ivan Ristic brought up the concept of connection consumption attacks in his 2005 book "Apache Security":
5.4.3. Programming Model Attacks
The brute-force attacks we have discussed are easy to perform but may require a lot of bandwidth, and they are easy to spot. With some programming skills, the attack can be improved to leave no trace in the logs and to require little bandwidth.
The trick is to open a connection to the server but not send a single byte. Opening the connection and waiting requires almost no resources by the attacker, but it permanently ties up one Apache process to wait patiently for a request. Apache will wait until the timeout expires, and then close the connection. As of Apache 1.3.31, request-line timeouts are logged to the access log (with status code 408). Request line timeout messages appear in the error log with the level info. Apache 2 does not log such messages to the error log, but efforts are underway to add the same functionality as is present in the 1.x branch.
Opening just one connection will not disrupt anything, but opening hundreds of connections at the same time will make all available Apache processes busy. When the maximal number of processes is reached, Apache will log the event into the error log ("server reached MaxClients setting, consider raising the MaxClients setting") and start holding new connections in a queue. This type of attack is similar to the SYN flood network attack we discussed earlier. If we continue to open new connections at a high rate, legitimate requests will hardly be served.
If we start opening our connections at an even higher rate, the waiting queue itself will become full (up to 511 connections are queued by default; another value can be configured using the ListenBackLog directive) and will result in new connections being rejected.
Defending against this type of attack is difficult. The only solution is to monitor server performance closely (in real-time) and deny access from the attacker's IP address when attacked.
The issue at hand with these attacks is that the client(s) are opening connections with the web server and sending request data very slowly. For those of you familiar with the old LaBrea Tarpit app for slowing down network based worms, this is somewhat of a reverse approach. Instead of the defender (LaBrea) sending back a TCP Window size of 0 to the attacker (worm) which would force the TCP client to wait for a period of time before resubmitting, in this scenario the attacker is the one forcing the web server to wait. If a web client opens a connection and doesn't send any data to the web server then the web server will default to waiting for the connection's Timeout value to be reached. Wanna guess how long that time interval is in Apache by default? 300 seconds (5 minutes). This means that if a client can simply open a connection and not send anything, that Apache child process thread will sit idle, waiting for data, for 5 minutes. Ouch... So the next logical question to ask from the attacker's perspective is - What is the upper limit on the number of concurrent connections for Apache? This depends on your configs but the main ServerLimit directive has a hard coded value of 20000 (most sites run much less). This limit makes it very feasible for a much smaller number of DDoS clients to take down a site vs. the extremely large number required for network-based pipe flooding.
There are two types of attack to cover when a malicious client never sends a complete Request as specified by the HTTP RFC:
0 comments:
Post a Comment