Browse Source

fix packet rate

aidmar.wainakh 6 years ago
parent
commit
8e3cf671e5
3 changed files with 64 additions and 77 deletions
  1. 29 31
      code/Attack/EternalBlueExploit.py
  2. 20 32
      code/Attack/JoomlaRegPrivExploit.py
  3. 15 14
      code/Attack/SQLiAttack.py

+ 29 - 31
code/Attack/EternalBlueExploit.py

@@ -1,5 +1,3 @@
-# Created by Aidmar
-
 import logging
 from random import randint, uniform
 
@@ -15,9 +13,7 @@ from scapy.utils import RawPcapReader
 from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 class EternalBlueExploit(BaseAttack.BaseAttack):
-    # Metasploit default packet rate
-    maxDefaultPPS = 100
-    minDefaultPPS = 5
+    template_attack_pcap_path = "resources/Win7_eternalblue_scan.pcap"
     # SMB port
     smb_port = 445
     # Empirical values from Metasploit experiments
@@ -54,7 +50,9 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         self.add_param_value(Param.IP_SOURCE, most_used_ip_address)
         self.add_param_value(Param.MAC_SOURCE, self.statistics.get_mac_address(most_used_ip_address))
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
-        self.add_param_value(Param.PACKETS_PER_SECOND,self.maxDefaultPPS)
+        self.add_param_value(Param.PACKETS_PER_SECOND,
+                             (self.statistics.get_pps_sent(most_used_ip_address) +
+                              self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
         # victim configuration
         random_ip_address = self.statistics.get_random_ip_address()
@@ -66,15 +64,17 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
 
     def generate_attack_pcap(self):
-        def update_timestamp(timestamp, pps, maxdelay):
+        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.
             """
-            return timestamp + uniform(1 / pps, maxdelay)
+            # 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())
 
-        # Aidmar
         def getIntervalPPS(complement_interval_pps, timestamp):
             """
             Gets the packet rate (pps) in specific time interval.
@@ -88,28 +88,24 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
-        # TO-DO: find better pkt rate
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
-        randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 30, 5 / pps: 15, 10 / pps: 3})
 
-        # Aidmar - calculate complement packet rates of BG traffic per interval
+        # calculate complement packet rates of BG traffic per interval
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
         packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
-        #port_source = self.get_param_value(Param.PORT_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
 
-        # Aidmar - check ip.src == ip.dst
+        # check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
         path_attack_pcap = None
         minDelay, maxDelay = self.get_reply_delay(ip_destination)
 
-
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
         if len(source_ttl_dist) > 0:
@@ -128,7 +124,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         # Scan (MS17) for EternalBlue
         # Read Win7_eternalblue_scan_vulnerable pcap file
         orig_ip_dst = None
-        exploit_raw_packets = RawPcapReader("resources/Win7_eternalblue_scan.pcap")
+        exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
 
@@ -156,9 +152,8 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 new_pkt.time = timestamp_next_pkt
 
-                maxdelay = randomdelay.random()
-                pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
-                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+                pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
             # Reply
             else:
                 # Ether
@@ -186,19 +181,18 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
         conversations, orderList_conversations = self.packetsToConvs(exploit_raw_packets)
 
-        # the last two connections have special treatment, they start after the other connections finish
-        # TO-DO
-
         conv_start_timesamp = timestamp_next_pkt
         for conv_index, conv in enumerate(orderList_conversations):
             conv_start_timesamp = conv_start_timesamp + uniform(0.001,0.01) # the distance between the starts of the converstaions
             timestamp_next_pkt = conv_start_timesamp
 
             conv_pkts = conversations[conv]
+            inter_arrival_time_dist = self.get_inter_arrival_time_dist(conv_pkts)
+            timeSteps = Lea.fromValFreqsDict(inter_arrival_time_dist)
+
             if conv_index == len(orderList_conversations) - 2:  # Not the last conversation
                 timestamp_next_pkt = packets[-1].time + uniform(0.001,0.01)
 
-
             if conv_index != len(orderList_conversations)-1: # Not the last conversation
                 port_source += 2
                 for pkt_num, pkt in enumerate(conv_pkts):
@@ -226,9 +220,8 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt.time = timestamp_next_pkt
 
-                        maxdelay = randomdelay.random()
-                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
-                        timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                        timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
 
                     # Reply
                     else:
@@ -242,7 +235,10 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         # TCP
                         tcp_pkt.setfieldval("dport", port_source)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-                        timestamp_next_pkt = timestamp_next_pkt + uniform(minDelay, maxDelay)
+
+                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                        timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
+
                         new_pkt.time = timestamp_next_pkt
 
                     packets.append(new_pkt)
@@ -271,9 +267,8 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt.time = timestamp_next_pkt
 
-                        maxdelay = randomdelay.random()
-                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
-                        timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                        timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
 
                     # Reply
                     else:
@@ -287,7 +282,10 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         # TCP
                         tcp_pkt.setfieldval("dport", port_source)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-                        timestamp_next_pkt = timestamp_next_pkt + uniform(minDelay, maxDelay)
+
+                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                        timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
+
                         new_pkt.time = timestamp_next_pkt
 
                     packets.append(new_pkt)

+ 20 - 32
code/Attack/JoomlaRegPrivExploit.py

@@ -1,19 +1,4 @@
-# Created by Aidmar
-"""
-Joomla Account Creation and Privilege Escalation
-
-This attack creates an arbitrary account with administrative privileges in Joomla versions 3.4.4 through 3.6.3.
-
-more info:
-https://www.rapid7.com/db/modules/auxiliary/admin/http/joomla_registration_privesc
-
-"""
-
-
 import logging
-import math
-from operator import itemgetter
-import operator
 from random import randint, uniform
 
 from lea import Lea
@@ -26,13 +11,10 @@ logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
 # noinspection PyPep8
 from scapy.utils import RawPcapReader
 from scapy.layers.inet import IP, Ether, TCP, RandShort
-#from scapy.all import *
 
 
 class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
-    # Metasploit default packet rate
-    maxDefaultPPS = 55
-    minDefaultPPS = 5
+    template_attack_pcap_path = "resources/joomla_registration_privesc.pcap"
     # HTTP port
     http_port = 80
     # Metasploit experiments show this range of ports
@@ -72,7 +54,9 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         #self.add_param_value(Param.TARGET_URI, '/')
         self.add_param_value(Param.TARGET_HOST, "www.hackme.com")
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
-        self.add_param_value(Param.PACKETS_PER_SECOND,self.maxDefaultPPS)
+        self.add_param_value(Param.PACKETS_PER_SECOND,
+                             (self.statistics.get_pps_sent(most_used_ip_address) +
+                              self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
         # victim configuration
         # consider that the destination has port 80 opened
@@ -85,13 +69,16 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
 
     def generate_attack_pcap(self):
-        def update_timestamp(timestamp, pps, maxdelay):
+        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.
             """
-            return timestamp + uniform(1 / pps, maxdelay)
+            # 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())
 
         # Aidmar
         def getIntervalPPS(complement_interval_pps, timestamp):
@@ -107,11 +94,10 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
 
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
-        # TO-DO: find better pkt rate
+
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
-        randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 30, 5 / pps: 15, 10 / pps: 3})
 
-        # Aidmar - calculate complement packet rates of BG traffic per interval
+        # Calculate complement packet rates of BG traffic per interval
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
@@ -123,11 +109,10 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         target_host = self.get_param_value(Param.TARGET_HOST)
         target_uri = "/" #self.get_param_value(Param.TARGET_URI)
 
-        # Aidmar - check ip.src == ip.dst
+        # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
         path_attack_pcap = None
-        minDelay, maxDelay = self.get_reply_delay(ip_destination)
 
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -147,7 +132,10 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         # Inject Joomla_registration_privesc
         # Read joomla_registration_privesc pcap file
         orig_ip_dst = None
-        exploit_raw_packets = RawPcapReader("resources/joomla_registration_privesc.pcap")
+        exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
+        inter_arrival_time_dist = self.get_inter_arrival_time_dist(exploit_raw_packets)
+        timeSteps = Lea.fromValFreqsDict(inter_arrival_time_dist)
+        exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
 
@@ -213,9 +201,8 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                 new_pkt = (eth_frame / ip_pkt/ tcp_pkt / str_tcp_seg)
                 new_pkt.time = timestamp_next_pkt
 
-                maxdelay = randomdelay.random()
-                pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
-                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+                pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
 
             # Reply: Victim --> attacker
             else:
@@ -245,7 +232,8 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                     victim_seq += max(strLen, 1)
 
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
-                timestamp_next_pkt = timestamp_next_pkt + uniform(minDelay, maxDelay)
+                pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
 
             packets.append(new_pkt)

+ 15 - 14
code/Attack/SQLiAttack.py

@@ -10,7 +10,6 @@ https://www.rapid7.com/db/modules/exploit/multi/http/atutor_sqli
 
 """
 
-
 import logging
 import math
 from operator import itemgetter
@@ -30,8 +29,8 @@ from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 
 class SQLiAttack(BaseAttack.BaseAttack):
+    template_attack_pcap_path = "resources/ATutorSQLi.pcap"
     # Metasploit default packet rate
-    maxDefaultPPS = 55
     minDefaultPPS = 5
     # HTTP port
     http_port = 80
@@ -72,8 +71,9 @@ class SQLiAttack(BaseAttack.BaseAttack):
         #self.add_param_value(Param.TARGET_URI, "/")
         self.add_param_value(Param.TARGET_HOST, "www.hackme.com")
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
-        self.add_param_value(Param.PACKETS_PER_SECOND,self.maxDefaultPPS)
-
+        self.add_param_value(Param.PACKETS_PER_SECOND,
+                             (self.statistics.get_pps_sent(most_used_ip_address) +
+                              self.statistics.get_pps_received(most_used_ip_address)) / 2)
         # victim configuration
         # consider that the destination has port 80 opened
         random_ip_address = self.statistics.get_random_ip_address()
@@ -85,13 +85,16 @@ class SQLiAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
 
     def generate_attack_pcap(self):
-        def update_timestamp(timestamp, pps, maxdelay):
+        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.
             """
-            return timestamp + uniform(1 / pps, maxdelay)
+            # 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())
 
         # Aidmar
         def getIntervalPPS(complement_interval_pps, timestamp):
@@ -123,7 +126,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         target_host = self.get_param_value(Param.TARGET_HOST)
         target_uri = "/" #self.get_param_value(Param.TARGET_URI)
 
-        # Aidmar - check ip.src == ip.dst
+        # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
         path_attack_pcap = None
@@ -147,7 +150,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         # Inject SQLi Attack
         # Read SQLi Attack pcap file
         orig_ip_dst = None
-        exploit_raw_packets = RawPcapReader("resources/ATutorSQLi.pcap")
+        exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
 
@@ -214,9 +217,8 @@ class SQLiAttack(BaseAttack.BaseAttack):
                     new_pkt = (eth_frame / ip_pkt/ tcp_pkt / str_tcp_seg)
                     new_pkt.time = timestamp_next_pkt
 
-                    maxdelay = randomdelay.random()
-                    pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
-                    timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+                    pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                    timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
 
                 # Victim --> attacker
                 else:
@@ -286,9 +288,8 @@ class SQLiAttack(BaseAttack.BaseAttack):
                     new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                     new_pkt.time = timestamp_next_pkt
 
-                    maxdelay = randomdelay.random()
-                    pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
-                    timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+                    pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
+                    timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
 
                 # Victim --> attacker
                 else: