class PacketManipulation: def __init__(self, packet_headers, net_info, data, connection, from_server): self.Checksum = Checksums() self.packet_headers = packet_headers self.dst_mac, self.wan_subnet = net_info self.data = data self.connection = connection self.from_server = from_server self.tcp_header_length = 0 self.dst_ip = None self.nat_port = None self.payload = b'' if (from_server): self.src_mac = connection['LAN']['MAC'] self.src_ip = connection['Server']['IP'] self.dst_ip = connection['Client']['IP'] self.client_port = connection['Client']['Port'] self.client_port = struct.pack('!H', connection['Client']['Port']) else: self.src_mac = connection['NAT']['MAC'] self.src_ip = connection['NAT']['IP'] self.nat_port = connection['NAT']['Port'] self.nat_port = struct.pack('!H', self.nat_port) self.dst_ip = self.packet_headers.dst self.dst_port = self.data[36:38] def Start(self): self.CheckDestination() self.TCP() self.PsuedoHeader() self.RebuildHeaders() def CheckDestination(self): if (self.dst_ip in self.wan_subnet): Int = Interface() dst_mac = Int.IPtoMAC(self.dst_ip) if (not dst_mac): run(f'ping {self.dst_ip} -c 1', shell=True) self.dst_mac = Int.IPtoMAC(self.dst_ip) else: self.dst_mac = dst_mac ''' Parsing TCP information like sequence and acknowledgement number amd calculated tcp header length to be used by other classes for offset/proper indexing of packet contents. Returning all relevant information back to HeaderParse Start method to be redistributed to other classes based on need ''' def TCP(self): bit_values = [32, 16, 8, 4] tcp = self.data[34:94] tmp_length = bin(tcp[12])[2:6] for i, bit in enumerate(tmp_length): if (bit == '1'): self.tcp_header_length += bit_values[i] self.tcp_header = self.data[34:34 + self.tcp_header_length] self.tcp_length = len(self.data) - 34 if (len(self.data) > 34 + self.tcp_header_length): self.payload = self.data[34 + self.tcp_header_length:] def PsuedoHeader(self): psuedo_header = b'' psuedo_header += inet_aton(self.src_ip) psuedo_header += inet_aton(self.dst_ip) psuedo_header += struct.pack('!2BH', 0, 6, self.tcp_length) if (self.from_server): psuedo_header += self.tcp_header[ 0:2] + self.client_port + self.tcp_header[ 4:16] + b'\x00\x00' + self.tcp_header[18:] else: psuedo_header += self.nat_port + self.tcp_header[ 2:16] + b'\x00\x00' + self.tcp_header[18:] psuedo_packet = psuedo_header + self.payload tcp_checksum = self.Checksum.TCP(psuedo_packet) self.tcp_checksum = struct.pack('<H', tcp_checksum) def RebuildHeaders(self): ethernet_header = self.RebuildEthernet() ip_header = self.RebuildIP() tcp_header = self.RebuildTCP() self.send_data = ethernet_header + ip_header + tcp_header + self.payload def RebuildEthernet(self): eth_header = struct.pack( '!6s6s', binascii.unhexlify(self.dst_mac.replace(':', '')), binascii.unhexlify(self.src_mac.replace(':', ''))) eth_header += self.packet_headers.eth_proto return eth_header def RebuildIP(self): ipv4_header = b'' ipv4_header += self.packet_headers.ipv4H[:10] ipv4_header += b'\x00\x00' ipv4_header += inet_aton(self.src_ip) ipv4_header += inet_aton(self.dst_ip) if (len(self.packet_headers.ipv4H) > 20): ipv4_header += self.packet_headers.ipv4H[20:] ipv4_checksum = self.Checksum.IPv4(ipv4_header) ipv4_checksum = struct.pack('<H', ipv4_checksum) ipv4_header = ipv4_header[:10] + ipv4_checksum + ipv4_header[12:] return ipv4_header def RebuildTCP(self): if (self.from_server): tcp_header = self.tcp_header[:2] + self.client_port + self.tcp_header[ 4:16] + self.tcp_checksum + b'\x00\x00' else: tcp_header = self.nat_port + self.tcp_header[ 2:16] + self.tcp_checksum + b'\x00\x00' if (self.tcp_header_length > 20): tcp_header += self.tcp_header[20:self.tcp_header_length] return tcp_header
class TCPPacket: def __init__(self, wan_int, packet): self.packet = packet self.wan_int = wan_int self.Checksum = Checksums() def Create(self): self.AssignValues() self.CreateIPv4() self.CreateTCP() self.AssembleIPv4() self.AssembleTCP() self.ipv4_checksum = self.Checksum.IPv4(self.ipv4_header) self.tcp_checksum = self.PseudoHeader() def AssignValues(self): self.l2pro = 0x0800 Int = Interface() self.smac = Int.MAC(self.wan_int) self.dmac = self.packet.src_mac self.src_ip = Int.IP(self.wan_int) self.dst_ip = self.packet.src_ip self.src_port = self.packet.dst_port self.dst_port = self.packet.src_port self.sport = struct.pack('!H', self.src_port) # print(self.packet.seq_number) self.ack_number = self.packet.seq_number + 1 ## -- L2 - Ethernet Section ---- ## def AssembleEthernet(self): self.ethernet_header = struct.pack( '!6s6sH', binascii.unhexlify(self.dmac.replace(':', '')), binascii.unhexlify(self.smac.replace(':', '')), self.l2pro) ## -- L3 - IP Section ---- ## def CreateIPv4(self): ip_ver = 4 ip_vhl = 5 self.ip_ver = (ip_ver << 4) + ip_vhl ip_dsc = 0 ip_ecn = 0 self.ip_dfc = (ip_dsc << 2) + ip_ecn self.ip_tol = 20 + 20 # ---- [ Total Length] self.ip_idf = 1 # ---- [ Identification ] ip_rsv = 0 # ---- [ Flags ] ip_dtf = 0 ip_mrf = 0 ip_frag_offset = 0 self.ip_flg = (ip_rsv << 7) + (ip_dtf << 6) + (ip_mrf << 5) + ( ip_frag_offset) self.ip_ttl = 255 # ---- [ Total Length ] self.ip_proto = TCP # ---- [ Protocol ] self.ipv4_checksum = 0 # ---- [ Check Sum ] self.ip_saddr = inet_aton(self.src_ip) # ---- [ Source Address ] self.ip_daddr = inet_aton(self.dst_ip) # ---- [ Destination Address ] def AssembleIPv4(self): self.ipv4_header = struct.pack( '!2B3H2B', self.ip_ver, # IP Version self.ip_dfc, # Differentiate Service Field self.ip_tol, # Total Length self.ip_idf, # Identification self.ip_flg, # Flags self.ip_ttl, # Time to leave self.ip_proto # protocol ) self.ipv4_header += struct.pack( '<H', self.ipv4_checksum # Checksum ) self.ipv4_header += struct.pack( '!4s4s', self.ip_saddr, # Source IP self.ip_daddr # Destination IP ) ## -- L4 - UDP Section ---- ## def CreateTCP(self): self.tcp_seq = 0 self.tcp_ack_seq = self.ack_number self.tcp_hdr_len = 80 tcp_urg = 0 tcp_ack = 1 tcp_psh = 0 tcp_rst = 1 tcp_syn = 0 tcp_fin = 0 tcp_doff = 5 self.tcp_offset_res = (tcp_doff << 4) + 0 self.tcp_flags = tcp_fin + (tcp_syn << 1) + (tcp_rst << 2) + ( tcp_psh << 3) + (tcp_ack << 4) + (tcp_urg << 5) self.tcp_wdw = htons(0) self.tcp_checksum = 0 self.tcp_urg_ptr = 0 self.padding = b'\x00' * 12 def AssembleTCP(self): self.tcp_header = struct.pack('!2H2L2B3H', self.src_port, self.dst_port, self.tcp_seq, self.tcp_ack_seq, self.tcp_offset_res, self.tcp_flags, self.tcp_wdw, self.tcp_checksum, self.tcp_urg_ptr) def PseudoHeader(self): pseudo_header = b'' pseudo_header += inet_aton(self.src_ip) pseudo_header += inet_aton(self.dst_ip) pseudo_header += struct.pack('!2BH', 0, 6, 54) pseudo_header += self.sport + self.tcp_header[ 2:16] + b'\x00\x00' + self.tcp_header[18:] tcp_checksum = self.Checksum.TCP(pseudo_header) return tcp_checksum
class CreatePacket: def __init__(self, connection, to_server=False): self.connection = connection self.to_server = to_server self.Checksum = Checksums() def Create(self): self.AssignValues() self.CreateIPv4() self.CreateTCP() self.AssembleIPv4() self.AssembleTCP() self.ipv4_checksum = self.Checksum.IPv4(self.ipv4_header) self.tcp_checksum = self.PseudoHeader() def AssignValues(self): self.l2pro = 0x0800 self.nat_port = struct.pack('!H', self.connection['NAT']['Port']) self.client_port = struct.pack('!H', self.connection['Client']['Port']) if (self.to_server): self.smac = self.connection['NAT']['MAC'] self.src_ip = self.connection['NAT']['IP'] self.sport = self.connection['NAT']['Port'] self.dmac = self.connection['DFG']['MAC'] self.dst_ip = self.connection['Server']['IP'] self.dport = self.connection['Server']['Port'] else: self.smac = self.connection['LAN']['MAC'] self.src_ip = self.connection['Server']['IP'] self.sport = self.connection['Server']['Port'] self.dmac = self.connection['Client']['MAC'] self.dst_ip = self.connection['Client']['IP'] self.dport = self.connection['Client']['Port'] ## -- L2 - Ethernet Section ---- ## def AssembleEthernet(self): self.ethernet_header = struct.pack('!6s6sH' , binascii.unhexlify(self.dmac.replace(":","")), binascii.unhexlify(self.smac.replace(":","")), self.l2pro) ## -- L3 - IP Section ---- ## def CreateIPv4(self): ip_ver = 4 ip_vhl = 5 self.ip_ver = (ip_ver << 4 ) + ip_vhl ip_dsc = 0 ip_ecn = 0 self.ip_dfc = (ip_dsc << 2 ) + ip_ecn self.ip_tol = 20 + 20 # ---- [ Total Length] self.ip_idf = 1 # ---- [ Identification ] ip_rsv = 0 # ---- [ Flags ] ip_dtf = 0 ip_mrf = 0 ip_frag_offset = 0 self.ip_flg = (ip_rsv << 7) + (ip_dtf << 6) + (ip_mrf << 5) + (ip_frag_offset) self.ip_ttl = 255 # ---- [ Total Length ] self.ip_proto = IPPROTO_TCP # ---- [ Protocol ] self.ipv4_checksum = 0 # ---- [ Check Sum ] self.ip_saddr = inet_aton(self.src_ip) # ---- [ Source Address ] self.ip_daddr = inet_aton(self.dst_ip) # ---- [ Destination Address ] def AssembleIPv4(self): self.ipv4_header = struct.pack('!2B3H2B' , self.ip_ver, # IP Version self.ip_dfc, # Differentiate Service Field self.ip_tol, # Total Length self.ip_idf, # Identification self.ip_flg, # Flags self.ip_ttl, # Time to leave self.ip_proto # protocol ) self.ipv4_header += struct.pack('<H' , self.ipv4_checksum # Checksum ) self.ipv4_header += struct.pack('!4s4s' , self.ip_saddr, # Source IP self.ip_daddr # Destination IP ) ## -- L4 - UDP Section ---- ## def CreateTCP(self): self.tcp_seq = 696969 self.tcp_ack_seq = 0 self.tcp_hdr_len = 80 tcp_urg = 0 tcp_ack = 0 tcp_psh = 0 tcp_rst = 1 tcp_syn = 0 tcp_fin = 0 tcp_doff = 5 self.tcp_offset_res = (tcp_doff << 4) + 0 self.tcp_flags = tcp_fin + (tcp_syn << 1) + (tcp_rst << 2) + (tcp_psh << 3) + (tcp_ack << 4) + (tcp_urg << 5) self.tcp_wdw = htons(5840) self.tcp_checksum = 0 self.tcp_urg_ptr = 0 self.padding = b'\x00'*12 def AssembleTCP(self): self.tcp_header = struct.pack('!2H2L2B3H', self.sport, self.dport, self.tcp_seq, self.tcp_ack_seq, self.tcp_offset_res, self.tcp_flags, self.tcp_wdw, self.tcp_checksum, self.tcp_urg_ptr ) def PseudoHeader(self): pseudo_header = b'' pseudo_header += inet_aton(self.src_ip) pseudo_header += inet_aton(self.dst_ip) pseudo_header += struct.pack('!2BH', 0, 6, 54) if (self.to_server): pseudo_header += self.nat_port + self.tcp_header[2:16] + b'\x00\x00' + self.tcp_header[18:] else: pseudo_header += self.tcp_header[0:2] + self.client_port + self.tcp_header[4:16] + b'\x00\x00' + self.tcp_header[18:] pseudo_packet = pseudo_header tcp_checksum = self.Checksum.TCP(pseudo_packet) return tcp_checksum