Browse Source

- Fixes several bugs introduced during restructure of get_packtes in the attack classes
- Optimizes the merging operation: Instead of merging each single attack pcap into the base pcap, first all attack pcaps are merged, then those are injected into the base pcap

Patrick Jattke 7 years ago
parent
commit
48844cbb47

+ 1 - 1
code/Attack/BaseAttack.py

@@ -326,7 +326,7 @@ class BaseAttack(metaclass=ABCMeta):
         if destination_path is not None and os.path.exists(destination_path):
             destination = destination_path
         else:
-            temp_file = tempfile.NamedTemporaryFile(delete=False)
+            temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.pcap')
             destination = temp_file.name
 
         # Write packets into pcap file

+ 9 - 3
code/Attack/DDoSAttack.py

@@ -1,11 +1,13 @@
 import logging
-from random import randint, choice, uniform
+from random import randint, uniform
+
 from lea import Lea
-from scipy.stats import stats, gamma
+from scipy.stats import gamma
 
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
+
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 from scapy.layers.inet import IP, Ether, TCP, RandShort
@@ -155,7 +157,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         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) + 1):
+        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)
 
@@ -183,6 +185,10 @@ class DDoSAttack(BaseAttack.BaseAttack):
                 path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
                 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)
+
         # Store timestamp of last packet
         self.attack_end_utime = last_packet.time
 

+ 27 - 27
code/CLI.py

@@ -105,32 +105,32 @@ def main(args):
 
 
 # Uncomment to enable calling by terminal
-# if __name__ == '__main__':
-#    main(sys.argv[1:])
-
 if __name__ == '__main__':
-    INPUT = ['-i']
-
-    #    FILES = ['/root/datasets/201506021400_1G.pcap',
-    #             '/root/datasets/201506021400_2G.pcap',
-    #             '/root/datasets/201506021400_5G.pcap']
-
-    FILES = ['/mnt/hgfs/datasets/201506021400_2G.pcap']
-
-    #    FILES = ['/mnt/hgfs/datasets/95M.pcap']
+    main(sys.argv[1:])
 
-    ATTACK_PS = ['-a', 'PortscanAttack', 'ip.src=10.2.2.4', 'mac.dst=05:AB:47:B5:19:11',
-                 'inject.at-timestamp=1449038705.316721', 'attack.note=Portscan2']
-    ATTACK_PS2 = ['-a', 'PortscanAttack', 'port.dst=1-1024']
-    ATTACK_DD = ['-a', 'DDoSAttack', 'attackers.count=10', 'packets.limit=1000']
-
-    STATS_RECALC = ['-r']
-    STATS_PRINT = ['-s']
-    STATS_PLOT = ['-p']
-
-    QUERY_MODE_LOOP = ['-q']
-    QUERY_DB = ['-q', 'ipAddress(pktsSent > 1000, kbytesSent >= 20)']
-
-    for f in FILES:
-        main(INPUT + [f] + ATTACK_PS2 + ATTACK_DD)  # Statistics Calculation
-        #main(INPUT + ATTACK_DD)  # Attack Packet Generation -> insert exit() | Merging
+# if __name__ == '__main__':
+#     INPUT = ['-i']
+#
+#     #    FILES = ['/root/datasets/201506021400_1G.pcap',
+#     #             '/root/datasets/201506021400_2G.pcap',
+#     #             '/root/datasets/201506021400_5G.pcap']
+#
+#     # FILES = ['/mnt/hgfs/datasets/201506021400_2G.pcap']
+#
+#     FILES = ['/home/pjattke/temp/test_me_short.pcap']
+#
+#     ATTACK_PS = ['-a', 'PortscanAttack', 'ip.src=10.2.2.4', 'mac.dst=05:AB:47:B5:19:11',
+#                  'inject.at-timestamp=1449038705.316721', 'attack.note=Portscan2']
+#     ATTACK_PS2 = ['-a', 'PortscanAttack', 'port.dst=1-1024', 'ip.src=3.3.3.3']
+#     ATTACK_DD = ['-a', 'DDoSAttack', 'ip.dst=9.9.9.9', 'attackers.count=10', 'packets.limit=100']
+#
+#     STATS_RECALC = ['-r']
+#     STATS_PRINT = ['-s']
+#     STATS_PLOT = ['-p']
+#
+#     QUERY_MODE_LOOP = ['-q']
+#     QUERY_DB = ['-q', 'ipAddress(pktsSent > 1000, kbytesSent >= 20)']
+#
+#     for f in FILES:
+#         main(INPUT + [f] + ATTACK_PS2 + ATTACK_DD)  # Statistics Calculation
+#         #main(INPUT + ATTACK_DD)  # Attack Packet Generation -> insert exit() | Merging

+ 3 - 12
code/ID2TLib/AttackController.py

@@ -1,8 +1,6 @@
 import importlib
-import os
-import tempfile
 import sys
-from scapy.utils import PcapWriter
+
 from Attack.AttackParameters import Parameter
 from ID2TLib import LabelManager
 from ID2TLib import Statistics
@@ -44,8 +42,7 @@ class AttackController:
     def process_attack(self, attack: str, params: str):
         """
         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, merges these packets into the existing
-        dataset and stores the label file of the injected attacks.
+        attack parameters, creates the attack by writing the attack packets and returns the path of the written pcap.
         :param attack: The classname of the attack to injecect.
         :param params: The parameters for attack customization, see attack class for supported params.
         :return: The file path to the created pcap file.
@@ -86,18 +83,12 @@ class AttackController:
         total_packets, temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
         print("done. (total: " + str(total_packets) + " pkts.)")
 
-        # Merge attack with existing pcap
-        pcap_dest_path = self.pcap_file.merge_attack(temp_attack_pcap_path)
-
-        # Delete temporary attack pcap
-        os.remove(temp_attack_pcap_path)
-
         # Store label into LabelManager
         l = Label(attack, self.get_attack_start_utime(),
                   self.get_attack_end_utime(), attack_note)
         self.label_mgr.add_labels(l)
 
-        return pcap_dest_path
+        return temp_attack_pcap_path
 
     def get_attack_start_utime(self):
         """

+ 27 - 7
code/ID2TLib/Controller.py

@@ -1,5 +1,4 @@
 import os
-
 import sys
 
 from ID2TLib.AttackController import AttackController
@@ -42,19 +41,40 @@ class Controller:
         """
         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.
-        [['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
+        input dataset.
         :param attacks_config: A list of attacks with their attack parameters.
         """
         # load attacks sequentially
         for attack in attacks_config:
-            self.pcap_dest_path = self.attack_controller.process_attack(attack[0], attack[1:])
-            self.written_pcaps.append(self.pcap_dest_path)
+            temp_attack_pcap = self.attack_controller.process_attack(attack[0], attack[1:])
+            self.written_pcaps.append(temp_attack_pcap)
+
+        # merge attack pcaps to get single attack pcap
+        if len(self.written_pcaps) > 1:
+            print("\nMerging temporary attack pcaps into single pcap file...", end=" ")
+            sys.stdout.flush()  # force python to print text immediately
+            attack_pcap_file = PcapFile(self.written_pcaps[0])
+            for attack in self.written_pcaps[1:]:
+                all_attacks_pcap = attack_pcap_file.merge_attack(attack)
+                os.remove(attack)  # remove merged pcap
+                # Create new PcapFile object for next iteration
+                attack_pcap_file = PcapFile(all_attacks_pcap)
+            print("done.")
+        else:
+            all_attacks_pcap = self.written_pcaps[0]
+
+        # merge single attack pcap with all attacks into base pcap
+        print("Merging base pcap with single attack pcap...", end=" ")
+        sys.stdout.flush()  # force python to print text immediately
+        self.pcap_dest_path = self.pcap_file.merge_attack(all_attacks_pcap)
+        print("done.")
 
         # delete intermediate PCAP files
-        print('Deleting intermediate attack pcaps...', end="")
+        print('Deleting intermediate attack pcap...', end="")
         sys.stdout.flush()  # force python to print text immediately
-        for i in range(len(self.written_pcaps) - 1):
-            os.remove(self.written_pcaps[i])
+        os.remove(all_attacks_pcap)
         print("done.")
 
         # write label file with attacks

+ 0 - 6
code/ID2TLib/PcapFile.py

@@ -1,6 +1,5 @@
 import hashlib
 import os.path
-import sys
 
 import ID2TLib.libpcapreader as pr
 
@@ -21,13 +20,8 @@ class PcapFile(object):
         :param attack_pcap_path: The path to the PCAP file to merge with the PCAP at pcap_file_path
         :return: The file path of the resulting PCAP file
         """
-        print("Merging base pcap with attack pcap...", end=" ")
-        sys.stdout.flush()  # force python to print text immediately
-
         pcap = pr.pcap_processor(self.pcap_file_path)
         file_out_path = pcap.merge_pcaps(attack_pcap_path)
-        print("done.")
-
         return file_out_path
 
     def get_file_hash(self):