Browse Source

Fix connections order

aidmar.wainakh 6 years ago
parent
commit
0e7f606a08
1 changed files with 41 additions and 59 deletions
  1. 41 59
      code/Attack/EternalBlueExploit.py

+ 41 - 59
code/Attack/EternalBlueExploit.py

@@ -39,7 +39,6 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         self.supported_params = {
             Param.MAC_SOURCE: ParameterTypes.TYPE_MAC_ADDRESS,
             Param.IP_SOURCE: ParameterTypes.TYPE_IP_ADDRESS,
-            #Param.PORT_SOURCE: ParameterTypes.TYPE_PORT,
             Param.MAC_DESTINATION: ParameterTypes.TYPE_MAC_ADDRESS,
             Param.IP_DESTINATION: ParameterTypes.TYPE_IP_ADDRESS,
             Param.INJECT_AT_TIMESTAMP: ParameterTypes.TYPE_FLOAT,
@@ -55,11 +54,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.PORT_SOURCE, str(RandShort()))
         self.add_param_value(Param.PACKETS_PER_SECOND,self.maxDefaultPPS)
 
         # victim configuration
-        # TO-DO: confirm that ip.dst uses Win OS
         random_ip_address = self.statistics.get_random_ip_address()
         self.add_param_value(Param.IP_DESTINATION, random_ip_address)
 
@@ -115,10 +112,26 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         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:
+            source_ttl_prob_dict = Lea.fromValFreqsDict(source_ttl_dist)
+            source_ttl_value = source_ttl_prob_dict.random()
+        else:
+            source_ttl_value = self.statistics.process_db_query("most_used(ttlValue)")
+
+        destination_ttl_dist = self.statistics.get_ttl_distribution(ip_destination)
+        if len(destination_ttl_dist) > 0:
+            destination_ttl_prob_dict = Lea.fromValFreqsDict(destination_ttl_dist)
+            destination_ttl_value = destination_ttl_prob_dict.random()
+        else:
+            destination_ttl_value = self.statistics.process_db_query("most_used(ttlValue)")
+
         # Scan (MS17) for EternalBlue
         # Read Win7_eternalblue_scan_vulnerable pcap file
         orig_ip_dst = None
-        exploit_raw_packets = RawPcapReader("Win7_eternalblue_scan.pcap")
+        exploit_raw_packets = RawPcapReader("resources/Win7_eternalblue_scan.pcap")
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
 
@@ -139,6 +152,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 # IP
                 ip_pkt.setfieldval("src", ip_source)
                 ip_pkt.setfieldval("dst", ip_destination)
+                ip_pkt.setfieldval("ttl", source_ttl_value)
                 # TCP
                 tcp_pkt.setfieldval("sport",port_source)
 
@@ -146,8 +160,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 new_pkt.time = timestamp_next_pkt
 
                 maxdelay = randomdelay.random()
-                pps = self.minDefaultPPS if getIntervalPPS(complement_interval_pps,timestamp_next_pkt) is None else max(
-                    getIntervalPPS(complement_interval_pps,timestamp_next_pkt), self.minDefaultPPS)
+                pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
             # Reply
             else:
@@ -157,6 +170,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 # IP
                 ip_pkt.setfieldval("src", ip_destination)
                 ip_pkt.setfieldval("dst", ip_source)
+                ip_pkt.setfieldval("ttl", destination_ttl_value)
                 # TCP
                 tcp_pkt.setfieldval("dport", port_source)
 
@@ -169,49 +183,25 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
         # Inject EternalBlue exploit packets
         # Read Win7_eternalblue_exploit pcap file
-        exploit_raw_packets = RawPcapReader("Win7_eternalblue_exploit.pcap")
-
-        # Group the packets in conversations
-        def packetsToConvs(exploit_raw_packets):
-            conversations = {}
-            orderList_conversations = []
-            for pkt_num, pkt in enumerate(exploit_raw_packets):
-                eth_frame = Ether(pkt[0])
-
-                ip_pkt = eth_frame.payload
-                ip_dst = ip_pkt.getfieldval("dst")
-                ip_src = ip_pkt.getfieldval("src")
-
-                tcp_pkt = ip_pkt.payload
-                port_dst = tcp_pkt.getfieldval("dport")
-                port_src = tcp_pkt.getfieldval("sport")
-
-                conv_req = (ip_src, port_src, ip_dst, port_dst)
-                conv_rep = (ip_dst, port_dst, ip_src, port_src)
-                if conv_req not in conversations and conv_rep not in conversations:
-                    pktList = [pkt]
-                    conversations[conv_req] = pktList
-                    # Order list of conv
-                    orderList_conversations.append(conv_req)
-                else:
-                    if conv_req in conversations:
-                        pktList = conversations[conv_req]
-                        pktList.append(pkt)
-                        conversations[conv_req] = pktList
-                    else:
-                        pktList = conversations[conv_rep]
-                        pktList.append(pkt)
-                        conversations[conv_rep] = pktList
-            return (conversations,orderList_conversations)
+        exploit_raw_packets = RawPcapReader("resources/Win7_eternalblue_exploit.pcap")
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
         # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
-        temp_tuple = packetsToConvs(exploit_raw_packets)
-        conversations = temp_tuple[0]
-        orderList_conversations = temp_tuple[1]
+        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]
+            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):
@@ -223,9 +213,8 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         if tcp_pkt.getfieldval("dport") == self.smb_port:
                             orig_ip_dst = ip_pkt.getfieldval("dst")
 
-
                     # defining req/rep should be adapted to fit the last converstaion where
-                    # victim start a connection with the attacker
+                    # victim starts a connection with the attacker
                     # Request
                     if ip_pkt.getfieldval("dst") == orig_ip_dst: # victim IP
                         # Ether
@@ -234,18 +223,15 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         # IP
                         ip_pkt.setfieldval("src", ip_source)
                         ip_pkt.setfieldval("dst", ip_destination)
+                        ip_pkt.setfieldval("ttl", source_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("sport", port_source)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-                        # TO-DO: reply should have different timestamp delay
                         new_pkt.time = timestamp_next_pkt
 
                         maxdelay = randomdelay.random()
-                        pps = self.minDefaultPPS if getIntervalPPS(complement_interval_pps, timestamp_next_pkt) is None else max(
-                            getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
+                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
                         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
-                        # Not perfect timestamp
-                        #req_time = req_time + randomDelay ||  rep_time + randomDelay
 
                     # Reply
                     else:
@@ -255,17 +241,17 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         # IP
                         ip_pkt.setfieldval("src", ip_destination)
                         ip_pkt.setfieldval("dst", ip_source)
+                        ip_pkt.setfieldval("ttl", destination_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("dport", port_source)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         timestamp_next_pkt = timestamp_next_pkt + uniform(minDelay, maxDelay)
                         new_pkt.time = timestamp_next_pkt
-                        # Not perfect timestamp
-                        # rep_time = req_time + replayDelay
 
                     packets.append(new_pkt)
 
             else: # Last conversation where the victim start a connection with the attacker
+                timestamp_next_pkt = packets[-1].time + uniform(0.001, 0.01)
                 port_source = randint(self.minDefaultPort,self.maxDefaultPort)
                 for pkt_num, pkt in enumerate(conv_pkts):
                     eth_frame = Ether(pkt[0])
@@ -282,18 +268,15 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         # IP
                         ip_pkt.setfieldval("src", ip_destination)
                         ip_pkt.setfieldval("dst", ip_source)
+                        ip_pkt.setfieldval("ttl", destination_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("sport", port_source)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-                        # TO-DO: reply should have different timestamp delay
                         new_pkt.time = timestamp_next_pkt
 
                         maxdelay = randomdelay.random()
-                        pps = self.minDefaultPPS if getIntervalPPS(complement_interval_pps, timestamp_next_pkt) is None else max(
-                            getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
+                        pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), self.minDefaultPPS)
                         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
-                        # Not perfect timestamp
-                        # req_time = req_time + randomDelay ||  rep_time + randomDelay
 
                     # Reply
                     else:
@@ -303,13 +286,12 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         # IP
                         ip_pkt.setfieldval("src", ip_source)
                         ip_pkt.setfieldval("dst", ip_destination)
+                        ip_pkt.setfieldval("ttl", source_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("dport", port_source)
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         timestamp_next_pkt = timestamp_next_pkt + uniform(minDelay, maxDelay)
                         new_pkt.time = timestamp_next_pkt
-                        # Not perfect timestamp
-                        # rep_time = req_time + replayDelay
 
                     packets.append(new_pkt)