def get_ip_data(self, ip_address: str): """ :param ip_address: the ip of which (packet-)data shall be returned :return: MSS, TTL and Window Size values of the given IP """ # Set MSS (Maximum Segment Size) based on MSS distribution of IP address mss_dist = self.statistics.get_mss_distribution(ip_address) if len(mss_dist) > 0: mss_prob_dict = lea.Lea.fromValFreqsDict(mss_dist) mss_value = mss_prob_dict.random() else: mss_value = Util.handle_most_used_outputs(self.most_used_mss_value) # Set TTL based on TTL distribution of IP address ttl_dist = self.statistics.get_ttl_distribution(ip_address) if len(ttl_dist) > 0: ttl_prob_dict = lea.Lea.fromValFreqsDict(ttl_dist) ttl_value = ttl_prob_dict.random() else: ttl_value = Util.handle_most_used_outputs(self.most_used_ttl_value) # Set Window Size based on Window Size distribution of IP address win_dist = self.statistics.get_win_distribution(ip_address) if len(win_dist) > 0: win_prob_dict = lea.Lea.fromValFreqsDict(win_dist) win_value = win_prob_dict.random() else: win_value = Util.handle_most_used_outputs(self.most_used_win_size) return mss_value, ttl_value, win_value
def get_smb_platform_data(platform: str, timestamp: float): """ Gets platform-dependent data for SMB 2 packets :param platform: the platform for which to get SMB 2 packet data :param timestamp: a timestamp for calculating the boot-time :return: server_guid, security_blob, capabilities, data_size and server_start_time of the given platform """ Util.check_platform(platform) if platform == "linux": server_guid = "ubuntu" security_blob = security_blob_ubuntu capabilities = 0x5 data_size = 0x800000 server_start_time = 0 elif platform == "macos": server_guid = binascii.b2a_hex(os.urandom(15)).decode() security_blob = security_blob_macos capabilities = 0x6 data_size = 0x400000 server_start_time = 0 else: server_guid = binascii.b2a_hex(os.urandom(15)).decode() security_blob = security_blob_windows capabilities = 0x7 data_size = 0x100000 server_start_time = Util.get_filetime_format( Util.get_rnd_boot_time(timestamp)) return server_guid, security_blob, capabilities, data_size, server_start_time
def get_smb_version(platform: str): """ Returns SMB version based on given platform :param platform: the platform as string :return: SMB version as string """ Util.check_platform(platform) if platform is "linux": return rnd.choice(list(smb_versions_per_samba.values())) elif platform is "macos": return "2.1" else: return smb_versions_per_win[platform]
def test_get_rnd_x86_nop_with_sideeffects(self): result = Utility.get_rnd_x86_nop(1000, False) for i in range(0, len(result)): with self.subTest(i=i): self.assertTrue( result[i].to_bytes(1, "little") in Utility.x86_nops or result[i].to_bytes(1, "little") in Utility.x86_pseudo_nops)
def init_params(self): """ Initialize the parameters of this attack using the user supplied command line parameters. Use the provided statistics to calculate default parameters and to process user supplied queries. """ # PARAMETERS: initialize with default values # (values are overwritten if user specifies them) most_used_ip_address = self.statistics.get_most_used_ip_address() # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class()) num_attackers = rnd.randint(1, 16) source_ip = self.generate_random_ipv4_address(most_used_ip_class, num_attackers) self.add_param_value(atkParam.Parameter.IP_SOURCE, source_ip) self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.generate_random_mac_address(num_attackers)) random_ip_address = self.statistics.get_random_ip_address() # ip-dst should be valid and not equal to ip.src while not self.is_valid_ip_address(random_ip_address) or random_ip_address == source_ip: random_ip_address = self.statistics.get_random_ip_address() self.add_param_value(atkParam.Parameter.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(atkParam.Parameter.MAC_DESTINATION, destination_mac) self.add_param_value(atkParam.Parameter.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(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count())) self.add_param_value(atkParam.Parameter.ATTACK_DURATION, 30)
def init_params(self): """ Initialize the parameters of this attack using the user supplied command line parameters. Use the provided statistics to calculate default parameters and to process user supplied queries. """ # PARAMETERS: initialize with default values # (values are overwritten if user specifies them) self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count())) # attacker configuration num_attackers = rnd.randint(1, 16) # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class()) self.add_param_value(atkParam.Parameter.IP_SOURCE, self.generate_random_ipv4_address(most_used_ip_class, num_attackers)) self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.generate_random_mac_address(num_attackers)) self.default_port = int(inet.RandShort()) self.add_param_value(atkParam.Parameter.PORT_SOURCE, self.default_port) self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND, 0) self.add_param_value(atkParam.Parameter.ATTACK_DURATION, rnd.randint(5, 30)) # victim configuration random_ip_address = self.statistics.get_random_ip_address() self.add_param_value(atkParam.Parameter.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(atkParam.Parameter.MAC_DESTINATION, destination_mac) self.add_param_value(atkParam.Parameter.VICTIM_BUFFER, rnd.randint(1000, 10000)) self.add_param_value(atkParam.Parameter.BANDWIDTH_MAX, 0) self.add_param_value(atkParam.Parameter.BANDWIDTH_MIN_LOCAL, 0) self.add_param_value(atkParam.Parameter.BANDWIDTH_MIN_PUBLIC, 0) self.add_param_value(atkParam.Parameter.LATENCY_MAX, 0)
def init_params(self): """ Initialize the parameters of this attack using the user supplied command line parameters. Use the provided statistics to calculate default parameters and to process user supplied queries. """ # PARAMETERS: initialize with default values # (values are overwritten if user specifies them) most_used_ip_address = self.statistics.get_most_used_ip_address() self.add_param_value(atkParam.Parameter.IP_SOURCE, most_used_ip_address) self.add_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE, 'False') self.add_param_value( atkParam.Parameter.MAC_SOURCE, self.statistics.get_mac_address(most_used_ip_address)) self.add_param_value(atkParam.Parameter.TARGET_COUNT, 200) self.add_param_value(atkParam.Parameter.IP_DESTINATION, "1.1.1.1") self.add_param_value(atkParam.Parameter.PORT_SOURCE, rnd.randint(1024, 65535)) self.add_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE, 'True') self.add_param_value( atkParam.Parameter.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( atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count())) start = Util.get_timestamp_from_datetime_str( self.statistics.get_pcap_timestamp_start()) end = Util.get_timestamp_from_datetime_str( self.statistics.get_pcap_timestamp_end()) self.add_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP, (start + end) / 2) self.add_param_value(atkParam.Parameter.INJECT_PPS, 0) self.add_param_value(atkParam.Parameter.HOSTING_PERCENTAGE, 0.5) self.add_param_value(atkParam.Parameter.HOSTING_IP, "1.1.1.1") self.add_param_value(atkParam.Parameter.HOSTING_VERSION, SMBLib.get_smb_version(platform=self.host_os)) self.add_param_value(atkParam.Parameter.SOURCE_PLATFORM, Util.get_rnd_os()) self.add_param_value(atkParam.Parameter.PROTOCOL_VERSION, "1")
def test_get_ip_range_backwards(self): end = "192.168.178.254" start = "192.168.179.1" result = [ "192.168.179.1", "192.168.179.0", "192.168.178.255", "192.168.178.254" ] self.assertEqual(Utility.get_ip_range(start, end), result)
def test_get_rnd_x86_nop_without_sideeffects(self): result = Utility.get_rnd_x86_nop(1000, True) for i in range(0, len(result)): with self.subTest(i=i): self.assertIn(result[i].to_bytes(1, "little"), Utility.x86_nops) self.assertNotIn(result[i].to_bytes(1, "little"), Utility.x86_pseudo_nops)
def generate_attack_packets(self) -> None: ip_attacker = self.get_param_value(atkParam.Parameter.IP_SOURCE) mac_attacker = self.get_param_value(atkParam.Parameter.MAC_SOURCE) ip_amplifier = self.get_param_value(atkParam.Parameter.IP_DESTINATION) mac_amplifier = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) ip_victim = self.get_param_value(atkParam.Parameter.IP_VICTIM) pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) self.attack_start_utime = timestamp_next_pkt attack_duration = self.get_param_value( atkParam.Parameter.ATTACK_DURATION) attack_ends_time = timestamp_next_pkt + attack_duration _, src_ttl, _ = self.get_ip_data(ip_attacker) sport = Util.generate_source_port_from_platform('linux') # Use MAC of the actual source, but the IP of the victim attacker_ether = inet.Ether(src=mac_attacker, dst=mac_amplifier) attacker_ip = inet.IP(src=ip_victim, dst=ip_amplifier, ttl=src_ttl, flags='DF') while timestamp_next_pkt <= attack_ends_time: request_udp = inet.UDP(sport=sport, dport=Memcd.memcached_port) request_memcd = Memcd.Memcached_Request(Request=b'stats\r\n', RequestID=inet.RandShort()) request = (attacker_ether / attacker_ip / request_udp / request_memcd) request.time = timestamp_next_pkt self.packets.append(request) timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
def __init__(self): """ Creates a new instance of the SMBScanAttack. This Attack injects TCP Syn Requests to the port 445 of several ips and related response into the output pcap file. If port 445 is open, it will simulate and inject the SMB Protocol Negotiation too. """ # Initialize attack super(SMBScanAttack, self).__init__("SmbScan Attack", "Injects an SMB scan", "Scanning/Probing") self.host_os = Util.get_rnd_os() # Define allowed parameters and their type self.supported_params.update({ atkParam.Parameter.IP_SOURCE: atkParam.ParameterTypes.TYPE_IP_ADDRESS, atkParam.Parameter.IP_DESTINATION: atkParam.ParameterTypes.TYPE_IP_ADDRESS, atkParam.Parameter.TARGET_COUNT: atkParam.ParameterTypes.TYPE_INTEGER_POSITIVE, atkParam.Parameter.HOSTING_PERCENTAGE: atkParam.ParameterTypes.TYPE_PERCENTAGE, atkParam.Parameter.PORT_SOURCE: atkParam.ParameterTypes.TYPE_PORT, atkParam.Parameter.MAC_SOURCE: atkParam.ParameterTypes.TYPE_MAC_ADDRESS, atkParam.Parameter.INJECT_AT_TIMESTAMP: atkParam.ParameterTypes.TYPE_FLOAT, atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION, atkParam.Parameter.IP_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN, atkParam.Parameter.PACKETS_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT, atkParam.Parameter.INJECT_PPS: atkParam.ParameterTypes.TYPE_FLOAT, atkParam.Parameter.PORT_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN, atkParam.Parameter.HOSTING_IP: atkParam.ParameterTypes.TYPE_IP_ADDRESS, atkParam.Parameter.HOSTING_VERSION: atkParam.ParameterTypes.TYPE_STRING, atkParam.Parameter.SOURCE_PLATFORM: atkParam.ParameterTypes.TYPE_STRING, atkParam.Parameter.PROTOCOL_VERSION: atkParam.ParameterTypes.TYPE_STRING })
def choose_attack(input_name): """" Finds the attack best matching to input_name :param input_name: The name of the attack the user put in :return: The best matching attack in case one was found """ import Attack # Find all attacks, exclude some classes package = Attack available_attacks = [] for _, name, __ in pkgutil.iter_modules(package.__path__): if name != 'BaseAttack' and name != 'AttackParameters': available_attacks.append(name) highest_sim = 0.0 highest_sim_attack = None for attack in available_attacks: # Check if attack name is accurate if input_name == attack: return attack # Compares input with one of the available attacks # Makes comparison with lowercase version with generic endings removed # List of generic attack name endings can be found in ID2TLib.Utility counter_check = attack.lower() if not any(ending in input_name for ending in Util.generic_attack_names): counter_check = Util.remove_generic_ending(counter_check) similarity = difflib.SequenceMatcher(None, input_name.lower(), counter_check).ratio() # Exact match, return appropriate attack name if similarity == 1.0: return attack # Found more likely match if similarity > highest_sim: highest_sim = similarity highest_sim_attack = attack # Found no exactly matching attack name, print best match and exit if highest_sim >= 0.6: print('Found no attack of name ' + input_name + '. The closest match was ' + highest_sim_attack + '. Use ./id2t -l for a list of available attacks.') exit(1) # Found no reasonably matching attack name, recommend -l and exit else: print('Found no attack of name ' + input_name + ' or one similar to it.' ' Use ./id2t -l for an overview of available attacks.') exit(1)
def get_reply_latency(self, ip_src, ip_dst, default: int = 0, mode: str = None): """ Gets the minimum and the maximum reply latency for all the connections of a specific IP. :param ip_src: The source IP for which to retrieve the reply latency. :param ip_dst: The destination IP for which to retrieve the reply latency. :param default: The default value to return if no latency could be calculated. :param mode: either "local" or "public" :return minimum and maximum latency """ if not mode: mode = Util.get_network_mode(ip_src, ip_dst) minimum = {"local": 900, "public": 3000} if default != 0: minimum[mode] = default result = self.statistics.process_db_query\ ("SELECT minLatency, maxLatency FROM ip_statistics WHERE ipAddress in ('{0}, {1}');". format(ip_src, ip_dst)) min_latency = minimum[mode] max_latency = minimum[mode] for ip in result: # retrieve minimum latency if ip[0]: retrieved = ip[0] else: retrieved = np.median(self.all_min_latencies) min_latency = min(min_latency, retrieved) # retrieve maximum latency if ip[1]: retrieved = ip[1] else: retrieved = np.median(self.all_max_latencies) max_latency = min(max_latency, retrieved) min_latency = int( min_latency) * 10**-6 # convert from micro to seconds max_latency = int(max_latency) * 10**-6 return min_latency, max_latency
def get_remaining_bandwidth(self, timestamp: int = 0, ip_src: str = "", ip_dst: str = "", custom_max_bandwidth: float = 0, custom_bandwidth_local: float = 0, custom_bandwidth_public: float = 0): """ This function calculates the remaining bandwidth based on the maximum bandwidth available and the kbytes already sent inside the interval corresponding to the timestamp given. !!! custom_max_bandwidth is mutually exclusive to custom_bandwidth_local and/or custom_bandwidth_public :param timestamp: the timestamp of the current packet :param ip_src: the source IP :param ip_dst: the destination IP :param custom_max_bandwidth: maximum bandwidth to be set as a hard limit, discarding the pcaps bandwidth :param custom_bandwidth_local: bandwidth minimum for local traffic :param custom_bandwidth_public: bandwidth minimum for public traffic :return: the remaining bandwidth in kbyte/s """ mode = Util.get_network_mode(ip_src, ip_dst) if custom_max_bandwidth != 0: bandwidth = custom_max_bandwidth else: bandwidth = self.statistics.get_kbyte_rate( mode, custom_bandwidth_local, custom_bandwidth_public) remaining_bandwidth = bandwidth current_table = self.statistics.stats_db.get_current_interval_statistics_table( ) kbytes_sent, interval = self.statistics.get_interval_stat( table_name=current_table, field="kbytes", timestamp=timestamp) if not kbytes_sent: kbytes_sent = 0 kbytes_sent = kbytes_sent duration = self.statistics.get_current_interval_len() used_bandwidth = float((kbytes_sent * 1000) / duration) remaining_bandwidth -= used_bandwidth return remaining_bandwidth, interval
def init_params(self): """ Initialize the parameters of this attack using the user supplied command line parameters. Use the provided statistics to calculate default parameters and to process user supplied queries. """ # PARAMETERS: initialize with default values # (values are overwritten if user specifies them) most_used_ip_address = self.statistics.get_most_used_ip_address() # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs( self.statistics.get_most_used_ip_class()) attacker_ip = self.generate_random_ipv4_address(most_used_ip_class) self.add_param_value(atkParam.Parameter.IP_DESTINATION, attacker_ip) self.add_param_value(atkParam.Parameter.MAC_DESTINATION, self.generate_random_mac_address()) random_ip_address = self.statistics.get_random_ip_address() # victim should be valid and not equal to attacker while not self.is_valid_ip_address( random_ip_address) or random_ip_address == attacker_ip: random_ip_address = self.statistics.get_random_ip_address() self.add_param_value(atkParam.Parameter.IP_SOURCE, random_ip_address) victim_mac = self.statistics.get_mac_address(random_ip_address) if isinstance(victim_mac, list) and len(victim_mac) == 0: victim_mac = self.generate_random_mac_address() self.add_param_value(atkParam.Parameter.MAC_SOURCE, victim_mac) self.add_param_value( atkParam.Parameter.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( atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count())) self.add_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE, 'False') self.add_param_value(atkParam.Parameter.CUSTOM_PAYLOAD, '') self.add_param_value(atkParam.Parameter.CUSTOM_PAYLOAD_FILE, '')
def append_ips( ip_address_input: t.List[str]) -> t.Tuple[bool, t.List[str]]: """ Recursive appending function to handle lists and ranges of IP addresses. :param ip_address_input: The IP address(es) as list of strings, comma-separated or dash-separated string. :return: List of all given IP addresses. """ ip_list = [] is_valid = True for ip in ip_address_input: if '-' in ip: ip_range = ip.split('-') ip_range = Util.get_ip_range(ip_range[0], ip_range[1]) is_valid, ips = append_ips(ip_range) ip_list.extend(ips) else: try: ipaddress.ip_address(ip) ip_list.append(ip) except ValueError: return False, ip_list return is_valid, ip_list
def generate_attack_packets(self): """ Creates the attack packets. """ pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = timestamp_next_pkt # Initialize parameters ip_victim = self.get_param_value(atkParam.Parameter.IP_SOURCE) ip_attacker = self.get_param_value(atkParam.Parameter.IP_DESTINATION) mac_victim = self.get_param_value(atkParam.Parameter.MAC_SOURCE) mac_attacker = self.get_param_value(atkParam.Parameter.MAC_DESTINATION) custom_payload = self.get_param_value( atkParam.Parameter.CUSTOM_PAYLOAD) custom_payload_len = len(custom_payload) custom_payload_limit = 1000 Util.check_payload_len(custom_payload_len, custom_payload_limit) self.packets = [] # Create random victim if specified if self.get_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE): # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs( self.statistics.get_most_used_ip_class()) ip_victim = self.generate_random_ipv4_address( most_used_ip_class, 1) mac_victim = self.generate_random_mac_address() # Get MSS, TTL and Window size value for victim/attacker IP victim_mss_value, victim_ttl_value, victim_win_value = self.get_ip_data( ip_victim) attacker_mss_value, attacker_ttl_value, attacker_win_value = self.get_ip_data( ip_attacker) min_delay, max_delay = self.get_reply_delay(ip_attacker) attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) sport = Util.generate_source_port_from_platform("win7") # connection request from victim (client) victim_ether = inet.Ether(src=mac_victim, dst=mac_attacker) victim_ip = inet.IP(src=ip_victim, dst=ip_attacker, ttl=victim_ttl_value, flags='DF') request_tcp = inet.TCP(sport=sport, dport=ftp_port, window=victim_win_value, flags='S', seq=victim_seq, options=[('MSS', victim_mss_value)]) victim_seq += 1 syn = (victim_ether / victim_ip / request_tcp) syn.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(syn) # response from attacker (server) attacker_ether = inet.Ether(src=mac_attacker, dst=mac_victim) attacker_ip = inet.IP(src=ip_attacker, dst=ip_victim, ttl=attacker_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='SA', window=attacker_win_value, options=[('MSS', attacker_mss_value)]) attacker_seq += 1 synack = (attacker_ether / attacker_ip / reply_tcp) synack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(synack) # acknowledgement from victim (client) ack_tcp = inet.TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A', window=victim_win_value, options=[('MSS', victim_mss_value)]) ack = (victim_ether / victim_ip / ack_tcp) ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ack) # FTP exploit packet ftp_tcp = inet.TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='PA', window=attacker_win_value, options=[('MSS', attacker_mss_value)]) characters = b'220' characters += Util.get_rnd_bytes(2065, Util.forbidden_chars) characters += b'\x96\x72\x01\x68' characters += Util.get_rnd_x86_nop(10, False, Util.forbidden_chars) custom_payload_file = self.get_param_value( atkParam.Parameter.CUSTOM_PAYLOAD_FILE) # Generation of payload of the FTP exploit packet if custom_payload == '': if custom_payload_file == '': payload = Util.get_rnd_bytes(custom_payload_limit, Util.forbidden_chars) else: payload = ID2TLib.Utility.get_bytes_from_file( custom_payload_file) Util.check_payload_len(len(payload), custom_payload_limit) payload += Util.get_rnd_x86_nop( custom_payload_limit - len(payload), False, Util.forbidden_chars) else: encoded_payload = custom_payload.encode() payload = Util.get_rnd_x86_nop( custom_payload_limit - custom_payload_len, False, Util.forbidden_chars) payload += encoded_payload characters += payload characters += Util.get_rnd_x86_nop(20, False, Util.forbidden_chars) characters += b'\r\n' ftp_tcp.add_payload(characters) ftp_buff = (attacker_ether / attacker_ip / ftp_tcp) ftp_buff.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ftp_buff) attacker_seq += len(ftp_tcp.payload) # Fin Ack from attacker fin_ack_tcp = inet.TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='FA', window=attacker_win_value, options=[('MSS', attacker_mss_value)]) fin_ack = (attacker_ether / attacker_ip / fin_ack_tcp) fin_ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(fin_ack) # Ack from victim on FTP packet ftp_ack_tcp = inet.TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A', window=victim_win_value, options=[('MSS', victim_mss_value)]) ftp_ack = (victim_ether / victim_ip / ftp_ack_tcp) ftp_ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ftp_ack) # Ack from victim on Fin/Ack of attacker fin_ack_ack_tcp = inet.TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq + 1, flags='A', window=victim_win_value, options=[('MSS', victim_mss_value)]) fin_ack_ack = (victim_ether / victim_ip / fin_ack_ack_tcp) fin_ack_ack.time = timestamp_next_pkt self.packets.append(fin_ack_ack)
def generate_attack_packets(self): """ Creates the attack packets. """ buffer_size = 1000 # Determine source IP and MAC address num_attackers = self.get_param_value( atkParam.Parameter.NUMBER_ATTACKERS) if (num_attackers is not None) and (num_attackers is not 0): # user supplied atkParam.Parameter.NUMBER_ATTACKERS # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs( self.statistics.get_most_used_ip_class()) # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS ip_source_list = self.generate_random_ipv4_address( most_used_ip_class, num_attackers) mac_source_list = self.generate_random_mac_address(num_attackers) else: # user did not supply atkParam.Parameter.NUMBER_ATTACKS # use default values for IP_SOURCE/MAC_SOURCE or overwritten values # if user supplied any values for those params ip_source_list = self.get_param_value(atkParam.Parameter.IP_SOURCE) mac_source_list = self.get_param_value( atkParam.Parameter.MAC_SOURCE) # Make sure IPs and MACs are lists if not isinstance(ip_source_list, list): ip_source_list = [ip_source_list] if not isinstance(mac_source_list, list): mac_source_list = [mac_source_list] # Generate MACs for each IP that has no corresponding MAC yet if (num_attackers is None) or (num_attackers is 0): if len(ip_source_list) > len(mac_source_list): mac_source_list.extend( self.generate_random_mac_address( len(ip_source_list) - len(mac_source_list))) num_attackers = min(len(ip_source_list), len(mac_source_list)) # Initialize parameters self.packets = col.deque(maxlen=buffer_size) port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE) if not isinstance(port_source_list, list): port_source_list = [port_source_list] mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) most_used_ip_address = self.statistics.get_most_used_ip_address() pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) if pps == 0: result = self.statistics.process_db_query( "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + ip_destination + "';") if result is not None and not 0: pps = num_attackers * result else: result = self.statistics.process_db_query( "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + most_used_ip_address + "';") pps = num_attackers * result # Calculate complement packet rates of the background traffic for each interval attacker_pps = pps / num_attackers complement_interval_attacker_pps = self.statistics.calculate_complement_packet_rates( attacker_pps) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source_list, ip_destination) port_destination = self.get_param_value( atkParam.Parameter.PORT_DESTINATION) if not port_destination: # user did not define port_dest port_destination = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "');") if not port_destination: # no port was retrieved port_destination = self.statistics.process_db_query( "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE " "portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) " "FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);" ) if not port_destination: port_destination = max(1, int(inet.RandShort())) port_destination = Util.handle_most_used_outputs(port_destination) self.path_attack_pcap = None min_delay, max_delay = self.get_reply_delay(ip_destination) victim_buffer = self.get_param_value(atkParam.Parameter.VICTIM_BUFFER) attack_duration = self.get_param_value( atkParam.Parameter.ATTACK_DURATION) pkts_num = int(pps * attack_duration) source_win_sizes = self.statistics.get_rnd_win_size(pkts_num) destination_win_dist = self.statistics.get_win_distribution( ip_destination) if len(destination_win_dist) > 0: destination_win_prob_dict = lea.Lea.fromValFreqsDict( destination_win_dist) destination_win_value = destination_win_prob_dict.random() else: destination_win_value = self.statistics.get_most_used_win_size() destination_win_value = Util.handle_most_used_outputs( destination_win_value) # MSS that was used by IP destination in background traffic mss_dst = self.statistics.get_most_used_mss(ip_destination) if mss_dst is None: mss_dst = self.statistics.get_most_used_mss_value() mss_dst = Util.handle_most_used_outputs(mss_dst) # Stores triples of (timestamp, source_id, destination_id) for each timestamp. # Victim has id=0. Attacker tuple does not need to specify the destination because it's always the victim. timestamps_tuples = [] # For each attacker(id), stores the current source-ports of SYN-packets # which still have to be acknowledged by the victim, as a "FIFO" for each attacker previous_attacker_port = [] replies_count = 0 self.total_pkt_num = 0 # For each attacker, generate his own packets, then merge all packets for attacker in range(num_attackers): # Initialize empty port "FIFO" for current attacker previous_attacker_port.append([]) # Calculate timestamp of first SYN-packet of attacker timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) attack_ends_time = timestamp_next_pkt + attack_duration timestamp_next_pkt = rnd.uniform( timestamp_next_pkt, Util.update_timestamp(timestamp_next_pkt, attacker_pps)) attacker_pkts_num = int(pkts_num / num_attackers) + rnd.randint( 0, 100) timestamp_prv_reply = 0 for pkt_num in range(attacker_pkts_num): # Stop the attack when it exceeds the duration if timestamp_next_pkt > attack_ends_time: break # Add timestamp of attacker SYN-packet. Attacker tuples do not need to specify destination timestamps_tuples.append((timestamp_next_pkt, attacker + 1)) # Calculate timestamp of victim ACK-packet timestamp_reply = Util.update_timestamp( timestamp_next_pkt, attacker_pps, min_delay) while timestamp_reply <= timestamp_prv_reply: timestamp_reply = Util.update_timestamp( timestamp_prv_reply, attacker_pps, min_delay) timestamp_prv_reply = timestamp_reply # Add timestamp of victim ACK-packet(victim always has id=0) timestamps_tuples.append((timestamp_reply, 0, attacker + 1)) # Calculate timestamp for next attacker SYN-packet attacker_pps = max( Util.get_interval_pps(complement_interval_attacker_pps, timestamp_next_pkt), (pps / num_attackers) / 2) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, attacker_pps) # Sort timestamp-triples according to their timestamps in ascending order timestamps_tuples.sort(key=lambda tmstmp: tmstmp[0]) self.attack_start_utime = timestamps_tuples[0][0] # For each triple, generate packet for timestamp in timestamps_tuples: # If current current triple is an attacker if timestamp[1] != 0: attacker_id = timestamp[1] - 1 # Build request package # Select one IP address and its corresponding MAC address ip_source = ip_source_list[attacker_id] mac_source = mac_source_list[attacker_id] # Determine source port (port_source, ttl_value) = Util.get_attacker_config(ip_source_list, ip_source) # If source ports were specified by the user, get random port from specified ports if port_source_list[0] != self.default_port: port_source = rnd.choice(port_source_list) # Push port of current attacker SYN-packet into port "FIFO" of the current attacker # only if victim can still respond, otherwise, memory is wasted if replies_count <= victim_buffer: previous_attacker_port[attacker_id].insert(0, port_source) request_ether = inet.Ether(dst=mac_destination, src=mac_source) request_ip = inet.IP(src=ip_source, dst=ip_destination, ttl=ttl_value) # Random win size for each packet source_win_size = rnd.choice(source_win_sizes) request_tcp = inet.TCP(sport=port_source, dport=port_destination, flags='S', ack=0, window=source_win_size) request = (request_ether / request_ip / request_tcp) request.time = timestamp[0] # Append request self.packets.append(request) self.total_pkt_num += 1 # If current triple is the victim else: # Build reply package if replies_count <= victim_buffer: attacker_id = timestamp[2] - 1 reply_ether = inet.Ether(src=mac_destination, dst=mac_source_list[attacker_id]) reply_ip = inet.IP(src=ip_destination, dst=ip_source_list[attacker_id], flags='DF') # Pop port from attacker's port "FIFO" into destination port reply_tcp = inet.TCP( sport=port_destination, dport=previous_attacker_port[attacker_id].pop(), seq=0, ack=1, flags='SA', window=destination_win_value, options=[('MSS', mss_dst)]) reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp[0] self.packets.append(reply) replies_count += 1 self.total_pkt_num += 1 # every 1000 packets write them to the pcap file (append) if (self.total_pkt_num > 0) and (self.total_pkt_num % buffer_size == 0) and (len(self.packets) > 0): self.last_packet = self.packets[-1] self.attack_end_utime = self.last_packet.time self.packets = sorted(self.packets, key=lambda pkt: pkt.time) self.path_attack_pcap = self.write_attack_pcap( self.packets, True, self.path_attack_pcap) self.packets = []
def process_attack(self, attack: str, params: str, time=False): """ Takes as input the name of an attack (classname) and the attack parameters as string. Parses the string of attack parameters, creates the attack by writing the attack packets and returns the path of the written pcap. :param attack: The classname of the attack to inject. :param params: The parameters for attack customization, see attack class for supported params. :param time: Measure packet generation time or not. :return: The file path to the created pcap file. """ attack = self.choose_attack(attack) self.create_attack(attack, self.seed) print("Validating and adding attack parameters.") # Add attack parameters if provided params_dict = [] if isinstance(params, list) and params: # Convert attack param list into dictionary for entry in params: params_dict.append(entry.split('=')) params_dict = dict(params_dict) # Check if Parameter.INJECT_AT_TIMESTAMP and Parameter.INJECT_AFTER_PACKET are provided at the same time # if TRUE: delete Parameter.INJECT_AT_TIMESTAMP (lower priority) and use Parameter.INJECT_AFTER_PACKET if (atkParam.Parameter.INJECT_AFTER_PACKET.value in params_dict) and ( atkParam.Parameter.INJECT_AT_TIMESTAMP.value in params_dict): print("CONFLICT: Parameters", atkParam.Parameter.INJECT_AT_TIMESTAMP.value, "and", atkParam.Parameter.INJECT_AFTER_PACKET.value, "given at the same time. Ignoring", atkParam.Parameter.INJECT_AT_TIMESTAMP.value, "and using", atkParam.Parameter.INJECT_AFTER_PACKET.value, "instead to derive the timestamp.") del params_dict[atkParam.Parameter.INJECT_AT_TIMESTAMP.value] # Extract attack_note parameter, if not provided returns an empty string key_attack_note = "attack.note" attack_note = params_dict.get(key_attack_note, "") params_dict.pop(key_attack_note, None) # delete entry if found, otherwise return an empty string # Pass paramters to attack controller self.set_params(params_dict) else: attack_note = "This attack used only (random) default parameters." self.current_attack.init_objects() print("Generating attack packets...", end=" ") sys.stdout.flush() # force python to print text immediately if time: self.current_attack.set_start_time() # Generate attack packets self.current_attack.generate_attack_packets() if time: self.current_attack.set_finish_time() duration = self.current_attack.get_packet_generation_time() # Write attack into pcap file attack_result = self.current_attack.generate_attack_pcap() self.total_packets = attack_result[0] temp_attack_pcap_path = attack_result[1] if len(attack_result) == 3: # Extract the list of additional files, if available self.additional_files += attack_result[2] print("done. (total: " + str(self.total_packets) + " pkts", end="") if time: print(" in ", duration, " seconds", end="") print(".)") # Warning if attack duration gets exceeded by more than 1 second if atkParam.Parameter.ATTACK_DURATION in self.current_attack.supported_params and \ self.current_attack.get_param_value(atkParam.Parameter.ATTACK_DURATION) != 0: attack_duration = self.current_attack.get_param_value(atkParam.Parameter.ATTACK_DURATION) packet_duration = abs(self.current_attack.attack_end_utime - self.current_attack.attack_start_utime) time_diff = abs(attack_duration - packet_duration) if self.current_attack.exceeding_packets > 0 and time_diff > 1: exceeding_packets = "" if self.current_attack.exceeding_packets: exceeding_packets = " ({} attack pkts)".format(self.current_attack.exceeding_packets) print("Warning: attack duration was exceeded by {0} seconds{1}.".format(time_diff, exceeding_packets)) elif time_diff > 1: print("Warning: attack duration was not reached by generated pkts by {} seconds.".format(time_diff)) # Warning if pcap length gets exceeded pcap_end = Util.get_timestamp_from_datetime_str(self.statistics.get_pcap_timestamp_end()) time_diff = pcap_end - self.current_attack.attack_end_utime if time_diff < 0: print("Warning: end of pcap exceeded by " + str(round(abs(time_diff), 2)) + " seconds.") # Store label into LabelManager label = Label.Label(attack, self.get_attack_start_utime(), self.get_attack_end_utime(), self.total_packets, self.seed, self.current_attack.params, attack_note) self.label_mgr.add_labels(label) return temp_attack_pcap_path, duration
def test_generate_source_port_from_platform_oldwin_maxport(self): self.assertTrue(1024 <= Utility.generate_source_port_from_platform( "winxp", 5000) <= 5000)
def test_generate_source_port_from_platform_linux(self): self.assertTrue(32768 <= Utility.generate_source_port_from_platform( "linux") <= 61000)
def generate_attack_packets(self): """ Creates the attack packets. """ pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # Calculate complement packet rates of the background traffic for each interval complement_interval_pps = self.statistics.calculate_complement_packet_rates( pps) # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = timestamp_next_pkt timestamp_prv_reply, timestamp_confirm = 0, 0 # Initialize parameters ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) dest_ip_count = self.get_param_value(atkParam.Parameter.TARGET_COUNT) ip_addr_count = self.statistics.get_ip_address_count() if ip_addr_count < dest_ip_count + 1: dest_ip_count = ip_addr_count # Check for user defined target IP addresses ip_destinations = self.get_param_value( atkParam.Parameter.IP_DESTINATION) if isinstance(ip_destinations, list): dest_ip_count = dest_ip_count - len(ip_destinations) elif ip_destinations is not "1.1.1.1": dest_ip_count = dest_ip_count - 1 ip_destinations = [ip_destinations] else: ip_destinations = [] # Take random targets from pcap rnd_ips = self.statistics.get_random_ip_address(dest_ip_count) if not isinstance(rnd_ips, list): rnd_ips = [rnd_ips] ip_destinations = ip_destinations + rnd_ips # Make sure the source IP is not part of targets if ip_source in ip_destinations and isinstance(ip_destinations, list): ip_destinations.remove(ip_source) self.add_param_value(atkParam.Parameter.IP_DESTINATION, ip_destinations) ip_destinations = self.get_param_value( atkParam.Parameter.IP_DESTINATION) # Calculate the amount of IP addresses which are hosting SMB host_percentage = self.get_param_value( atkParam.Parameter.HOSTING_PERCENTAGE) rnd_ip_count = len(ip_destinations) * host_percentage # Check for user defined IP addresses which are hosting SMB hosting_ip = self.get_param_value(atkParam.Parameter.HOSTING_IP) if isinstance(hosting_ip, list): rnd_ip_count = rnd_ip_count - len(hosting_ip) elif hosting_ip is not "1.1.1.1": rnd_ip_count = rnd_ip_count - 1 hosting_ip = [hosting_ip] else: hosting_ip = [] hosting_ip = hosting_ip + ip_destinations[:int(rnd_ip_count)] self.add_param_value(atkParam.Parameter.HOSTING_IP, hosting_ip) # Shuffle targets rnd.shuffle(ip_destinations) # FIXME: Handle mac addresses correctly mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) mac_dest = self.get_param_value(atkParam.Parameter.MAC_DESTINATION) # Check smb version smb_version = self.get_param_value(atkParam.Parameter.PROTOCOL_VERSION) if smb_version not in SMBLib.smb_versions: SMBLib.invalid_smb_version(smb_version) hosting_version = self.get_param_value( atkParam.Parameter.HOSTING_VERSION) if hosting_version not in SMBLib.smb_versions: SMBLib.invalid_smb_version(hosting_version) # Check source platform src_platform = self.get_param_value( atkParam.Parameter.SOURCE_PLATFORM).lower() self.packets = [] # randomize source ports according to platform, if specified if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE): sport = Util.generate_source_port_from_platform(src_platform) else: sport = self.get_param_value(atkParam.Parameter.PORT_SOURCE) # No destination IP was specified, but a destination MAC was specified, generate IP that fits MAC if isinstance(ip_destinations, list) and isinstance(mac_dest, str): ip_destinations = self.statistics.get_ip_address_from_mac(mac_dest) if len(ip_destinations) == 0: ip_destinations = self.generate_random_ipv4_address( "Unknown", 1) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source, ip_destinations) ip_dests = [] if isinstance(ip_destinations, list): ip_dests = ip_destinations else: ip_dests.append(ip_destinations) if isinstance(ip_dests, list): rnd.shuffle(ip_dests) # Randomize source IP, if specified if self.get_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE): ip_source = self.generate_random_ipv4_address("Unknown", 1) while ip_source in ip_dests: ip_source = self.generate_random_ipv4_address("Unknown", 1) mac_source = self.statistics.get_mac_address(str(ip_source)) if len(mac_source) == 0: mac_source = self.generate_random_mac_address() # Get MSS, TTL and Window size value for source IP source_mss_value, source_ttl_value, source_win_value = self.get_ip_data( ip_source) mac_dests = self.statistics.get_mac_addresses(ip_dests) first_timestamp_smb = self.statistics.get_pcap_timestamp_start()[:19] # get inject pss inject_pps = self.get_param_value(atkParam.Parameter.INJECT_PPS) for ip in ip_dests: if ip != ip_source: # Get destination Mac Address mac_destination = "" if ip in mac_dests.keys(): mac_destination = mac_dests[ip] if len(mac_destination) == 0: if isinstance(mac_dest, str): ip_from_mac = self.statistics.get_ip_address_from_mac( mac_dest) if len(ip_from_mac) != 0: ip = ip_from_mac self.ip_src_dst_equal_check(ip_source, ip) mac_destination = mac_dest else: mac_destination = self.generate_random_mac_address() # Get MSS, TTL and Window size value for destination IP destination_mss_value, destination_ttl_value, destination_win_value = self.get_ip_data( ip) min_delay, max_delay = self.get_reply_delay(ip) # New connection, new random TCP sequence numbers attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) # Randomize source port for each connection if specified if self.get_param_value( atkParam.Parameter.PORT_SOURCE_RANDOMIZE): sport = Util.generate_source_port_from_platform( src_platform, sport) # 1) Build request package request_ether = inet.Ether(src=mac_source, dst=mac_destination) request_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value, flags='DF') request_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, window=source_win_value, flags='S', seq=attacker_seq, options=[('MSS', source_mss_value)]) attacker_seq += 1 request = (request_ether / request_ip / request_tcp) request.time = timestamp_next_pkt # Append request self.packets.append(request) # Update timestamp for next package timestamp_reply = Util.update_timestamp( timestamp_next_pkt, pps, min_delay, inj_pps=inject_pps, inj_timestamp=self.attack_start_utime) while timestamp_reply <= timestamp_prv_reply: timestamp_reply = Util.update_timestamp( timestamp_prv_reply, pps, min_delay, inj_pps=inject_pps, inj_timestamp=self.attack_start_utime) timestamp_prv_reply = timestamp_reply if ip in hosting_ip: # 2) Build TCP packages for ip that hosts SMB # destination sends SYN, ACK reply_ether = inet.Ether(src=mac_destination, dst=mac_source) reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='SA', window=destination_win_value, options=[('MSS', destination_mss_value)]) victim_seq += 1 reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp_reply self.packets.append(reply) # requester confirms, ACK confirm_ether = request_ether confirm_ip = request_ip confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='A') confirm = (confirm_ether / confirm_ip / confirm_tcp) timestamp_confirm = Util.update_timestamp( timestamp_reply, pps, min_delay) confirm.time = timestamp_confirm self.packets.append(confirm) # 3) Build SMB Negotiation packets smb_mid = rnd.randint(1, 65535) smb_pid = rnd.randint(1, 65535) smb_req_tail_arr = [] smb_req_tail_size = 0 # select dialects based on smb version if smb_version is "1": smb_req_dialects = SMBLib.smb_dialects[0:6] else: smb_req_dialects = SMBLib.smb_dialects if len(smb_req_dialects) == 0: smb_req_tail_arr.append( SMBNegociate_Protocol_Request_Tail()) smb_req_tail_size = len( SMBNegociate_Protocol_Request_Tail()) else: for dia in smb_req_dialects: smb_req_tail_arr.append( SMBNegociate_Protocol_Request_Tail( BufferData=dia)) smb_req_tail_size += len( SMBNegociate_Protocol_Request_Tail( BufferData=dia)) # Creation of SMB Negotiate Protocol Request packet smb_req_head = SMBNegociate_Protocol_Request_Header( Flags2=0x2801, PID=smb_pid, MID=smb_mid, ByteCount=smb_req_tail_size) smb_req_length = len(smb_req_head) + smb_req_tail_size smb_req_net_bio = NBTSession(TYPE=0x00, LENGTH=smb_req_length) smb_req_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, flags='PA', seq=attacker_seq, ack=victim_seq) smb_req_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value) smb_req_ether = inet.Ether(src=mac_source, dst=mac_destination) attacker_seq += len(smb_req_net_bio) + len( smb_req_head) + smb_req_tail_size smb_req_combined = (smb_req_ether / smb_req_ip / smb_req_tcp / smb_req_net_bio / smb_req_head) for i in range(0, len(smb_req_tail_arr)): smb_req_combined = smb_req_combined / smb_req_tail_arr[ i] timestamp_smb_req = Util.update_timestamp( timestamp_confirm, pps, min_delay) smb_req_combined.time = timestamp_smb_req self.packets.append(smb_req_combined) # destination confirms SMB request package reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, window=destination_win_value, flags='A') confirm_smb_req = (reply_ether / reply_ip / reply_tcp) timestamp_reply = Util.update_timestamp( timestamp_smb_req, pps, min_delay) confirm_smb_req.time = timestamp_reply self.packets.append(confirm_smb_req) # smb response package first_timestamp = time.mktime( time.strptime(first_timestamp_smb, "%Y-%m-%d %H:%M:%S")) server_guid, security_blob, capabilities, data_size, server_start_time =\ SMBLib.get_smb_platform_data(self.host_os, first_timestamp) timestamp_smb_rsp = Util.update_timestamp( timestamp_reply, pps, min_delay) diff = timestamp_smb_rsp - timestamp_smb_req begin = Util.get_filetime_format(timestamp_smb_req + diff * 0.1) end = Util.get_filetime_format(timestamp_smb_rsp - diff * 0.1) system_time = rnd.randint(begin, end) # Creation of SMB Negotiate Protocol Response packets if smb_version is not "1" and hosting_version is not "1": smb_rsp_packet = SMB2.SMB2_SYNC_Header(Flags=1) smb_rsp_negotiate_body =\ SMB2.SMB2_Negotiate_Protocol_Response(DialectRevision=0x02ff, SecurityBufferOffset=124, SecurityBufferLength=len(security_blob), SecurityBlob=security_blob, Capabilities=capabilities, MaxTransactSize=data_size, MaxReadSize=data_size, MaxWriteSize=data_size, SystemTime=system_time, ServerStartTime=server_start_time, ServerGuid=server_guid) smb_rsp_length = len(smb_rsp_packet) + len( smb_rsp_negotiate_body) else: smb_rsp_packet =\ SMBNegociate_Protocol_Response_Advanced_Security(Start="\xffSMB", PID=smb_pid, MID=smb_mid, DialectIndex=5, SecurityBlob=security_blob) smb_rsp_length = len(smb_rsp_packet) smb_rsp_net_bio = NBTSession(TYPE=0x00, LENGTH=smb_rsp_length) smb_rsp_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, flags='PA', seq=victim_seq, ack=attacker_seq) smb_rsp_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value) smb_rsp_ether = inet.Ether(src=mac_destination, dst=mac_source) victim_seq += len(smb_rsp_net_bio) + len(smb_rsp_packet) if smb_version is not "1" and hosting_version is not "1": victim_seq += len(smb_rsp_negotiate_body) smb_rsp_combined = (smb_rsp_ether / smb_rsp_ip / smb_rsp_tcp / smb_rsp_net_bio / smb_rsp_packet) if smb_version is not "1" and hosting_version is not "1": smb_rsp_combined = (smb_rsp_combined / smb_rsp_negotiate_body) smb_rsp_combined.time = timestamp_smb_rsp self.packets.append(smb_rsp_combined) # source confirms SMB response package confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='A') confirm_smb_res = (confirm_ether / confirm_ip / confirm_tcp) timestamp_confirm = Util.update_timestamp( timestamp_smb_rsp, pps, min_delay) confirm_smb_res.time = timestamp_confirm self.packets.append(confirm_smb_res) # attacker sends FIN ACK confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='FA') source_fin_ack = (confirm_ether / confirm_ip / confirm_tcp) timestamp_src_fin_ack = Util.update_timestamp( timestamp_confirm, pps, min_delay) source_fin_ack.time = timestamp_src_fin_ack attacker_seq += 1 self.packets.append(source_fin_ack) # victim sends FIN ACK reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, window=destination_win_value, flags='FA') destination_fin_ack = (reply_ether / reply_ip / reply_tcp) timestamp_dest_fin_ack = Util.update_timestamp( timestamp_src_fin_ack, pps, min_delay) victim_seq += 1 destination_fin_ack.time = timestamp_dest_fin_ack self.packets.append(destination_fin_ack) # source sends final ACK confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='A') final_ack = (confirm_ether / confirm_ip / confirm_tcp) timestamp_final_ack = Util.update_timestamp( timestamp_dest_fin_ack, pps, min_delay) final_ack.time = timestamp_final_ack self.packets.append(final_ack) else: # Build RST package reply_ether = inet.Ether(src=mac_destination, dst=mac_source) reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=0, ack=attacker_seq, flags='RA', window=destination_win_value, options=[('MSS', destination_mss_value)]) reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp_reply self.packets.append(reply) pps = max( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
def test_generate_source_port_from_platform_newwinmac_firstport(self): self.assertTrue(49152 <= Utility.generate_source_port_from_platform( "win7") <= 65535)
def generate_attack_packets(self): """ Creates the attack packets. """ # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # Initialize parameters self.packets = [] mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) # Pick a DNS server from the background traffic ip_dns_server = self.statistics.process_db_query( "SELECT ipAddress FROM ip_protocols WHERE protocolName='DNS' AND protocolCount=(SELECT MAX(protocolCount) " "FROM ip_protocols WHERE protocolName='DNS');") ip_dns_server = Util.handle_most_used_outputs(ip_dns_server) if not ip_dns_server or ip_source == ip_dns_server: ip_dns_server = self.statistics.get_random_ip_address() mac_dns_server = self.statistics.get_mac_address(ip_dns_server) # Bot original config in the template PCAP origin_mac_src = "08:00:27:e5:d7:b0" origin_ip_src = "10.0.2.15" origin_mac_dns_server = "52:54:00:12:35:02" origin_ip_dns_server = "10.0.2.2" ttl_map = {} ip_map = { origin_ip_src: ip_source, origin_ip_dns_server: ip_dns_server } mac_map = { origin_mac_src: mac_source, origin_mac_dns_server: mac_dns_server } # Inject Sality botnet # Read sality_botnet pcap file exploit_raw_packets = scapy.utils.RawPcapReader( self.template_attack_pcap_path) for self.pkt_num, pkt in enumerate(exploit_raw_packets): eth_frame = inet.Ether(pkt[0]) ip_pkt = eth_frame.payload # Ether if eth_frame.getfieldval("src") in mac_map: eth_frame.setfieldval("src", mac_map[eth_frame.getfieldval("src")]) if eth_frame.getfieldval("dst") in mac_map: eth_frame.setfieldval("dst", mac_map[eth_frame.getfieldval("dst")]) # IP if ip_pkt.getfieldval("src") in ip_map: ip_pkt.setfieldval("src", ip_map[ip_pkt.getfieldval("src")]) if ip_pkt.getfieldval("dst") in ip_map: ip_pkt.setfieldval("dst", ip_map[ip_pkt.getfieldval("dst")]) # TTL if ip_pkt.getfieldval("ttl") not in ttl_map: source_ttl = self.statistics.get_most_used_ttl( ip_pkt.getfieldval("src")) if not source_ttl: source_ttl = self.statistics.process_db_query( "SELECT ttlValue FROM ip_ttl;") if isinstance(source_ttl, list): source_ttl = rnd.choice(source_ttl) ttl_map[ip_pkt.getfieldval("ttl")] = source_ttl ip_pkt.setfieldval("ttl", ttl_map[ip_pkt.getfieldval("ttl")]) new_pkt = (eth_frame / ip_pkt) new_pkt.time = timestamp_next_pkt timestamp_next_pkt = self.timestamp_controller.next_timestamp() self.packets.append(new_pkt) exploit_raw_packets.close()
def generate_attack_packets(self): """ Creates the attack packets. """ # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # calculate complement packet rates of BG traffic per interval complement_interval_pps = self.statistics.calculate_complement_packet_rates( pps) # Initialize parameters self.packets = [] mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) # FIXME: why is port_source never used? port_source = self.get_param_value(atkParam.Parameter.PORT_SOURCE) mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) port_destination = self.get_param_value( atkParam.Parameter.PORT_DESTINATION) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source, 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.Lea.fromValFreqsDict(source_ttl_dist) source_ttl_value = source_ttl_prob_dict.random() else: source_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) destination_ttl_dist = self.statistics.get_ttl_distribution( ip_destination) if len(destination_ttl_dist) > 0: destination_ttl_prob_dict = lea.Lea.fromValFreqsDict( destination_ttl_dist) destination_ttl_value = destination_ttl_prob_dict.random() else: destination_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) # 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.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.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.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.Lea.fromValFreqsDict( destination_win_dist) # Set MSS (Maximum Segment Size) based on MSS distribution of IP address mss_value = Util.handle_most_used_outputs( self.statistics.get_most_used_mss_value()) if not mss_value: mss_value = 1465 # Inject EternalBlue exploit packets # Read Win7_eternalblue_exploit pcap file source_origin_wins, destination_origin_wins = {}, {} exploit_raw_packets = scapy.utils.RawPcapReader( self.template_attack_pcap_path) port_source = rnd.randint( self.minDefaultPort, self.maxDefaultPort) # experiments show this range of ports # conversations = {(ip.src, ip.dst, port.src, port.dst): packets} conversations, order_list_conversations = self.packets_to_convs( exploit_raw_packets) exploit_raw_packets.close() conv_start_timesamp = timestamp_next_pkt for conv_index, conv in enumerate(order_list_conversations): # the distance between the starts of the converstaions conv_start_timesamp = conv_start_timesamp + rnd.uniform( 0.001, 0.01) timestamp_next_pkt = conv_start_timesamp conv_pkts = conversations[conv] inter_arrival_times = self.get_inter_arrival_time(conv_pkts) if conv_index == len( order_list_conversations) - 2: # Not the last conversation timestamp_next_pkt = self.packets[-1].time + rnd.uniform( 0.001, 0.01) if conv_index != len( order_list_conversations) - 1: # Not the last conversation port_source += 2 for self.pkt_num, pkt in enumerate(conv_pkts): eth_frame = inet.Ether(pkt[0]) ip_pkt = eth_frame.payload tcp_pkt = ip_pkt.payload if self.pkt_num == 0: if tcp_pkt.getfieldval("dport") == SMBLib.smb_port: orig_ip_dst = ip_pkt.getfieldval("dst") # 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) ip_pkt.setfieldval("ttl", source_ttl_value) # TCP tcp_pkt.setfieldval("sport", port_source) tcp_pkt.setfieldval("dport", port_destination) # 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( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + inter_arrival_times[ self.pkt_num] # float(timeSteps.random()) # 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) ip_pkt.setfieldval("ttl", destination_ttl_value) # TCP tcp_pkt.setfieldval("dport", port_source) tcp_pkt.setfieldval("sport", port_destination) # 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( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + inter_arrival_times[ self.pkt_num] # float(timeSteps.random()) new_pkt.time = timestamp_next_pkt self.packets.append(new_pkt) else: # Last conversation where the victim start a connection with the attacker timestamp_next_pkt = self.packets[-1].time + rnd.uniform( 0.001, 0.01) port_source = rnd.randint(self.minDefaultPort, self.maxDefaultPort) for self.pkt_num, pkt in enumerate(conv_pkts): eth_frame = inet.Ether(pkt[0]) ip_pkt = eth_frame.payload tcp_pkt = ip_pkt.payload # 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) ip_pkt.setfieldval("ttl", destination_ttl_value) # TCP tcp_pkt.setfieldval("sport", port_source) # destination port is fixed 4444 # 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( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + inter_arrival_times[ self.pkt_num] # float(timeSteps.random()) # 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) ip_pkt.setfieldval("ttl", source_ttl_value) # TCP tcp_pkt.setfieldval("dport", port_source) # source port is fixed 4444 # 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( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + inter_arrival_times[ self.pkt_num] # float(timeSteps.random()) new_pkt.time = timestamp_next_pkt self.packets.append(new_pkt)
def generate_attack_packets(self): """ Creates the attack packets. """ mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) # Determine ports dest_ports = self.get_param_value(atkParam.Parameter.PORT_DESTINATION) if self.get_param_value(atkParam.Parameter.PORT_DEST_ORDER_DESC): dest_ports.reverse() elif self.get_param_value(atkParam.Parameter.PORT_DEST_SHUFFLE): rnd.shuffle(dest_ports) if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE): # FIXME: why is sport never used? sport = rnd.randint(1, 65535) else: sport = self.get_param_value(atkParam.Parameter.PORT_SOURCE) # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = timestamp_next_pkt # Initialize parameters self.packets = [] ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) if isinstance(ip_source, list): ip_source = ip_source[0] ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) if not isinstance(ip_destination, list): ip_destination = [ip_destination] # Check ip.src == ip.dst self.ip_src_dst_catch_equal(ip_source, ip_destination) for ip in ip_destination: # Select open ports ports_open = self.get_param_value(atkParam.Parameter.PORT_OPEN) if ports_open == 1: # user did not specify open ports # the ports that were already used by ip.dst (direction in) in the background traffic are open ports ports_used_by_ip_dst = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip + "'") if ports_used_by_ip_dst: ports_open = ports_used_by_ip_dst else: # if no ports were retrieved from database # Take open ports from nmap-service file # ports_temp = self.get_ports_from_nmap_service_dst(100) # ports_open = ports_temp[0:rnd.randint(1,10)] # OR take open ports from the most used ports in traffic statistics ports_open = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT " + str(rnd.randint(1, 10))) # in case of one open port, convert ports_open to array if not isinstance(ports_open, list): ports_open = [ports_open] # Set MSS (Maximum Segment Size) based on MSS distribution of IP address source_mss_dist = self.statistics.get_mss_distribution(ip_source) if len(source_mss_dist) > 0: source_mss_prob_dict = lea.Lea.fromValFreqsDict( source_mss_dist) source_mss_value = source_mss_prob_dict.random() else: source_mss_value = Util.handle_most_used_outputs( self.statistics.get_most_used_mss_value()) destination_mss_dist = self.statistics.get_mss_distribution(ip) if len(destination_mss_dist) > 0: destination_mss_prob_dict = lea.Lea.fromValFreqsDict( destination_mss_dist) destination_mss_value = destination_mss_prob_dict.random() else: destination_mss_value = Util.handle_most_used_outputs( self.statistics.get_most_used_mss_value()) # 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.Lea.fromValFreqsDict( source_ttl_dist) source_ttl_value = source_ttl_prob_dict.random() else: source_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) destination_ttl_dist = self.statistics.get_ttl_distribution(ip) if len(destination_ttl_dist) > 0: destination_ttl_prob_dict = lea.Lea.fromValFreqsDict( destination_ttl_dist) destination_ttl_value = destination_ttl_prob_dict.random() else: destination_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) # 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.Lea.fromValFreqsDict( source_win_dist) source_win_value = source_win_prob_dict.random() else: source_win_value = Util.handle_most_used_outputs( self.statistics.get_most_used_win_size()) destination_win_dist = self.statistics.get_win_distribution(ip) if len(destination_win_dist) > 0: destination_win_prob_dict = lea.Lea.fromValFreqsDict( destination_win_dist) destination_win_value = destination_win_prob_dict.random() else: destination_win_value = Util.handle_most_used_outputs( self.statistics.get_most_used_win_size()) min_delay, max_delay = self.get_reply_latency(ip_source, ip) for dport in dest_ports: # Parameters changing each iteration if self.get_param_value( atkParam.Parameter.IP_SOURCE_RANDOMIZE) and isinstance( ip_source, list): ip_source = rnd.choice(ip_source) # 1) Build request package request_ether = inet.Ether(src=mac_source, dst=mac_destination) request_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value) # Random src port for each packet sport = rnd.randint(1, 65535) request_tcp = inet.TCP(sport=sport, dport=dport, window=source_win_value, flags='S', options=[('MSS', source_mss_value)]) request = (request_ether / request_ip / request_tcp) request.time = timestamp_next_pkt # Append request self.packets.append(request) # 2) Build reply (for open ports) package if dport in ports_open: # destination port is OPEN reply_ether = inet.Ether(src=mac_destination, dst=mac_source) reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=dport, dport=sport, seq=0, ack=1, flags='SA', window=destination_win_value, options=[('MSS', destination_mss_value)]) reply = (reply_ether / reply_ip / reply_tcp) timestamp_reply = self.timestamp_controller.next_timestamp( latency=min_delay) reply.time = timestamp_reply self.packets.append(reply) # requester confirms confirm_ether = request_ether confirm_ip = request_ip confirm_tcp = inet.TCP(sport=sport, dport=dport, seq=1, window=0, flags='R') confirm = (confirm_ether / confirm_ip / confirm_tcp) self.timestamp_controller.set_timestamp(timestamp_reply) timestamp_confirm = self.timestamp_controller.next_timestamp( latency=min_delay) confirm.time = timestamp_confirm self.packets.append(confirm) # else: destination port is NOT OPEN -> no reply is sent by target self.timestamp_controller.set_timestamp(timestamp_next_pkt) timestamp_next_pkt = self.timestamp_controller.next_timestamp()
def generate_attack_packets(self): """ Creates the attack packets. """ # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # calculate complement packet rates of BG traffic per interval complement_interval_pps = self.statistics.calculate_complement_packet_rates( pps) # Initialize parameters self.packets = [] mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) port_source = self.get_param_value(atkParam.Parameter.PORT_SOURCE) mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) port_destination = self.get_param_value( atkParam.Parameter.PORT_DESTINATION) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source, 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.Lea.fromValFreqsDict(source_ttl_dist) source_ttl_value = source_ttl_prob_dict.random() else: source_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) destination_ttl_dist = self.statistics.get_ttl_distribution( ip_destination) if len(destination_ttl_dist) > 0: destination_ttl_prob_dict = lea.Lea.fromValFreqsDict( destination_ttl_dist) destination_ttl_value = destination_ttl_prob_dict.random() else: destination_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) # 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.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.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.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.Lea.fromValFreqsDict( destination_win_dist) # Set MSS (Maximum Segment Size) based on MSS distribution of IP address mss_value = Util.handle_most_used_outputs( self.statistics.get_most_used_mss_value()) if not mss_value: mss_value = 1465 # Scan (MS17) # Read Win7_eternalblue_scan pcap file orig_ip_dst = None exploit_raw_packets = scapy.utils.RawPcapReader( self.template_scan_pcap_path) inter_arrival_times = self.get_inter_arrival_time(exploit_raw_packets) exploit_raw_packets.close() exploit_raw_packets = scapy.utils.RawPcapReader( self.template_scan_pcap_path) source_origin_wins, destination_origin_wins = {}, {} for self.pkt_num, pkt in enumerate(exploit_raw_packets): eth_frame = inet.Ether(pkt[0]) ip_pkt = eth_frame.payload tcp_pkt = ip_pkt.payload if self.pkt_num == 0: if tcp_pkt.getfieldval("dport") == SMBLib.smb_port: orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP # 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) ip_pkt.setfieldval("ttl", source_ttl_value) # TCP tcp_pkt.setfieldval("sport", port_source) tcp_pkt.setfieldval("dport", port_destination) # Window Size (mapping) 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( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + inter_arrival_times[ self.pkt_num] # float(timeSteps.random()) # 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) ip_pkt.setfieldval("ttl", destination_ttl_value) # TCP tcp_pkt.setfieldval("dport", port_source) tcp_pkt.setfieldval("sport", port_destination) # 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 = Util.update_timestamp( timestamp_next_pkt, pps) + inter_arrival_times[ self.pkt_num] # + float(timeSteps.random()) new_pkt.time = timestamp_next_pkt self.packets.append(new_pkt) exploit_raw_packets.close()
def test_get_smb_platform_data_win(self): guid, blob, cap, d_size, time = SMBLib.get_smb_platform_data("win7", 100) self.assertEqual((blob, cap, d_size), (SMBLib.security_blob_windows, 0x7, 0x100000)) self.assertTrue(isinstance(guid, str) and len(guid) > 0) self.assertTrue(time <= Utility.get_filetime_format(100))
def generate_attack_packets(self): """ Creates the attack packets. """ buffer_size = 1000 # Determine source IP and MAC address num_attackers = self.get_param_value(atkParam.Parameter.NUMBER_ATTACKERS) if (num_attackers is not None) and (num_attackers is not 0): # user supplied atkParam.Parameter.NUMBER_ATTACKERS # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class()) # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS ip_source_list = self.generate_random_ipv4_address(most_used_ip_class, num_attackers) mac_source_list = self.generate_random_mac_address(num_attackers) else: # user did not supply atkParam.Parameter.NUMBER_ATTACKS # use default values for IP_SOURCE/MAC_SOURCE or overwritten values # if user supplied any values for those params ip_source_list = self.get_param_value(atkParam.Parameter.IP_SOURCE) mac_source_list = self.get_param_value(atkParam.Parameter.MAC_SOURCE) # Make sure IPs and MACs are lists if not isinstance(ip_source_list, list): ip_source_list = [ip_source_list] if not isinstance(mac_source_list, list): mac_source_list = [mac_source_list] # Generate MACs for each IP that has no corresponding MAC yet if (num_attackers is None) or (num_attackers is 0): if len(ip_source_list) > len(mac_source_list): mac_source_list.extend(self.generate_random_mac_address(len(ip_source_list)-len(mac_source_list))) num_attackers = min(len(ip_source_list), len(mac_source_list)) # Initialize parameters self.packets = col.deque(maxlen=buffer_size) port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE) if not isinstance(port_source_list, list): port_source_list = [port_source_list] mac_destination = self.get_param_value(atkParam.Parameter.MAC_DESTINATION) ip_destination = self.get_param_value(atkParam.Parameter.IP_DESTINATION) most_used_ip_address = self.statistics.get_most_used_ip_address() pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) if pps == 0: result = self.statistics.process_db_query( "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + ip_destination + "';") if result is not None and not 0: pps = num_attackers * result else: result = self.statistics.process_db_query( "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + most_used_ip_address + "';") pps = num_attackers * result # Calculate complement packet rates of the background traffic for each interval attacker_pps = pps / num_attackers #complement_interval_attacker_pps = self.statistics.calculate_complement_packet_rates(attacker_pps) # Check ip.src == ip.dst self.ip_src_dst_catch_equal(ip_source_list, ip_destination) port_destination = self.get_param_value(atkParam.Parameter.PORT_DESTINATION) if not port_destination: # user did not define port_dest port_destination = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "');") if not port_destination: # no port was retrieved port_destination = self.statistics.process_db_query( "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE " "portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) " "FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);") if not port_destination: port_destination = max(1, int(inet.RandShort())) port_destination = Util.handle_most_used_outputs(port_destination) self.path_attack_pcap = None victim_buffer = self.get_param_value(atkParam.Parameter.VICTIM_BUFFER) attack_duration = self.get_param_value(atkParam.Parameter.ATTACK_DURATION) pkts_num = int(pps * attack_duration) source_win_sizes = self.statistics.get_rnd_win_size(pkts_num) destination_win_dist = self.statistics.get_win_distribution(ip_destination) if len(destination_win_dist) > 0: destination_win_prob_dict = lea.Lea.fromValFreqsDict(destination_win_dist) destination_win_value = destination_win_prob_dict.random() else: destination_win_value = self.statistics.get_most_used_win_size() destination_win_value = Util.handle_most_used_outputs(destination_win_value) # MSS that was used by IP destination in background traffic mss_dst = self.statistics.get_most_used_mss(ip_destination) if mss_dst is None: mss_dst = self.statistics.get_most_used_mss_value() mss_dst = Util.handle_most_used_outputs(mss_dst) # get user defined bandwidth bandwidth_max = self.get_param_value(atkParam.Parameter.BANDWIDTH_MAX) bandwidth_min_local = self.get_param_value(atkParam.Parameter.BANDWIDTH_MIN_LOCAL) bandwidth_min_public = self.get_param_value(atkParam.Parameter.BANDWIDTH_MIN_PUBLIC) # check user defined latency latency_limit = None latency_max = self.get_param_value(atkParam.Parameter.LATENCY_MAX) if latency_max != 0: latency_limit = latency_max # Stores triples of (timestamp, source_id, destination_id) for each timestamp. # Victim has id=0. Attacker tuple does not need to specify the destination because it's always the victim. timestamps_tuples = [] # For each attacker(id), stores the current source-ports of SYN-packets # which still have to be acknowledged by the victim, as a "FIFO" for each attacker previous_attacker_port = [] replies_count = 0 self.total_pkt_num = 0 already_used_pkts = 0 sum_diff = 0 self.attack_start_utime = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP) self.timestamp_controller.set_pps(attacker_pps) attack_ends_time = self.timestamp_controller.get_timestamp() + attack_duration # For each attacker, generate his own packets, then merge all packets for attacker in range(num_attackers): # set latency limit to either the minimal latency occurring in the pcap, the default or the user specified limit # get minimal and maximal latency found in the pcap if not latency_limit: min_latency, max_latency = self.get_reply_latency(ip_source_list[attacker], ip_destination) latency_limit = min_latency # Initialize empty port "FIFO" for current attacker previous_attacker_port.append([]) # Calculate timestamp of first SYN-packet of attacker timestamp_next_pkt = self.timestamp_controller.reset_timestamp() if attacker != 0: timestamp_next_pkt = rnd.uniform(timestamp_next_pkt, self.timestamp_controller.next_timestamp(latency=latency_limit)) # calculate each attackers packet count without exceeding the total number of attackers attacker_pkts_num = 0 if already_used_pkts < pkts_num: random_offset = rnd.randint(0, int(pkts_num / num_attackers / 2)) if attacker == num_attackers-1: random_offset = 0 attacker_pkts_num = int((pkts_num - already_used_pkts) / (num_attackers - attacker)) + random_offset already_used_pkts += attacker_pkts_num # each attacker gets a different pps according to his pkt count offset ratio = float(attacker_pkts_num) / float(pkts_num) attacker_pps = pps * ratio self.timestamp_controller.set_pps(attacker_pps) for pkt_num in range(attacker_pkts_num): # Count attack packets that exceed the attack duration if timestamp_next_pkt > attack_ends_time: diff = timestamp_next_pkt-attack_ends_time sum_diff += diff self.exceeding_packets += 1 # Add timestamp of attacker SYN-packet. Attacker tuples do not need to specify destination timestamps_tuples.append((timestamp_next_pkt, attacker+1)) # Calculate timestamp of victim ACK-packet timestamp_reply = self.timestamp_controller.next_timestamp(latency=latency_limit) # Add timestamp of victim ACK-packet(victim always has id=0) timestamps_tuples.append((timestamp_reply, 0, attacker+1)) # Calculate timestamp for next attacker SYN-packet self.timestamp_controller.set_timestamp(timestamp_next_pkt) timestamp_next_pkt = self.timestamp_controller.next_timestamp() # Sort timestamp-triples according to their timestamps in ascending order timestamps_tuples.sort(key=lambda tmstmp: tmstmp[0]) self.attack_start_utime = timestamps_tuples[0][0] sent_bytes = 0 previous_interval = 0 interval_count = 0 full_interval = None reply = None # For each triple, generate packet for timestamp in timestamps_tuples: # tuple layout: [timestamp, attacker_id] # If current current triple is an attacker if timestamp[1] != 0: attacker_id = timestamp[1]-1 # Build request package # Select one IP address and its corresponding MAC address ip_source = ip_source_list[attacker_id] mac_source = mac_source_list[attacker_id] # Determine source port (port_source, ttl_value) = Util.get_attacker_config(ip_source_list, ip_source) # If source ports were specified by the user, get random port from specified ports if port_source_list[0] != self.default_port: port_source = rnd.choice(port_source_list) # Push port of current attacker SYN-packet into port "FIFO" of the current attacker # only if victim can still respond, otherwise, memory is wasted if replies_count <= victim_buffer: previous_attacker_port[attacker_id].insert(0, port_source) request_ether = inet.Ether(dst=mac_destination, src=mac_source) request_ip = inet.IP(src=ip_source, dst=ip_destination, ttl=ttl_value) # Random win size for each packet source_win_size = rnd.choice(source_win_sizes) request_tcp = inet.TCP(sport=port_source, dport=port_destination, flags='S', ack=0, window=source_win_size) request = (request_ether / request_ip / request_tcp) request.time = timestamp[0] pkt = request # If current triple is the victim else: # Build reply package if replies_count <= victim_buffer: attacker_id = timestamp[2]-1 ip_source = ip_source_list[attacker_id] reply_ether = inet.Ether(src=mac_destination, dst=mac_source_list[attacker_id]) reply_ip = inet.IP(src=ip_destination, dst=ip_source, flags='DF') # Pop port from attacker's port "FIFO" into destination port reply_tcp = inet.TCP(sport=port_destination, dport=previous_attacker_port[attacker_id].pop(), seq=0, ack=1, flags='SA', window=destination_win_value, options=[('MSS', mss_dst)]) reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp[0] pkt = reply bytes = len(pkt) remaining_bytes, current_interval = self.get_remaining_bandwidth(pkt.time, ip_source, ip_destination, bandwidth_max, bandwidth_min_local, bandwidth_min_public) if previous_interval != current_interval: sent_bytes = 0 interval_count += 1 previous_interval = current_interval if current_interval != full_interval: remaining_bytes *= 1000 remaining_bytes -= sent_bytes if remaining_bytes >= bytes: sent_bytes += bytes self.packets.append(pkt) self.total_pkt_num += 1 if pkt == reply: replies_count += 1 else: print("Warning: generated attack packets exceeded bandwidth. Packets in interval {} " "were omitted.".format(interval_count)) full_interval = current_interval # every 1000 packets write them to the pcap file (append) if (self.total_pkt_num > 0) and (self.total_pkt_num % buffer_size == 0) and (len(self.packets) > 0): self.last_packet = self.packets[-1] self.attack_end_utime = self.last_packet.time self.packets = sorted(self.packets, key=lambda pkt: pkt.time) self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap) self.packets = []
def generate_attack_packets(self): """ Creates the attack packets. """ # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # Calculate complement packet rates of BG traffic per interval complement_interval_pps = self.statistics.calculate_complement_packet_rates( pps) # Initialize parameters self.packets = [] mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) if isinstance(ip_source, list): ip_source = ip_source[0] mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) if isinstance(ip_destination, list): ip_destination = ip_destination[0] port_destination = self.get_param_value( atkParam.Parameter.PORT_DESTINATION) target_host = self.get_param_value(atkParam.Parameter.TARGET_HOST) target_uri = "/" # self.get_param_value(atkParam.Parameter.TARGET_URI) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source, 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.Lea.fromValFreqsDict(source_ttl_dist) source_ttl_value = source_ttl_prob_dict.random() else: source_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) destination_ttl_dist = self.statistics.get_ttl_distribution( ip_destination) if len(destination_ttl_dist) > 0: destination_ttl_prob_dict = lea.Lea.fromValFreqsDict( destination_ttl_dist) destination_ttl_value = destination_ttl_prob_dict.random() else: destination_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) # Inject SQLi Attack # Read SQLi Attack pcap file orig_ip_dst = None exploit_raw_packets = scapy.utils.RawPcapReader( self.template_attack_pcap_path) inter_arrival_times, inter_arrival_time_dist = self.get_inter_arrival_time( exploit_raw_packets, True) time_steps = lea.Lea.fromValFreqsDict(inter_arrival_time_dist) exploit_raw_packets.close() exploit_raw_packets = scapy.utils.RawPcapReader( self.template_attack_pcap_path) port_source = rnd.randint( self.minDefaultPort, self.maxDefaultPort) # experiments show this range of ports # Random TCP sequence numbers global attacker_seq attacker_seq = rnd.randint(1000, 50000) global victim_seq victim_seq = rnd.randint(1000, 50000) for self.pkt_num, pkt in enumerate(exploit_raw_packets): eth_frame = inet.Ether(pkt[0]) ip_pkt = eth_frame.payload tcp_pkt = ip_pkt.payload str_tcp_seg = str(tcp_pkt.payload) # Clean payloads eth_frame.payload = b'' ip_pkt.payload = b'' tcp_pkt.payload = b'' # FIXME: no getfieldval in class bytes if self.pkt_num == 0: prev_orig_port_source = tcp_pkt.getfieldval("sport") orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP # Last connection if tcp_pkt.getfieldval("dport") != 80 and tcp_pkt.getfieldval( "sport") != 80: # New connection, new random TCP sequence numbers attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) # First packet in a connection has ACK = 0 tcp_pkt.setfieldval("ack", 0) # Attacker --> vicitm if ip_pkt.getfieldval("dst") == orig_ip_dst: # victim IP # There are 363 TCP connections with different source ports, for each of them we generate random port if tcp_pkt.getfieldval("sport") != prev_orig_port_source and tcp_pkt.getfieldval("dport") != 4444 \ and (tcp_pkt.getfieldval("dport") == 80 or tcp_pkt.getfieldval("sport") == 80): port_source = rnd.randint(self.minDefaultPort, self.maxDefaultPort) prev_orig_port_source = tcp_pkt.getfieldval("sport") # New connection, new random TCP sequence numbers attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) # First packet in a connection has ACK = 0 tcp_pkt.setfieldval("ack", 0) # 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) ip_pkt.setfieldval("ttl", source_ttl_value) # TCP # Regular connection if tcp_pkt.getfieldval("dport") == 80 or tcp_pkt.getfieldval( "sport") == 80: tcp_pkt.setfieldval("sport", port_source) tcp_pkt.setfieldval("dport", port_destination) str_tcp_seg = self.modify_http_header(str_tcp_seg, '/ATutor', target_uri, orig_ip_dst, target_host) # TCP Seq, Ack if tcp_pkt.getfieldval("ack") != 0: tcp_pkt.setfieldval("ack", victim_seq) tcp_pkt.setfieldval("seq", attacker_seq) if not (tcp_pkt.getfieldval("flags") == 16 and len(str_tcp_seg) == 0): # flags=A: attacker_seq += max(len(str_tcp_seg), 1) new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg) new_pkt.time = timestamp_next_pkt pps = max( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + float(time_steps.random()) # Victim --> attacker 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) ip_pkt.setfieldval("ttl", destination_ttl_value) # TCP # Regular connection if tcp_pkt.getfieldval("dport") == 80 or tcp_pkt.getfieldval( "sport") == 80: tcp_pkt.setfieldval("dport", port_source) tcp_pkt.setfieldval("sport", port_destination) str_tcp_seg = self.modify_http_header(str_tcp_seg, '/ATutor', target_uri, orig_ip_dst, target_host) # TCP Seq, ACK tcp_pkt.setfieldval("ack", attacker_seq) tcp_pkt.setfieldval("seq", victim_seq) strLen = len(str_tcp_seg) if not (tcp_pkt.getfieldval("flags") == 16 and strLen == 0): # flags=A: victim_seq += max(strLen, 1) new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, pps) + float(time_steps.random()) new_pkt.time = timestamp_next_pkt self.packets.append(new_pkt) exploit_raw_packets.close()