Browse Source

- Fixes errors introduced during merge of master branch
- Moves the merging attack pcap with base pcap into the BaseAttack to enable intermediate writing (append) for DDoS attack

Patrick Jattke 8 years ago
parent
commit
c7167456f3

+ 36 - 3
code/Attack/BaseAttack.py

@@ -1,9 +1,12 @@
 import ipaddress
 import ipaddress
+import os
 import random
 import random
 import re
 import re
+import tempfile
 from abc import abstractmethod, ABCMeta
 from abc import abstractmethod, ABCMeta
 
 
 import ID2TLib.libpcapreader as pr
 import ID2TLib.libpcapreader as pr
+from scapy.utils import PcapWriter
 
 
 from Attack import AttackParameters
 from Attack import AttackParameters
 from Attack.AttackParameters import Parameter
 from Attack.AttackParameters import Parameter
@@ -37,11 +40,11 @@ class BaseAttack(metaclass=ABCMeta):
         self.attack_end_utime = 0
         self.attack_end_utime = 0
 
 
     @abstractmethod
     @abstractmethod
-    def get_packets(self):
+    def generate_attack_pcap(self):
         """
         """
-        Creates the packets containing the attack.
+        Creates a pcap containing the attack packets.
 
 
-        :return: A list of packets ordered ascending by the packet's timestamp.
+        :return: The location of the generated pcap file.
         """
         """
         pass
         pass
 
 
@@ -309,6 +312,36 @@ class BaseAttack(metaclass=ABCMeta):
                 import sys
                 import sys
                 sys.exit(0)
                 sys.exit(0)
 
 
+    def write_attack_pcap(self, packets: list, append_flag: bool = False, destination_path: str = None):
+        """
+        Writes the attack's packets into a PCAP file with a temporary filename.
+        :return: The path of the written PCAP file.
+        """
+        # Only check params initially when attack generation starts
+        if append_flag is False and destination_path is None:
+            # Check if all req. parameters are set
+            self.check_parameters()
+
+        # Determine destination path
+        if destination_path is not None and os.path.exists(destination_path):
+            destination = destination_path
+        else:
+            temp_file = tempfile.NamedTemporaryFile(delete=False)
+            destination = temp_file.name
+
+        # Write packets into pcap file
+        pktdump = PcapWriter(destination, append=append_flag)
+        pktdump.write(packets)
+
+        # Store pcap path and close file objects
+        pktdump.close()
+
+        return destination
+
+    #########################################
+    # RANDOM IP/MAC ADDRESS GENERATORS
+    #########################################
+
     @staticmethod
     @staticmethod
     def generate_random_ipv4_address(n: int = 1):
     def generate_random_ipv4_address(n: int = 1):
         """
         """

+ 22 - 11
code/Attack/DDoSAttack.py

@@ -59,7 +59,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.PORT_DESTINATION, port_destination)
         self.add_param_value(Param.PORT_DESTINATION, port_destination)
         self.add_param_value(Param.PACKETS_LIMIT, randint(1000, 5000))
         self.add_param_value(Param.PACKETS_LIMIT, randint(1000, 5000))
 
 
-    def get_packets(self):
+    def generate_attack_pcap(self):
         def update_timestamp(timestamp, pps, maxdelay):
         def update_timestamp(timestamp, pps, maxdelay):
             """
             """
             Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
             Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
@@ -89,9 +89,10 @@ class DDoSAttack(BaseAttack.BaseAttack):
 
 
         def get_attacker_config(ipAddress: str):
         def get_attacker_config(ipAddress: str):
             """
             """
-
-            :param ipAddress:
-            :return:
+            Returns the attacker configuration depending on the IP address, this includes the port for the next
+            attacking packet and the previously used (fixed) TTL value.
+            :param ipAddress: The IP address of the attacker
+            :return: A tuple consisting of (port, ttlValue)
             """
             """
             # Determine port
             # Determine port
             port = attacker_port_mapping.get(ipAddress)
             port = attacker_port_mapping.get(ipAddress)
@@ -112,11 +113,14 @@ class DDoSAttack(BaseAttack.BaseAttack):
                     ttl = int(round(gd[pos]))
                     ttl = int(round(gd[pos]))
                     if 0 < ttl < 256:  # validity check
                     if 0 < ttl < 256:  # validity check
                         is_invalid = False
                         is_invalid = False
+                    else:
                         pos = index_increment(pos, pos_max)
                         pos = index_increment(pos, pos_max)
                 attacker_ttl_mapping[ipAddress] = ttl
                 attacker_ttl_mapping[ipAddress] = ttl
             # return port and TTL
             # return port and TTL
             return next_port, ttl
             return next_port, ttl
 
 
+        BUFFER_SIZE = 1000
+
         # Determine source IP and MAC address
         # Determine source IP and MAC address
         num_attackers = self.get_param_value(Param.NUMBER_ATTACKERS)
         num_attackers = self.get_param_value(Param.NUMBER_ATTACKERS)
         if num_attackers is not None:  # user supplied Param.NUMBER_ATTACKERS
         if num_attackers is not None:  # user supplied Param.NUMBER_ATTACKERS
@@ -129,15 +133,13 @@ class DDoSAttack(BaseAttack.BaseAttack):
             ip_source_list = self.get_param_value(Param.IP_SOURCE)
             ip_source_list = self.get_param_value(Param.IP_SOURCE)
             mac_source_list = self.get_param_value(Param.MAC_SOURCE)
             mac_source_list = self.get_param_value(Param.MAC_SOURCE)
 
 
-        BUFFER_SIZE_PACKETS = self.get_param_value(Param.PACKETS_LIMIT)
-
         # 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)
         randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 30, 5 / pps: 15, 10 / pps: 3})
         randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 30, 5 / pps: 15, 10 / pps: 3})
 
 
         # Initialize parameters
         # Initialize parameters
-        packets = deque(maxlen=BUFFER_SIZE_PACKETS)
+        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)
@@ -149,6 +151,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
         for pkt_num in range(self.get_param_value(Param.PACKETS_LIMIT)):
         for pkt_num in range(self.get_param_value(Param.PACKETS_LIMIT)):
             # Select one IP address and its corresponding MAC address
             # Select one IP address and its corresponding MAC address
             (ip_source, mac_source) = get_nth_random_element(ip_source_list, mac_source_list)
             (ip_source, mac_source) = get_nth_random_element(ip_source_list, mac_source_list)
@@ -168,9 +171,17 @@ class DDoSAttack(BaseAttack.BaseAttack):
 
 
             timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
             timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
 
 
-        # Store timestamp of first and last packet
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+            # Store timestamp of first packet (for attack label)
+            if pkt_num == 1:
+                self.attack_start_utime = packets[0].time
+            elif pkt_num % BUFFER_SIZE == 0:
+                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 = []
+
+        # Store timestamp of last packet
+        self.attack_end_utime = last_packet.time
 
 
         # return packets sorted by packet time_sec_start
         # return packets sorted by packet time_sec_start
-        return sorted(packets, key=lambda pkt: pkt.time)
+        return path_attack_pcap

+ 3 - 13
code/Attack/PortscanAttack.py

@@ -49,28 +49,18 @@ class PortscanAttack(BaseAttack.BaseAttack):
 
 
         self.add_param_value(Param.IP_SOURCE, most_used_ip_address)
         self.add_param_value(Param.IP_SOURCE, most_used_ip_address)
         self.add_param_value(Param.IP_SOURCE_RANDOMIZE, 'False')
         self.add_param_value(Param.IP_SOURCE_RANDOMIZE, 'False')
-        self.add_param_value(Param.IP_DESTINATION, '192.168.178.13')
-        self.add_param_value(Param.PORT_DESTINATION, '1-1023,1720,1900,8080')
-        self.add_param_value(Param.PORT_SOURCE, '8542')
         self.add_param_value(Param.MAC_SOURCE, self.statistics.get_mac_address(most_used_ip_address))
         self.add_param_value(Param.MAC_SOURCE, self.statistics.get_mac_address(most_used_ip_address))
 
 
         random_ip_address = self.statistics.get_random_ip_address()
         random_ip_address = self.statistics.get_random_ip_address()
         self.add_param_value(Param.IP_DESTINATION, random_ip_address)
         self.add_param_value(Param.IP_DESTINATION, random_ip_address)
         self.add_param_value(Param.MAC_DESTINATION, self.statistics.get_mac_address(random_ip_address))
         self.add_param_value(Param.MAC_DESTINATION, self.statistics.get_mac_address(random_ip_address))
 
 
-        self.add_param_value(Param.PORT_DESTINATION, '0-1023,1720,1900,8080')
+        self.add_param_value(Param.PORT_DESTINATION, '1-1023,1720,1900,8080')
         self.add_param_value(Param.PORT_OPEN, '8080,9232,9233')
         self.add_param_value(Param.PORT_OPEN, '8080,9232,9233')
         self.add_param_value(Param.PORT_DEST_SHUFFLE, 'False')
         self.add_param_value(Param.PORT_DEST_SHUFFLE, 'False')
-        self.add_param_value(Param.PORT_ORDER_DESC, 'False')
-        self.add_param_value(Param.MAC_SOURCE, 'macAddress(ipAddress=' + most_used_ipAddress + ')')
-        self.add_param_value(Param.MAC_DESTINATION, 'A0:1A:28:0B:62:F4')
-        self.add_param_value(Param.PACKETS_PER_SECOND,
-                             (self.statistics.get_pps_sent(most_used_ipAddress) +
-                              self.statistics.get_pps_received(most_used_ipAddress)) / 2)
-        self.add_param_value(Param.INJECT_AT_TIMESTAMP, '1410733342')  # Sun, 14 Sep 2014 22:22:22 GMT
         self.add_param_value(Param.PORT_DEST_ORDER_DESC, 'False')
         self.add_param_value(Param.PORT_DEST_ORDER_DESC, 'False')
 
 
-        self.add_param_value(Param.PORT_SOURCE, '8542')
+        self.add_param_value(Param.PORT_SOURCE, randint(1024, 65535))
         self.add_param_value(Param.PORT_SOURCE_RANDOMIZE, 'False')
         self.add_param_value(Param.PORT_SOURCE_RANDOMIZE, 'False')
 
 
         self.add_param_value(Param.PACKETS_PER_SECOND,
         self.add_param_value(Param.PACKETS_PER_SECOND,
@@ -78,7 +68,7 @@ class PortscanAttack(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 get_packets(self):
+    def generate_attack_pcap(self):
         def update_timestamp(timestamp, pps, maxdelay):
         def update_timestamp(timestamp, pps, maxdelay):
             """
             """
             Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
             Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.

+ 4 - 27
code/ID2TLib/AttackController.py

@@ -26,32 +26,6 @@ class AttackController:
         # The PCAP where the attack should be injected into
         # The PCAP where the attack should be injected into
         self.base_pcap = self.statistics.pcap_filepath
         self.base_pcap = self.statistics.pcap_filepath
 
 
-    def write_attack_pcap(self):
-        """
-        Writes the attack's packets into a PCAP file with a temporary filename.
-        :return: The path of the written PCAP file.
-        """
-        # Check if all req. parameters are set
-        self.current_attack.check_parameters()
-
-        # Create attack packets
-        print("Generating attack packets...", end=" ")
-        sys.stdout.flush()  # force python to print text immediately
-        packets = self.current_attack.get_packets()
-        print("done.")
-
-        # Write packets into pcap file
-        temp_pcap = tempfile.NamedTemporaryFile(delete=False)
-        pktdump = PcapWriter(temp_pcap.name)
-        pktdump.write(packets)
-
-        # Store pcap path and close file objects
-        pcap_path = temp_pcap.name
-        pktdump.close()
-        temp_pcap.close()
-
-        return pcap_path
-
     def create_attack(self, attack_name: str):
     def create_attack(self, attack_name: str):
         """
         """
         Creates dynamically a new class instance based on the given attack_name.
         Creates dynamically a new class instance based on the given attack_name.
@@ -107,7 +81,10 @@ class AttackController:
             attack_note = ""
             attack_note = ""
 
 
         # Write attack into pcap file
         # Write attack into pcap file
-        temp_attack_pcap_path = self.write_attack_pcap()
+        print("Generating attack packets...", end=" ")
+        sys.stdout.flush()  # force python to print text immediately
+        temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
+        print("done.")
 
 
         # Merge attack with existing pcap
         # Merge attack with existing pcap
         pcap_dest_path = self.pcap_file.merge_attack(temp_attack_pcap_path)
         pcap_dest_path = self.pcap_file.merge_attack(temp_attack_pcap_path)

+ 1 - 1
code/ID2TLib/Controller.py

@@ -15,7 +15,7 @@ class Controller:
         :param pcap_file_path:
         :param pcap_file_path:
         """
         """
         # Fields
         # Fields
-        self.pcap_src_path = pcap_file_path
+        self.pcap_src_path = pcap_file_path.strip()
         self.pcap_dest_path = ''
         self.pcap_dest_path = ''
         self.written_pcaps = []
         self.written_pcaps = []