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
Exemple #3
0
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