|
@@ -13,7 +13,8 @@ from scapy.utils import RawPcapReader
|
|
from scapy.layers.inet import IP, Ether, TCP, RandShort
|
|
from scapy.layers.inet import IP, Ether, TCP, RandShort
|
|
|
|
|
|
class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
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
|
|
smb_port = 445
|
|
smb_port = 445
|
|
# Empirical values from Metasploit experiments
|
|
# Empirical values from Metasploit experiments
|
|
@@ -51,25 +52,27 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
"""
|
|
"""
|
|
# PARAMETERS: initialize with default utilsvalues
|
|
# PARAMETERS: initialize with default utilsvalues
|
|
# (values are overwritten if user specifies them)
|
|
# (values are overwritten if user specifies them)
|
|
|
|
+ # Attacker configuration
|
|
most_used_ip_address = self.statistics.get_most_used_ip_address()
|
|
most_used_ip_address = self.statistics.get_most_used_ip_address()
|
|
if isinstance(most_used_ip_address, list):
|
|
if isinstance(most_used_ip_address, list):
|
|
most_used_ip_address = most_used_ip_address[0]
|
|
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()
|
|
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:
|
|
if isinstance(destination_mac, list) and len(destination_mac) == 0:
|
|
destination_mac = self.generate_random_mac_address()
|
|
destination_mac = self.generate_random_mac_address()
|
|
self.add_param_value(Param.MAC_DESTINATION, destination_mac)
|
|
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 generate_attack_pcap(self):
|
|
def update_timestamp(timestamp, pps):
|
|
def update_timestamp(timestamp, pps):
|
|
"""
|
|
"""
|
|
@@ -127,16 +130,37 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
else:
|
|
else:
|
|
destination_ttl_value = self.statistics.process_db_query("most_used(ttlValue)")
|
|
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
|
|
# Scan (MS17) for EternalBlue
|
|
- # Read Win7_eternalblue_scan_vulnerable pcap file
|
|
|
|
|
|
+ # Read Win7_eternalblue_scan pcap file
|
|
orig_ip_dst = None
|
|
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
|
|
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):
|
|
for pkt_num, pkt in enumerate(exploit_raw_packets):
|
|
eth_frame = Ether(pkt[0])
|
|
eth_frame = Ether(pkt[0])
|
|
ip_pkt = eth_frame.payload
|
|
ip_pkt = eth_frame.payload
|
|
@@ -157,12 +181,24 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
ip_pkt.setfieldval("ttl", source_ttl_value)
|
|
ip_pkt.setfieldval("ttl", source_ttl_value)
|
|
# TCP
|
|
# TCP
|
|
tcp_pkt.setfieldval("sport",port_source)
|
|
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 = (eth_frame / ip_pkt / tcp_pkt)
|
|
new_pkt.time = timestamp_next_pkt
|
|
new_pkt.time = timestamp_next_pkt
|
|
|
|
|
|
pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
|
|
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
|
|
# Reply
|
|
else:
|
|
else:
|
|
# Ether
|
|
# Ether
|
|
@@ -174,9 +210,21 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
ip_pkt.setfieldval("ttl", destination_ttl_value)
|
|
ip_pkt.setfieldval("ttl", destination_ttl_value)
|
|
# TCP
|
|
# TCP
|
|
tcp_pkt.setfieldval("dport", port_source)
|
|
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)
|
|
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
|
|
new_pkt.time = timestamp_next_pkt
|
|
|
|
|
|
packets.append(new_pkt)
|
|
packets.append(new_pkt)
|
|
@@ -184,7 +232,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
|
|
|
|
# Inject EternalBlue exploit packets
|
|
# Inject EternalBlue exploit packets
|
|
# Read Win7_eternalblue_exploit pcap file
|
|
# 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
|
|
port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
|
|
# conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
|
|
# conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
|
|
@@ -196,8 +244,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
timestamp_next_pkt = conv_start_timesamp
|
|
timestamp_next_pkt = conv_start_timesamp
|
|
|
|
|
|
conv_pkts = conversations[conv]
|
|
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
|
|
if conv_index == len(orderList_conversations) - 2: # Not the last conversation
|
|
timestamp_next_pkt = packets[-1].time + uniform(0.001,0.01)
|
|
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)
|
|
ip_pkt.setfieldval("ttl", source_ttl_value)
|
|
# TCP
|
|
# TCP
|
|
tcp_pkt.setfieldval("sport", port_source)
|
|
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 = (eth_frame / ip_pkt / tcp_pkt)
|
|
new_pkt.time = timestamp_next_pkt
|
|
new_pkt.time = timestamp_next_pkt
|
|
|
|
|
|
pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
|
|
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
|
|
# Reply
|
|
else:
|
|
else:
|
|
@@ -241,10 +301,23 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
ip_pkt.setfieldval("ttl", destination_ttl_value)
|
|
ip_pkt.setfieldval("ttl", destination_ttl_value)
|
|
# TCP
|
|
# TCP
|
|
tcp_pkt.setfieldval("dport", port_source)
|
|
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)
|
|
new_pkt = (eth_frame / ip_pkt / tcp_pkt)
|
|
|
|
|
|
pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
|
|
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
|
|
new_pkt.time = timestamp_next_pkt
|
|
|
|
|
|
@@ -258,8 +331,6 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
ip_pkt = eth_frame.payload
|
|
ip_pkt = eth_frame.payload
|
|
tcp_pkt = ip_pkt.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
|
|
# Request
|
|
if tcp_pkt.getfieldval("dport") == self.last_conn_dst_port:
|
|
if tcp_pkt.getfieldval("dport") == self.last_conn_dst_port:
|
|
# Ether
|
|
# Ether
|
|
@@ -271,11 +342,24 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
ip_pkt.setfieldval("ttl", destination_ttl_value)
|
|
ip_pkt.setfieldval("ttl", destination_ttl_value)
|
|
# TCP
|
|
# TCP
|
|
tcp_pkt.setfieldval("sport", port_source)
|
|
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 = (eth_frame / ip_pkt / tcp_pkt)
|
|
new_pkt.time = timestamp_next_pkt
|
|
new_pkt.time = timestamp_next_pkt
|
|
|
|
|
|
pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
|
|
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
|
|
# Reply
|
|
else:
|
|
else:
|
|
@@ -288,10 +372,23 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
ip_pkt.setfieldval("ttl", source_ttl_value)
|
|
ip_pkt.setfieldval("ttl", source_ttl_value)
|
|
# TCP
|
|
# TCP
|
|
tcp_pkt.setfieldval("dport", port_source)
|
|
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)
|
|
new_pkt = (eth_frame / ip_pkt / tcp_pkt)
|
|
|
|
|
|
pps = max(getIntervalPPS(complement_interval_pps, timestamp_next_pkt), 10)
|
|
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
|
|
new_pkt.time = timestamp_next_pkt
|
|
|
|
|