|
@@ -0,0 +1,184 @@
|
|
|
+import logging
|
|
|
+from random import randint, uniform
|
|
|
+
|
|
|
+from lea import Lea
|
|
|
+
|
|
|
+from Attack import BaseAttack
|
|
|
+from Attack.AttackParameters import Parameter as Param
|
|
|
+from Attack.AttackParameters import ParameterTypes
|
|
|
+
|
|
|
+logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
|
|
|
+
|
|
|
+from scapy.utils import RawPcapReader
|
|
|
+from scapy.layers.inet import IP, Ether, TCP, RandShort
|
|
|
+
|
|
|
+class EternalBlueExploit(BaseAttack.BaseAttack):
|
|
|
+ def __init__(self, statistics, pcap_file_path):
|
|
|
+ """
|
|
|
+ Creates a new instance of the EternalBlue Exploit.
|
|
|
+
|
|
|
+ :param statistics: A reference to the statistics class.
|
|
|
+ """
|
|
|
+
|
|
|
+ super(EternalBlueExploit, self).__init__(statistics, "EternalBlue Exploit", "Injects an EternalBlue exploit'",
|
|
|
+ "Resource Exhaustion")
|
|
|
+
|
|
|
+
|
|
|
+ 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,
|
|
|
+ Param.INJECT_AFTER_PACKET: ParameterTypes.TYPE_PACKET_POSITION,
|
|
|
+ Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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.PORT_SOURCE, str(RandShort()))
|
|
|
+ self.add_param_value(Param.PACKETS_PER_SECOND, randint(1, 64))
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ random_ip_address = self.statistics.get_random_ip_address()
|
|
|
+ self.add_param_value(Param.IP_DESTINATION, random_ip_address)
|
|
|
+
|
|
|
+ destination_mac = self.statistics.get_mac_address(random_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)
|
|
|
+
|
|
|
+ def generate_attack_pcap(self):
|
|
|
+ def update_timestamp(timestamp, pps, maxdelay):
|
|
|
+ """
|
|
|
+ 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(0.1 / pps, maxdelay)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
|
|
|
+
|
|
|
+ pps = self.get_param_value(Param.PACKETS_PER_SECOND)
|
|
|
+ randomdelay = Lea.fromValFreqsDict({1 / pps: 70, 2 / pps: 30, 5 / pps: 15, 10 / pps: 3})
|
|
|
+
|
|
|
+
|
|
|
+ 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)
|
|
|
+
|
|
|
+ path_attack_pcap = None
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ orig_ip_dst = None
|
|
|
+ exploit_raw_packets = RawPcapReader("Win7_eternalblue_scan.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")
|
|
|
+
|
|
|
+
|
|
|
+ if ip_pkt.getfieldval("dst") == orig_ip_dst:
|
|
|
+
|
|
|
+ eth_frame.setfieldval("src", mac_source)
|
|
|
+ eth_frame.setfieldval("dst", mac_destination)
|
|
|
+
|
|
|
+ ip_pkt.setfieldval("src", ip_source)
|
|
|
+ ip_pkt.setfieldval("dst", ip_destination)
|
|
|
+
|
|
|
+ tcp_pkt.setfieldval("sport",port_source)
|
|
|
+
|
|
|
+ else:
|
|
|
+
|
|
|
+ eth_frame.setfieldval("src", mac_destination)
|
|
|
+ eth_frame.setfieldval("dst", mac_source)
|
|
|
+
|
|
|
+ ip_pkt.setfieldval("src", ip_destination)
|
|
|
+ ip_pkt.setfieldval("dst", ip_source)
|
|
|
+
|
|
|
+ tcp_pkt.setfieldval("dport", port_source)
|
|
|
+
|
|
|
+ new_pkt = (eth_frame / ip_pkt / tcp_pkt)
|
|
|
+
|
|
|
+ new_pkt.time = timestamp_next_pkt
|
|
|
+
|
|
|
+ packets.append(new_pkt)
|
|
|
+
|
|
|
+ maxdelay = randomdelay.random()
|
|
|
+ timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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")
|
|
|
+
|
|
|
+
|
|
|
+ if ip_pkt.getfieldval("dst") == orig_ip_dst:
|
|
|
+
|
|
|
+ eth_frame.setfieldval("src", mac_source)
|
|
|
+ eth_frame.setfieldval("dst", mac_destination)
|
|
|
+
|
|
|
+ ip_pkt.setfieldval("src", ip_source)
|
|
|
+ ip_pkt.setfieldval("dst", ip_destination)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ else:
|
|
|
+
|
|
|
+ eth_frame.setfieldval("src", mac_destination)
|
|
|
+ eth_frame.setfieldval("dst", mac_source)
|
|
|
+
|
|
|
+ ip_pkt.setfieldval("src", ip_destination)
|
|
|
+ ip_pkt.setfieldval("dst", ip_source)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ new_pkt = (eth_frame / ip_pkt / tcp_pkt)
|
|
|
+
|
|
|
+ new_pkt.time = timestamp_next_pkt
|
|
|
+
|
|
|
+ packets.append(new_pkt)
|
|
|
+
|
|
|
+ maxdelay = randomdelay.random()
|
|
|
+ timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, maxdelay)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ self.attack_start_utime = packets[0].time
|
|
|
+ self.attack_end_utime = packets[-1].time
|
|
|
+
|
|
|
+ if len(packets) > 0:
|
|
|
+ packets = sorted(packets, key=lambda pkt: pkt.time)
|
|
|
+ path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ return pkt_num + 1, path_attack_pcap
|