Browse Source

Fix issues in EnternalBlueExploit, Small changes in PortscanAttack

aidmar.wainakh 6 years ago
parent
commit
162743ca9e
4 changed files with 349 additions and 100 deletions
  1. 13 0
      code/Attack/BaseAttack.py
  2. 214 53
      code/Attack/EternalBlueExploit.py
  3. 2 14
      code/Attack/PortscanAttack.py
  4. 120 33
      code/ID2TLib/Statistics.py

+ 13 - 0
code/Attack/BaseAttack.py

@@ -4,6 +4,7 @@ import random
 import re
 import tempfile
 from abc import abstractmethod, ABCMeta
+import numpy as np
 
 import ID2TLib.libpcapreader as pr
 from scapy.utils import PcapWriter
@@ -460,3 +461,15 @@ class BaseAttack(metaclass=ABCMeta):
             return mac_addresses[0]
         else:
             return mac_addresses
+
+
+    # Aidmar
+    def get_reply_delay(self, ip_dst):
+        replyDelay = self.statistics.process_db_query(
+         "SELECT avgDelay FROM conv_statistics WHERE ipAddressB='" + ip_dst + "' LIMIT 1")
+        if not replyDelay:
+            allDelays = self.statistics.process_db_query("SELECT avgDelay FROM conv_statistics")
+            replyDelay = np.median(allDelays)
+        replyDelay = int(replyDelay) * 10 ** -6 # convert from micro to seconds
+        #print(replyDelay)
+        return replyDelay

+ 214 - 53
code/Attack/EternalBlueExploit.py

@@ -1,4 +1,9 @@
+# Created by Aidmar
+
 import logging
+import math
+from operator import itemgetter
+import operator
 from random import randint, uniform
 
 from lea import Lea
@@ -13,6 +18,16 @@ 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
+    # SMB port
+    smb_port = 445
+    # Metasploit experiments show this range of ports
+    minDefaultPort = 30000
+    maxDefaultPort = 50000
+    last_conn_dst_port = 4444
+
     def __init__(self, statistics, pcap_file_path):
         """
         Creates a new instance of the EternalBlue Exploit.
@@ -27,7 +42,7 @@ 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.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,
@@ -43,8 +58,8 @@ 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, randint(1, 64))
+        #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
@@ -63,7 +78,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
             :return: Timestamp to be used for the next packet.
             """
-            return timestamp + uniform(0.1 / pps, maxdelay)
+            return timestamp + uniform(1 / pps, maxdelay)
 
 
         # Timestamp
@@ -72,32 +87,70 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         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 the complement packet rates of the background traffic packet rates per interval
+        result = self.statistics.process_db_query(
+            "SELECT timestamp,pktsCount FROM interval_statistics ORDER BY timestamp")
+        print(result)
+        bg_interval_pps = []
+        intervalsSum = 0
+        if result:
+            # Get the interval in seconds
+            for i, row in enumerate(result):
+                if i < len(result) - 1:
+                    intervalsSum += math.ceil((int(result[i + 1][0]) * 10 ** -6) - (int(row[0]) * 10 ** -6))
+            interval = intervalsSum / (len(result) - 1)
+            # Convert timestamp from micro to seconds, convert packet rate "per interval" to "per second"
+            for row in result:
+                bg_interval_pps.append((int(row[0]) * 10 ** -6, int(row[1] / interval)))
+            # Find max PPS
+            maxPPS = max(bg_interval_pps, key=itemgetter(1))[1]
+            complement_interval_pps = []
+            for row in bg_interval_pps:
+                complement_interval_pps.append((row[0], int(pps * (maxPPS - row[1]) / maxPPS)))
+            print(complement_interval_pps)
+
+        def getIntervalPPS(timestamp):
+            for row in complement_interval_pps:
+                if timestamp <= row[0]:
+                    return row[1]
+            return complement_interval_pps[-1][1]  # in case the timstamp > capture max timestamp
+
         # 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)
+        #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
+        if ip_source == ip_destination:
+            print("\nERROR: Invalid IP addresses; source IP is the same as destination IP: " + ip_source + ".")
+            import sys
+            sys.exit(0)
+
         path_attack_pcap = None
+        replayDelay = self.get_reply_delay(ip_destination)
 
         # Scan (MS17) for EternalBlue
         # Read Win7_eternalblue_scan_vulnerable pcap file
         orig_ip_dst = None
         exploit_raw_packets = RawPcapReader("Win7_eternalblue_scan.pcap")
+
+        port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
+
         for pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
 
-            smb_port = 445
             if pkt_num == 0:
-                if tcp_pkt.getfieldval("dport") == smb_port:
-                    orig_ip_dst = ip_pkt.getfieldval("dst")
+                if tcp_pkt.getfieldval("dport") == self.smb_port:
+                    orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP
 
             # Request
-            if ip_pkt.getfieldval("dst") == orig_ip_dst:
+            if ip_pkt.getfieldval("dst") == orig_ip_dst: # victim IP
                 # Ether
                 eth_frame.setfieldval("src", mac_source)
                 eth_frame.setfieldval("dst", mac_destination)
@@ -106,6 +159,14 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 ip_pkt.setfieldval("dst", ip_destination)
                 # TCP
                 tcp_pkt.setfieldval("sport",port_source)
+
+                new_pkt = (eth_frame / ip_pkt / tcp_pkt)
+                new_pkt.time = timestamp_next_pkt
+
+                maxdelay = randomdelay.random()
+                pps = self.minDefaultPPS if getIntervalPPS(timestamp_next_pkt) is None else max(
+                    getIntervalPPS(timestamp_next_pkt), self.minDefaultPPS)
+                timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
             # Reply
             else:
                 # Ether
@@ -117,58 +178,158 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                 # TCP
                 tcp_pkt.setfieldval("dport", port_source)
 
-            new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-            # TO-DO: reply should have different timestamp delay
-            new_pkt.time = timestamp_next_pkt
+                new_pkt = (eth_frame / ip_pkt / tcp_pkt)
+                timestamp_next_pkt = timestamp_next_pkt + uniform(replayDelay, 2 * replayDelay)
+                new_pkt.time = timestamp_next_pkt
 
             packets.append(new_pkt)
 
-            maxdelay = randomdelay.random()
-            timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
-
 
         # Inject EternalBlue exploit packets
         # Read Win7_eternalblue_exploit pcap file
         exploit_raw_packets = RawPcapReader("Win7_eternalblue_exploit.pcap")
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
-            eth_frame = Ether(pkt[0])
-            ip_pkt = eth_frame.payload
-            tcp_pkt = ip_pkt.payload
-
-            smb_port = 445
-            if pkt_num == 0:
-                if tcp_pkt.getfieldval("dport") == smb_port:
-                    orig_ip_dst = ip_pkt.getfieldval("dst")
-
-            # Request
-            if ip_pkt.getfieldval("dst") == orig_ip_dst:
-                # Ether
-                eth_frame.setfieldval("src", mac_source)
-                eth_frame.setfieldval("dst", mac_destination)
-                # IP
-                ip_pkt.setfieldval("src", ip_source)
-                ip_pkt.setfieldval("dst", ip_destination)
-                # TCP
-                #tcp_pkt.setfieldval("sport", port_source)
-            # Reply
-            else:
-                # Ether
-                eth_frame.setfieldval("src", mac_destination)
-                eth_frame.setfieldval("dst", mac_source)
-                # IP
-                ip_pkt.setfieldval("src", ip_destination)
-                ip_pkt.setfieldval("dst", ip_source)
-                # TCP
-                #tcp_pkt.setfieldval("dport", port_source)
-
-            new_pkt = (eth_frame / ip_pkt / tcp_pkt)
-            # TO-DO: reply should have different timestamp delay
-            new_pkt.time = timestamp_next_pkt
-
-            packets.append(new_pkt)
 
-            maxdelay = randomdelay.random()
-            timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
+        # 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)
+
+        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]
+
+        for conv_index, conv in enumerate(orderList_conversations):
+            conv_pkts = conversations[conv]
+            if conv_index != len(orderList_conversations)-1: # Not the last conversation
+                port_source += 2
+                for pkt_num, pkt in enumerate(conv_pkts):
+                    eth_frame = Ether(pkt[0])
+                    ip_pkt = eth_frame.payload
+                    tcp_pkt = ip_pkt.payload
+
+                    if pkt_num == 0:
+                        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
+                    # Request
+                    if ip_pkt.getfieldval("dst") == orig_ip_dst: # victim IP
+                        # Ether
+                        eth_frame.setfieldval("src", mac_source)
+                        eth_frame.setfieldval("dst", mac_destination)
+                        # IP
+                        ip_pkt.setfieldval("src", ip_source)
+                        ip_pkt.setfieldval("dst", ip_destination)
+                        # 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(timestamp_next_pkt) is None else max(
+                            getIntervalPPS(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:
+                        # Ether
+                        eth_frame.setfieldval("src", mac_destination)
+                        eth_frame.setfieldval("dst", mac_source)
+                        # IP
+                        ip_pkt.setfieldval("src", ip_destination)
+                        ip_pkt.setfieldval("dst", ip_source)
+                        # TCP
+                        tcp_pkt.setfieldval("dport", port_source)
+                        new_pkt = (eth_frame / ip_pkt / tcp_pkt)
+                        timestamp_next_pkt = timestamp_next_pkt + uniform(replayDelay, 2 * replayDelay)
+                        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
+                port_source = randint(self.minDefaultPort,self.maxDefaultPort)
+                for pkt_num, pkt in enumerate(conv_pkts):
+                    eth_frame = Ether(pkt[0])
+                    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
+                        eth_frame.setfieldval("src", mac_destination)
+                        eth_frame.setfieldval("dst", mac_source)
+                        # IP
+                        ip_pkt.setfieldval("src", ip_destination)
+                        ip_pkt.setfieldval("dst", ip_source)
+                        # 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(timestamp_next_pkt) is None else max(
+                            getIntervalPPS(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:
+                        # Ether
+                        eth_frame.setfieldval("src", mac_source)
+                        eth_frame.setfieldval("dst", mac_destination)
+                        # IP
+                        ip_pkt.setfieldval("src", ip_source)
+                        ip_pkt.setfieldval("dst", ip_destination)
+                        # TCP
+                        tcp_pkt.setfieldval("dport", port_source)
+                        new_pkt = (eth_frame / ip_pkt / tcp_pkt)
+                        timestamp_next_pkt = timestamp_next_pkt + uniform(replayDelay, 2 * replayDelay)
+                        new_pkt.time = timestamp_next_pkt
+                        # Not perfect timestamp
+                        # rep_time = req_time + replayDelay
+
+                    packets.append(new_pkt)
 
 
         # Store timestamp of first packet (for attack label)

+ 2 - 14
code/Attack/PortscanAttack.py

@@ -5,7 +5,6 @@ import socket
 # Aidmar
 from operator import itemgetter
 import math
-import numpy as np
 
 from random import shuffle, randint, choice, uniform
 
@@ -66,16 +65,6 @@ class PortscanAttack(BaseAttack.BaseAttack):
         except socket.error:
             return False
 
-    def get_reply_delay(self, ip_dst):
-        replyDelay = self.statistics.process_db_query(
-         "SELECT avgDelay FROM conv_statistics WHERE ipAddressB='" + ip_dst + "' LIMIT 1")
-        if not replyDelay:
-            allDelays = self.statistics.process_db_query("SELECT avgDelay FROM conv_statistics")
-            replyDelay = np.median(allDelays)
-        replyDelay = int(replyDelay) * 10 ** -6 # convert from micro to seconds
-        print(replyDelay)
-        return replyDelay
-
 
     def __init__(self, statistics, pcap_file_path):
         """
@@ -276,7 +265,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
 
         for dport in dest_ports:
             # Aidmar - move to here to generate different maxdelay for each packet
-            randomdelay = Lea.fromValFreqsDict({1 / pps: 85, 2 / pps: 10, 5 / pps: 5})
+            randomdelay = Lea.fromValFreqsDict({1 / pps: 85, 2 / pps: 10, 5 / pps: 5}) # TO-DO: is it perfect? here?
             maxdelay = randomdelay.random()
 
             # Parameters changing each iteration
@@ -326,7 +315,6 @@ class PortscanAttack(BaseAttack.BaseAttack):
                 B_A_packets.append(reply)
 
                 # requester confirms
-                # TO-DO: confirms should be in Attacker queue not in victim (reply) queue
                 confirm_ether = request_ether
                 confirm_ip = request_ip
                 confirm_tcp = TCP(sport=sport, dport=dport, seq=1, window=0, flags='R')
@@ -358,7 +346,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
             packets.append(request)
 
             # Aidmar
-            pps = self.minDefaultPPS if getIntervalPPS(timestamp_next_pkt) is None else max(getIntervalPPS(timestamp_next_pkt),1) # avoid case of pps = 0
+            pps = self.minDefaultPPS if getIntervalPPS(timestamp_next_pkt) is None else max(getIntervalPPS(timestamp_next_pkt),self.minDefaultPPS) # avoid case of pps = 0
             timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
 
         # In case all requests are already sent, send all replies and confirms

+ 120 - 33
code/ID2TLib/Statistics.py

@@ -501,6 +501,117 @@ class Statistics:
             plt.savefig(out, dpi=500)
             return out
 
+        # Aidmar
+        def plot_interval_ip_src_ent(file_ending: str):
+            plt.gcf().clear()
+            result = self.stats_db._process_user_defined_query(
+                "SELECT timestamp, ipSrcEntropy FROM interval_statistics ORDER BY timestamp")
+            graphx, graphy = [], []
+            for row in result:
+                graphx.append(row[0])
+                graphy.append(row[1])
+            plt.autoscale(enable=True, axis='both')
+            plt.title("Source IP Entropy")
+            plt.xlabel('Timestamp')
+            plt.ylabel('Entropy')
+            width = 0.5
+            plt.xlim([0, len(graphx)])
+            plt.grid(True)
+
+            # IPs on x-axis
+            x = range(0, len(graphx))
+            my_xticks = graphx
+            plt.xticks(x, my_xticks, rotation='vertical', fontsize=5)
+            plt.tight_layout()
+
+            plt.bar(x, graphy, width, align='center', linewidth=2, color='red', edgecolor='red')
+            out = self.pcap_filepath.replace('.pcap', '_plot-interval-ip-src-ent' + file_ending)
+            plt.savefig(out, dpi=500)
+            return out
+
+        # Aidmar
+        def plot_interval_ip_dst_ent(file_ending: str):
+            plt.gcf().clear()
+            result = self.stats_db._process_user_defined_query(
+                "SELECT timestamp, ipDstEntropy FROM interval_statistics ORDER BY timestamp")
+            graphx, graphy = [], []
+            for row in result:
+                graphx.append(row[0])
+                graphy.append(row[1])
+            plt.autoscale(enable=True, axis='both')
+            plt.title("Destination IP Entropy")
+            plt.xlabel('Timestamp')
+            plt.ylabel('Entropy')
+            width = 0.5
+            plt.xlim([0, len(graphx)])
+            plt.grid(True)
+
+            # IPs on x-axis
+            x = range(0, len(graphx))
+            my_xticks = graphx
+            plt.xticks(x, my_xticks, rotation='vertical', fontsize=5)
+            plt.tight_layout()
+
+            plt.bar(x, graphy, width, align='center', linewidth=2, color='red', edgecolor='red')
+            out = self.pcap_filepath.replace('.pcap', '_plot-interval-ip-dst-ent' + file_ending)
+            plt.savefig(out, dpi=500)
+            return out
+
+        # Aidmar
+        def plot_interval_ip_dst_cum_ent(file_ending: str):
+            plt.gcf().clear()
+            result = self.stats_db._process_user_defined_query(
+                "SELECT timestamp, ipDstCumEntropy FROM interval_statistics ORDER BY timestamp")
+            graphx, graphy = [], []
+            for row in result:
+                graphx.append(row[0])
+                graphy.append(row[1])
+            plt.autoscale(enable=True, axis='both')
+            plt.title("Destination IP Cumulative Entropy")
+            plt.xlabel('Timestamp')
+            plt.ylabel('Entropy')
+            width = 0.5
+            plt.xlim([0, len(graphx)])
+            plt.grid(True)
+
+            # IPs on x-axis
+            x = range(0, len(graphx))
+            my_xticks = graphx
+            plt.xticks(x, my_xticks, rotation='vertical', fontsize=5)
+            plt.tight_layout()
+
+            plt.plot(x, graphy, 'r')
+            out = self.pcap_filepath.replace('.pcap', '_plot-interval-ip-dst-cum-ent' + file_ending)
+            plt.savefig(out, dpi=500)
+            return out
+
+        # Aidmar
+        def plot_interval_ip_src_cum_ent(file_ending: str):
+            plt.gcf().clear()
+            result = self.stats_db._process_user_defined_query(
+                "SELECT timestamp, ipSrcCumEntropy FROM interval_statistics ORDER BY timestamp")
+            graphx, graphy = [], []
+            for row in result:
+                graphx.append(row[0])
+                graphy.append(row[1])
+            plt.autoscale(enable=True, axis='both')
+            plt.title("Source IP Cumulative Entropy")
+            plt.xlabel('Timestamp')
+            plt.ylabel('Entropy')
+            width = 0.5
+            plt.xlim([0, len(graphx)])
+            plt.grid(True)
+
+            # IPs on x-axis
+            x = range(0, len(graphx))
+            my_xticks = graphx
+            plt.xticks(x, my_xticks, rotation='vertical', fontsize=5)
+            plt.tight_layout()
+
+            plt.plot(x, graphy, 'r')
+            out = self.pcap_filepath.replace('.pcap', '_plot-interval-ip-src-cum-ent' + file_ending)
+            plt.savefig(out, dpi=500)
+            return out
 
         ttl_out_path = plot_ttl('.' + format)
         mss_out_path = plot_mss('.' + format)
@@ -511,42 +622,18 @@ class Statistics:
         ip_dst_out_path = plot_ip_dst('.' + format)
         ip_dst_out_path = plot_ip_dst('.' + format)
         plot_interval_pktCount = plot_interval_pktCount('.' + format)
-        print("Saved distributions plots at: %s, %s, %s, %s, %s, %s, %s, %s" %(ttl_out_path,mss_out_path, win_out_path,
-        protocol_out_path, port_out_path,ip_src_out_path,ip_dst_out_path, plot_interval_pktCount))
+        plot_interval_ip_src_ent = plot_interval_ip_src_ent('.' + format)
+        plot_interval_ip_dst_ent = plot_interval_ip_dst_ent('.' + format)
+        plot_interval_ip_src_cum_ent = plot_interval_ip_src_cum_ent('.' + format)
+        plot_interval_ip_dst_cum_ent = plot_interval_ip_dst_cum_ent('.' + format)
 
 
-"""
- # Aidmar
-            graphx_aftr, graphy_aftr = [], []
-            ttlValue = self.stats_db._process_user_defined_query(
-                "SELECT ttlValue FROM ip_ttl GROUP BY ttlValue ORDER BY SUM(ttlCount) DESC LIMIT 1")
-            for row in result:
-                if(row[0] == 64):
-                    graphy_aftr.append(row[1]+1000)
-                else:
-                    graphy_aftr.append(row[1])
-                graphx_aftr.append(row[0])
+        #print("Saved distributions plots at: %s, %s, %s, %s, %s, %s, %s, %s %s" %(ttl_out_path,mss_out_path, win_out_path,
+        #protocol_out_path, port_out_path,ip_src_out_path,ip_dst_out_path, plot_interval_pktCount))
 
-            plt.autoscale(enable=False, axis='both')
-            plt.title("TTL Distribution")
-            plt.xlabel('TTL Value')
-            plt.ylabel('Number of Packets')
-            width = 0.5
-            plt.xlim([0, max(graphx_aftr)])
-            # Aidmar
-            plt.ylim([0, 11000])  # temp
-            plt.grid(True)
-            plt.bar(graphx_aftr, graphy_aftr, width, align='center', linewidth=2, color='red', edgecolor='red')
-            out = self.pcap_filepath.replace('.pcap', '_plot-ttl_2' + file_ending)
-            plt.savefig(out)
-
-            print(graphy)
-            print(graphy_aftr)
-            print("\neuclidean distance: "+str(dist.euclidean(graphy, graphy_aftr)))
-            print("\ncityblock distance: " + str(dist.cityblock(graphy, graphy_aftr)))
-            print("\nchebyshev distance: " + str(dist.chebyshev(graphy, graphy_aftr)))
-            print("\nsqeuclidean distance: " + str(dist.sqeuclidean(graphy, graphy_aftr)))
-            print("\nhamming distance: " + str(dist.hamming(graphy, graphy_aftr)))
+
+"""
+ # Aidmar      
 
             # bhattacharyya test
             import math