Browse Source

Merge branch 'utility-lib-final' of stefan.schmidt/ID2T-toolkit into master

Carlos Garcia 6 years ago
parent
commit
6c6d80dbba

+ 3 - 3
code/Attack/BaseAttack.py

@@ -5,16 +5,16 @@ import os
 import random
 import random
 import re
 import re
 import tempfile
 import tempfile
-from abc import abstractmethod, ABCMeta
-from scapy.layers.inet import Ether
 import numpy as np
 import numpy as np
 
 
-import ID2TLib.libpcapreader as pr
+from abc import abstractmethod, ABCMeta
+from scapy.layers.inet import Ether
 from scapy.utils import PcapWriter
 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
+import ID2TLib.libpcapreader as pr
 
 
 
 
 class BaseAttack(metaclass=ABCMeta):
 class BaseAttack(metaclass=ABCMeta):

+ 5 - 53
code/Attack/DDoSAttack.py

@@ -1,17 +1,18 @@
 import logging
 import logging
-from random import randint, uniform, choice
 
 
+from random import randint, choice
 from lea import Lea
 from lea import Lea
+from collections import deque
 from scipy.stats import gamma
 from scipy.stats import gamma
+from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
+from ID2TLib.Utility import update_timestamp, get_interval_pps, get_nth_random_element, index_increment
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.layers.inet import IP, Ether, TCP, RandShort
-from collections import deque
 
 
 
 
 class DDoSAttack(BaseAttack.BaseAttack):
 class DDoSAttack(BaseAttack.BaseAttack):
@@ -72,54 +73,6 @@ class DDoSAttack(BaseAttack.BaseAttack):
         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_pcap(self):
-        def update_timestamp(timestamp, pps, delay=0):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            if delay == 0:
-                # Calculate the request timestamp
-                # A distribution to imitate the bursty behavior of traffic
-                randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-                return timestamp + uniform(1 / pps, randomdelay.random())
-            else:
-                # Calculate the reply timestamp
-                randomdelay = Lea.fromValFreqsDict({2 * delay: 70, 3 * delay: 20, 5 * delay: 7, 10 * delay: 3})
-                return timestamp + uniform(1 / pps + delay, 1 / pps + randomdelay.random())
-
-        def get_nth_random_element(*element_list):
-            """
-            Returns the n-th element of every list from an arbitrary number of given lists.
-            For example, list1 contains IP addresses, list 2 contains MAC addresses. Use of this function ensures that
-            the n-th IP address uses always the n-th MAC address.
-            :param element_list: An arbitrary number of lists.
-            :return: A tuple of the n-th element of every list.
-            """
-            range_max = min([len(x) for x in element_list])
-            if range_max > 0: range_max -= 1
-            n = randint(0, range_max)
-            return tuple(x[n] for x in element_list)
-
-        def index_increment(number: int, max: int):
-            if number + 1 < max:
-                return number + 1
-            else:
-                return 0
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) for a specific time interval.
-            :param complement_interval_pps: an array of tuples (the last timestamp in the interval, the packet rate in the crresponding interval).
-            :param timestamp: the timestamp at which the packet rate is required.
-            :return: the corresponding packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp <= row[0]:
-                    return row[1]
-            # In case the timestamp > capture max timestamp
-            return complement_interval_pps[-1][1]
-
         def get_attacker_config(ipAddress: str):
         def get_attacker_config(ipAddress: str):
             """
             """
             Returns the attacker configuration depending on the IP address, this includes the port for the next
             Returns the attacker configuration depending on the IP address, this includes the port for the next
@@ -151,7 +104,6 @@ class DDoSAttack(BaseAttack.BaseAttack):
                 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
         BUFFER_SIZE = 1000
 
 
         # Determine source IP and MAC address
         # Determine source IP and MAC address
@@ -280,7 +232,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
                     replies_count+=1
                     replies_count+=1
                     total_pkt_num += 1
                     total_pkt_num += 1
 
 
-                attacker_pps = max(getIntervalPPS(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)

+ 11 - 29
code/Attack/EternalBlueExploit.py

@@ -1,16 +1,18 @@
 import logging
 import logging
-from random import randint, uniform
 
 
+from random import randint, uniform
 from lea import Lea
 from lea import Lea
+from scapy.utils import RawPcapReader
+from scapy.layers.inet import Ether
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
+from ID2TLib.Utility import update_timestamp, get_interval_pps
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.utils import RawPcapReader
-from scapy.layers.inet import IP, Ether, TCP, RandShort
+
 
 
 class EternalBlueExploit(BaseAttack.BaseAttack):
 class EternalBlueExploit(BaseAttack.BaseAttack):
     template_scan_pcap_path = "resources/Win7_eternalblue_scan.pcap"
     template_scan_pcap_path = "resources/Win7_eternalblue_scan.pcap"
@@ -78,27 +80,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         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_pcap(self):
-        def update_timestamp(timestamp, pps):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            # Calculate the request timestamp
-            # A distribution to imitate the bursty behavior of traffic
-            randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-            return timestamp + uniform(1 / pps, randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) in specific time interval.
-
-            :return: the corresponding packet rate for packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp<=row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1] # in case the timstamp > capture max timestamp
+
 
 
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -202,7 +184,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 new_pkt.time = timestamp_next_pkt
                 new_pkt.time = timestamp_next_pkt
 
 
-                pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]#float(timeSteps.random())
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]#float(timeSteps.random())
             # Reply
             # Reply
             else:
             else:
@@ -294,7 +276,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
 
 
-                        pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num] #float(timeSteps.random())
                         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num] #float(timeSteps.random())
 
 
                     # Reply
                     # Reply
@@ -324,7 +306,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
 
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
 
-                        pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]#float(timeSteps.random())
                         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]#float(timeSteps.random())
 
 
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
@@ -367,7 +349,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt
 
 
-                        pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]# float(timeSteps.random())
                         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]# float(timeSteps.random())
 
 
                     # Reply
                     # Reply
@@ -397,7 +379,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
 
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
 
-                        pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]# float(timeSteps.random())
                         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]# float(timeSteps.random())
 
 
                         new_pkt.time = timestamp_next_pkt
                         new_pkt.time = timestamp_next_pkt

+ 6 - 26
code/Attack/JoomlaRegPrivExploit.py

@@ -1,16 +1,17 @@
 import logging
 import logging
-from random import randint, uniform
 
 
+from random import randint
 from lea import Lea
 from lea import Lea
+from scapy.utils import RawPcapReader
+from scapy.layers.inet import Ether
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
+from ID2TLib.Utility import update_timestamp, get_interval_pps
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.utils import RawPcapReader
-from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 
 
 
 class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
 class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
@@ -79,27 +80,6 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                               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_pcap(self):
-        def update_timestamp(timestamp, pps):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            # Calculate the request timestamp
-            # A distribution to imitate the bursty behavior of traffic
-            randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-            return timestamp + uniform(1 / pps, randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) in specific time interval.
-
-            :return: the corresponding packet rate for packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp <= row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1]  # in case the timstamp > capture max timestamp
 
 
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -206,7 +186,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                 new_pkt = (eth_frame / ip_pkt/ tcp_pkt / str_tcp_seg)
                 new_pkt = (eth_frame / ip_pkt/ tcp_pkt / str_tcp_seg)
                 new_pkt.time = timestamp_next_pkt
                 new_pkt.time = timestamp_next_pkt
 
 
-                pps = max(getIntervalPPS(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) + float(timeSteps.random())
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
 
 
             # Reply: Victim --> attacker
             # Reply: Victim --> attacker
@@ -232,7 +212,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                     victim_seq += max(strLen, 1)
                     victim_seq += max(strLen, 1)
 
 
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
-                pps = max(getIntervalPPS(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) + float(timeSteps.random())
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
                 new_pkt.time = timestamp_next_pkt
 
 

+ 8 - 32
code/Attack/PortscanAttack.py

@@ -1,17 +1,18 @@
 import logging
 import logging
 import csv
 import csv
 
 
-from random import shuffle, randint, choice, uniform
-
+from random import shuffle, randint, choice
 from lea import Lea
 from lea import Lea
+from scapy.layers.inet import IP, Ether, TCP
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
+from ID2TLib.Utility import update_timestamp, get_interval_pps
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.layers.inet import IP, Ether, TCP
+
 
 
 class PortscanAttack(BaseAttack.BaseAttack):
 class PortscanAttack(BaseAttack.BaseAttack):
 
 
@@ -108,34 +109,9 @@ class PortscanAttack(BaseAttack.BaseAttack):
         return port_dst_shuffled
         return port_dst_shuffled
 
 
     def generate_attack_pcap(self):
     def generate_attack_pcap(self):
-        def update_timestamp(timestamp, pps, delay=0):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            if delay == 0:
-                # Calculate request timestamp
-                # To imitate the bursty behavior of traffic
-                randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-                return timestamp + uniform(1/pps ,  randomdelay.random())
-            else:
-                # Calculate reply timestamp
-                randomdelay = Lea.fromValFreqsDict({2*delay: 70, 3*delay: 20, 5*delay: 7, 10*delay: 3})
-                return timestamp + uniform(1 / pps + delay,  1 / pps + randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) for a specific time interval.
-
-            :param complement_interval_pps: an array of tuples (the last timestamp in the interval, the packet rate in the crresponding interval).
-            :param timestamp: the timestamp at which the packet rate is required.
-            :return: the corresponding packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp<=row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1] # in case the timstamp > capture max timestamp
+
+
+
 
 
         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)
@@ -279,7 +255,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
 
 
                 # 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(getIntervalPPS(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)
 
 
         # store end time of attack
         # store end time of attack

+ 11 - 41
code/Attack/SMBLorisAttack.py

@@ -1,18 +1,18 @@
 import logging
 import logging
-import csv
-
-from random import shuffle, randint, choice, uniform
 
 
+from random import randint, uniform
 from lea import Lea
 from lea import Lea
+from scapy.layers.inet import IP, Ether, TCP
+from scapy.layers.netbios import NBTSession
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
+from ID2TLib.Utility import update_timestamp
+from ID2TLib.SMBLib import smb_port
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.layers.inet import IP, Ether, TCP
-from scapy.layers.netbios import NBTSession
 
 
 # Resources:
 # Resources:
 # https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/dos/smb/smb_loris.rb
 # https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/dos/smb/smb_loris.rb
@@ -20,9 +20,8 @@ from scapy.layers.netbios import NBTSession
 # https://gist.githubusercontent.com/marcan/6a2d14b0e3eaa5de1795a763fb58641e/raw/565befecf4d9a4a27248d027a90b6e3e5994b5b6/smbloris.c
 # https://gist.githubusercontent.com/marcan/6a2d14b0e3eaa5de1795a763fb58641e/raw/565befecf4d9a4a27248d027a90b6e3e5994b5b6/smbloris.c
 # http://smbloris.com/
 # http://smbloris.com/
 
 
+
 class SMBLorisAttack(BaseAttack.BaseAttack):
 class SMBLorisAttack(BaseAttack.BaseAttack):
-    # SMB port
-    smb_port = 445
 
 
     def __init__(self):
     def __init__(self):
         """
         """
@@ -85,35 +84,6 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.ATTACK_DURATION, 30)
         self.add_param_value(Param.ATTACK_DURATION, 30)
 
 
     def generate_attack_pcap(self):
     def generate_attack_pcap(self):
-        def update_timestamp(timestamp, pps, delay=0):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            if delay == 0:
-                # Calculate request timestamp
-                # To imitate the bursty behavior of traffic
-                randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-                return timestamp + uniform(1/pps ,  randomdelay.random())
-            else:
-                # Calculate reply timestamp
-                randomdelay = Lea.fromValFreqsDict({2*delay: 70, 3*delay: 20, 5*delay: 7, 10*delay: 3})
-                return timestamp + uniform(1 / pps + delay,  1 / pps + randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) for a specific time interval.
-
-            :param complement_interval_pps: an array of tuples (the last timestamp in the interval, the packet rate in the crresponding interval).
-            :param timestamp: the timestamp at which the packet rate is required.
-            :return: the corresponding packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp<=row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1] # in case the timstamp > capture max timestamp
-
         def getIpData(ip_address: str):
         def getIpData(ip_address: str):
             """
             """
             :param ip_address: the ip of which (packet-)data shall be returned
             :param ip_address: the ip of which (packet-)data shall be returned
@@ -224,7 +194,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 victim_ip = IP(src=ip_destination, dst=ip_source_list[attacker], ttl=destination_ttl_value, flags='DF')
                 victim_ip = IP(src=ip_destination, dst=ip_source_list[attacker], ttl=destination_ttl_value, flags='DF')
 
 
                 # connection request from attacker (client)
                 # connection request from attacker (client)
-                syn_tcp = TCP(sport=sport, dport=self.smb_port, window=source_win_value, flags='S',
+                syn_tcp = TCP(sport=sport, dport=smb_port, window=source_win_value, flags='S',
                               seq=attacker_seq, options=[('MSS', source_mss_value)])
                               seq=attacker_seq, options=[('MSS', source_mss_value)])
                 attacker_seq += 1
                 attacker_seq += 1
                 syn = (attacker_ether / attacker_ip / syn_tcp)
                 syn = (attacker_ether / attacker_ip / syn_tcp)
@@ -233,7 +203,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 packets.append(syn)
                 packets.append(syn)
 
 
                 # response from victim (server)
                 # response from victim (server)
-                synack_tcp = TCP(sport=self.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',
                                  window=destination_win_value, options=[('MSS', destination_mss_value)])
                                  window=destination_win_value, options=[('MSS', destination_mss_value)])
                 victim_seq += 1
                 victim_seq += 1
                 synack = (victim_ether / victim_ip / synack_tcp)
                 synack = (victim_ether / victim_ip / synack_tcp)
@@ -242,7 +212,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 packets.append(synack)
                 packets.append(synack)
 
 
                 # acknowledgement from attacker (client)
                 # acknowledgement from attacker (client)
-                ack_tcp = TCP(sport=sport, dport=self.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',
                               window=source_win_value, options=[('MSS', source_mss_value)])
                               window=source_win_value, options=[('MSS', source_mss_value)])
                 ack = (attacker_ether / attacker_ip / ack_tcp)
                 ack = (attacker_ether / attacker_ip / ack_tcp)
                 ack.time = timestamp_next_pkt
                 ack.time = timestamp_next_pkt
@@ -250,7 +220,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 packets.append(ack)
                 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=self.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',
                               window=source_win_value, options=[('MSS', source_mss_value)])
                               window=source_win_value, options=[('MSS', source_mss_value)])
                 req_payload = NBTSession(TYPE=0x00, LENGTH=0x1FFFF)
                 req_payload = NBTSession(TYPE=0x00, LENGTH=0x1FFFF)
 
 
@@ -261,7 +231,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 packets.append(req)
                 packets.append(req)
 
 
                 # final ack from victim (server)
                 # final ack from victim (server)
-                last_ack_tcp = TCP(sport=self.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',
                                    window=destination_win_value, options=[('MSS', destination_mss_value)])
                                    window=destination_win_value, options=[('MSS', destination_mss_value)])
                 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

+ 10 - 37
code/Attack/SMBScanAttack.py

@@ -1,21 +1,23 @@
 import logging
 import logging
 
 
-from random import shuffle, randint, choice, uniform
+from random import shuffle, randint
 from lea import Lea
 from lea import Lea
+from scapy.layers.inet import IP, Ether, TCP
+from scapy.layers.smb import *
+from scapy.layers.netbios import *
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
 from ID2TLib.SMB2 import *
 from ID2TLib.SMB2 import *
-from ID2TLib.Utility import *
-from ID2TLib.SMBLib import *
-
+from ID2TLib.Utility import update_timestamp, get_interval_pps, get_rnd_os, get_ip_range,\
+    generate_source_port_from_platform, get_filetime_format
+from ID2TLib.SMBLib import smb_port, smb_versions, smb_dialects, get_smb_version, get_smb_platform_data,\
+    invalid_smb_version
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.layers.inet import IP, Ether, TCP
-from scapy.layers.smb import *
-from scapy.layers.netbios import *
+
 
 
 class SMBScanAttack(BaseAttack.BaseAttack):
 class SMBScanAttack(BaseAttack.BaseAttack):
 
 
@@ -94,35 +96,6 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.IP_DESTINATION_END, "0.0.0.0")
         self.add_param_value(Param.IP_DESTINATION_END, "0.0.0.0")
 
 
     def generate_attack_pcap(self):
     def generate_attack_pcap(self):
-        def update_timestamp(timestamp, pps, delay=0):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            if delay == 0:
-                # Calculate request timestamp
-                # To imitate the bursty behavior of traffic
-                randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-                return timestamp + uniform(1/pps ,  randomdelay.random())
-            else:
-                # Calculate reply timestamp
-                randomdelay = Lea.fromValFreqsDict({2*delay: 70, 3*delay: 20, 5*delay: 7, 10*delay: 3})
-                return timestamp + uniform(1 / pps + delay,  1 / pps + randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) for a specific time interval.
-
-            :param complement_interval_pps: an array of tuples (the last timestamp in the interval, the packet rate in the crresponding interval).
-            :param timestamp: the timestamp at which the packet rate is required.
-            :return: the corresponding packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp<=row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1] # in case the timstamp > capture max timestamp
-
         def get_ip_data(ip_address: str):
         def get_ip_data(ip_address: str):
             """
             """
             Gets the MSS, TTL and Windows Size values of a given IP
             Gets the MSS, TTL and Windows Size values of a given IP
@@ -424,7 +397,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     reply.time = timestamp_reply
                     reply.time = timestamp_reply
                     packets.append(reply)
                     packets.append(reply)
 
 
-            pps = max(getIntervalPPS(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)
 
 
         # store end time of attack
         # store end time of attack

+ 6 - 27
code/Attack/SQLiAttack.py

@@ -1,7 +1,10 @@
 import logging
 import logging
-from random import randint, uniform
 
 
+from random import randint
 from lea import Lea
 from lea import Lea
+from scapy.utils import RawPcapReader
+from scapy.layers.inet import Ether
+from ID2TLib.Utility import update_timestamp, get_interval_pps
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
@@ -9,8 +12,6 @@ from Attack.AttackParameters import ParameterTypes
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.utils import RawPcapReader
-from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 
 
 
 class SQLiAttack(BaseAttack.BaseAttack):
 class SQLiAttack(BaseAttack.BaseAttack):
@@ -79,28 +80,6 @@ class SQLiAttack(BaseAttack.BaseAttack):
                               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_pcap(self):
-        def update_timestamp(timestamp, pps):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            # Calculate the request timestamp
-            # A distribution to imitate the bursty behavior of traffic
-            randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-            return timestamp + uniform(1 / pps, randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) in specific time interval.
-
-            :return: the corresponding packet rate for packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp <= row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1]  # in case the timstamp > capture max timestamp
-
         # 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)
@@ -208,7 +187,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
                     new_pkt = (eth_frame / ip_pkt/ tcp_pkt / str_tcp_seg)
                     new_pkt = (eth_frame / ip_pkt/ tcp_pkt / str_tcp_seg)
                     new_pkt.time = timestamp_next_pkt
                     new_pkt.time = timestamp_next_pkt
 
 
-                    pps = max(getIntervalPPS(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) + float(timeSteps.random())
                     timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
 
 
                 # Victim --> attacker
                 # Victim --> attacker
@@ -270,7 +249,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
                     new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                     new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                     new_pkt.time = timestamp_next_pkt
                     new_pkt.time = timestamp_next_pkt
 
 
-                    pps = max(getIntervalPPS(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) + float(timeSteps.random())
                     timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
 
 
                 # Victim --> attacker
                 # Victim --> attacker

+ 5 - 26
code/Attack/SalityBotnet.py

@@ -1,16 +1,16 @@
 import logging
 import logging
-from random import randint, uniform
 
 
-from lea import Lea
+from random import randint
+from scapy.utils import RawPcapReader
+from scapy.layers.inet import Ether
 
 
 from Attack import BaseAttack
 from Attack import BaseAttack
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import Parameter as Param
 from Attack.AttackParameters import ParameterTypes
 from Attack.AttackParameters import ParameterTypes
+from ID2TLib.Utility import update_timestamp, get_interval_pps
 
 
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 # noinspection PyPep8
-from scapy.utils import RawPcapReader
-from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 
 
 
 class SalityBotnet(BaseAttack.BaseAttack):
 class SalityBotnet(BaseAttack.BaseAttack):
@@ -57,27 +57,6 @@ class SalityBotnet(BaseAttack.BaseAttack):
                               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_pcap(self):
-        def update_timestamp(timestamp, pps):
-            """
-            Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
-
-            :return: Timestamp to be used for the next packet.
-            """
-            # Calculate the request timestamp
-            # A distribution to imitate the bursty behavior of traffic
-            randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-            return timestamp + uniform(1 / pps, randomdelay.random())
-
-        def getIntervalPPS(complement_interval_pps, timestamp):
-            """
-            Gets the packet rate (pps) in specific time interval.
-
-            :return: the corresponding packet rate for packet rate (pps) .
-            """
-            for row in complement_interval_pps:
-                if timestamp <= row[0]:
-                    return row[1]
-            return complement_interval_pps[-1][1]  # in case the timstamp > capture max timestamp
 
 
         # Timestamp
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -143,7 +122,7 @@ class SalityBotnet(BaseAttack.BaseAttack):
             new_pkt = (eth_frame / ip_pkt)
             new_pkt = (eth_frame / ip_pkt)
             new_pkt.time = timestamp_next_pkt
             new_pkt.time = timestamp_next_pkt
 
 
-            pps = max(getIntervalPPS(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)
 
 
             packets.append(new_pkt)
             packets.append(new_pkt)

+ 1 - 2
code/ID2TLib/SMB2.py

@@ -3,7 +3,6 @@ from scapy.fields import *
 from scapy.layers.netbios import NBTSession
 from scapy.layers.netbios import NBTSession
 
 
 
 
-
 class SMB2_SYNC_Header(Packet):
 class SMB2_SYNC_Header(Packet):
     namez = "SMB2Negociate Protocol Response Header"
     namez = "SMB2Negociate Protocol Response Header"
     fields_desc = [StrFixedLenField("Start","\xfeSMB", 4),
     fields_desc = [StrFixedLenField("Start","\xfeSMB", 4),
@@ -21,6 +20,7 @@ class SMB2_SYNC_Header(Packet):
                    LELongField("Signature1", 0),
                    LELongField("Signature1", 0),
                    LELongField("Signature2", 0)]
                    LELongField("Signature2", 0)]
 
 
+
 #No Support of Security Buffer , Padding or Dialect Revision 0x0311
 #No Support of Security Buffer , Padding or Dialect Revision 0x0311
 class SMB2_Negotiate_Protocol_Response(Packet):
 class SMB2_Negotiate_Protocol_Response(Packet):
     namez = "SMB2Negociate Protocol Response"
     namez = "SMB2Negociate Protocol Response"
@@ -41,6 +41,5 @@ class SMB2_Negotiate_Protocol_Response(Packet):
                    LEIntField("NegotiateContextOffset/Reserved2", 0)]
                    LEIntField("NegotiateContextOffset/Reserved2", 0)]
 
 
 
 
-
 bind_layers(NBTSession, SMB2_SYNC_Header,)
 bind_layers(NBTSession, SMB2_SYNC_Header,)
 bind_layers(SMB2_SYNC_Header, SMB2_Negotiate_Protocol_Response,)
 bind_layers(SMB2_SYNC_Header, SMB2_Negotiate_Protocol_Response,)

+ 2 - 3
code/ID2TLib/SMBLib.py

@@ -1,9 +1,8 @@
 from os import urandom
 from os import urandom
 from binascii import b2a_hex
 from binascii import b2a_hex
+from random import random
 
 
-from ID2TLib.Utility import *
-
-from scapy.layers.netbios import *
+from ID2TLib.Utility import check_platform, get_filetime_format, get_rnd_boot_time
 
 
 # SMB port
 # SMB port
 smb_port = 445
 smb_port = 445

+ 61 - 8
code/ID2TLib/Utility.py

@@ -1,12 +1,66 @@
-from random import randint
-from datetime import datetime, timedelta, tzinfo
-from calendar import timegm
+import ipaddress
 
 
+from random import randint, uniform
+from datetime import datetime
+from calendar import timegm
 from lea import Lea
 from lea import Lea
 
 
-from scapy.layers.netbios import *
-
 platforms = {"win7", "win10", "winxp", "win8.1", "macos", "linux", "win8", "winvista", "winnt", "win2000"}
 platforms = {"win7", "win10", "winxp", "win8.1", "macos", "linux", "win8", "winvista", "winnt", "win2000"}
+platform_probability = {"win7": 48.43, "win10": 27.99, "winxp": 6.07, "win8.1": 6.07, "macos": 5.94, "linux": 3.38,
+                        "win8": 1.35, "winvista": 0.46, "winnt": 0.31}
+
+
+def update_timestamp(timestamp, pps, delay=0):
+    """
+    Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
+
+    :return: Timestamp to be used for the next packet.
+    """
+    if delay == 0:
+        # Calculate request timestamp
+        # To imitate the bursty behavior of traffic
+        randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
+        return timestamp + uniform(1 / pps, randomdelay.random())
+    else:
+        # Calculate reply timestamp
+        randomdelay = Lea.fromValFreqsDict({2 * delay: 70, 3 * delay: 20, 5 * delay: 7, 10 * delay: 3})
+        return timestamp + uniform(1 / pps + delay, 1 / pps + randomdelay.random())
+
+
+def get_interval_pps(complement_interval_pps, timestamp):
+    """
+    Gets the packet rate (pps) for a specific time interval.
+
+    :param complement_interval_pps: an array of tuples (the last timestamp in the interval, the packet rate in the
+    corresponding interval).
+    :param timestamp: the timestamp at which the packet rate is required.
+    :return: the corresponding packet rate (pps) .
+    """
+    for row in complement_interval_pps:
+        if timestamp<=row[0]:
+            return row[1]
+    return complement_interval_pps[-1][1] # in case the timstamp > capture max timestamp
+
+
+def get_nth_random_element(*element_list):
+    """
+    Returns the n-th element of every list from an arbitrary number of given lists.
+    For example, list1 contains IP addresses, list 2 contains MAC addresses. Use of this function ensures that
+    the n-th IP address uses always the n-th MAC address.
+    :param element_list: An arbitrary number of lists.
+    :return: A tuple of the n-th element of every list.
+    """
+    range_max = min([len(x) for x in element_list])
+    if range_max > 0: range_max -= 1
+    n = randint(0, range_max)
+    return tuple(x[n] for x in element_list)
+
+
+def index_increment(number: int, max: int):
+            if number + 1 < max:
+                return number + 1
+            else:
+                return 0
 
 
 
 
 def get_rnd_os():
 def get_rnd_os():
@@ -15,8 +69,7 @@ def get_rnd_os():
 
 
     :return: random platform as string
     :return: random platform as string
     """
     """
-    os_dist = Lea.fromValFreqsDict({"win7": 48.43, "win10": 27.99, "winxp": 6.07, "win8.1": 6.07, "macos": 5.94,
-                                    "linux": 3.38, "win8": 1.35, "winvista": 0.46, "winnt": 0.31})
+    os_dist = Lea.fromValFreqsDict(platform_probability)
     return os_dist.random()
     return os_dist.random()
 
 
 
 
@@ -113,4 +166,4 @@ def get_rnd_boot_time(timestamp, platform="winxp"):
         uptime_in_days = Lea.fromValFreqsDict({3: 50, 7: 25, 14: 12.5, 31: 6.25, 92: 3.125, 183: 1.5625,
         uptime_in_days = Lea.fromValFreqsDict({3: 50, 7: 25, 14: 12.5, 31: 6.25, 92: 3.125, 183: 1.5625,
                                                365: 0.78125, 1461: 0.78125})
                                                365: 0.78125, 1461: 0.78125})
     timestamp -= randint(0, uptime_in_days.random()*86400)
     timestamp -= randint(0, uptime_in_days.random()*86400)
-    return timestamp
+    return timestamp