Browse Source

Merge branch 'benchmark_final' of stefan.schmidt/ID2T-toolkit into master

Carlos Garcia 6 years ago
parent
commit
d9437bf5c8

+ 53 - 17
code/Attack/BaseAttack.py

@@ -5,6 +5,7 @@ import os
 import random
 import random
 import re
 import re
 import tempfile
 import tempfile
+import time
 import numpy as np
 import numpy as np
 
 
 from abc import abstractmethod, ABCMeta
 from abc import abstractmethod, ABCMeta
@@ -14,7 +15,7 @@ from scapy.utils import PcapWriter
 from Attack import AttackParameters
 from Attack import AttackParameters
 from Attack.AttackParameters import Parameter
 from Attack.AttackParameters import Parameter
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
-from ID2TLib.Utility import handle_most_used_outputs
+import ID2TLib.Utility as Util
 from lea import Lea
 from lea import Lea
 import ID2TLib.libpcapreader as pr
 import ID2TLib.libpcapreader as pr
 
 
@@ -44,6 +45,10 @@ class BaseAttack(metaclass=ABCMeta):
         self.supported_params = {}
         self.supported_params = {}
         self.attack_start_utime = 0
         self.attack_start_utime = 0
         self.attack_end_utime = 0
         self.attack_end_utime = 0
+        self.start_time = 0
+        self.finish_time = 0
+        self.packets = []
+        self.path_attack_pcap = ""
 
 
     def set_statistics(self, statistics):
     def set_statistics(self, statistics):
         """
         """
@@ -64,6 +69,13 @@ class BaseAttack(metaclass=ABCMeta):
         """
         """
         pass
         pass
 
 
+    @abstractmethod
+    def generate_attack_packets(self):
+        """
+        Creates the attack packets.
+        """
+        pass
+
     @abstractmethod
     @abstractmethod
     def generate_attack_pcap(self):
     def generate_attack_pcap(self):
         """
         """
@@ -103,26 +115,44 @@ class BaseAttack(metaclass=ABCMeta):
         Verifies that the given string or list of IP addresses (strings) is a valid IPv4/IPv6 address.
         Verifies that the given string or list of IP addresses (strings) is a valid IPv4/IPv6 address.
         Accepts comma-separated lists of IP addresses, like "192.169.178.1, 192.168.178.2"
         Accepts comma-separated lists of IP addresses, like "192.169.178.1, 192.168.178.2"
 
 
-        :param ip_address: The IP address(es) as list of strings or comma-separated string.
+        :param ip_address: The IP address(es) as list of strings, comma-separated or dash-separated string.
         :return: True if all IP addresses are valid, otherwise False. And a list of IP addresses as string.
         :return: True if all IP addresses are valid, otherwise False. And a list of IP addresses as string.
         """
         """
+        def append_ips(ip_address_input):
+            """
+            Recursive appending function to handle lists and ranges of IP addresses.
+
+            :param ip_address_input: The IP address(es) as list of strings, comma-separated or dash-separated string.
+            :return: List of all given IP addresses.
+            """
+            ip_list = []
+            is_valid = True
+            for ip in ip_address_input:
+                if '-' in ip:
+                    ip_range = ip.split('-')
+                    ip_range = Util.get_ip_range(ip_range[0], ip_range[1])
+                    is_valid, ips = append_ips(ip_range)
+                    ip_list.extend(ips)
+                else:
+                    try:
+                        ipaddress.ip_address(ip)
+                        ip_list.append(ip)
+                    except ValueError:
+                        return False, ip_list
+            return is_valid, ip_list
+
         ip_address_output = []
         ip_address_output = []
 
 
         # a comma-separated list of IP addresses must be splitted first
         # a comma-separated list of IP addresses must be splitted first
         if isinstance(ip_address, str):
         if isinstance(ip_address, str):
             ip_address = ip_address.split(',')
             ip_address = ip_address.split(',')
 
 
-        for ip in ip_address:
-            try:
-                ipaddress.ip_address(ip)
-                ip_address_output.append(ip)
-            except ValueError:
-                return False, ip_address_output
+        result, ip_address_output = append_ips(ip_address)
 
 
         if len(ip_address_output) == 1:
         if len(ip_address_output) == 1:
-            return True, ip_address_output[0]
+            return result, ip_address_output[0]
         else:
         else:
-            return True, ip_address_output
+            return result, ip_address_output
 
 
     @staticmethod
     @staticmethod
     def _is_port(ports_input: str):
     def _is_port(ports_input: str):
@@ -260,6 +290,15 @@ class BaseAttack(metaclass=ABCMeta):
         if isinstance(seed, int):
         if isinstance(seed, int):
             random.seed(seed)
             random.seed(seed)
 
 
+    def set_start_time(self):
+        self.start_time = time.time()
+
+    def set_finish_time(self):
+        self.finish_time = time.time()
+
+    def get_packet_generation_time(self):
+        return self.finish_time - self.start_time
+
     def add_param_value(self, param, value):
     def add_param_value(self, param, value):
         """
         """
         Adds the pair param : value to the dictionary of attack parameters. Prints and error message and skips the
         Adds the pair param : value to the dictionary of attack parameters. Prints and error message and skips the
@@ -420,7 +459,7 @@ class BaseAttack(metaclass=ABCMeta):
         maxDelay = int(maxDelay) * 10 ** -6
         maxDelay = int(maxDelay) * 10 ** -6
         return minDelay, maxDelay
         return minDelay, maxDelay
 
 
-    def packetsToConvs(self,exploit_raw_packets):
+    def packets_to_convs(self,exploit_raw_packets):
         """
         """
            Classifies a bunch of packets to conversations groups. A conversation is a set of packets go between host A (IP,port)
            Classifies a bunch of packets to conversations groups. A conversation is a set of packets go between host A (IP,port)
            to host B (IP,port)
            to host B (IP,port)
@@ -460,7 +499,6 @@ class BaseAttack(metaclass=ABCMeta):
                     conversations[conv_rep] = pktList
                     conversations[conv_rep] = pktList
         return (conversations, orderList_conversations)
         return (conversations, orderList_conversations)
 
 
-
     def is_valid_ip_address(self,addr):
     def is_valid_ip_address(self,addr):
         """
         """
         Checks if the IP address family is supported.
         Checks if the IP address family is supported.
@@ -492,7 +530,6 @@ class BaseAttack(metaclass=ABCMeta):
             print("\nERROR: Invalid IP addresses; source IP is the same as destination IP: " + ip_destination + ".")
             print("\nERROR: Invalid IP addresses; source IP is the same as destination IP: " + ip_destination + ".")
             sys.exit(0)
             sys.exit(0)
 
 
-
     def get_inter_arrival_time(self, packets, distribution:bool=False):
     def get_inter_arrival_time(self, packets, distribution:bool=False):
         """
         """
         Gets the inter-arrival times array and its distribution of a set of packets.
         Gets the inter-arrival times array and its distribution of a set of packets.
@@ -525,7 +562,6 @@ class BaseAttack(metaclass=ABCMeta):
         else:
         else:
             return inter_arrival_times
             return inter_arrival_times
 
 
-
     def clean_white_spaces(self, str):
     def clean_white_spaces(self, str):
         """
         """
         Delete extra backslash from white spaces. This function is used to process the payload of packets.
         Delete extra backslash from white spaces. This function is used to process the payload of packets.
@@ -567,7 +603,7 @@ class BaseAttack(metaclass=ABCMeta):
             mss_prob_dict = Lea.fromValFreqsDict(mss_dist)
             mss_prob_dict = Lea.fromValFreqsDict(mss_dist)
             mss_value = mss_prob_dict.random()
             mss_value = mss_prob_dict.random()
         else:
         else:
-            mss_value = handle_most_used_outputs(self.statistics.process_db_query("most_used(mssValue)"))
+            mss_value = Util.handle_most_used_outputs(self.statistics.process_db_query("most_used(mssValue)"))
 
 
         # Set TTL based on TTL distribution of IP address
         # Set TTL based on TTL distribution of IP address
         ttl_dist = self.statistics.get_ttl_distribution(ip_address)
         ttl_dist = self.statistics.get_ttl_distribution(ip_address)
@@ -575,7 +611,7 @@ class BaseAttack(metaclass=ABCMeta):
             ttl_prob_dict = Lea.fromValFreqsDict(ttl_dist)
             ttl_prob_dict = Lea.fromValFreqsDict(ttl_dist)
             ttl_value = ttl_prob_dict.random()
             ttl_value = ttl_prob_dict.random()
         else:
         else:
-            ttl_value = handle_most_used_outputs(self.statistics.process_db_query("most_used(ttlValue)"))
+            ttl_value = Util.handle_most_used_outputs(self.statistics.process_db_query("most_used(ttlValue)"))
 
 
         # Set Window Size based on Window Size distribution of IP address
         # Set Window Size based on Window Size distribution of IP address
         win_dist = self.statistics.get_win_distribution(ip_address)
         win_dist = self.statistics.get_win_distribution(ip_address)
@@ -583,7 +619,7 @@ class BaseAttack(metaclass=ABCMeta):
             win_prob_dict = Lea.fromValFreqsDict(win_dist)
             win_prob_dict = Lea.fromValFreqsDict(win_dist)
             win_value = win_prob_dict.random()
             win_value = win_prob_dict.random()
         else:
         else:
-            win_value = handle_most_used_outputs(self.statistics.process_db_query("most_used(winSize)"))
+            win_value = Util.handle_most_used_outputs(self.statistics.process_db_query("most_used(winSize)"))
 
 
         return mss_value, ttl_value, win_value
         return mss_value, ttl_value, win_value
 
 

+ 23 - 19
code/Attack/DDoSAttack.py

@@ -27,6 +27,9 @@ class DDoSAttack(BaseAttack.BaseAttack):
         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.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.IP_SOURCE: ParameterTypes.TYPE_IP_ADDRESS,
@@ -74,7 +77,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
         self.add_param_value(Param.VICTIM_BUFFER, randint(1000,10000))
         self.add_param_value(Param.VICTIM_BUFFER, randint(1000,10000))
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
         BUFFER_SIZE = 1000
         BUFFER_SIZE = 1000
 
 
         # Determine source IP and MAC address
         # Determine source IP and MAC address
@@ -93,7 +96,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
             num_attackers = len(ip_source_list)
             num_attackers = len(ip_source_list)
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = deque(maxlen=BUFFER_SIZE)
+        self.packets = deque(maxlen=BUFFER_SIZE)
         port_source_list = self.get_param_value(Param.PORT_SOURCE)
         port_source_list = self.get_param_value(Param.PORT_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
@@ -134,7 +137,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         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))
         gd = gamma.rvs(alpha, loc=loc, scale=beta, size=len(ip_source_list))
 
 
-        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)
         minDelay, maxDelay = self.get_reply_delay(ip_destination)
@@ -162,7 +165,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         mss_dst = handle_most_used_outputs(mss_dst)
         mss_dst = handle_most_used_outputs(mss_dst)
 
 
         replies_count = 0
         replies_count = 0
-        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
@@ -188,8 +191,8 @@ class DDoSAttack(BaseAttack.BaseAttack):
                 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
-                packets.append(request)
-                total_pkt_num +=1
+                self.packets.append(request)
+                self.total_pkt_num +=1
 
 
                 # Build reply package
                 # Build reply package
                 if replies_count <= victim_buffer:
                 if replies_count <= victim_buffer:
@@ -204,29 +207,30 @@ class DDoSAttack(BaseAttack.BaseAttack):
                     timestamp_prv_reply = timestamp_reply
                     timestamp_prv_reply = timestamp_reply
 
 
                     reply.time = timestamp_reply
                     reply.time = timestamp_reply
-                    packets.append(reply)
+                    self.packets.append(reply)
                     replies_count+=1
                     replies_count+=1
-                    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)
                 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)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, attacker_pps)
 
 
                 # Store timestamp of first packet (for attack label)
                 # Store timestamp of first packet (for attack label)
-                if total_pkt_num <= 2 :
-                    self.attack_start_utime = packets[0].time
+                if self.total_pkt_num <= 2 :
+                    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)
-                    last_packet = packets[-1]
-                    packets = sorted(packets, key=lambda pkt: pkt.time)
-                    path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
-                    packets = []
+                    self.last_packet = self.packets[-1]
+                    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.packets = []
 
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+    def generate_attack_pcap(self):
+        if len(self.packets) > 0:
+            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)
 
 
         # Store timestamp of last packet
         # Store timestamp of last packet
-        self.attack_end_utime = last_packet.time
+        self.attack_end_utime = self.last_packet.time
 
 
         # Return packets sorted by packet time_sec_start
         # Return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
         # pkt_num+1: because pkt_num starts at 0
-        return total_pkt_num , path_attack_pcap
+        return self.total_pkt_num, self.path_attack_pcap

+ 22 - 22
code/Attack/EternalBlueExploit.py

@@ -78,8 +78,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
 
 
-    def generate_attack_pcap(self):
-
+    def generate_attack_packets(self):
 
 
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -89,7 +88,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         port_source = self.get_param_value(Param.PORT_SOURCE)
         port_source = self.get_param_value(Param.PORT_SOURCE)
@@ -100,7 +99,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
 
         # Set TTL based on TTL distribution of IP address
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -144,7 +143,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
         # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
         # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
-        conversations, orderList_conversations = self.packetsToConvs(exploit_raw_packets)
+        conversations, orderList_conversations = self.packets_to_convs(exploit_raw_packets)
         exploit_raw_packets.close()
         exploit_raw_packets.close()
 
 
         conv_start_timesamp = timestamp_next_pkt
         conv_start_timesamp = timestamp_next_pkt
@@ -156,16 +155,16 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
             inter_arrival_times = self.get_inter_arrival_time(conv_pkts)
             inter_arrival_times = self.get_inter_arrival_time(conv_pkts)
 
 
             if conv_index == len(orderList_conversations) - 2:  # Not the last conversation
             if conv_index == len(orderList_conversations) - 2:  # Not the last conversation
-                timestamp_next_pkt = packets[-1].time + uniform(0.001,0.01)
+                timestamp_next_pkt = self.packets[-1].time + uniform(0.001,0.01)
 
 
             if conv_index != len(orderList_conversations)-1: # Not the last conversation
             if conv_index != len(orderList_conversations)-1: # Not the last conversation
                 port_source += 2
                 port_source += 2
-                for pkt_num, pkt in enumerate(conv_pkts):
+                for self.pkt_num, pkt in enumerate(conv_pkts):
                     eth_frame = Ether(pkt[0])
                     eth_frame = Ether(pkt[0])
                     ip_pkt = eth_frame.payload
                     ip_pkt = eth_frame.payload
                     tcp_pkt = ip_pkt.payload
                     tcp_pkt = ip_pkt.payload
 
 
-                    if pkt_num == 0:
+                    if self.pkt_num == 0:
                         if tcp_pkt.getfieldval("dport") == smb_port:
                         if tcp_pkt.getfieldval("dport") == smb_port:
                             orig_ip_dst = ip_pkt.getfieldval("dst")
                             orig_ip_dst = ip_pkt.getfieldval("dst")
 
 
@@ -198,7 +197,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
 
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num] #float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num] #float(timeSteps.random())
 
 
                     # Reply
                     # Reply
                     else:
                     else:
@@ -228,16 +227,16 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]#float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num]#float(timeSteps.random())
 
 
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
 
 
-                    packets.append(new_pkt)
+                    self.packets.append(new_pkt)
 
 
             else: # Last conversation where the victim start a connection with the attacker
             else: # Last conversation where the victim start a connection with the attacker
-                timestamp_next_pkt = packets[-1].time + uniform(0.001, 0.01)
+                timestamp_next_pkt = self.packets[-1].time + uniform(0.001, 0.01)
                 port_source = randint(self.minDefaultPort,self.maxDefaultPort)
                 port_source = randint(self.minDefaultPort,self.maxDefaultPort)
-                for pkt_num, pkt in enumerate(conv_pkts):
+                for self.pkt_num, pkt in enumerate(conv_pkts):
                     eth_frame = Ether(pkt[0])
                     eth_frame = Ether(pkt[0])
                     ip_pkt = eth_frame.payload
                     ip_pkt = eth_frame.payload
                     tcp_pkt = ip_pkt.payload
                     tcp_pkt = ip_pkt.payload
@@ -271,7 +270,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
 
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]# float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num]# float(timeSteps.random())
 
 
                     # Reply
                     # Reply
                     else:
                     else:
@@ -301,20 +300,21 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]# float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num]# float(timeSteps.random())
 
 
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
 
 
-                    packets.append(new_pkt)
+                    self.packets.append(new_pkt)
 
 
+    def generate_attack_pcap(self):
         # Store timestamp of first packet (for attack label)
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            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)
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 13 - 12
code/Attack/FTPWinaXeExploit.py

@@ -77,7 +77,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         self.add_param_value(Param.CUSTOM_PAYLOAD, '')
         self.add_param_value(Param.CUSTOM_PAYLOAD, '')
         self.add_param_value(Param.CUSTOM_PAYLOAD_FILE, '')
         self.add_param_value(Param.CUSTOM_PAYLOAD_FILE, '')
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
 
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
 
 
@@ -97,7 +97,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         custom_payload_limit = 1000
         custom_payload_limit = 1000
         check_payload_len(custom_payload_len, custom_payload_limit)
         check_payload_len(custom_payload_len, custom_payload_limit)
 
 
-        packets = []
+        self.packets = []
 
 
         # Create random victim if specified
         # Create random victim if specified
         if self.get_param_value(Param.IP_SOURCE_RANDOMIZE):
         if self.get_param_value(Param.IP_SOURCE_RANDOMIZE):
@@ -126,7 +126,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         syn = (victim_ether / victim_ip / request_tcp)
         syn = (victim_ether / victim_ip / request_tcp)
         syn.time = timestamp_next_pkt
         syn.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-        packets.append(syn)
+        self.packets.append(syn)
 
 
         # response from attacker (server)
         # response from attacker (server)
         attacker_ether = Ether(src=mac_attacker, dst=mac_victim)
         attacker_ether = Ether(src=mac_attacker, dst=mac_victim)
@@ -137,7 +137,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         synack = (attacker_ether / attacker_ip / reply_tcp)
         synack = (attacker_ether / attacker_ip / reply_tcp)
         synack.time = timestamp_next_pkt
         synack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-        packets.append(synack)
+        self.packets.append(synack)
 
 
         # acknowledgement from victim (client)
         # acknowledgement from victim (client)
         ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A',
         ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A',
@@ -145,7 +145,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         ack = (victim_ether / victim_ip / ack_tcp)
         ack = (victim_ether / victim_ip / ack_tcp)
         ack.time = timestamp_next_pkt
         ack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-        packets.append(ack)
+        self.packets.append(ack)
 
 
         # FTP exploit packet
         # FTP exploit packet
         ftp_tcp = TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='PA',
         ftp_tcp = TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='PA',
@@ -179,7 +179,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         ftp_buff = (attacker_ether / attacker_ip / ftp_tcp)
         ftp_buff = (attacker_ether / attacker_ip / ftp_tcp)
         ftp_buff.time = timestamp_next_pkt
         ftp_buff.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-        packets.append(ftp_buff)
+        self.packets.append(ftp_buff)
         attacker_seq += len(ftp_tcp.payload)
         attacker_seq += len(ftp_tcp.payload)
 
 
         # Fin Ack from attacker
         # Fin Ack from attacker
@@ -189,7 +189,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         fin_ack = (attacker_ether / attacker_ip / fin_ack_tcp)
         fin_ack = (attacker_ether / attacker_ip / fin_ack_tcp)
         fin_ack.time = timestamp_next_pkt
         fin_ack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-        packets.append(fin_ack)
+        self.packets.append(fin_ack)
 
 
         # Ack from victim on FTP packet
         # Ack from victim on FTP packet
         ftp_ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A',
         ftp_ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A',
@@ -197,20 +197,21 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         ftp_ack = (victim_ether / victim_ip / ftp_ack_tcp)
         ftp_ack = (victim_ether / victim_ip / ftp_ack_tcp)
         ftp_ack.time = timestamp_next_pkt
         ftp_ack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-        packets.append(ftp_ack)
+        self.packets.append(ftp_ack)
 
 
         # Ack from victim on Fin/Ack of attacker
         # Ack from victim on Fin/Ack of attacker
         fin_ack_ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq+1, flags='A',
         fin_ack_ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq+1, flags='A',
                       window=victim_win_value, options=[('MSS', victim_mss_value)])
                       window=victim_win_value, options=[('MSS', victim_mss_value)])
         fin_ack_ack = (victim_ether / victim_ip / fin_ack_ack_tcp)
         fin_ack_ack = (victim_ether / victim_ip / fin_ack_ack_tcp)
         fin_ack_ack.time = timestamp_next_pkt
         fin_ack_ack.time = timestamp_next_pkt
-        packets.append(fin_ack_ack)
+        self.packets.append(fin_ack_ack)
 
 
+    def generate_attack_pcap(self):
         # store end time of attack
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
 
         # write attack packets to pcap
         # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 15 - 13
code/Attack/JoomlaRegPrivExploit.py

@@ -77,8 +77,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
 
-    def generate_attack_pcap(self):
-
+    def generate_attack_packets(self):
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
 
 
@@ -88,7 +87,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         port_source = randint(self.minDefaultPort, self.maxDefaultPort)
         port_source = randint(self.minDefaultPort, self.maxDefaultPort)
@@ -102,7 +101,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
 
         # Set TTL based on TTL distribution of IP address
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -134,7 +133,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         global victim_seq
         global victim_seq
         victim_seq = randint(1000,50000)
         victim_seq = randint(1000,50000)
 
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
             tcp_pkt = ip_pkt.payload
@@ -145,7 +144,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
             ip_pkt.payload = b''
             ip_pkt.payload = b''
             tcp_pkt.payload = b''
             tcp_pkt.payload = b''
 
 
-            if pkt_num == 0:
+            if self.pkt_num == 0:
                 prev_orig_port_source = tcp_pkt.getfieldval("sport")
                 prev_orig_port_source = tcp_pkt.getfieldval("sport")
                 if tcp_pkt.getfieldval("dport") == self.http_port:
                 if tcp_pkt.getfieldval("dport") == self.http_port:
                     orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP
                     orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP
@@ -215,17 +214,20 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
                 new_pkt.time = timestamp_next_pkt
 
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
 
         exploit_raw_packets.close()
         exploit_raw_packets.close()
+
+    def generate_attack_pcap(self):
+
         # Store timestamp of first packet (for attack label)
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            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)
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 15 - 14
code/Attack/MS17ScanAttack.py

@@ -77,7 +77,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
 
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -87,7 +87,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         port_source = self.get_param_value(Param.PORT_SOURCE)
         port_source = self.get_param_value(Param.PORT_SOURCE)
@@ -98,7 +98,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
 
         # Set TTL based on TTL distribution of IP address
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -146,12 +146,12 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
 
 
         source_origin_wins, destination_origin_wins = {}, {}
         source_origin_wins, destination_origin_wins = {}, {}
 
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
             tcp_pkt = ip_pkt.payload
 
 
-            if pkt_num == 0:
+            if self.pkt_num == 0:
                 if tcp_pkt.getfieldval("dport") == smb_port:
                 if tcp_pkt.getfieldval("dport") == smb_port:
                     orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP
                     orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP
 
 
@@ -185,7 +185,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
 
 
                 pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                 pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[
-                    pkt_num]  # float(timeSteps.random())
+                    self.pkt_num]  # float(timeSteps.random())
             # Reply
             # Reply
             else:
             else:
                 # Ether
                 # Ether
@@ -213,21 +213,22 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
 
 
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[
-                    pkt_num]  # + float(timeSteps.random())
+                    self.pkt_num]  # + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
                 new_pkt.time = timestamp_next_pkt
 
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
 
         exploit_raw_packets.close()
         exploit_raw_packets.close()
 
 
+    def generate_attack_pcap(self):
         # Store timestamp of first packet (for attack label)
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            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)
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 13 - 8
code/Attack/PortscanAttack.py

@@ -108,7 +108,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
             port_dst_shuffled = ports_dst
             port_dst_shuffled = ports_dst
         return port_dst_shuffled
         return port_dst_shuffled
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
@@ -134,9 +134,13 @@ class PortscanAttack(BaseAttack.BaseAttack):
         timestamp_prv_reply, timestamp_confirm = 0,0
         timestamp_prv_reply, timestamp_confirm = 0,0
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
+        if isinstance(ip_source, list):
+            ip_source = ip_source[0]
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
+        if isinstance(ip_destination, list):
+            ip_destination = ip_destination[0]
 
 
         # Check ip.src == ip.dst
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
         self.ip_src_dst_equal_check(ip_source, ip_destination)
@@ -222,7 +226,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
 
 
             request.time = timestamp_next_pkt
             request.time = timestamp_next_pkt
             # Append request
             # Append request
-            packets.append(request)
+            self.packets.append(request)
 
 
             # 2) Build reply (for open ports) package
             # 2) Build reply (for open ports) package
             if dport in ports_open:  # destination port is OPEN
             if dport in ports_open:  # destination port is OPEN
@@ -238,7 +242,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
                 timestamp_prv_reply = timestamp_reply
                 timestamp_prv_reply = timestamp_reply
 
 
                 reply.time = timestamp_reply
                 reply.time = timestamp_reply
-                packets.append(reply)
+                self.packets.append(reply)
 
 
                 # requester confirms
                 # requester confirms
                 confirm_ether = request_ether
                 confirm_ether = request_ether
@@ -247,18 +251,19 @@ class PortscanAttack(BaseAttack.BaseAttack):
                 confirm = (confirm_ether / confirm_ip / confirm_tcp)
                 confirm = (confirm_ether / confirm_ip / confirm_tcp)
                 timestamp_confirm = Util.update_timestamp(timestamp_reply,pps,minDelay)
                 timestamp_confirm = Util.update_timestamp(timestamp_reply,pps,minDelay)
                 confirm.time = timestamp_confirm
                 confirm.time = timestamp_confirm
-                packets.append(confirm)
+                self.packets.append(confirm)
 
 
                 # else: destination port is NOT OPEN -> no reply is sent by target
                 # else: destination port is NOT OPEN -> no reply is sent by target
 
 
             pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
             timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
 
 
+    def generate_attack_pcap(self):
         # store end time of attack
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
 
         # write attack packets to pcap
         # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 13 - 13
code/Attack/SMBLorisAttack.py

@@ -74,8 +74,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.INJECT_AFTER_PACKET, random.randint(0, self.statistics.get_packet_count()))
         self.add_param_value(Param.INJECT_AFTER_PACKET, random.randint(0, self.statistics.get_packet_count()))
         self.add_param_value(Param.ATTACK_DURATION, 30)
         self.add_param_value(Param.ATTACK_DURATION, 30)
 
 
-    def generate_attack_pcap(self):
-
+    def generate_attack_packets(self):
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
 
 
         # Timestamp
         # Timestamp
@@ -84,7 +83,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
         self.attack_start_utime = first_timestamp
         self.attack_start_utime = first_timestamp
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
 
 
@@ -140,7 +139,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
 
 
             sport = 1025
             sport = 1025
 
 
-            # Timestamps of first packets shouldn't be exactly the same to look more realistic
+            # Timestamps of first self.packets shouldn't be exactly the same to look more realistic
             timestamp_next_pkt = random.uniform(first_timestamp, update_timestamp(first_timestamp, pps))
             timestamp_next_pkt = random.uniform(first_timestamp, update_timestamp(first_timestamp, pps))
 
 
             while timestamp_next_pkt <= attack_ends_time:
             while timestamp_next_pkt <= attack_ends_time:
@@ -161,7 +160,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 syn = (attacker_ether / attacker_ip / syn_tcp)
                 syn = (attacker_ether / attacker_ip / syn_tcp)
                 syn.time = timestamp_next_pkt
                 syn.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, victim_pps, minDelay)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, victim_pps, minDelay)
-                packets.append(syn)
+                self.packets.append(syn)
 
 
                 # response from victim (server)
                 # response from victim (server)
                 synack_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='SA',
                 synack_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='SA',
@@ -170,7 +169,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 synack = (victim_ether / victim_ip / synack_tcp)
                 synack = (victim_ether / victim_ip / synack_tcp)
                 synack.time = timestamp_next_pkt
                 synack.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-                packets.append(synack)
+                self.packets.append(synack)
 
 
                 # acknowledgement from attacker (client)
                 # acknowledgement from attacker (client)
                 ack_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq, flags='A',
                 ack_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq, flags='A',
@@ -178,7 +177,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 ack = (attacker_ether / attacker_ip / ack_tcp)
                 ack = (attacker_ether / attacker_ip / ack_tcp)
                 ack.time = timestamp_next_pkt
                 ack.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-                packets.append(ack)
+                self.packets.append(ack)
 
 
                 # send NBT session header paket with maximum LENGTH-field
                 # send NBT session header paket with maximum LENGTH-field
                 req_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq, flags='AP',
                 req_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq, flags='AP',
@@ -189,7 +188,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 req = (attacker_ether / attacker_ip / req_tcp / req_payload)
                 req = (attacker_ether / attacker_ip / req_tcp / req_payload)
                 req.time = timestamp_next_pkt
                 req.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, victim_pps, minDelay)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, victim_pps, minDelay)
-                packets.append(req)
+                self.packets.append(req)
 
 
                 # final ack from victim (server)
                 # final ack from victim (server)
                 last_ack_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='A',
                 last_ack_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='A',
@@ -197,15 +196,16 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 last_ack = (victim_ether / victim_ip / last_ack_tcp)
                 last_ack = (victim_ether / victim_ip / last_ack_tcp)
                 last_ack.time = timestamp_next_pkt
                 last_ack.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-                packets.append(last_ack)
+                self.packets.append(last_ack)
 
 
                 sport += 1
                 sport += 1
 
 
+    def generate_attack_pcap(self):
         # store end time of attack
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        # write attack self.packets to pcap
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 21 - 24
code/Attack/SMBScanAttack.py

@@ -46,8 +46,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
             Param.HOSTING_IP: ParameterTypes.TYPE_IP_ADDRESS,
             Param.HOSTING_IP: ParameterTypes.TYPE_IP_ADDRESS,
             Param.HOSTING_VERSION: ParameterTypes.TYPE_STRING,
             Param.HOSTING_VERSION: ParameterTypes.TYPE_STRING,
             Param.SOURCE_PLATFORM: ParameterTypes.TYPE_STRING,
             Param.SOURCE_PLATFORM: ParameterTypes.TYPE_STRING,
-            Param.PROTOCOL_VERSION: ParameterTypes.TYPE_STRING,
-            Param.IP_DESTINATION_END: ParameterTypes.TYPE_IP_ADDRESS
+            Param.PROTOCOL_VERSION: ParameterTypes.TYPE_STRING
         })
         })
 
 
     def init_params(self):
     def init_params(self):
@@ -91,9 +90,8 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.HOSTING_VERSION, get_smb_version(platform=self.host_os))
         self.add_param_value(Param.HOSTING_VERSION, get_smb_version(platform=self.host_os))
         self.add_param_value(Param.SOURCE_PLATFORM, ID2TLib.Utility.get_rnd_os())
         self.add_param_value(Param.SOURCE_PLATFORM, ID2TLib.Utility.get_rnd_os())
         self.add_param_value(Param.PROTOCOL_VERSION, "1")
         self.add_param_value(Param.PROTOCOL_VERSION, "1")
-        self.add_param_value(Param.IP_DESTINATION_END, "0.0.0.0")
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
 
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
 
 
@@ -111,7 +109,6 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_destinations = self.get_param_value(Param.IP_DESTINATION)
         ip_destinations = self.get_param_value(Param.IP_DESTINATION)
         hosting_ip = self.get_param_value(Param.HOSTING_IP)
         hosting_ip = self.get_param_value(Param.HOSTING_IP)
-        ip_range_end = self.get_param_value(Param.IP_DESTINATION_END)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_dest = self.get_param_value(Param.MAC_DESTINATION)
         mac_dest = self.get_param_value(Param.MAC_DESTINATION)
 
 
@@ -124,7 +121,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
             invalid_smb_version(hosting_version)
             invalid_smb_version(hosting_version)
         # Check source platform
         # Check source platform
         src_platform = self.get_param_value(Param.SOURCE_PLATFORM).lower()
         src_platform = self.get_param_value(Param.SOURCE_PLATFORM).lower()
-        packets = []
+        self.packets = []
 
 
         # randomize source ports according to platform, if specified
         # randomize source ports according to platform, if specified
         if self.get_param_value(Param.PORT_SOURCE_RANDOMIZE):
         if self.get_param_value(Param.PORT_SOURCE_RANDOMIZE):
@@ -146,9 +143,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         else:
         else:
             ip_dests.append(ip_destinations)
             ip_dests.append(ip_destinations)
 
 
-        # Generate IPs of destination IP range, if specified
-        if ip_range_end != "0.0.0.0":
-            ip_dests = get_ip_range(ip_dests[0], ip_range_end)
+        if isinstance(ip_dests, list):
             shuffle(ip_dests)
             shuffle(ip_dests)
 
 
         # Randomize source IP, if specified
         # Randomize source IP, if specified
@@ -203,7 +198,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                 request.time = timestamp_next_pkt
                 request.time = timestamp_next_pkt
 
 
                 # Append request
                 # Append request
-                packets.append(request)
+                self.packets.append(request)
 
 
                 # Update timestamp for next package
                 # Update timestamp for next package
                 timestamp_reply = update_timestamp(timestamp_next_pkt, pps, minDelay)
                 timestamp_reply = update_timestamp(timestamp_next_pkt, pps, minDelay)
@@ -223,7 +218,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     victim_seq += 1
                     victim_seq += 1
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply.time = timestamp_reply
                     reply.time = timestamp_reply
-                    packets.append(reply)
+                    self.packets.append(reply)
 
 
                     # requester confirms, ACK
                     # requester confirms, ACK
                     confirm_ether = request_ether
                     confirm_ether = request_ether
@@ -233,7 +228,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     confirm = (confirm_ether / confirm_ip / confirm_tcp)
                     confirm = (confirm_ether / confirm_ip / confirm_tcp)
                     timestamp_confirm = update_timestamp(timestamp_reply, pps, minDelay)
                     timestamp_confirm = update_timestamp(timestamp_reply, pps, minDelay)
                     confirm.time = timestamp_confirm
                     confirm.time = timestamp_confirm
-                    packets.append(confirm)
+                    self.packets.append(confirm)
 
 
                     smb_MID = randint(1, 65535)
                     smb_MID = randint(1, 65535)
                     smb_PID = randint(1, 65535)
                     smb_PID = randint(1, 65535)
@@ -269,7 +264,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
 
 
                     timestamp_smb_req = update_timestamp(timestamp_confirm, pps, minDelay)
                     timestamp_smb_req = update_timestamp(timestamp_confirm, pps, minDelay)
                     smb_req_combined.time = timestamp_smb_req
                     smb_req_combined.time = timestamp_smb_req
-                    packets.append(smb_req_combined)
+                    self.packets.append(smb_req_combined)
 
 
                     # destination confirms SMB request package
                     # destination confirms SMB request package
                     reply_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
                     reply_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
@@ -277,7 +272,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     confirm_smb_req = (reply_ether / reply_ip / reply_tcp)
                     confirm_smb_req = (reply_ether / reply_ip / reply_tcp)
                     timestamp_reply = update_timestamp(timestamp_smb_req, pps, minDelay)
                     timestamp_reply = update_timestamp(timestamp_smb_req, pps, minDelay)
                     confirm_smb_req.time = timestamp_reply
                     confirm_smb_req.time = timestamp_reply
-                    packets.append(confirm_smb_req)
+                    self.packets.append(confirm_smb_req)
 
 
                     # smb response package
                     # smb response package
                     first_timestamp = time.mktime(time.strptime(self.statistics.get_pcap_timestamp_start()[:19],
                     first_timestamp = time.mktime(time.strptime(self.statistics.get_pcap_timestamp_start()[:19],
@@ -316,7 +311,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                         smb_rsp_combined = (smb_rsp_combined / smb_rsp_negotiate_body)
                         smb_rsp_combined = (smb_rsp_combined / smb_rsp_negotiate_body)
 
 
                     smb_rsp_combined.time = timestamp_smb_rsp
                     smb_rsp_combined.time = timestamp_smb_rsp
-                    packets.append(smb_rsp_combined)
+                    self.packets.append(smb_rsp_combined)
 
 
 
 
                     # source confirms SMB response package
                     # source confirms SMB response package
@@ -325,7 +320,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     confirm_smb_res = (confirm_ether / confirm_ip / confirm_tcp)
                     confirm_smb_res = (confirm_ether / confirm_ip / confirm_tcp)
                     timestamp_confirm = update_timestamp(timestamp_smb_rsp, pps, minDelay)
                     timestamp_confirm = update_timestamp(timestamp_smb_rsp, pps, minDelay)
                     confirm_smb_res.time = timestamp_confirm
                     confirm_smb_res.time = timestamp_confirm
-                    packets.append(confirm_smb_res)
+                    self.packets.append(confirm_smb_res)
 
 
                     # attacker sends FIN ACK
                     # attacker sends FIN ACK
                     confirm_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq,
                     confirm_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq,
@@ -334,7 +329,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     timestamp_src_fin_ack = update_timestamp(timestamp_confirm, pps, minDelay)
                     timestamp_src_fin_ack = update_timestamp(timestamp_confirm, pps, minDelay)
                     source_fin_ack.time = timestamp_src_fin_ack
                     source_fin_ack.time = timestamp_src_fin_ack
                     attacker_seq += 1
                     attacker_seq += 1
-                    packets.append(source_fin_ack)
+                    self.packets.append(source_fin_ack)
 
 
                     # victim sends FIN ACK
                     # victim sends FIN ACK
                     reply_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
                     reply_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
@@ -343,7 +338,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     timestamp_dest_fin_ack = update_timestamp(timestamp_src_fin_ack, pps, minDelay)
                     timestamp_dest_fin_ack = update_timestamp(timestamp_src_fin_ack, pps, minDelay)
                     victim_seq += 1
                     victim_seq += 1
                     destination_fin_ack.time = timestamp_dest_fin_ack
                     destination_fin_ack.time = timestamp_dest_fin_ack
-                    packets.append(destination_fin_ack)
+                    self.packets.append(destination_fin_ack)
 
 
                     # source sends final ACK
                     # source sends final ACK
                     confirm_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq,
                     confirm_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq,
@@ -351,7 +346,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     final_ack = (confirm_ether / confirm_ip / confirm_tcp)
                     final_ack = (confirm_ether / confirm_ip / confirm_tcp)
                     timestamp_final_ack = update_timestamp(timestamp_dest_fin_ack, pps, minDelay)
                     timestamp_final_ack = update_timestamp(timestamp_dest_fin_ack, pps, minDelay)
                     final_ack.time = timestamp_final_ack
                     final_ack.time = timestamp_final_ack
-                    packets.append(final_ack)
+                    self.packets.append(final_ack)
 
 
                 else:
                 else:
                     # Build RST package
                     # Build RST package
@@ -361,16 +356,18 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                                     window=destination_win_value, options=[('MSS', destination_mss_value)])
                                     window=destination_win_value, options=[('MSS', destination_mss_value)])
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply.time = timestamp_reply
                     reply.time = timestamp_reply
-                    packets.append(reply)
+                    self.packets.append(reply)
 
 
             pps = max(get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             pps = max(get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
             timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
 
 
+    def generate_attack_pcap(self):
+
         # store end time of attack
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        # write attack self.packets to pcap
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 20 - 13
code/Attack/SQLiAttack.py

@@ -77,7 +77,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
@@ -86,11 +86,15 @@ class SQLiAttack(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
+        if isinstance(ip_source, list):
+            ip_source = ip_source[0]
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
+        if isinstance(ip_destination, list):
+            ip_destination = ip_destination[0]
         port_destination = self.get_param_value(Param.PORT_DESTINATION)
         port_destination = self.get_param_value(Param.PORT_DESTINATION)
 
 
         target_host = self.get_param_value(Param.TARGET_HOST)
         target_host = self.get_param_value(Param.TARGET_HOST)
@@ -99,7 +103,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
 
         # Set TTL based on TTL distribution of IP address
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -133,7 +137,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         global victim_seq
         global victim_seq
         victim_seq = random.randint(1000, 50000)
         victim_seq = random.randint(1000, 50000)
 
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
             tcp_pkt = ip_pkt.payload
@@ -144,7 +148,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
             ip_pkt.payload = b''
             ip_pkt.payload = b''
             tcp_pkt.payload = b''
             tcp_pkt.payload = b''
 
 
-            if pkt_num == 0:
+            if self.pkt_num == 0:
                 prev_orig_port_source = tcp_pkt.getfieldval("sport")
                 prev_orig_port_source = tcp_pkt.getfieldval("sport")
                 orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP
                 orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP
 
 
@@ -231,17 +235,20 @@ class SQLiAttack(BaseAttack.BaseAttack):
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
                 new_pkt.time = timestamp_next_pkt
 
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
 
         exploit_raw_packets.close()
         exploit_raw_packets.close()
+
+    def generate_attack_pcap(self):
+
         # Store timestamp of first packet (for attack label)
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            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)
 
 
-        # return packets sorted by packet time_sec_start
+        # return self.packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 13 - 11
code/Attack/SalityBotnet.py

@@ -55,7 +55,7 @@ class SalityBotnet(BaseAttack.BaseAttack):
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
 
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -66,7 +66,7 @@ class SalityBotnet(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
 
 
@@ -89,13 +89,13 @@ class SalityBotnet(BaseAttack.BaseAttack):
         ip_map = {origin_ip_src : ip_source, origin_ip_dns_server: ip_dns_server}
         ip_map = {origin_ip_src : ip_source, origin_ip_dns_server: ip_dns_server}
         mac_map = {origin_mac_src : mac_source, origin_mac_dns_server: mac_dns_server}
         mac_map = {origin_mac_src : mac_source, origin_mac_dns_server: mac_dns_server}
 
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
 
         # Inject Sality botnet
         # Inject Sality botnet
         # Read sality_botnet pcap file
         # Read sality_botnet pcap file
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             ip_pkt = eth_frame.payload
 
 
@@ -127,17 +127,19 @@ class SalityBotnet(BaseAttack.BaseAttack):
             pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
             timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
 
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
 
         exploit_raw_packets.close()
         exploit_raw_packets.close()
+
+    def generate_attack_pcap(self):
         # Store timestamp of first packet (for attack label)
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            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)
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 2 - 1
code/CLI.py

@@ -63,6 +63,7 @@ class CLI(object):
                                                        'in interval-wise, TCP checksum, and checking payload availability.', action='store_true')
                                                        'in interval-wise, TCP checksum, and checking payload availability.', action='store_true')
         parser.add_argument('-S', '--randomSeed', action='append', help='sets random seed for testing or benchmarking',
         parser.add_argument('-S', '--randomSeed', action='append', help='sets random seed for testing or benchmarking',
                             nargs='+', default=[])
                             nargs='+', default=[])
+        parser.add_argument('-T', '--time', help='measures packet generation time', action='store_true', default=False)
 
 
         # Attack arguments
         # Attack arguments
         parser.add_argument('-a', '--attack', metavar="ATTACK", action='append',
         parser.add_argument('-a', '--attack', metavar="ATTACK", action='append',
@@ -151,7 +152,7 @@ class CLI(object):
         # Process attack(s) with given attack params
         # Process attack(s) with given attack params
         if self.args.attack is not None:
         if self.args.attack is not None:
             # If attack is present, load attack with params
             # If attack is present, load attack with params
-            controller.process_attacks(self.args.attack, self.args.randomSeed)
+            controller.process_attacks(self.args.attack, self.args.randomSeed, self.args.time)
 
 
         # Parameter -q without arguments was given -> go into query loop
         # Parameter -q without arguments was given -> go into query loop
         if self.args.query == [None]:
         if self.args.query == [None]:

+ 14 - 5
code/ID2TLib/AttackController.py

@@ -52,7 +52,7 @@ class AttackController:
         # Record the attack
         # Record the attack
         self.added_attacks.append(self.current_attack)
         self.added_attacks.append(self.current_attack)
 
 
-    def process_attack(self, attack: str, params: str):
+    def process_attack(self, attack: str, params: str, time=False):
         """
         """
         Takes as input the name of an attack (classname) and the attack parameters as string. Parses the string of
         Takes as input the name of an attack (classname) and the attack parameters as string. Parses the string of
         attack parameters, creates the attack by writing the attack packets and returns the path of the written pcap.
         attack parameters, creates the attack by writing the attack packets and returns the path of the written pcap.
@@ -94,15 +94,24 @@ class AttackController:
         # Write attack into pcap file
         # Write attack into pcap file
         print("Generating attack packets...", end=" ")
         print("Generating attack packets...", end=" ")
         sys.stdout.flush()  # force python to print text immediately
         sys.stdout.flush()  # force python to print text immediately
-        total_packets, temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
-        print("done. (total: " + str(total_packets) + " pkts.)")
+        if time:
+            self.current_attack.set_start_time()
+        self.current_attack.generate_attack_packets()
+        if time:
+            self.current_attack.set_finish_time()
+        duration = self.current_attack.get_packet_generation_time()
+        self.total_packets, temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
+        print("done. (total: " + str(self.total_packets) + " pkts", end="")
+        if time:
+            print(" in ", duration, " seconds", end="")
+        print(".)")
 
 
         # Store label into LabelManager
         # Store label into LabelManager
         l = Label(attack, self.get_attack_start_utime(),
         l = Label(attack, self.get_attack_start_utime(),
                   self.get_attack_end_utime(), attack_note)
                   self.get_attack_end_utime(), attack_note)
         self.label_mgr.add_labels(l)
         self.label_mgr.add_labels(l)
 
 
-        return temp_attack_pcap_path
+        return temp_attack_pcap_path, duration
 
 
     def get_attack_start_utime(self):
     def get_attack_start_utime(self):
         """
         """
@@ -123,4 +132,4 @@ class AttackController:
         :return: None
         :return: None
         """
         """
         for param_key, param_value in params.items():
         for param_key, param_value in params.items():
-            self.current_attack.add_param_value(param_key, param_value)
+            self.current_attack.add_param_value(param_key, param_value)

+ 7 - 2
code/ID2TLib/Controller.py

@@ -41,21 +41,26 @@ class Controller:
         """
         """
         self.statistics.load_pcap_statistics(flag_write_file, flag_recalculate_stats, flag_print_statistics)
         self.statistics.load_pcap_statistics(flag_write_file, flag_recalculate_stats, flag_print_statistics)
 
 
-    def process_attacks(self, attacks_config: list, seeds=[]):
+    def process_attacks(self, attacks_config: list, seeds=[], time=False):
         """
         """
         Creates the attack based on the attack name and the attack parameters given in the attacks_config. The
         Creates the attack based on the attack name and the attack parameters given in the attacks_config. The
         attacks_config is a list of attacks, e.g.
         attacks_config is a list of attacks, e.g.
         [['PortscanAttack', 'ip.src="192.168.178.2",'dst.port=80'],['PortscanAttack', 'ip.src="10.10.10.2"]].
         [['PortscanAttack', 'ip.src="192.168.178.2",'dst.port=80'],['PortscanAttack', 'ip.src="10.10.10.2"]].
         Merges the individual temporary attack pcaps into one single pcap and merges this single pcap with the
         Merges the individual temporary attack pcaps into one single pcap and merges this single pcap with the
         input dataset.
         input dataset.
+
         :param attacks_config: A list of attacks with their attack parameters.
         :param attacks_config: A list of attacks with their attack parameters.
+        :param seeds: A list of random seeds for the given attacks.
+        :param time: Measure time for packet generation.
         """
         """
         # load attacks sequentially
         # load attacks sequentially
+        self.durations = []
         i = 0
         i = 0
         for attack in attacks_config:
         for attack in attacks_config:
             if len(seeds) > i:
             if len(seeds) > i:
                 self.attack_controller.set_seed(seed=seeds[i][0])
                 self.attack_controller.set_seed(seed=seeds[i][0])
-            temp_attack_pcap = self.attack_controller.process_attack(attack[0], attack[1:])
+            temp_attack_pcap, duration = self.attack_controller.process_attack(attack[0], attack[1:], time)
+            self.durations.append(duration)
             self.written_pcaps.append(temp_attack_pcap)
             self.written_pcaps.append(temp_attack_pcap)
             i += 1
             i += 1
 
 

+ 9 - 0
code/ID2TLib/TestLibrary.py

@@ -124,3 +124,12 @@ def get_attacker_config(ip_source_list, ipAddress: str):
 
 
     return next_port, ttl
     return next_port, ttl
 
 
+
+def write_attack_pcap(self, packets: list, append_flag: bool = False, destination_path: str = None):
+    """
+    temporal efficiency test patch for write_attack_pcap (Attack.BaseAttack.py)
+
+    :return: The path to a dummy pcap file.
+    """
+    os.system("cp " + test_pcap + " " + test_resource_dir + "dummy.pcap")
+    return test_resource_dir + 'dummy.pcap'

+ 47 - 2
code/Test/ID2TAttackTest.py

@@ -13,7 +13,7 @@ class ID2TAttackTest(unittest.TestCase):
 
 
     def checksum_test(self, attack_args, sha256_checksum, seed=5, cleanup=True, pcap=Lib.test_pcap,
     def checksum_test(self, attack_args, sha256_checksum, seed=5, cleanup=True, pcap=Lib.test_pcap,
                       flag_write_file=False, flag_recalculate_stats=False, flag_print_statistics=False,
                       flag_write_file=False, flag_recalculate_stats=False, flag_print_statistics=False,
-                      attack_sub_dir=True, test_sub_dir=True):
+                      attack_sub_dir=True, test_sub_dir=True, time=False):
         """
         """
         Runs the attack against a given sha256 checksum.
         Runs the attack against a given sha256 checksum.
 
 
@@ -27,11 +27,13 @@ class ID2TAttackTest(unittest.TestCase):
         :param flag_print_statistics: Prints the statistics on the terminal.
         :param flag_print_statistics: Prints the statistics on the terminal.
         :param attack_sub_dir: create sub-directory for each attack-class if True
         :param attack_sub_dir: create sub-directory for each attack-class if True
         :param test_sub_dir: create sub-directory for each test-function/case if True
         :param test_sub_dir: create sub-directory for each test-function/case if True
+        :param time: Measure time for packet generation.
         """
         """
 
 
         controller = Ctrl.Controller(pcap_file_path=pcap, do_extra_tests=False)
         controller = Ctrl.Controller(pcap_file_path=pcap, do_extra_tests=False)
         controller.load_pcap_statistics(flag_write_file, flag_recalculate_stats, flag_print_statistics)
         controller.load_pcap_statistics(flag_write_file, flag_recalculate_stats, flag_print_statistics)
-        controller.process_attacks(attack_args, [[seed]])
+
+        controller.process_attacks(attack_args, [[seed]], time)
 
 
         caller_function = inspect.stack()[1].function
         caller_function = inspect.stack()[1].function
 
 
@@ -46,6 +48,49 @@ class ID2TAttackTest(unittest.TestCase):
         else:
         else:
             Lib.rename_test_result_files(controller, caller_function, attack_sub_dir, test_sub_dir)
             Lib.rename_test_result_files(controller, caller_function, attack_sub_dir, test_sub_dir)
 
 
+    def temporal_efficiency_test(self, attack_args, time_limit=15, factor=1, seed=None, cleanup=True, pcap=Lib.test_pcap,
+                                 flag_write_file=False, flag_recalculate_stats=False, flag_print_statistics=False,
+                                 attack_sub_dir=True, test_sub_dir=True):
+        """
+        Runs the attack with given aruments and monitors time efficiency.
+
+        :param attack_args: A list of attacks with their attack parameters (as defined in Controller.process_attacks).
+        :param time_limit: The given time limit in seconds.
+        :param factor: A factor to scale the generation time (e.g. only 7 pkts generated -> *10000/7 for 15 seconds).
+        :param seed: A random seed to keep random values static (care for count and order of random generation).
+        :param cleanup: Clean up attack output after testing.
+        :param pcap: The input pcap for the attack.
+        :param flag_write_file: Writes the statistics to a file.
+        :param flag_recalculate_stats: Forces the recalculation of statistics.
+        :param flag_print_statistics: Prints the statistics on the terminal.
+        :param attack_sub_dir: create sub-directory for each attack-class if True
+        :param test_sub_dir: create sub-directory for each test-function/case if True
+        """
+
+        controller = Ctrl.Controller(pcap_file_path=pcap, do_extra_tests=False)
+        controller.load_pcap_statistics(flag_write_file, flag_recalculate_stats, flag_print_statistics)
+
+        if seed is None:
+            controller.process_attacks(attack_args, time=True)
+        else:
+            controller.process_attacks(attack_args, [[seed]], time=True)
+
+        duration = controller.durations[0]*factor/controller.attack_controller.total_packets
+        print(attack_args[0][0] + ' needs ' + str(duration) + ' seconds to generate ' + str(factor) + ' packets.')
+
+        caller_function = inspect.stack()[1].function
+
+        try:
+            self.assertLessEqual(duration, time_limit)
+        except self.failureException:
+            Lib.rename_test_result_files(controller, caller_function, attack_sub_dir, test_sub_dir)
+            raise
+
+        if cleanup:
+            Lib.clean_up(controller)
+        else:
+            Lib.rename_test_result_files(self.controller, caller_function, attack_sub_dir, test_sub_dir)
+
     def order_test(self, attack_args, seed=None, cleanup=True, pcap=Lib.test_pcap,
     def order_test(self, attack_args, seed=None, cleanup=True, pcap=Lib.test_pcap,
                    flag_write_file=False, flag_recalculate_stats=False, flag_print_statistics=False,
                    flag_write_file=False, flag_recalculate_stats=False, flag_print_statistics=False,
                    attack_sub_dir=True, test_sub_dir=True):
                    attack_sub_dir=True, test_sub_dir=True):

+ 70 - 0
code/Test/efficiency_testing.py

@@ -0,0 +1,70 @@
+import unittest.mock as mock
+
+import ID2TLib.TestLibrary as Lib
+import Test.ID2TAttackTest as Test
+
+
+class EfficiencyTests(Test.ID2TAttackTest):
+
+    def test_SMBLoris_10_000(self):
+        self.temporal_efficiency_test([['SMBLorisAttack', 'attackers.count=30', 'packets.per-second=8.0']],
+                                      time_limit=15, factor=10000)
+
+    def test_SMBLoris_100_000(self):
+        self.temporal_efficiency_test([['SMBLorisAttack', 'attackers.count=30', 'packets.per-second=98']],
+                                      time_limit=150, factor=100000)
+
+    def test_SMBScan_10_000(self):
+        self.temporal_efficiency_test([['SMBScanAttack', 'ip.src=192.168.178.1',
+                                        'ip.dst=192.168.178.10-192.168.197.145']], time_limit=15, factor=10000)
+
+    def test_SMBScan_100_000(self):
+        self.temporal_efficiency_test([['SMBScanAttack', 'ip.src=192.168.178.1', 'ip.dst=192.168.0.1-192.168.195.76']],
+                                      time_limit=150, factor=100000)
+
+    def test_SMBScan_hosting_10_000(self):
+        self.temporal_efficiency_test([['SMBScanAttack', 'ip.src=192.168.178.1',
+                                        'ip.dst=192.168.178.10-192.168.181.241',
+                                        'hosting.ip=192.168.178.10-192.168.181.241']], time_limit=15, factor=10000)
+
+    def test_SMBScan_hosting_100_000(self):
+        self.temporal_efficiency_test([['SMBScanAttack', 'ip.src=192.168.178.1', 'ip.dst=192.168.178.10-192.168.217.25',
+                                        'hosting.ip=192.168.178.10-192.168.217.25']], time_limit=150, factor=100000)
+
+    @mock.patch('ID2TLib.Utility.get_rnd_bytes', side_effect=Lib.get_bytes)
+    @mock.patch('ID2TLib.Utility.get_rnd_x86_nop', side_effect=Lib.get_x86_nop)
+    def test_FTPExploit(self, mock_get_rnd_x86_nop, mock_get_rnd_bytes):
+        self.temporal_efficiency_test([['FTPWinaXeExploit', 'ip.src=192.168.178.1', 'ip.dst=192.168.178.10']],
+                                      time_limit=15, factor=10000)
+
+    def test_PortscanAttack_open_10_000(self):
+        self.temporal_efficiency_test([['PortscanAttack', 'ip.src=192.168.178.1', 'port.open=80']], time_limit=15,
+                                      factor=10000)
+
+    def test_PortscanAttack_close_10_000(self):
+        self.temporal_efficiency_test([['PortscanAttack', 'ip.src=192.168.178.1', 'port.open=20']], time_limit=15,
+                                      factor=10000)
+
+    def test_SQLi_10_000(self):
+        # FIXME: sometimes it takes 15.34028493521018 instead of the normal 7.150923313737726 seconds
+        self.temporal_efficiency_test([['SQLiAttack', 'ip.dst=192.168.0.1']], time_limit=15, factor=10000)
+
+    def test_Joomla_10_000(self):
+        self.temporal_efficiency_test([['JoomlaRegPrivExploit', 'ip.src=192.168.178.1']], time_limit=15, factor=10000)
+
+    def test_SalityBotnet_10_000(self):
+        self.temporal_efficiency_test([['SalityBotnet']], time_limit=15, factor=10000)
+
+    @mock.patch('Attack.BaseAttack.BaseAttack.write_attack_pcap', side_effect=Lib.write_attack_pcap)
+    def test_DDoS_10_000(self, mock_write_attack_pcap):
+        # TODO: update attack args, when DDoS gets refactored
+        self.temporal_efficiency_test([['DDoSAttack', 'attackers.count=100', 'packets.per-second=95',
+                                        'attack.duration=150']], time_limit=15, factor=10000)
+
+    @mock.patch('Attack.BaseAttack.BaseAttack.write_attack_pcap', side_effect=Lib.write_attack_pcap)
+    def test_DDoS_100_000(self, mock_write_attack_pcap):
+        # TODO: update attack args, when DDoS gets refactored
+        self.temporal_efficiency_test([['DDoSAttack', 'attackers.count=1000', 'packets.per-second=950',
+                                        'attack.duration=300']], time_limit=150, factor=100000)
+
+    # TODO: add temporal efficiency test(s) for EternalBlue and MS17

+ 6 - 6
code/Test/test_SMBScan.py

@@ -2,14 +2,14 @@ import unittest.mock as mock
 
 
 import Test.ID2TAttackTest as Test
 import Test.ID2TAttackTest as Test
 
 
-sha_default = '213e194da7bc952cc093868c7450901b0fb93c7255d694eb37ea0b9b48bca65d'
+sha_default = 'ef321877edfd828f6e6cd4abbffb5ade9cb66b3acd54ba9f3a5e2bfbeac9c964'
 sha_one_victim_linux = '4928d421caaec8f2c4e5c5bb835b5521b705478779cbc8f343b77143a5a66995'
 sha_one_victim_linux = '4928d421caaec8f2c4e5c5bb835b5521b705478779cbc8f343b77143a5a66995'
-sha_victim_range_winxp_hosting = '4c6cb5cb4f838e75b41af4feb2fd9a6fe7e1b226a38b3e8759ce3d31e5a2535e'
-sha_multiple_victims_macos = '0be79b9ad7346562f392e07a5156de978e02f4f25ae8d409b81cc6e0d726012c'
-sha_port_shuffle = '8ef501fa31135b8fea845a2be6a9605e0c3f9c4895b717f9206d485a669c2a73'
+sha_victim_range_winxp_hosting = '57a0b7dd69a5bba35404af574d4f06ef52ac2b3b292703596dabd2d1c31721b0'
+sha_multiple_victims_macos = '82d6d7e0471e6395c77df7b5bac141e48d50afe22841c7c53747bbfdd0de184d'
+sha_port_shuffle = '85d4fd1b44e41cfb30d5758c7264f4d5509701c04a0f12495b4155011fc3aaaa'
 sha_dest_mac_only = '0814dadb666e0056ef5b3a572a4971f333376b61e602acb84cb99c851845f016'
 sha_dest_mac_only = '0814dadb666e0056ef5b3a572a4971f333376b61e602acb84cb99c851845f016'
-sha_ip_src_shuffle = '6c0c9ccbedb631e4965ec36932276a1bd73b8a4aca5a5c46f01fd0a2800a064f'
-sha_smb2 = '8755a901295a90362d8041ecf1243a31fff582f5fe64555205625263c253476e'
+sha_ip_src_shuffle = 'f070db569ecf4e17003e60f9ac53c064279c732ccb2128c13c8a7e3b64adc846'
+sha_smb2 = '9d78ac62d76a811c62e0ba7f0ed88569fd133cc06756451a58021be5e1c9fb61'
 
 
 # TODO: improve coverage
 # TODO: improve coverage