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 7 years ago
parent
commit
c7167456f3

+ 36 - 3
code/Attack/BaseAttack.py

@@ -1,9 +1,12 @@
 import ipaddress
+import os
 import random
 import re
+import tempfile
 from abc import abstractmethod, ABCMeta
 
 import ID2TLib.libpcapreader as pr
+from scapy.utils import PcapWriter
 
 from Attack import AttackParameters
 from Attack.AttackParameters import Parameter
@@ -37,11 +40,11 @@ class BaseAttack(metaclass=ABCMeta):
         self.attack_end_utime = 0
 
     @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
 
@@ -309,6 +312,36 @@ class BaseAttack(metaclass=ABCMeta):
                 import sys
                 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
     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.PACKETS_LIMIT, randint(1000, 5000))
 
-    def get_packets(self):
+    def generate_attack_pcap(self):
         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.
@@ -89,9 +89,10 @@ class DDoSAttack(BaseAttack.BaseAttack):
 
         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
             port = attacker_port_mapping.get(ipAddress)
@@ -112,11 +113,14 @@ class DDoSAttack(BaseAttack.BaseAttack):
                     ttl = int(round(gd[pos]))
                     if 0 < ttl < 256:  # validity check
                         is_invalid = False
+                    else:
                         pos = index_increment(pos, pos_max)
                 attacker_ttl_mapping[ipAddress] = ttl
             # return port and TTL
             return next_port, ttl
 
+        BUFFER_SIZE = 1000
+
         # Determine source IP and MAC address
         num_attackers = self.get_param_value(Param.NUMBER_ATTACKERS)
         if num_attackers is not None:  # user supplied Param.NUMBER_ATTACKERS
@@ -129,15 +133,13 @@ class DDoSAttack(BaseAttack.BaseAttack):
             ip_source_list = self.get_param_value(Param.IP_SOURCE)
             mac_source_list = self.get_param_value(Param.MAC_SOURCE)
 
-        BUFFER_SIZE_PACKETS = self.get_param_value(Param.PACKETS_LIMIT)
-
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
         randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 30, 5 / pps: 15, 10 / pps: 3})
 
         # Initialize parameters
-        packets = deque(maxlen=BUFFER_SIZE_PACKETS)
+        packets = deque(maxlen=BUFFER_SIZE)
         port_source_list = self.get_param_value(Param.PORT_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
@@ -149,6 +151,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         alpha, loc, beta = (2.3261710235, -0.188306914406, 44.4853123884)
         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)):
             # Select one IP address and its corresponding MAC address
             (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)
 
-        # 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 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_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))
 
         random_ip_address = self.statistics.get_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.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_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_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.PACKETS_PER_SECOND,
@@ -78,7 +68,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
                               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()))
 
-    def get_packets(self):
+    def generate_attack_pcap(self):
         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.

+ 4 - 27
code/ID2TLib/AttackController.py

@@ -26,32 +26,6 @@ class AttackController:
         # The PCAP where the attack should be injected into
         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):
         """
         Creates dynamically a new class instance based on the given attack_name.
@@ -107,7 +81,10 @@ class AttackController:
             attack_note = ""
 
         # 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
         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:
         """
         # Fields
-        self.pcap_src_path = pcap_file_path
+        self.pcap_src_path = pcap_file_path.strip()
         self.pcap_dest_path = ''
         self.written_pcaps = []