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 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() # 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) 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 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 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. """ 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. """ pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # Timestamp first_timestamp = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = first_timestamp # Initialize parameters self.packets = [] ip_destination = self.get_param_value(atkParam.Parameter.IP_DESTINATION) mac_destination = self.get_param_value(atkParam.Parameter.MAC_DESTINATION) # Determine source IP and MAC address num_attackers = self.get_param_value(atkParam.Parameter.NUMBER_ATTACKERS) # user supplied atkParam.Parameter.NUMBER_ATTACKERS if (num_attackers is not None) and (num_attackers is not 0): # 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 = self.generate_random_ipv4_address(most_used_ip_class, num_attackers) mac_source = 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 = self.get_param_value(atkParam.Parameter.IP_SOURCE) mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) ip_source_list = [] mac_source_list = [] if isinstance(ip_source, list): ip_source_list = ip_source else: ip_source_list.append(ip_source) if isinstance(mac_source, list): mac_source_list = mac_source else: mac_source_list.append(mac_source) if (num_attackers is None) or (num_attackers is 0): num_attackers = min(len(ip_source_list), len(mac_source_list)) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source_list, ip_destination) # Get MSS, TTL and Window size value for destination IP destination_mss_value, destination_ttl_value, destination_win_value = self.get_ip_data(ip_destination) min_delay, max_delay = self.get_reply_delay(ip_destination) attack_duration = self.get_param_value(atkParam.Parameter.ATTACK_DURATION) attack_ends_time = first_timestamp + attack_duration victim_pps = pps * num_attackers for attacker in range(num_attackers): # Get MSS, TTL and Window size value for source IP(attacker) source_mss_value, source_ttl_value, source_win_value = self.get_ip_data(ip_source_list[attacker]) attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) sport = 1025 # Timestamps of first self.packets shouldn't be exactly the same to look more realistic timestamp_next_pkt = rnd.uniform(first_timestamp, Util.update_timestamp(first_timestamp, pps)) while timestamp_next_pkt <= attack_ends_time: # Establish TCP connection if sport > 65535: sport = 1025 # prepare reusable Ethernet- and IP-headers attacker_ether = inet.Ether(src=mac_source_list[attacker], dst=mac_destination) attacker_ip = inet.IP(src=ip_source_list[attacker], dst=ip_destination, ttl=source_ttl_value, flags='DF') victim_ether = inet.Ether(src=mac_destination, dst=mac_source_list[attacker]) victim_ip = inet.IP(src=ip_destination, dst=ip_source_list[attacker], ttl=destination_ttl_value, flags='DF') # connection request from attacker (client) syn_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 syn = (attacker_ether / attacker_ip / syn_tcp) syn.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, victim_pps, min_delay) self.packets.append(syn) # response from victim (server) synack_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 synack = (victim_ether / victim_ip / synack_tcp) synack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(synack) # acknowledgement from attacker (client) ack_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, flags='A', window=source_win_value, options=[('MSS', source_mss_value)]) ack = (attacker_ether / attacker_ip / ack_tcp) ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ack) # send NBT session header packet with maximum LENGTH-field req_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, flags='AP', window=source_win_value, options=[('MSS', source_mss_value)]) req_payload = NBTSession(TYPE=0x00, LENGTH=0x1FFFF) attacker_seq += len(req_payload) req = (attacker_ether / attacker_ip / req_tcp / req_payload) req.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, victim_pps, min_delay) self.packets.append(req) # final ack from victim (server) last_ack_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='A', window=destination_win_value, options=[('MSS', destination_mss_value)]) last_ack = (victim_ether / victim_ip / last_ack_tcp) last_ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(last_ack) sport += 1
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 test_handle_most_used_outputs_list_unsorted(self): test_input = [2, 4, 0, 1, 3] self.assertEqual(Utility.handle_most_used_outputs(test_input), 0)
def test_handle_most_used_outputs_list_sorted(self): test_input = [0, 1, 2, 3, 4] self.assertEqual(Utility.handle_most_used_outputs(test_input), 0)
def test_handle_most_used_outputs_one_list(self): test_input = ["SomeTest"] self.assertEqual(Utility.handle_most_used_outputs(test_input), test_input[0])
def test_handle_most_used_outputs_one(self): test_input = "SomeTest" self.assertEqual(Utility.handle_most_used_outputs(test_input), test_input)
def test_handle_most_used_outputs_empty(self): self.assertIsNone(Utility.handle_most_used_outputs([]))
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) port_source = rnd.randint(self.minDefaultPort, self.maxDefaultPort) 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) 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_catch_equal(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 Joomla_registration_privesc # Read joomla_registration_privesc 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) exploit_raw_packets.close() time_steps = lea.Lea.fromValFreqsDict(inter_arrival_time_dist) exploit_raw_packets = scapy.utils.RawPcapReader( self.template_attack_pcap_path) # 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") if tcp_pkt.getfieldval("dport") == self.http_port: orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP # Request: Attacker --> vicitm if ip_pkt.getfieldval("dst") == orig_ip_dst: # victim IP # There are 7 TCP connections with different source ports, for each of them we generate random port if tcp_pkt.getfieldval("sport") != prev_orig_port_source: 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 tcp_pkt.setfieldval("sport", port_source) tcp_pkt.setfieldval("dport", port_destination) str_tcp_seg = self.modify_http_header(str_tcp_seg, '/joomla360', 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 timestamp_next_pkt = self.timestamp_controller.next_timestamp( ) + float(time_steps.random()) # Reply: 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 tcp_pkt.setfieldval("dport", port_source) tcp_pkt.setfieldval("sport", port_destination) str_tcp_seg = self.modify_http_header(str_tcp_seg, '/joomla360', target_uri, orig_ip_dst, target_host) # TCP Seq, ACK tcp_pkt.setfieldval("ack", attacker_seq) tcp_pkt.setfieldval("seq", victim_seq) str_len = len(str_tcp_seg) if not (tcp_pkt.getfieldval("flags") == 16 and str_len == 0): # flags=A: victim_seq += max(str_len, 1) new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg) timestamp_next_pkt = self.timestamp_controller.next_timestamp( ) + float(time_steps.random()) new_pkt.time = timestamp_next_pkt self.packets.append(new_pkt) exploit_raw_packets.close()
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. """ # 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) 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 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()