Browse Source

clean code

aidmar.wainakh 6 years ago
parent
commit
86a91699f4

+ 1 - 0
.gitignore

@@ -23,6 +23,7 @@ code/*.xml
 dbs/
 *.csv
 *.stat
+*pdf
 code_boost/src/cxx/CMakeLists.txt
 code_boost/src/cxx/cmake-build-debug/
 code_boost/src/SQLiteCpp/

+ 24 - 15
code/Attack/BaseAttack.py

@@ -476,29 +476,38 @@ class BaseAttack(metaclass=ABCMeta):
             sys.exit(0)
 
 
-    def get_inter_arrival_time_dist(self, packets):
+    def get_inter_arrival_time(self, packets, distribution:bool=False):
         """
-        Gets the inter-arrival time distribution of a set of packets.
+        Gets the inter-arrival times array and its distribution of a set of packets.
 
         :param packets: the packets to extract their inter-arrival time.
+        :return inter_arrival_times: array of the inter-arrival times
+        :return dict: the inter-arrival time distribution as a histogram {inter-arrival time:frequency}
         """
-        timeSteps = []
+        inter_arrival_times = []
         prvsPktTime = 0
         for index, pkt in enumerate(packets):
-            eth_frame = Ether(pkt[0])
+            timestamp = pkt[1][0] + pkt[1][1]/10**6
+
             if index == 0:
-                prvsPktTime = eth_frame.time
+                prvsPktTime = timestamp
+                inter_arrival_times.append(0)
             else:
-                timeSteps.append(eth_frame.time - prvsPktTime)
-                prvsPktTime = eth_frame.time
-
-        import numpy as np
-        freq,values = np.histogram(timeSteps,bins=20)
-        dict = {}
-        for i,val in enumerate(values):
-            if i < len(freq):
-                dict[str(val)] = freq[i]
-        return dict
+                inter_arrival_times.append(timestamp - prvsPktTime)
+                prvsPktTime = timestamp
+
+        if distribution:
+            # Build a distribution dictionary
+            import numpy as np
+            freq,values = np.histogram(inter_arrival_times,bins=20)
+            dict = {}
+            for i,val in enumerate(values):
+                if i < len(freq):
+                    dict[str(val)] = freq[i]
+            return inter_arrival_times, dict
+        else:
+            return inter_arrival_times
+
 
     def clean_white_spaces(self, str):
         """

+ 124 - 27
code/Attack/EternalBlueExploit.py

@@ -13,7 +13,8 @@ from scapy.utils import RawPcapReader
 from scapy.layers.inet import IP, Ether, TCP, RandShort
 
 class EternalBlueExploit(BaseAttack.BaseAttack):
-    template_attack_pcap_path = "resources/Win7_eternalblue_scan.pcap"
+    template_scan_pcap_path = "resources/Win7_eternalblue_scan.pcap"
+    template_attack_pcap_path = "resources/Win7_eternalblue_exploit.pcap"
     # SMB port
     smb_port = 445
     # Empirical values from Metasploit experiments
@@ -51,25 +52,27 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         """
         # PARAMETERS: initialize with default utilsvalues
         # (values are overwritten if user specifies them)
+        # Attacker configuration
         most_used_ip_address = self.statistics.get_most_used_ip_address()
         if isinstance(most_used_ip_address, list):
             most_used_ip_address = most_used_ip_address[0]
-        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.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()
-        self.add_param_value(Param.IP_DESTINATION, random_ip_address)
+        self.add_param_value(Param.IP_SOURCE, random_ip_address)
+        self.add_param_value(Param.MAC_SOURCE, self.statistics.get_mac_address(random_ip_address))
 
-        destination_mac = self.statistics.get_mac_address(random_ip_address)
+        # Victim configuration
+        self.add_param_value(Param.IP_DESTINATION, most_used_ip_address)
+        destination_mac = self.statistics.get_mac_address(most_used_ip_address)
         if isinstance(destination_mac, list) and len(destination_mac) == 0:
             destination_mac = self.generate_random_mac_address()
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
 
+        # Attack configuration
+        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)
+        self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
+
     def generate_attack_pcap(self):
         def update_timestamp(timestamp, pps):
             """
@@ -127,16 +130,37 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         else:
             destination_ttl_value = self.statistics.process_db_query("most_used(ttlValue)")
 
+        # Set Window Size based on Window Size distribution of IP address
+        source_win_dist = self.statistics.get_win_distribution(ip_source)
+        if len(source_win_dist) > 0:
+            source_win_prob_dict = Lea.fromValFreqsDict(source_win_dist)           
+        else:
+            source_win_dist =  self.statistics.get_win_distribution(self.statistics.get_most_used_ip_address())
+            source_win_prob_dict = Lea.fromValFreqsDict(source_win_dist)
+      
+        destination_win_dist = self.statistics.get_win_distribution(ip_destination)
+        if len(destination_win_dist) > 0:
+            destination_win_prob_dict = Lea.fromValFreqsDict(destination_win_dist)
+        else:
+            destination_win_dist = self.statistics.get_win_distribution(self.statistics.get_most_used_ip_address())
+            destination_win_prob_dict = Lea.fromValFreqsDict(destination_win_dist)
+
+        # Set MSS (Maximum Segment Size) based on MSS distribution of IP address
+        mss_value = self.statistics.process_db_query("most_used(mssValue)")
+        if not mss_value:
+            mss_value = 1465
+
         # Scan (MS17) for EternalBlue
-        # Read Win7_eternalblue_scan_vulnerable pcap file
+        # Read Win7_eternalblue_scan pcap file
         orig_ip_dst = None
-        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)
+        exploit_raw_packets = RawPcapReader(self.template_scan_pcap_path)
+        inter_arrival_times = self.get_inter_arrival_time(exploit_raw_packets)
+        exploit_raw_packets = RawPcapReader(self.template_scan_pcap_path)
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
 
+        source_origin_wins, destination_origin_wins = {}, {}
+
         for pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
@@ -157,12 +181,24 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 ip_pkt.setfieldval("ttl", source_ttl_value)
                 # TCP
                 tcp_pkt.setfieldval("sport",port_source)
+                ## Window Size
+                source_origin_win = tcp_pkt.getfieldval("window")
+                if source_origin_win not in source_origin_wins:
+                    source_origin_wins[source_origin_win] = source_win_prob_dict.random()
+                new_win = source_origin_wins[source_origin_win]
+                tcp_pkt.setfieldval("window", new_win)
+                ## MSS
+                tcp_options = tcp_pkt.getfieldval("options")
+                if tcp_options:
+                    if tcp_options[0][0] == "MSS":
+                        tcp_options [0] = ("MSS",mss_value)
+                        tcp_pkt.setfieldval("options", tcp_options)
 
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 new_pkt.time = timestamp_next_pkt
 
                 pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]#float(timeSteps.random())
             # Reply
             else:
                 # Ether
@@ -174,9 +210,21 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 ip_pkt.setfieldval("ttl", destination_ttl_value)
                 # TCP
                 tcp_pkt.setfieldval("dport", port_source)
+                ## Window Size
+                destination_origin_win = tcp_pkt.getfieldval("window")
+                if destination_origin_win not in destination_origin_wins:
+                    destination_origin_wins[destination_origin_win] = destination_win_prob_dict.random()
+                new_win = destination_origin_wins[destination_origin_win]
+                tcp_pkt.setfieldval("window", new_win)
+                ## MSS
+                tcp_options = tcp_pkt.getfieldval("options")
+                if tcp_options:
+                    if tcp_options[0][0] == "MSS":
+                        tcp_options[0] = ("MSS", mss_value)
+                        tcp_pkt.setfieldval("options", tcp_options)
 
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps) + 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
 
             packets.append(new_pkt)
@@ -184,7 +232,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
         # Inject EternalBlue exploit packets
         # Read Win7_eternalblue_exploit pcap file
-        exploit_raw_packets = RawPcapReader("resources/Win7_eternalblue_exploit.pcap")
+        exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
         # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
@@ -196,8 +244,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
             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)
+            inter_arrival_times = self.get_inter_arrival_time(conv_pkts)
 
             if conv_index == len(orderList_conversations) - 2:  # Not the last conversation
                 timestamp_next_pkt = packets[-1].time + uniform(0.001,0.01)
@@ -224,11 +271,24 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         ip_pkt.setfieldval("ttl", source_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("sport", port_source)
+                        ## Window Size
+                        source_origin_win = tcp_pkt.getfieldval("window")
+                        if source_origin_win not in source_origin_wins:
+                            source_origin_wins[source_origin_win] = source_win_prob_dict.random()
+                        new_win = source_origin_wins[source_origin_win]
+                        tcp_pkt.setfieldval("window", new_win)
+                        ## MSS
+                        tcp_options = tcp_pkt.getfieldval("options")
+                        if tcp_options:
+                            if tcp_options[0][0] == "MSS":
+                                tcp_options[0] = ("MSS", mss_value)
+                                tcp_pkt.setfieldval("options", tcp_options)
+
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt.time = timestamp_next_pkt
 
                         pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num] #float(timeSteps.random())
 
                     # Reply
                     else:
@@ -241,10 +301,23 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         ip_pkt.setfieldval("ttl", destination_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("dport", port_source)
+                        ## Window Size
+                        destination_origin_win = tcp_pkt.getfieldval("window")
+                        if destination_origin_win not in destination_origin_wins:
+                            destination_origin_wins[destination_origin_win] = destination_win_prob_dict.random()
+                        new_win = destination_origin_wins[destination_origin_win]
+                        tcp_pkt.setfieldval("window", new_win)
+                        ## MSS
+                        tcp_options = tcp_pkt.getfieldval("options")
+                        if tcp_options:
+                            if tcp_options[0][0] == "MSS":
+                                tcp_options[0] = ("MSS", mss_value)
+                                tcp_pkt.setfieldval("options", tcp_options)
+
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
                         pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]#float(timeSteps.random())
 
                         new_pkt.time = timestamp_next_pkt
 
@@ -258,8 +331,6 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                     ip_pkt = eth_frame.payload
                     tcp_pkt = ip_pkt.payload
 
-                    # defining req/rep should be adapted to fit the last converstaion where
-                    # victim start a connection with the attacker
                     # Request
                     if tcp_pkt.getfieldval("dport") == self.last_conn_dst_port:
                         # Ether
@@ -271,11 +342,24 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         ip_pkt.setfieldval("ttl", destination_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("sport", port_source)
+                        ## Window Size
+                        destination_origin_win = tcp_pkt.getfieldval("window")
+                        if destination_origin_win not in destination_origin_wins:
+                            destination_origin_wins[destination_origin_win] = destination_win_prob_dict.random()
+                        new_win = destination_origin_wins[destination_origin_win]
+                        tcp_pkt.setfieldval("window", new_win)
+                        ## MSS
+                        tcp_options = tcp_pkt.getfieldval("options")
+                        if tcp_options:
+                            if tcp_options[0][0] == "MSS":
+                                tcp_options[0] = ("MSS", mss_value)
+                                tcp_pkt.setfieldval("options", tcp_options)
+
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                         new_pkt.time = timestamp_next_pkt
 
                         pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]# float(timeSteps.random())
 
                     # Reply
                     else:
@@ -288,10 +372,23 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         ip_pkt.setfieldval("ttl", source_ttl_value)
                         # TCP
                         tcp_pkt.setfieldval("dport", port_source)
+                        ## Window Size
+                        source_origin_win = tcp_pkt.getfieldval("window")
+                        if source_origin_win not in source_origin_wins:
+                            source_origin_wins[source_origin_win] = source_win_prob_dict.random()
+                        new_win = source_origin_wins[source_origin_win]
+                        tcp_pkt.setfieldval("window", new_win)
+                        ## MSS
+                        tcp_options = tcp_pkt.getfieldval("options")
+                        if tcp_options:
+                            if tcp_options[0][0] == "MSS":
+                                tcp_options[0] = ("MSS", mss_value)
+                                tcp_pkt.setfieldval("options", tcp_options)
+
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
                         pps = max(getIntervalPPS(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) + inter_arrival_times[pkt_num]# float(timeSteps.random())
 
                         new_pkt.time = timestamp_next_pkt
 

+ 1 - 1
code/Attack/JoomlaRegPrivExploit.py

@@ -139,7 +139,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         # Read joomla_registration_privesc pcap file
         orig_ip_dst = None
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
-        inter_arrival_time_dist = self.get_inter_arrival_time_dist(exploit_raw_packets)
+        inter_arrival_times, inter_arrival_time_dist = self.get_inter_arrival_time(exploit_raw_packets,True)
         timeSteps = Lea.fromValFreqsDict(inter_arrival_time_dist)
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 

+ 1 - 1
code/Attack/SQLiAttack.py

@@ -137,7 +137,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         # Read SQLi Attack pcap file
         orig_ip_dst = None
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
-        inter_arrival_time_dist = self.get_inter_arrival_time_dist(exploit_raw_packets)
+        inter_arrival_times, inter_arrival_time_dist = self.get_inter_arrival_time(exploit_raw_packets,True)
         timeSteps = Lea.fromValFreqsDict(inter_arrival_time_dist)
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 

+ 11 - 10
code_boost/src/cxx/pcap_processor.cpp

@@ -114,7 +114,7 @@ void pcap_processor::collect_statistics() {
         FileSniffer snifferOverview(filePath);
         
         SnifferIterator i = sniffer.begin();                
-        Tins::Timestamp lastProcessedPacket;
+        std::chrono::microseconds currentPktTimestamp;
 
         // Save timestamp of first packet
         stats.setTimestampFirstPacket(i->timestamp());
@@ -140,23 +140,24 @@ void pcap_processor::collect_statistics() {
 
         // Iterate over all packets and collect statistics
         for (; i != sniffer.end(); i++) {
-            std::chrono::microseconds lastPktTimestamp = i->timestamp();
-            std::chrono::microseconds currentCaptureDuration = lastPktTimestamp - firstTimestamp;
+            currentPktTimestamp = i->timestamp();
+            std::chrono::microseconds currentDuration = currentPktTimestamp - firstTimestamp;
 
             // For each interval
-            if(currentCaptureDuration>barrier && barrier.count() > 0){ // TO-DO: ensure this case does not happen: barrier becomes negative in last interval
-                stats.addIntervalStat(timeInterval, intervalStartTimestamp, lastPktTimestamp);
+            if(currentDuration>barrier){
+                stats.addIntervalStat(timeInterval, intervalStartTimestamp, currentPktTimestamp);
                 timeIntervalCounter++;
-                barrier =  barrier+timeInterval;
-                intervalStartTimestamp = lastPktTimestamp;
+
+                barrier =  barrier + timeInterval;
+                intervalStartTimestamp = currentPktTimestamp;
             }
+
             stats.incrementPacketCount();
-            this->process_packets(*i);                    
-            lastProcessedPacket = i->timestamp();
+            this->process_packets(*i);
         }
         
         // Save timestamp of last packet into statistics
-        stats.setTimestampLastPacket(lastProcessedPacket);
+        stats.setTimestampLastPacket(currentPktTimestamp);
     }
 }