Browse Source

fix ddos actually using source_port_list

ddos actually uses source_port_list now
accepts a single port, multiple ports and portranges
if source ports are specified, take a random port from list for each packet
add test for user-specified source portrange
Stefano Acquaviti 6 years ago
parent
commit
2bc251c791
2 changed files with 17 additions and 5 deletions
  1. 11 3
      code/Attack/DDoSAttack.py
  2. 6 2
      code/Test/test_DDoSAttack.py

+ 11 - 3
code/Attack/DDoSAttack.py

@@ -4,7 +4,6 @@ import random as rnd
 
 import lea
 import scapy.layers.inet as inet
-import scipy.stats as stats
 
 import Attack.AttackParameters as atkParam
 import Attack.BaseAttack as BaseAttack
@@ -26,6 +25,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
 
         self.last_packet = None
         self.total_pkt_num = 0
+        self.default_port = 0
 
         # Define allowed parameters and their type
         self.supported_params.update({
@@ -60,7 +60,8 @@ class DDoSAttack(BaseAttack.BaseAttack):
         self.add_param_value(atkParam.Parameter.IP_SOURCE,
                              self.generate_random_ipv4_address(most_used_ip_class, num_attackers))
         self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.generate_random_mac_address(num_attackers))
-        self.add_param_value(atkParam.Parameter.PORT_SOURCE, str(inet.RandShort()))
+        self.default_port = int(inet.RandShort())
+        self.add_param_value(atkParam.Parameter.PORT_SOURCE, self.default_port)
         self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND, 0)
         self.add_param_value(atkParam.Parameter.ATTACK_DURATION, rnd.randint(5, 30))
 
@@ -106,8 +107,10 @@ class DDoSAttack(BaseAttack.BaseAttack):
 
         # Initialize parameters
         self.packets = col.deque(maxlen=buffer_size)
-        # FIXME: why is port_source_list never used?
+
         port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
+        if not isinstance(port_source_list, list):
+            port_source_list = [port_source_list]
         mac_destination = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)
         ip_destination = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
 
@@ -230,6 +233,11 @@ class DDoSAttack(BaseAttack.BaseAttack):
 
                 # Determine source port
                 (port_source, ttl_value) = Util.get_attacker_config(ip_source_list, ip_source)
+
+                # If source ports were specified by the user, get random port from specified ports
+                if port_source_list[0] != self.default_port:
+                    port_source = rnd.choice(port_source_list)
+
                 # Push port of current attacker SYN-packet into port "FIFO" of the current attacker
                 # only if victim can still respond, otherwise, memory is wasted
                 if replies_count <= victim_buffer:

+ 6 - 2
code/Test/test_DDoSAttack.py

@@ -9,8 +9,7 @@ sha_dest_mac_length_zero_ddos = '55720bc3aa43a6abad2db1bd1f9c7ff71cb50f11ca5f179
 sha_mss_none_ddos = 'd30a14ba0568cb9c3be0db6a6d8e5d68b703d995015fc2215bfa150a8aff8b2a'
 sha_one_attacker_ddos = '8bb7798e85cff15b91c5ee2c0bb65f01ff3097a417bdd2e58a540f89d542bea9'
 sha_ip_range_ddos = 'bef5deb3cc7ee7537a90a85323cf885cf5a0431e15ae7001c0c762afc643e7a6'
-
-# TODO: improve coverage
+sha_port_range_ddos = '082f9bee607931751087fc4004bc95bf225f23b2a54ce1f771969019a5443ee7'
 
 
 class UnitTestDDoS(Test.ID2TAttackTest):
@@ -44,5 +43,10 @@ class UnitTestDDoS(Test.ID2TAttackTest):
         self.checksum_test([['DDoSAttack', 'ip.src=1.1.1.1-1.1.1.10']],
                            sha_ip_range_ddos)
 
+    @mock.patch('ID2TLib.Utility.get_attacker_config', side_effect=Lib.get_attacker_config)
+    def test_ddos_port_range(self, mock_get_attacker_config):
+        self.checksum_test([['DDoSAttack', 'attackers.count=5', 'port.src=1000-2000']],
+                           sha_port_range_ddos)
+
     def test_ddos_order(self):
         self.order_test([['DDoSAttack', 'attackers.count=5']])