Преглед изворни кода

refactor imports in Attack/DDoSAttack.py

refactor whitspaces in Attack/DDoSAttack.py
deep refactoring Attack/DDoSAttack.py
add FIXMEs for DDoS rework
Jens Keim пре 6 година
родитељ
комит
4d39816f01
1 измењених фајлова са 94 додато и 86 уклоњено
  1. 94 86
      code/Attack/DDoSAttack.py

+ 94 - 86
code/Attack/DDoSAttack.py

@@ -1,19 +1,17 @@
+import collections as col
 import logging
 import logging
+import random as rnd
 
 
-from random import randint, choice
-from lea import Lea
-from collections import deque
-from scipy.stats import gamma
-from scapy.layers.inet import IP, Ether, TCP, RandShort
+import lea
+import scapy.layers.inet as inet
+import scipy.stats as stats
 
 
-from Attack import BaseAttack
-from Attack.AttackParameters import Parameter as Param
-from Attack.AttackParameters import ParameterTypes
-from ID2TLib.Utility import update_timestamp, get_interval_pps, get_nth_random_element, index_increment, \
-    handle_most_used_outputs, get_attacker_config
-from ID2TLib.Utility import update_timestamp, get_interval_pps, get_nth_random_element
+import Attack.AttackParameters as atkParam
+import Attack.BaseAttack as BaseAttack
+import ID2TLib.Utility as Util
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
+
 # noinspection PyPep8
 # noinspection PyPep8
 
 
 
 
@@ -21,29 +19,28 @@ class DDoSAttack(BaseAttack.BaseAttack):
     def __init__(self):
     def __init__(self):
         """
         """
         Creates a new instance of the DDoS attack.
         Creates a new instance of the DDoS attack.
-
         """
         """
         # Initialize attack
         # Initialize attack
         super(DDoSAttack, self).__init__("DDoS Attack", "Injects a DDoS attack'",
         super(DDoSAttack, self).__init__("DDoS Attack", "Injects a DDoS attack'",
-                                        "Resource Exhaustion")
+                                         "Resource Exhaustion")
 
 
         self.last_packet = None
         self.last_packet = None
         self.total_pkt_num = 0
         self.total_pkt_num = 0
 
 
         # Define allowed parameters and their type
         # Define allowed parameters and their type
         self.supported_params.update({
         self.supported_params.update({
-            Param.IP_SOURCE: ParameterTypes.TYPE_IP_ADDRESS,
-            Param.MAC_SOURCE: ParameterTypes.TYPE_MAC_ADDRESS,
-            Param.PORT_SOURCE: ParameterTypes.TYPE_PORT,
-            Param.IP_DESTINATION: ParameterTypes.TYPE_IP_ADDRESS,
-            Param.MAC_DESTINATION: ParameterTypes.TYPE_MAC_ADDRESS,
-            Param.PORT_DESTINATION: ParameterTypes.TYPE_PORT,
-            Param.INJECT_AT_TIMESTAMP: ParameterTypes.TYPE_FLOAT,
-            Param.INJECT_AFTER_PACKET: ParameterTypes.TYPE_PACKET_POSITION,
-            Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT,
-            Param.NUMBER_ATTACKERS: ParameterTypes.TYPE_INTEGER_POSITIVE,
-            Param.ATTACK_DURATION: ParameterTypes.TYPE_INTEGER_POSITIVE,
-            Param.VICTIM_BUFFER: ParameterTypes.TYPE_INTEGER_POSITIVE
+            atkParam.Parameter.IP_SOURCE: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
+            atkParam.Parameter.MAC_SOURCE: atkParam.ParameterTypes.TYPE_MAC_ADDRESS,
+            atkParam.Parameter.PORT_SOURCE: atkParam.ParameterTypes.TYPE_PORT,
+            atkParam.Parameter.IP_DESTINATION: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
+            atkParam.Parameter.MAC_DESTINATION: atkParam.ParameterTypes.TYPE_MAC_ADDRESS,
+            atkParam.Parameter.PORT_DESTINATION: atkParam.ParameterTypes.TYPE_PORT,
+            atkParam.Parameter.INJECT_AT_TIMESTAMP: atkParam.ParameterTypes.TYPE_FLOAT,
+            atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION,
+            atkParam.Parameter.PACKETS_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT,
+            atkParam.Parameter.NUMBER_ATTACKERS: atkParam.ParameterTypes.TYPE_INTEGER_POSITIVE,
+            atkParam.Parameter.ATTACK_DURATION: atkParam.ParameterTypes.TYPE_INTEGER_POSITIVE,
+            atkParam.Parameter.VICTIM_BUFFER: atkParam.ParameterTypes.TYPE_INTEGER_POSITIVE
         })
         })
 
 
     def init_params(self):
     def init_params(self):
@@ -51,64 +48,66 @@ class DDoSAttack(BaseAttack.BaseAttack):
         Initialize the parameters of this attack using the user supplied command line parameters.
         Initialize the parameters of this attack using the user supplied command line parameters.
         Use the provided statistics to calculate default parameters and to process user
         Use the provided statistics to calculate default parameters and to process user
         supplied queries.
         supplied queries.
-
-        :param statistics: Reference to a statistics object.
         """
         """
         # PARAMETERS: initialize with default values
         # PARAMETERS: initialize with default values
         # (values are overwritten if user specifies them)
         # (values are overwritten if user specifies them)
-        self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
+        self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
         # attacker configuration
         # attacker configuration
-        num_attackers = randint(1, 16)
+        num_attackers = rnd.randint(1, 16)
         # The most used IP class in background traffic
         # The most used IP class in background traffic
-        most_used_ip_class = handle_most_used_outputs(self.statistics.process_db_query("most_used(ipClass)"))
+        most_used_ip_class = Util.handle_most_used_outputs(self.statistics.process_db_query("most_used(ipClass)"))
 
 
-        self.add_param_value(Param.IP_SOURCE, self.generate_random_ipv4_address(most_used_ip_class, num_attackers))
-        self.add_param_value(Param.MAC_SOURCE, self.generate_random_mac_address(num_attackers))
-        self.add_param_value(Param.PORT_SOURCE, str(RandShort()))
-        self.add_param_value(Param.PACKETS_PER_SECOND, 0)
-        self.add_param_value(Param.ATTACK_DURATION, randint(5,30))
+        self.add_param_value(atkParam.Parameter.IP_SOURCE,
+                             self.generate_random_ipv4_address(most_used_ip_class, num_attackers))
+        self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.generate_random_mac_address(num_attackers))
+        self.add_param_value(atkParam.Parameter.PORT_SOURCE, str(inet.RandShort()))
+        self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND, 0)
+        self.add_param_value(atkParam.Parameter.ATTACK_DURATION, rnd.randint(5, 30))
 
 
         # victim configuration
         # victim configuration
         random_ip_address = self.statistics.get_random_ip_address()
         random_ip_address = self.statistics.get_random_ip_address()
-        self.add_param_value(Param.IP_DESTINATION, random_ip_address)
+        self.add_param_value(atkParam.Parameter.IP_DESTINATION, random_ip_address)
         destination_mac = self.statistics.get_mac_address(random_ip_address)
         destination_mac = self.statistics.get_mac_address(random_ip_address)
         if isinstance(destination_mac, list) and len(destination_mac) == 0:
         if isinstance(destination_mac, list) and len(destination_mac) == 0:
             destination_mac = self.generate_random_mac_address()
             destination_mac = self.generate_random_mac_address()
-        self.add_param_value(Param.MAC_DESTINATION, destination_mac)
-        self.add_param_value(Param.VICTIM_BUFFER, randint(1000,10000))
+        self.add_param_value(atkParam.Parameter.MAC_DESTINATION, destination_mac)
+        self.add_param_value(atkParam.Parameter.VICTIM_BUFFER, rnd.randint(1000, 10000))
 
 
     def generate_attack_packets(self):
     def generate_attack_packets(self):
-        BUFFER_SIZE = 1000
+        buffer_size = 1000
 
 
         # Determine source IP and MAC address
         # Determine source IP and MAC address
-        num_attackers = self.get_param_value(Param.NUMBER_ATTACKERS)
-        if num_attackers is not None:  # user supplied Param.NUMBER_ATTACKERS
+        num_attackers = self.get_param_value(atkParam.Parameter.NUMBER_ATTACKERS)
+        if num_attackers is not None:  # user supplied atkParam.Parameter.NUMBER_ATTACKERS
             # The most used IP class in background traffic
             # The most used IP class in background traffic
-            most_used_ip_class = handle_most_used_outputs(self.statistics.process_db_query("most_used(ipClass)"))
-            # Create random attackers based on user input Param.NUMBER_ATTACKERS
+            most_used_ip_class = Util.handle_most_used_outputs(self.statistics.process_db_query("most_used(ipClass)"))
+            # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS
             ip_source_list = self.generate_random_ipv4_address(most_used_ip_class, num_attackers)
             ip_source_list = self.generate_random_ipv4_address(most_used_ip_class, num_attackers)
             mac_source_list = self.generate_random_mac_address(num_attackers)
             mac_source_list = self.generate_random_mac_address(num_attackers)
-        else:  # user did not supply Param.NUMBER_ATTACKS
+        else:  # user did not supply atkParam.Parameter.NUMBER_ATTACKS
             # use default values for IP_SOURCE/MAC_SOURCE or overwritten values
             # use default values for IP_SOURCE/MAC_SOURCE or overwritten values
             # if user supplied any values for those params
             # if user supplied any values for those params
-            ip_source_list = self.get_param_value(Param.IP_SOURCE)
-            mac_source_list = self.get_param_value(Param.MAC_SOURCE)
+            ip_source_list = self.get_param_value(atkParam.Parameter.IP_SOURCE)
+            mac_source_list = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
             num_attackers = len(ip_source_list)
             num_attackers = len(ip_source_list)
 
 
         # Initialize parameters
         # Initialize parameters
-        self.packets = deque(maxlen=BUFFER_SIZE)
-        port_source_list = self.get_param_value(Param.PORT_SOURCE)
-        mac_destination = self.get_param_value(Param.MAC_DESTINATION)
-        ip_destination = self.get_param_value(Param.IP_DESTINATION)
+        self.packets = col.deque(maxlen=buffer_size)
+        # FIXME: why is port_source_list never used?
+        port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
+        mac_destination = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)
+        ip_destination = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
 
 
         most_used_ip_address = self.statistics.get_most_used_ip_address()
         most_used_ip_address = self.statistics.get_most_used_ip_address()
-        pps = self.get_param_value(Param.PACKETS_PER_SECOND)
+        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)
         if pps == 0:
         if pps == 0:
-            result = self.statistics.process_db_query("SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='"+ip_destination+"';")
+            result = self.statistics.process_db_query(
+                "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + ip_destination + "';")
             if result is not None and not 0:
             if result is not None and not 0:
                 pps = num_attackers * result
                 pps = num_attackers * result
             else:
             else:
-                result = self.statistics.process_db_query("SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='"+most_used_ip_address+"';")
+                result = self.statistics.process_db_query(
+                    "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + most_used_ip_address + "';")
                 pps = num_attackers * result
                 pps = num_attackers * result
 
 
         # Calculate complement packet rates of the background traffic for each interval
         # Calculate complement packet rates of the background traffic for each interval
@@ -118,106 +117,115 @@ class DDoSAttack(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source_list, ip_destination)
         self.ip_src_dst_equal_check(ip_source_list, ip_destination)
 
 
-        port_destination = self.get_param_value(Param.PORT_DESTINATION)
+        port_destination = self.get_param_value(atkParam.Parameter.PORT_DESTINATION)
         if not port_destination:  # user did not define port_dest
         if not port_destination:  # user did not define port_dest
             port_destination = self.statistics.process_db_query(
             port_destination = self.statistics.process_db_query(
-                "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "');")
+                "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination +
+                "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='" +
+                ip_destination + "');")
         if not port_destination:  # no port was retrieved
         if not port_destination:  # no port was retrieved
             port_destination = self.statistics.process_db_query(
             port_destination = self.statistics.process_db_query(
-                "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);")
+                "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE "
+                "portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) "
+                "FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);")
         if not port_destination:
         if not port_destination:
-            port_destination = max(1, str(RandShort()))
+            port_destination = max(1, int(inet.RandShort()))
 
 
-        port_destination = handle_most_used_outputs(port_destination)
+        port_destination = Util.handle_most_used_outputs(port_destination)
 
 
+        # FIXME: why are attacker_port_mapping and attacker_ttl_mapping never used?
         attacker_port_mapping = {}
         attacker_port_mapping = {}
         attacker_ttl_mapping = {}
         attacker_ttl_mapping = {}
 
 
         # Gamma distribution parameters derived from MAWI 13.8G dataset
         # Gamma distribution parameters derived from MAWI 13.8G dataset
         alpha, loc, beta = (2.3261710235, -0.188306914406, 44.4853123884)
         alpha, loc, beta = (2.3261710235, -0.188306914406, 44.4853123884)
-        gd = gamma.rvs(alpha, loc=loc, scale=beta, size=len(ip_source_list))
+        # FIXME: why is gd never used?
+        gd = stats.gamma.rvs(alpha, loc=loc, scale=beta, size=len(ip_source_list))
 
 
         self.path_attack_pcap = None
         self.path_attack_pcap = None
 
 
         timestamp_prv_reply, timestamp_confirm = 0, 0
         timestamp_prv_reply, timestamp_confirm = 0, 0
-        minDelay, maxDelay = self.get_reply_delay(ip_destination)
-        victim_buffer = self.get_param_value(Param.VICTIM_BUFFER)
+        min_delay, max_delay = self.get_reply_delay(ip_destination)
+        victim_buffer = self.get_param_value(atkParam.Parameter.VICTIM_BUFFER)
 
 
-        attack_duration = self.get_param_value(Param.ATTACK_DURATION)
+        attack_duration = self.get_param_value(atkParam.Parameter.ATTACK_DURATION)
         pkts_num = int(pps * attack_duration)
         pkts_num = int(pps * attack_duration)
 
 
         source_win_sizes = self.statistics.get_rnd_win_size(pkts_num)
         source_win_sizes = self.statistics.get_rnd_win_size(pkts_num)
 
 
         destination_win_dist = self.statistics.get_win_distribution(ip_destination)
         destination_win_dist = self.statistics.get_win_distribution(ip_destination)
         if len(destination_win_dist) > 0:
         if len(destination_win_dist) > 0:
-            destination_win_prob_dict = Lea.fromValFreqsDict(destination_win_dist)
+            destination_win_prob_dict = lea.Lea.fromValFreqsDict(destination_win_dist)
             destination_win_value = destination_win_prob_dict.random()
             destination_win_value = destination_win_prob_dict.random()
         else:
         else:
             destination_win_value = self.statistics.process_db_query("most_used(winSize)")
             destination_win_value = self.statistics.process_db_query("most_used(winSize)")
 
 
-        destination_win_value = handle_most_used_outputs(destination_win_value)
+        destination_win_value = Util.handle_most_used_outputs(destination_win_value)
 
 
         # MSS that was used by IP destination in background traffic
         # MSS that was used by IP destination in background traffic
         mss_dst = self.statistics.get_most_used_mss(ip_destination)
         mss_dst = self.statistics.get_most_used_mss(ip_destination)
         if mss_dst is None:
         if mss_dst is None:
             mss_dst = self.statistics.process_db_query("most_used(mssValue)")
             mss_dst = self.statistics.process_db_query("most_used(mssValue)")
 
 
-        mss_dst = handle_most_used_outputs(mss_dst)
+        mss_dst = Util.handle_most_used_outputs(mss_dst)
 
 
         replies_count = 0
         replies_count = 0
         self.total_pkt_num = 0
         self.total_pkt_num = 0
         # For each attacker, generate his own packets, then merge all packets
         # For each attacker, generate his own packets, then merge all packets
         for attacker in range(num_attackers):
         for attacker in range(num_attackers):
             # Timestamp
             # Timestamp
-            timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
+            timestamp_next_pkt = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP)
             attack_ends_time = timestamp_next_pkt + attack_duration
             attack_ends_time = timestamp_next_pkt + attack_duration
-            timestamp_next_pkt = update_timestamp(timestamp_next_pkt, attacker_pps)
-            attacker_pkts_num = int(pkts_num / num_attackers) + randint(0,100)
+            timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, attacker_pps)
+            attacker_pkts_num = int(pkts_num / num_attackers) + rnd.randint(0, 100)
             for pkt_num in range(attacker_pkts_num):
             for pkt_num in range(attacker_pkts_num):
                 # Stop the attack when it exceeds the duration
                 # Stop the attack when it exceeds the duration
                 if timestamp_next_pkt > attack_ends_time:
                 if timestamp_next_pkt > attack_ends_time:
                     break
                     break
                 # Build request package
                 # Build request package
                 # Select one IP address and its corresponding MAC address
                 # Select one IP address and its corresponding MAC address
-                (ip_source, mac_source) = get_nth_random_element(ip_source_list, mac_source_list)
+                (ip_source, mac_source) = Util.get_nth_random_element(ip_source_list, mac_source_list)
                 # Determine source port
                 # Determine source port
-                (port_source, ttl_value) = get_attacker_config(ip_source_list ,ip_source)
-                request_ether = Ether(dst=mac_destination, src=mac_source)
-                request_ip = IP(src=ip_source, dst=ip_destination, ttl=ttl_value)
+                (port_source, ttl_value) = Util.get_attacker_config(ip_source_list, ip_source)
+                request_ether = inet.Ether(dst=mac_destination, src=mac_source)
+                request_ip = inet.IP(src=ip_source, dst=ip_destination, ttl=ttl_value)
                 # Random win size for each packet
                 # Random win size for each packet
-                source_win_size = choice(source_win_sizes)
-                request_tcp = TCP(sport=port_source, dport=port_destination, flags='S', ack=0, window=source_win_size)
+                source_win_size = rnd.choice(source_win_sizes)
+                request_tcp = inet.TCP(sport=port_source, dport=port_destination, flags='S', ack=0,
+                                       window=source_win_size)
 
 
                 request = (request_ether / request_ip / request_tcp)
                 request = (request_ether / request_ip / request_tcp)
                 request.time = timestamp_next_pkt
                 request.time = timestamp_next_pkt
                 # Append request
                 # Append request
                 self.packets.append(request)
                 self.packets.append(request)
-                self.total_pkt_num +=1
+                self.total_pkt_num += 1
 
 
                 # Build reply package
                 # Build reply package
                 if replies_count <= victim_buffer:
                 if replies_count <= victim_buffer:
-                    reply_ether = Ether(src=mac_destination, dst=mac_source)
-                    reply_ip = IP(src=ip_destination, dst=ip_source, flags='DF')
-                    reply_tcp = TCP(sport=port_destination, dport=port_source, seq=0, ack=1, flags='SA', window=destination_win_value,options=[('MSS', mss_dst)])
+                    reply_ether = inet.Ether(src=mac_destination, dst=mac_source)
+                    reply_ip = inet.IP(src=ip_destination, dst=ip_source, flags='DF')
+                    reply_tcp = inet.TCP(sport=port_destination, dport=port_source, seq=0, ack=1, flags='SA',
+                                         window=destination_win_value, options=[('MSS', mss_dst)])
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply = (reply_ether / reply_ip / reply_tcp)
 
 
-                    timestamp_reply = update_timestamp(timestamp_next_pkt, attacker_pps, minDelay)
-                    while (timestamp_reply <= timestamp_prv_reply):
-                        timestamp_reply = update_timestamp(timestamp_prv_reply, attacker_pps, minDelay)
+                    timestamp_reply = Util.update_timestamp(timestamp_next_pkt, attacker_pps, min_delay)
+                    while timestamp_reply <= timestamp_prv_reply:
+                        timestamp_reply = Util.update_timestamp(timestamp_prv_reply, attacker_pps, min_delay)
                     timestamp_prv_reply = timestamp_reply
                     timestamp_prv_reply = timestamp_reply
 
 
                     reply.time = timestamp_reply
                     reply.time = timestamp_reply
                     self.packets.append(reply)
                     self.packets.append(reply)
-                    replies_count+=1
+                    replies_count += 1
                     self.total_pkt_num += 1
                     self.total_pkt_num += 1
 
 
-                attacker_pps = max(get_interval_pps(complement_interval_attacker_pps, timestamp_next_pkt), (pps / num_attackers) / 2)
-                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, attacker_pps)
+                attacker_pps = max(Util.get_interval_pps(complement_interval_attacker_pps, timestamp_next_pkt),
+                                   (pps / num_attackers) / 2)
+                timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, attacker_pps)
 
 
                 # Store timestamp of first packet (for attack label)
                 # Store timestamp of first packet (for attack label)
-                if self.total_pkt_num <= 2 :
+                if self.total_pkt_num <= 2:
                     self.attack_start_utime = self.packets[0].time
                     self.attack_start_utime = self.packets[0].time
-                elif pkt_num % BUFFER_SIZE == 0: # every 1000 packets write them to the pcap file (append)
+                elif pkt_num % buffer_size == 0:  # every 1000 packets write them to the pcap file (append)
                     self.last_packet = self.packets[-1]
                     self.last_packet = self.packets[-1]
                     self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
                     self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
                     self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
                     self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)