Browse Source

Add Carlos changes

aidmar.wainakh 6 years ago
parent
commit
01107a681c

+ 6 - 4
.gitignore

@@ -14,14 +14,16 @@ code_boost/src/build/*
 
 #captures
 captures/*
+
+#labels
 tures/*
+
 code/*.pcap
 code/*.xml
-code_boost/src/SQLiteCpp/
-code_boost/src/cmake-build-debug/*
-test.py
 dbs/
 *.csv
-code_boost/src/CMakeLists.txt
+*.stat
 code_boost/src/cxx/CMakeLists.txt
 code_boost/src/cxx/cmake-build-debug/
+code_boost/src/SQLiteCpp/
+code_boost/src/cmake-build-debug/

+ 11 - 4
build.sh

@@ -1,24 +1,31 @@
 #!/bin/bash
 
+# Create the Makefile using cmake, from a clean build directory
 cd code_boost/src/build/
+if [ ${PWD##*/} = 'build' ]; then
+    # Only delete everything if we are in a folder called 'build'.
+    rm -rf ./*
+else
+    echo "Error: The 'build' directory was not found."
+    exit
+fi
 cmake ..
 
 if [ -f Makefile ]; then
     make
 else
-    echo "CMake did not finish successfully."
+    echo "Error: 'cmake' did not finish successfully."
     exit
 fi
 
 if [ $? -eq 0 ]; then
     cp libpcapreader.so ../../../code/ID2TLib/
 else
-    echo "Make did not finish successfully."
+    echo "Error: 'make' did not finish successfully."
     exit
 fi
 
 cd ../../../
-#ln -s code/CLI.py id2t.py
 
 # Create the ID2T script
 cat >./id2t  <<EOF
@@ -34,5 +41,5 @@ EOF
 chmod +x ./code/CLI.py
 chmod +x ./id2t
 
-echo -e "\n\nAll is set. ID2T is ready to be used."
+echo -e "\n\nAll is set. ID2T is ready."
 echo -e "\nRun ID2T with the command './id2t'"

+ 35 - 14
code/Attack/BaseAttack.py

@@ -1,16 +1,13 @@
-# Aidmar
-from scapy.layers.inet import Ether
 import socket
 import sys
-from math import sqrt
-
 import ipaddress
 import os
 import random
 import re
 import tempfile
 from abc import abstractmethod, ABCMeta
-import numpy as np # TO-DO: it needs to be added to required packages
+from scapy.layers.inet import Ether
+import numpy as np
 
 import ID2TLib.libpcapreader as pr
 from scapy.utils import PcapWriter
@@ -20,13 +17,12 @@ from Attack.AttackParameters import Parameter
 from Attack.AttackParameters import ParameterTypes
 
 
-
 class BaseAttack(metaclass=ABCMeta):
     """
     Abstract base class for all attack classes. Provides basic functionalities, like parameter validation.
     """
 
-    def __init__(self, statistics, name, description, attack_type):
+    def __init__(self, name, description, attack_type):
         """
         To be called within the individual attack class to initialize the required parameters.
 
@@ -36,7 +32,7 @@ class BaseAttack(metaclass=ABCMeta):
         :param attack_type: The type the attack belongs to, like probing/scanning, malware.
         """
         # Reference to statistics class
-        self.statistics = statistics
+        self.statistics = None
 
         # Class fields
         self.attack_name = name
@@ -47,6 +43,25 @@ class BaseAttack(metaclass=ABCMeta):
         self.attack_start_utime = 0
         self.attack_end_utime = 0
 
+    def set_statistics(self, statistics):
+        """
+        Specify the statistics object that will be used to calculate the parameters of this attack.
+        The statistics are used to calculate default parameters and to process user supplied
+        queries.
+
+        :param statistics: Reference to a statistics object.
+        """
+        self.statistics = statistics
+
+    @abstractmethod
+    def init_params(self):
+        """
+        Initialize all required parameters taking into account user supplied values. If no value is supplied,
+        or if a user defined query is supplied, use a statistics object to do the calculations.
+        A call to this function requires a call to 'set_statistics' first.
+        """
+        pass
+
     @abstractmethod
     def generate_attack_pcap(self):
         """
@@ -237,10 +252,16 @@ class BaseAttack(metaclass=ABCMeta):
         Adds the pair param : value to the dictionary of attack parameters. Prints and error message and skips the
         parameter if the validation fails.
 
-        :param param: The parameter name.
-        :param value: The parameter's value.
+        :param stats: Statistics used to calculate user queries or default values.
+        :param param: Name of the parameter that we wish to modify.
+        :param value: The value we wish to assign to the specifried parameter.
         :return: None.
         """
+        # This function call is valid only if there is a statistics object available.
+        if self.statistics is None:
+            print('Error: Attack parameter added without setting a statistics object first.')
+            exit(1)
+
         # by default no param is valid
         is_valid = False
 
@@ -479,10 +500,10 @@ class BaseAttack(metaclass=ABCMeta):
 
            """
         result = self.statistics.process_db_query(
-            "SELECT AVG(minDelay), AVG(maxDelay) FROM conv_statistics WHERE ipAddressB='" + ip_dst + "';")
-        if result[0][1] and result[0][2]:
-            minDelay = result[0][1]
-            maxDelay = result[0][2]
+            "SELECT AVG(minDelay), AVG(maxDelay) FROM conv_statistics WHERE ipAddressB='6.6.6.6';") #" + ip_dst + "';")
+        if result[0][0] and result[0][1]:
+            minDelay = result[0][0]
+            maxDelay = result[0][1]
         else:
             allMinDelays = self.statistics.process_db_query("SELECT minDelay FROM conv_statistics LIMIT 500;")
             minDelay = np.median(allMinDelays)

+ 10 - 3
code/Attack/DDoSAttack.py

@@ -15,14 +15,13 @@ from collections import deque
 
 
 class DDoSAttack(BaseAttack.BaseAttack):
-    def __init__(self, statistics, pcap_file_path):
+    def __init__(self):
         """
         Creates a new instance of the DDoS attack.
 
-        :param statistics: A reference to the statistics class.
         """
         # Initialize attack
-        super(DDoSAttack, self).__init__(statistics, "DDoS Attack", "Injects a DDoS attack'",
+        super(DDoSAttack, self).__init__("DDoS Attack", "Injects a DDoS attack'",
                                         "Resource Exhaustion")
 
         # Define allowed parameters and their type
@@ -42,6 +41,14 @@ class DDoSAttack(BaseAttack.BaseAttack):
             Param.VICTIM_BUFFER: ParameterTypes.TYPE_INTEGER_POSITIVE
         }
 
+    def init_params(self):
+        """
+        Initialize the parameters of this attack using the user supplied command line parameters.
+        Use the provided statistics to calculate default parameters and to process user
+        supplied queries.
+
+        :param statistics: Reference to a statistics object.
+        """
         # PARAMETERS: initialize with default values
         # (values are overwritten if user specifies them)
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))

+ 10 - 3
code/Attack/EternalBlueExploit.py

@@ -21,14 +21,13 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
     maxDefaultPort = 50000
     last_conn_dst_port = 4444
 
-    def __init__(self, statistics, pcap_file_path):
+    def __init__(self):
         """
         Creates a new instance of the EternalBlue Exploit.
 
-        :param statistics: A reference to the statistics class.
         """
         # Initialize attack
-        super(EternalBlueExploit, self).__init__(statistics, "EternalBlue Exploit", "Injects an EternalBlue exploit'",
+        super(EternalBlueExploit, self).__init__("EternalBlue Exploit", "Injects an EternalBlue exploit'",
                                         "Resource Exhaustion")
 
         # Define allowed parameters and their type
@@ -42,6 +41,14 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
             Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT
         }
 
+    def init_params(self):
+        """
+        Initialize the parameters of this attack using the user supplied command line parameters.
+        Use the provided statistics to calculate default parameters and to process user
+        supplied queries.
+
+        :param statistics: Reference to a statistics object.
+        """
         # PARAMETERS: initialize with default utilsvalues
         # (values are overwritten if user specifies them)
         most_used_ip_address = self.statistics.get_most_used_ip_address()

+ 10 - 3
code/Attack/JoomlaRegPrivExploit.py

@@ -21,14 +21,13 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
     minDefaultPort = 30000
     maxDefaultPort = 50000
 
-    def __init__(self, statistics, pcap_file_path):
+    def __init__(self):
         """
         Creates a new instance of the Joomla Registeration Privileges Escalation Exploit.
 
-        :param statistics: A reference to the statistics class.
         """
         # Initialize attack
-        super(JoomlaRegPrivExploit, self).__init__(statistics, "JoomlaRegPrivesc Exploit", "Injects an JoomlaRegPrivesc exploit'",
+        super(JoomlaRegPrivExploit, self).__init__("JoomlaRegPrivesc Exploit", "Injects an JoomlaRegPrivesc exploit'",
                                         "Resource Exhaustion")
 
         # Define allowed parameters and their type
@@ -44,6 +43,14 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
             Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT
         }
 
+    def init_params(self):
+        """
+        Initialize the parameters of this attack using the user supplied command line parameters.
+        Use the provided statistics to calculate default parameters and to process user
+        supplied queries.
+
+        :param statistics: Reference to a statistics object.
+        """
         # PARAMETERS: initialize with default utilsvalues
         # (values are overwritten if user specifies them)
         most_used_ip_address = self.statistics.get_most_used_ip_address()

+ 37 - 29
code/Attack/PortscanAttack.py

@@ -15,41 +15,14 @@ from scapy.layers.inet import IP, Ether, TCP
 import numpy as np
 
 class PortscanAttack(BaseAttack.BaseAttack):
-    # Aidmar
-    def get_ports_from_nmap_service_dst(self, ports_num):
-        """
-        Read the most ports_num frequently open ports from nmap-service-tcp file to be used in the port scan.
-
-        :return: Ports numbers to be used as default destination ports or default open ports in the port scan.
-        """
-        ports_dst = []
-        spamreader = csv.reader(open('resources/nmap-services-tcp.csv', 'rt'), delimiter=',')
-        for count in range(ports_num):
-            # escape first row (header)
-            next(spamreader)
-            # save ports numbers
-            ports_dst.append(next(spamreader)[0])
-        # shuffle ports numbers partially
-        if(ports_num==1000): # used for port.dst
-            temp_array = [[0 for i in range(10)] for i in range(100)]
-            port_dst_shuffled = []
-            for count in range(0, 9):
-                temp_array[count] = ports_dst[count * 100:count * 100 + 99]
-                shuffle(temp_array[count])
-                port_dst_shuffled += temp_array[count]
-        else: # used for port.open
-            shuffle(ports_dst)
-            port_dst_shuffled = ports_dst
-        return port_dst_shuffled
 
-    def __init__(self, statistics, pcap_file_path):
+    def __init__(self):
         """
         Creates a new instance of the PortscanAttack.
 
-        :param statistics: A reference to the statistics class.
         """
         # Initialize attack
-        super(PortscanAttack, self).__init__(statistics, "Portscan Attack", "Injects a nmap 'regular scan'",
+        super(PortscanAttack, self).__init__("Portscan Attack", "Injects a nmap 'regular scan'",
                                              "Scanning/Probing")
 
         # Define allowed parameters and their type
@@ -70,6 +43,14 @@ class PortscanAttack(BaseAttack.BaseAttack):
             Param.PORT_SOURCE_RANDOMIZE: ParameterTypes.TYPE_BOOLEAN
         }
 
+    def init_params(self):
+        """
+        Initialize the parameters of this attack using the user supplied command line parameters.
+        Use the provided statistics to calculate default parameters and to process user
+        supplied queries.
+
+        :param statistics: Reference to a statistics object.
+        """
         # PARAMETERS: initialize with default values
         # (values are overwritten if user specifies them)
         most_used_ip_address = self.statistics.get_most_used_ip_address()
@@ -102,6 +83,33 @@ 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()))
 
+    # Aidmar
+    def get_ports_from_nmap_service_dst(self, ports_num):
+        """
+        Read the most ports_num frequently open ports from nmap-service-tcp file to be used in the port scan.
+
+        :return: Ports numbers to be used as default destination ports or default open ports in the port scan.
+        """
+        ports_dst = []
+        spamreader = csv.reader(open('resources/nmap-services-tcp.csv', 'rt'), delimiter=',')
+        for count in range(ports_num):
+            # escape first row (header)
+            next(spamreader)
+            # save ports numbers
+            ports_dst.append(next(spamreader)[0])
+        # shuffle ports numbers partially
+        if (ports_num == 1000):  # used for port.dst
+            temp_array = [[0 for i in range(10)] for i in range(100)]
+            port_dst_shuffled = []
+            for count in range(0, 9):
+                temp_array[count] = ports_dst[count * 100:count * 100 + 99]
+                shuffle(temp_array[count])
+                port_dst_shuffled += temp_array[count]
+        else:  # used for port.open
+            shuffle(ports_dst)
+            port_dst_shuffled = ports_dst
+        return port_dst_shuffled
+
     def generate_attack_pcap(self):
         def update_timestamp(timestamp, pps, delay=0):
             """

+ 10 - 3
code/Attack/SQLiAttack.py

@@ -21,14 +21,13 @@ class SQLiAttack(BaseAttack.BaseAttack):
     minDefaultPort = 30000
     maxDefaultPort = 50000
 
-    def __init__(self, statistics, pcap_file_path):
+    def __init__(self):
         """
         Creates a new instance of the SQLi Attack.
 
-        :param statistics: A reference to the statistics class.
         """
         # Initialize attack
-        super(SQLiAttack, self).__init__(statistics, "SQLi Attack", "Injects a SQLi attack'",
+        super(SQLiAttack, self).__init__("SQLi Attack", "Injects a SQLi attack'",
                                         "Resource Exhaustion")
 
         # Define allowed parameters and their type
@@ -44,6 +43,14 @@ class SQLiAttack(BaseAttack.BaseAttack):
             Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT
         }
 
+    def init_params(self):
+        """
+        Initialize the parameters of this attack using the user supplied command line parameters.
+        Use the provided statistics to calculate default parameters and to process user
+        supplied queries.
+
+        :param statistics: Reference to a statistics object.
+        """
         # PARAMETERS: initialize with default utilsvalues
         # (values are overwritten if user specifies them)
         most_used_ip_address = self.statistics.get_most_used_ip_address()

+ 101 - 73
code/CLI.py

@@ -23,13 +23,112 @@ class CLI(object):
         self.args = None
         self.attack_config = None
 
+    def parse_arguments(self, args):
+        """
+        Defines the allowed application arguments and invokes the evaluation of the arguments.
+
+        :param args: The application arguments
+        """
+        # Create parser for arguments
+        parser = argparse.ArgumentParser(description="Intrusion Detection Dataset Toolkit (ID2T) - A toolkit for "
+                                         "injecting synthetically created attacks into PCAP files.",
+                                         prog="id2t")
+        # Required arguments
+        required_group = parser.add_argument_group('required arguments')
+        required_args_group = required_group.add_mutually_exclusive_group(required=True)
+        required_args_group.add_argument('-i', '--input', metavar="PCAP_FILE",
+                                         help='path to the input pcap file')
+        required_args_group.add_argument('-l', '--list-attacks', action='store_true')
+
+        # Optional arguments
+        parser.add_argument('-c', '--config', metavar='CONFIG_FILE', help='file containing configuration parameters.',
+                            action=LoadFromFile, type=open)
+        parser.add_argument('-e', '--export',
+                            help='store statistics as a ".stat" file',
+                            action='store_true', default=False)
+        parser.add_argument('-r', '--recalculate',
+                            help='recalculate statistics even if a cached version exists.',
+                            action='store_true', default=False)
+        parser.add_argument('-s', '--statistics', help='print file statistics to stdout.', action='store_true',
+                            default=False)
+        parser.add_argument('-p', '--plot', help='creates statistics plots.', action='append',
+                            nargs='?')
+        parser.add_argument('-q', '--query', metavar="QUERY",
+                            action='append', nargs='?',
+                            help='query the statistics database. If no query is provided, the application enters query mode.')
+        parser.add_argument('-t', '--extraTests', help='perform extra tests on the input pcap file, including calculating IP entropy'
+                                                       'in interval-wise, TCP checksum, and checking payload availability.', action='store_true')
+
+        # Attack arguments
+        parser.add_argument('-a', '--attack', metavar="ATTACK", action='append',
+                                       help='injects ATTACK into a PCAP file.', nargs='+')
+
+        # Parse arguments
+        self.args = parser.parse_args(args)
+
+        self.process_arguments()
+
     def process_arguments(self):
+        """
+        Decide what to do with each  of the command line parameters.
+        """
+        if self.args.list_attacks:
+            # User wants to see the available attacks
+            self.process_attack_listing()
+        else:
+            # User wants to process a PCAP
+            self.process_pcap()
+
+    def process_attack_listing(self):
+        import pkgutil
+        import importlib
+        import Attack
+
+        # Find all attacks, exclude some classes
+        package = Attack
+        attack_names = []
+        for _, name, __ in pkgutil.iter_modules(package.__path__):
+            if name != 'BaseAttack' and name != 'AttackParameters':
+                attack_names.append(name)
+
+        # List the attacks and their parameters
+        emph_start = '\033[1m'
+        emph_end = '\033[0m'
+        for attack_name in attack_names:
+            attack_module = importlib.import_module('Attack.{}'.format(attack_name))
+            attack_class = getattr(attack_module, attack_name)
+            # Instantiate the attack to get to its definitions.
+            attack_obj = attack_class()
+            print('* {}{}{}'.format(emph_start, attack_obj.attack_name, emph_end))
+            print('\t- {}Description:{} {}'.format(emph_start, emph_end,
+                                                   attack_obj.attack_description))
+            print('\t- {}Type:{} {}'.format(emph_start, emph_end,
+                                            attack_obj.attack_type))
+            print('\t- {}Supported Parameters:{}'.format(emph_start, emph_end), end=' ')
+            # Get all the parameter names in a list and sort them
+            param_list = []
+            for key in attack_obj.supported_params:
+                param_list.append(key.value)
+            param_list.sort()
+            # Print each parameter type per line
+            last_prefix = None
+            current_prefix = None
+            for param in param_list:
+                current_prefix = param.split('.')[0]
+                if not last_prefix or current_prefix != last_prefix:
+                    print('\n\t + |', end=' ')
+                print(param, end=' | ')
+                last_prefix = current_prefix
+            # Print an empty line
+            print()
+
+    def process_pcap(self):
         """
         Loads the application controller, the PCAP file statistics and if present, processes the given attacks. Evaluates
         given queries.
         """
         # Create ID2T Controller
-        controller = Controller(self.args.input, self.args.tests)
+        controller = Controller(self.args.input, self.args.extraTests)
 
         # Load PCAP statistics
         controller.load_pcap_statistics(self.args.export, self.args.recalculate, self.args.statistics)
@@ -50,54 +149,6 @@ class CLI(object):
         elif self.args.query is not None:
             controller.process_db_queries(self.args.query, True)
 
-    def parse_arguments(self, args):
-        """
-        Defines the allowed application arguments and invokes the evaluation of the arguments.
-
-        :param args: The application arguments
-        """
-        # Create parser for arguments
-        parser = argparse.ArgumentParser(description="Intrusion Detection Dataset Toolkit (ID2T) - A toolkit for "
-                                         "injection of synthetically created attacks into PCAP datasets.",
-                                         prog="id2t")
-        # Define required arguments
-        requiredNamed = parser.add_argument_group('required named arguments')
-        requiredNamed.add_argument('-i', '--input', metavar="FILEPATH", help='path to the input pcap file', required=True)
-
-        # Define optional arguments
-        parser.add_argument('-c', '--config', metavar='FILEPATH', help='file containing parameters used as input.',
-                            action=LoadFromFile, type=open)
-        parser.add_argument('-e', '--export',
-                            help='stores the statistics as a textfile with ending .stat into the dataset directory',
-                            action='store_true', default=False)
-        parser.add_argument('-a', '--attack', metavar="ATTACKNAME", action='append',
-                            help='injects a new attack into the given dataset. '
-                                 'Attacks parameters are: ip.src, ip.dst, ip.dns, mac.src, mac.dst, port.open, '
-                                 'port.dst, port.src, packets.limit, attackers.count, attack.duration, victim.buffer, '
-                                 'target.uri, target.host, packets.per-second, inject.at-timestamp, inject.after-pkt, '
-                                 'port.dst.shuffle, port.dst.order-desc, ip.src.shuffle, port.src.shuffle', nargs='+')
-        parser.add_argument('-r', '--recalculate',
-                            help='forces to recalculate the statistics in case of an already existing statistics database.',
-                            action='store_true', default=False)
-        parser.add_argument('-s', '--statistics', help='print general file statistics to stdout.', action='store_true',
-                            default=False)
-        parser.add_argument('-p', '--plot', help='creates a plot of common dataset statistics', action='append',
-                            nargs='?')
-        parser.add_argument('-q', '--query', metavar="QUERY",
-                            action='append', nargs='?',
-                            help='queries the statistics database. If no query is provided, the application enters into query mode.')
-        # Aidmar
-        parser.add_argument('-t', '--tests', help='perform defects tests on input pcap file.', action='store_true')
-
-        # Parse arguments
-        self.args = parser.parse_args(args)
-
-        # Either PCAP filepath or GUI mode must be enabled
-        if not self.args.input:
-            parser.error("Parameter -i/--input required. See available options with -h/--help ")
-
-        self.process_arguments()
-
 def main(args):
     """
     Creates a new CLI object and invokes the arguments parsing.
@@ -108,29 +159,6 @@ def main(args):
     # Check arguments
     cli.parse_arguments(args)
 
-# Test main
-"""def main_0(args):
-    from scapy.utils import RawPcapReader
-    from scapy.layers.inet import IP, Ether, TCP
-
-    pkts = RawPcapReader("Win7_eternalblue_scan_vulnerable.pcap")
-    for pkt in pkts:
-        eth_frame = Ether(pkt[0])
-        ip_pkt = eth_frame.payload
-        tcp_pkt = ip_pkt.payload
-
-        new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-        new_pkt.time = 0
-
-
-        print(tcp_pkt.getfieldval("sport"))
-"""
-
-
-
 # Uncomment to enable calling by terminal
 if __name__ == '__main__':
-    main(sys.argv[1:])
-
-
-
+    main(sys.argv[1:])

+ 10 - 19
code/ID2TLib/AttackController.py

@@ -1,16 +1,13 @@
 import importlib
 import sys
 
-#Aidmar
-import time
-
 from Attack.AttackParameters import Parameter
 from ID2TLib import LabelManager
 from ID2TLib import Statistics
 from ID2TLib.Label import Label
 from ID2TLib.PcapFile import PcapFile
 
- 
+
 class AttackController:
     def __init__(self, pcap_file: PcapFile, statistics_class: Statistics, label_manager: LabelManager):
         """
@@ -24,9 +21,6 @@ class AttackController:
         self.current_attack = None
         self.added_attacks = []
 
-        # The PCAP where the attack should be injected into
-        self.base_pcap = self.statistics.pcap_filepath
-
     def create_attack(self, attack_name: str):
         """
         Creates dynamically a new class instance based on the given attack_name.
@@ -38,8 +32,12 @@ class AttackController:
         attack_module = importlib.import_module("Attack." + attack_name)
         attack_class = getattr(attack_module, attack_name)
 
-        # Set current attack
-        self.current_attack = attack_class(self.statistics, self.base_pcap)
+        # Instantiate the desired attack
+        self.current_attack = attack_class()
+        # Initialize the parameters of the attack with defaults or user supplied values.
+        self.current_attack.set_statistics(self.statistics)
+        self.current_attack.init_params()
+        # Record the attack
         self.added_attacks.append(self.current_attack)
 
     def process_attack(self, attack: str, params: str):
@@ -55,7 +53,7 @@ class AttackController:
         # Add attack parameters if provided
         print("Validating and adding attack parameters.")
         params_dict = []
-        if params is not None:
+        if isinstance(params, list) and params:
             # Convert attack param list into dictionary
             for entry in params:
                 params_dict.append(entry.split('='))
@@ -78,10 +76,7 @@ class AttackController:
             # Pass paramters to attack controller
             self.set_params(params_dict)
         else:
-            attack_note = ""
-
-        # Aidmar
-        start_time = time.clock()
+            attack_note = "This attack used only (random) default parameters."
 
         # Write attack into pcap file
         print("Generating attack packets...", end=" ")
@@ -89,10 +84,6 @@ class AttackController:
         total_packets, temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
         print("done. (total: " + str(total_packets) + " pkts.)")
 
-        # Aidmar
-        end_time = time.clock()
-        print("Generated Attack in " + str(end_time-start_time)[:4] + " sec")
-
         # Store label into LabelManager
         l = Label(attack, self.get_attack_start_utime(),
                   self.get_attack_end_utime(), attack_note)
@@ -119,4 +110,4 @@ class AttackController:
         :return: None
         """
         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)

+ 4 - 8
code/ID2TLib/Controller.py

@@ -8,7 +8,7 @@ from ID2TLib.Statistics import Statistics
 
 
 class Controller:
-    def __init__(self, pcap_file_path: str, do_tests: bool): #Aidmar - do_tests
+    def __init__(self, pcap_file_path: str, do_extra_tests: bool):
         """
         Creates a new Controller, acting as a central coordinator for the whole application.
         :param pcap_file_path:
@@ -17,17 +17,13 @@ class Controller:
         self.pcap_src_path = pcap_file_path.strip()
         self.pcap_dest_path = ''
         self.written_pcaps = []
-        # Aidmar
-        self.do_tests = do_tests
+        self.do_extra_tests = do_extra_tests
 
         # Initialize class instances
         print("Input file: %s" % self.pcap_src_path)
         self.pcap_file = PcapFile(self.pcap_src_path)
         self.label_manager = LabelManager(self.pcap_src_path)
         self.statistics = Statistics(self.pcap_file)
-        # Aidmar
-        self.statistics.do_tests = self.do_tests
-
         self.statisticsDB = self.statistics.get_statistics_database()
         self.attack_controller = AttackController(self.pcap_file, self.statistics, self.label_manager)
 
@@ -75,7 +71,7 @@ class Controller:
         print("done.")
 
         # delete intermediate PCAP files
-        print('Deleting intermediate attack pcap...', end="")
+        print('Deleting intermediate attack pcap...', end=" ")
         sys.stdout.flush()  # force python to print text immediately
         os.remove(attacks_pcap_path)
         print("done.")
@@ -130,4 +126,4 @@ class Controller:
             params_dict = dict([z.split("=") for z in params])
             self.statistics.plot_statistics(format=params_dict['format'])
         else:
-            self.statistics.plot_statistics()
+            self.statistics.plot_statistics()

+ 3 - 5
code/ID2TLib/Statistics.py

@@ -6,8 +6,6 @@ import os
 import time
 import ID2TLib.libpcapreader as pr
 import matplotlib
-from numpy.random.mtrand import normal
-from scipy.linalg.misc import norm
 
 matplotlib.use('Agg')
 import matplotlib.pyplot as plt
@@ -55,7 +53,7 @@ class Statistics:
         if flag_recalculate_stats:
             print("Flag -r/--recalculate found. Recalculating statistics.")
 
-        # Recalculate statistics if database not exists OR param -r/--recalculate was provided
+        # Recalculate statistics if database does not exist OR param -r/--recalculate is provided
         if (not self.stats_db.get_db_exists()) or flag_recalculate_stats:
             self.pcap_proc = pr.pcap_processor(self.pcap_filepath, str(self.do_tests)) # Aidmar - do_tests
             self.pcap_proc.collect_statistics()
@@ -85,7 +83,7 @@ class Statistics:
         :return: a list of tuples, each consisting of (description, value, unit), where unit is optional.
         """
         return [("Pcap file", self.pcap_filepath),
-                ("#Packets", self.get_packet_count(), "packets"),
+                ("Packets", self.get_packet_count(), "packets"),
                 ("Capture length", self.get_capture_duration(), "seconds"),
                 ("Capture start", self.get_pcap_timestamp_start()),
                 ("Capture end", self.get_pcap_timestamp_end())]
@@ -567,7 +565,7 @@ class Statistics:
 
     def plot_statistics(self, format: str = 'pdf'): #'png'):
         """
-        Plots the statistics associated with the dataset prior attack injection.
+        Plots the statistics associated with the dataset.
         :param format: The format to be used to save the statistics diagrams.
         """
 

+ 0 - 40
code/capture_1.pcap.stat

@@ -1,40 +0,0 @@
-====================== 
-PCAP file information 
-====================== 
-Pcap file:	capture_1.pcap
-#Packets:	23211 packets
-Capture length:	32.503 seconds
-Capture start:	2017-06-12 15:40:36.142820
-Capture end:	2017-06-12 15:47:08.645789
-====================== 
-General statistics 
-====================== 
-Avg. packet rate:	714.1194 packets/sec
-Avg. packet size:	0.0 kbytes
-Avg. packets sent:	321.0 packets
-Avg. bandwidth in:	57.2475 kbit/s
-Avg. bandwidth out:	57.2475 kbit/s
-====================== 
-Tests statistics 
-====================== 
-Payload ratio:	60.0362 %
-Incorrect TCP checksum ratio:	0.0 %
-IP Src Entropy:	3.333 
-IP Src Normalized Entropy:	0.5494 
-IP Dst Entropy:	2.8234 
-IP Dst Normalized Entropy:	0.4606 
-Port 0 count:	0 
-Reserved ports:	0.0 %
-TTL Entropy:	2.8017 
-TTL Normalized Entropy:	0.5892 
-TTL Distribution Entropy:	0.8138 
-WinSize Entropy:	1.9959 
-WinSize Normalized Entropy:	0.6008 
-WinSize Distribution Entropy:	0.415 
-ToS Entropy:	0.3158 
-ToS Normalized Entropy:	0.1579 
-ToS Distribution Entropy:	0.2219 
-MSS Entropy:	1.5384 
-MSS Normalized Entropy:	0.7692 
-MSS Distribution Entropy:	0.2219 
-536 < MSS < 1460:	50.0 %

+ 82 - 0
code_boost/src/CMakeLists.txt

@@ -0,0 +1,82 @@
+##################################
+# DEFINITION OF C++ PROJECT
+##################################
+project(cpp-pcapreader)
+
+# Define CMake settings
+cmake_minimum_required(VERSION 3.2)
+
+IF(NOT CMAKE_BUILD_TYPE)
+   SET(CMAKE_BUILD_TYPE "Release")
+ENDIF()
+
+IF (CMAKE_BUILD_TYPE MATCHES Debug)
+    MESSAGE(STATUS "Running Debug configuration.")
+ELSEIF (CMAKE_BUILD_TYPE MATCHES Release)
+    MESSAGE(STATUS "Running Release configuration.")
+ENDIF()
+
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
+SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
+
+SET(CMAKE_CXX_STANDARD 11)
+SET(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# Add the library source files
+SET(SOURCE_FILES cxx/pcap_processor.cpp cxx/pcap_processor.h cxx/statistics.cpp cxx/statistics.h cxx/statistics_db.cpp cxx/statistics_db.h cxx/utilities.h cxx/utilities.cpp)
+
+# Include SQLiteCpp library and build it
+option(SQLITECPP_RUN_CPPLINT OFF)
+include_directories(SQLiteCpp/include)
+add_subdirectory(SQLiteCpp)
+
+# Find libtins library
+FIND_LIBRARY(TINS_LIBRARY tins)
+IF(TINS_LIBRARY)
+  MESSAGE(STATUS "Tins library found in ${TINS_LIBRARY}")
+ELSE()
+  MESSAGE(FATAL_ERROR "Tins library not found.")
+ENDIF()
+
+FIND_PACKAGE(PythonLibs 3.0 REQUIRED)
+IF(PYTHONLIBS_FOUND)
+  INCLUDE_DIRECTORIES("${PYTHON_INCLUDE_DIRS}")
+  MESSAGE(STATUS "Python includes found in: " ${PYTHON_INCLUDE_DIRS} )
+  MESSAGE(STATUS "Python libs found in: " ${PYTHON_LIBRARIES} )
+ELSE()
+  MESSAGE(FATAL_ERROR "Unable to find Python libraries.")
+ENDIF()
+
+# Find and configure BOOST library
+FIND_PACKAGE(Boost 1.54 QUIET)
+IF (Boost_FOUND)
+    INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}")
+    MESSAGE(STATUS "Boots includes found in: " ${Boost_INCLUDE_DIRS} )
+    SET(Boost_USE_STATIC_LIBS OFF)
+    SET(Boost_USE_MULTITHREADED ON)
+    SET(Boost_USE_STATIC_RUNTIME OFF)
+    # Find the boost python 3 component
+    SET(PYTHON_VERSIONS python3 python-py35 python-py34 python-py33 python-py32)
+    FOREACH(VERSION ${PYTHON_VERSIONS})
+      FIND_PACKAGE(Boost COMPONENTS ${VERSION} QUIET)
+      IF(Boost_FOUND)
+        MESSAGE(STATUS "Python Boost found as '${VERSION}'.")
+        BREAK()
+      ENDIF()
+    ENDFOREACH(VERSION)
+    IF(NOT Boost_FOUND)
+      MESSAGE(FATAL_ERROR "Python Boost component not found.")
+    ENDIF()
+ELSE ()
+    MESSAGE(FATAL_ERROR "Unable to find the Boost libraries (version 1.54 or higher).")
+ENDIF ()
+
+SET_target_properties(sqlite3 PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+ADD_LIBRARY(pcapreader SHARED ${SOURCE_FILES})
+# Libs pthread and dl are prerequisites of SQLiteCpp
+TARGET_LINK_LIBRARIES(pcapreader ${Boost_LIBRARIES} "${TINS_LIBRARY}" ${PYTHON_LIBRARIES} SQLiteCpp sqlite3 pthread dl)
+
+# comment this out to build executable (for development)
+#ADD_EXECUTABLE(cpp-pcapreader ${SOURCE_FILES})
+#TARGET_LINK_LIBRARIES(cpp-pcapreader ${Boost_LIBRARIES} "${TINS_LIBRARY}" SQLiteCpp sqlite3 pthread dl)