Browse Source

Merge branch 'interval_param_smb_scan'

Jens Keim 5 years ago
parent
commit
ddd3b7af85

+ 1 - 0
code/Attack/AttackParameters.py

@@ -34,6 +34,7 @@ class Parameter(enum.Enum):
     TARGET_HOST = 'target.host'
     TARGET_HOST = 'target.host'
     # recommended type: Float ------------------------------------
     # recommended type: Float ------------------------------------
     PACKETS_PER_SECOND = 'packets.per-second'  # packets per second
     PACKETS_PER_SECOND = 'packets.per-second'  # packets per second
+    INJECT_PPS = 'inject.pps'  # packets per seconds injected by the attack
     INJECT_AT_TIMESTAMP = 'inject.at-timestamp'  # unix epoch time (seconds.millis) where attack should be injected
     INJECT_AT_TIMESTAMP = 'inject.at-timestamp'  # unix epoch time (seconds.millis) where attack should be injected
     # recommended type: Packet Position ----------------------------------
     # recommended type: Packet Position ----------------------------------
     INJECT_AFTER_PACKET = 'inject.after-pkt'  # packet after which attack should be injected
     INJECT_AFTER_PACKET = 'inject.after-pkt'  # packet after which attack should be injected

+ 5 - 1
code/Attack/BaseAttack.py

@@ -354,15 +354,19 @@ class BaseAttack(metaclass=abc.ABCMeta):
 
 
         # by default no param is valid
         # by default no param is valid
         is_valid = False
         is_valid = False
+        param_name = None
 
 
         # get AttackParameters instance associated with param
         # get AttackParameters instance associated with param
         # for default values assigned in attack classes, like Parameter.PORT_OPEN
         # for default values assigned in attack classes, like Parameter.PORT_OPEN
         if isinstance(param, atkParam.Parameter):
         if isinstance(param, atkParam.Parameter):
             param_name = param
             param_name = param
         # for values given by user input, like port.open
         # for values given by user input, like port.open
-        else:
+        elif atkParam.Parameter(param):
             # Get Enum key of given string identifier
             # Get Enum key of given string identifier
             param_name = atkParam.Parameter(param)
             param_name = atkParam.Parameter(param)
+        else:
+            print("ERROR: Parameter " + param + " is not supported by ID2T.")
+            sys.exit(-1)
 
 
         # Get parameter type of attack's required_params
         # Get parameter type of attack's required_params
         param_type = self.supported_params.get(param_name)
         param_type = self.supported_params.get(param_name)

+ 13 - 2
code/Attack/SMBScanAttack.py

@@ -41,6 +41,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
             atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION,
             atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION,
             atkParam.Parameter.IP_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN,
             atkParam.Parameter.IP_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN,
             atkParam.Parameter.PACKETS_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT,
             atkParam.Parameter.PACKETS_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT,
+            atkParam.Parameter.INJECT_PPS: atkParam.ParameterTypes.TYPE_FLOAT,
             atkParam.Parameter.PORT_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN,
             atkParam.Parameter.PORT_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN,
             atkParam.Parameter.HOSTING_IP: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
             atkParam.Parameter.HOSTING_IP: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
             atkParam.Parameter.HOSTING_VERSION: atkParam.ParameterTypes.TYPE_STRING,
             atkParam.Parameter.HOSTING_VERSION: atkParam.ParameterTypes.TYPE_STRING,
@@ -71,7 +72,12 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND,
         self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND,
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
+
         self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
         self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
+        start = Util.get_timestamp_from_datetime_str(self.statistics.get_pcap_timestamp_start())
+        end = Util.get_timestamp_from_datetime_str(self.statistics.get_pcap_timestamp_end())
+        self.add_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP, (start + end) / 2)
+        self.add_param_value(atkParam.Parameter.INJECT_PPS, 0)
 
 
         self.add_param_value(atkParam.Parameter.HOSTING_PERCENTAGE, 0.5)
         self.add_param_value(atkParam.Parameter.HOSTING_PERCENTAGE, 0.5)
         self.add_param_value(atkParam.Parameter.HOSTING_IP, "1.1.1.1")
         self.add_param_value(atkParam.Parameter.HOSTING_IP, "1.1.1.1")
@@ -199,6 +205,9 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         mac_dests = self.statistics.get_mac_addresses(ip_dests)
         mac_dests = self.statistics.get_mac_addresses(ip_dests)
         first_timestamp_smb = self.statistics.get_pcap_timestamp_start()[:19]
         first_timestamp_smb = self.statistics.get_pcap_timestamp_start()[:19]
 
 
+        # get inject pss
+        inject_pps = self.get_param_value(atkParam.Parameter.INJECT_PPS)
+
         for ip in ip_dests:
         for ip in ip_dests:
 
 
             if ip != ip_source:
             if ip != ip_source:
@@ -243,9 +252,11 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                 self.packets.append(request)
                 self.packets.append(request)
 
 
                 # Update timestamp for next package
                 # Update timestamp for next package
-                timestamp_reply = Util.update_timestamp(timestamp_next_pkt, pps, min_delay)
+                timestamp_reply = Util.update_timestamp(timestamp_next_pkt, pps, min_delay, inj_pps=inject_pps,
+                                                        inj_timestamp=self.attack_start_utime)
                 while timestamp_reply <= timestamp_prv_reply:
                 while timestamp_reply <= timestamp_prv_reply:
-                    timestamp_reply = Util.update_timestamp(timestamp_prv_reply, pps, min_delay)
+                    timestamp_reply = Util.update_timestamp(timestamp_prv_reply, pps, min_delay, inj_pps=inject_pps,
+                                                            inj_timestamp=self.attack_start_utime)
                 timestamp_prv_reply = timestamp_reply
                 timestamp_prv_reply = timestamp_reply
 
 
                 if ip in hosting_ip:
                 if ip in hosting_ip:

+ 22 - 5
code/ID2TLib/Utility.py

@@ -45,22 +45,39 @@ attacker_ttl_mapping = {}
 generic_attack_names = {"attack", "exploit"}
 generic_attack_names = {"attack", "exploit"}
 
 
 
 
-def update_timestamp(timestamp, pps, delay=0):
+def update_timestamp(timestamp: float, pps: float, delay: float=0, inj_pps: float=0, inj_timestamp: float=0):
     """
     """
     Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
     Calculates the next timestamp to be used based on the packet per second rate (pps) and the maximum delay.
 
 
     :return: Timestamp to be used for the next packet.
     :return: Timestamp to be used for the next packet.
     """
     """
     # FIXME: throw Exception if pps==0
     # FIXME: throw Exception if pps==0
+    second = 0
+    packets_this_second = 0
+    if inj_pps != 0 and inj_timestamp != 0:
+        time = timestamp - inj_timestamp
+        packets_so_far = time / inj_pps
+        packets_this_second = packets_so_far % inj_pps
+    else:
+        inj_pps = 0
     if delay == 0:
     if delay == 0:
         # Calculate request timestamp
         # Calculate request timestamp
         # To imitate the bursty behavior of traffic
         # To imitate the bursty behavior of traffic
-        randomdelay = lea.Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
-        return timestamp + rnd.uniform(1 / pps, randomdelay.random())
+        random_delay = lea.Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 20, 5 / pps: 7, 10 / pps: 3})
+        result_delay = rnd.uniform(1 / pps, random_delay.random())
     else:
     else:
         # Calculate reply timestamp
         # Calculate reply timestamp
-        randomdelay = lea.Lea.fromValFreqsDict({delay / 2: 70, delay / 3: 20, delay / 5: 7, delay / 10: 3})
-        return timestamp + rnd.uniform(1 / pps + delay, 1 / pps + randomdelay.random())
+        random_delay = lea.Lea.fromValFreqsDict({delay / 2: 70, delay / 3: 20, delay / 5: 7, delay / 10: 3})
+        result_delay = rnd.uniform(1 / pps + delay, 1 / pps + random_delay.random())
+
+    result = timestamp + result_delay
+    if inj_pps > packets_this_second and int(result) - int(timestamp) != 1:
+        result = result + 1
+    return result
+
+
+def get_timestamp_from_datetime_str(time: str):
+    return dt.datetime.strptime(time, "%Y-%m-%d %H:%M:%S.%f").timestamp()
 
 
 
 
 def get_interval_pps(complement_interval_pps, timestamp):
 def get_interval_pps(complement_interval_pps, timestamp):

+ 8 - 8
code/Test/test_SMBScanAttack.py

@@ -2,14 +2,14 @@ import unittest.mock as mock
 
 
 import Test.ID2TAttackTest as Test
 import Test.ID2TAttackTest as Test
 
 
-sha_default = '20797cfbe1d040481bdc70be9690344389e1c79333914b1480655156789917a0'
-sha_one_victim_linux = '0c3c476bc44a38e399673d2f7a8bd3020f80669108628fd868c1924f1547ccf2'
-sha_victim_range_winxp_hosting = '84d8f748bec162f1fdc5252625d1fbcd782df66b828d2928764fdb3f0b83d26b'
-sha_multiple_victims_macos = 'fa66856113e0bb584b3aa10987c6bb10cfd0fdb060abcdb4fcec8c0149395660'
-sha_port_shuffle = 'aa69d1541c7f131386a3783d7f6179d105f16fc7fb117dd2e7e723f80c53d51a'
-sha_dest_mac_only = '329d771d6c4730de60f1c14991b3b421878bdf677ae37bb7474b7dc442efd48d'
-sha_ip_src_shuffle = 'afad0659245010ad907ab9b6471f75441f006c61fa25bdf41829ace05dcd4946'
-sha_smb2 = 'f49a05391d0824a3ce6ebcb02cd2bd997d7da4a877864a336d7317794f1d431b'
+sha_default = 'c61cb8ce03e6b8b19132ec6a47adcfb02c4dba4234926653df5443d33b08f33b'
+sha_dest_mac_only = 'c42a1775db981a139abd42d031273805cbebd2316b0d8c097217c12193fb8a70'
+sha_multiple_victims_macos = 'b9a9f423d4154bc38723214124ad74dfdd07a39753563d21f5b453a8c069914a'
+sha_one_victim_linux = '3bb17444446334cf4feee9dd7cbeabd17acbb5ef48525fb3963591f30c37d17a'
+sha_port_shuffle = '08bdecc68fa1a2d1b0dd9802d7d025d42d90b9184d1fb6e1bcab234fac7db1b4'
+sha_smb2 = 'ef525fb61612a3db90bd0bbfaf4412f682933954357c941e1d8ac05c9ec373d4'
+sha_ip_src_shuffle = '1d699ca109c62000b77b53002f1087ebf5ccc2c2dead1dbc5c18b5f6311273d0'
+sha_victim_range_winxp_hosting = 'bd624da4e3b7a3f06b8154ed9d6274d498b589aaaa11c2d0dc207a80ab7205b9'
 
 
 # TODO: improve coverage
 # TODO: improve coverage