forked from hotpxl/low-rate-tcp-targeted-dos-attacks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dos.py
153 lines (132 loc) · 4.9 KB
/
dos.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import os
import time
import subprocess
import signal
import numpy as np
import mininet.topo
import mininet.net
import mininet.node
class Topo(mininet.topo.Topo):
def build(self):
# Topology:
# alice ---------+
# [s0]----[s1]----- bob
# mallory -------+
local_switch = self.addSwitch('s0')
alice = self.addHost('alice')
self.addLink(
alice, local_switch, bw=100, delay='1ms', max_queue_size=10)
mallory = self.addHost('mallory')
self.addLink(
mallory, local_switch, bw=100, delay='1ms', max_queue_size=10)
# bob is the recipient of both the normal flow and the
# malicious attack flow...
server_switch = self.addSwitch('s1')
bob = self.addHost('bob')
self.addLink(
bob, server_switch, bw=100, delay='1ms', max_queue_size=10)
self.addLink(
server_switch,
local_switch,
bw=1.5,
delay='20ms',
max_queue_size=1000)
# "In these experiments, we again consider the scenario of Figure 2 but
# with a single TCP flow.4 The TCP Reno flow has minRTO = 1 second and
# satisfies conditions (C1) and (C2)."
def set_interface(net, min_rto_ms):
# From: https://serverfault.com/questions/529347/how-to-apply-rto-min-to-a-certain-host-in-centos
for host in ['alice', 'bob']:
node = net.get(host)
current_config = node.cmd('ip route show').strip()
new_config = '%s rto_min %dms' % (current_config, min_rto_ms)
node.cmd('ip route change %s' % new_config, shell=True)
node.cmd('ethtool -K {}-eth0 tso off gso off gro off'.format(host))
def run_flow(net, cwnd_file=None):
alice = net.get('alice')
bob = net.get('bob')
print('Starting receiver on {}.'.format(bob.IP()))
s = bob.popen('./run_receiver.sh', shell=True)
# Wait for receiver to start listening.
time.sleep(1.0)
print('Starting sender on {}.'.format(alice.IP()))
start = time.time()
sender_cmd = './run_sender.sh -t {}'.format(bob.IP())
if cwnd_file is not None:
sender_cmd += ' -p {}'.format(cwnd_file)
c = alice.popen(sender_cmd, shell=True)
print('TCP flow started on Alice and Bob.')
assert c.wait() == 0
assert s.wait() == 0
return time.time() - start
def start_attack(net, period, burst):
mallory = net.get('mallory')
bob = net.get('bob')
print('UDP attack started from {} to {}.'.format(mallory.IP(), bob.IP()))
return mallory.popen([
'python', 'run_attacker.py', '--period', str(period), '--burst',
str(burst), '--destination', bob.IP()
])
def main():
parser = argparse.ArgumentParser(description="TCP DoS simulator.")
parser.add_argument(
'--burst',
'-b',
help="Burst duration in seconds of each DoS attack.",
type=float,
default=0.15)
parser.add_argument(
'--cong', help="Congestion control algorithm to use.", default='reno')
parser.add_argument(
'--suffix',
'-s',
help="Suffix for output directory",
type=str,
default='default')
parser.add_argument(
'--period',
'-p',
help="Seconds between low-rate DoS attacks, e.g. 0.5",
type=float,
default=0.5)
parser.add_argument(
'--rto', '-r', help="rto_min value, in ms", type=int, default=1000)
args = parser.parse_args()
# Initialize kernel parameters.
subprocess.check_call(
'sysctl -q -w net.ipv4.tcp_congestion_control=%s' % args.cong,
shell=True)
subprocess.check_call('sysctl -q -w net.ipv4.tcp_sack=0', shell=True)
subprocess.check_call('sysctl -q -w net.ipv4.tcp_dsack=0', shell=True)
subprocess.check_call('sysctl -q -w net.ipv4.tcp_fack=0', shell=True)
topo = Topo()
net = mininet.net.Mininet(
topo=topo, host=mininet.node.CPULimitedHost, link=mininet.link.TCLink)
net.start()
set_interface(net, args.rto)
print('Alice\'s IP is {}.'.format(net.get('alice').IP()))
print('Bob\'s IP is {}.'.format(net.get('bob').IP()))
print('Mallory\'s IP is {}.'.format(net.get('mallory').IP()))
print('')
output_dir = 'results-{}'.format(args.suffix)
if not os.path.isdir(output_dir):
os.mkdir(output_dir)
time_file = os.path.join(output_dir, 't-{}-{}.txt'.format(
args.period, args.burst))
cwnd_file = os.path.join(output_dir, 'cwnd-{}-{}.txt'.format(
args.period, args.burst))
attack = start_attack(net, args.period, args.burst)
t = run_flow(net, cwnd_file=cwnd_file)
print('Sending completed in %.4f seconds.' % t)
with open(time_file, 'w') as f:
f.write(str(t) + '\n')
attack.terminate()
net.stop()
if __name__ == '__main__':
main()