Server Slow Reading Vulnerabilities

I want to tell you what I dabbled in my free time at Qualys. Since there is surprisingly a lot of noise about the Slow Read DoS attack on the English-speaking Internet , I’m sure that I’ll get a lot of useful criticism and practical suggestions here.

In August 2011, he wrote the program slowhttptest , which tests web servers for vulnerabilities related to the processing of slow HTTP requests, such as slowloris and slow HTTP Post. The goal is to create a configurable tool that facilitates the work of developers and allow them to concentrate on creating effective defenses, rather than picking in the python, on which the majority of proof-of-concept exploits are written.

And then I decided to try how the servers react to the slow reading by clients of HTTP responses. Surprisingly, they react poorly. The default apache, nginx, lightpd, IIS denied service with a bang.

But the essence is this:

if you find a resource on a web server that is larger than send buffer, which the kernel has allocated for the connection to which the server program will send the resource, then if you somehow force the kernel to not accept all the data, the server will try to send the remaining piece data, occupying a limited in size connection queue, processor time, memory, and system administrator free time. If such connections clog the entire queue - the server, it will accordingly begin to refuse service to fast clients.

Making the kernel behave this way is quite simple and was described back in 2008 by the guys from Outpost24 in the Sockstress method : for example, send a window size of 0 in a TCP packet, i.e. the client has no place to receive data. The TCP design correctly implies that the application, and not the kernel, is required to control slow and dead connections. However, for 4 years no one lifted a finger.

Sockstress manually creates packets, calculates when to send the next confirmation, so as not to reset the persist timer on the server, it is difficult in short.
My student is even able to put my method into practice:
Create a socket, set a relatively small receive buffer size on the client, send a completely consistent and normal HTTP request to a 100Kb picture, for example. The server takes a picture from memory, gives the kernel to transfer it to the network. The server takes a piece of the picture and sends it, the client receives the first thousand bytes, and says stop, there is no place. The server poll the socket, trying to understand when it will be ready for recording, but it is not ready! Once a minute you read a couple of bytes from the client receive buffer so that the TCP stack sends something other than zero, thereby creating the appearance of a live connection for firewalls and IDSs.

That's all. I ask you not to kick much, the first technical post in Russian, but I like it, I didn’t hold back. A detailed description can be found here .
PS For the previous version, slowhttptest wrote a wiki in Russian, if at least one soul is interested, I will translate it for the new version.

ModSecurity admonished, show in detail how to defend:
ModSecurity Advanced Topic of the Week: Mitigation of 'Slow Read "Denial of Service Attack
Update 2:
Semy indicated build errors on BSD. Corrected in svn.

Also popular now: