Example #1
0
 def sendSYN(self, target, ethhead):
     """Method sending a given SYN packet to target. The SYN packet will be
     changed to not support TCPOPT_TIMESTAMP.
     """
     eth = ethhead
     iphead = eth.child()
     tcphead = iphead.child()
     if target == TCPConnection.TAIL:
         out = TCPConnection.alt_stdout
         host = self.head
     # target == Connection.HEAD
     else:
         out = TCPConnection.stdout
         host = self.tail
     nop = ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_NOP)
     # If there is a Maximum Segment Size (MSS) give, we need to set it as
     # the upper threshold for the packet size.
     for option in tcphead.get_options():
         if option.get_kind() == ImpactPacket.TCPOption.TCPOPT_MAXSEG:
             host.mss = option.get_mss()
     # We need to check the availiable options and only delete all
     # non MSS options. (TODO: Very bad practice. Do this properly!!)
     i = 0
     for option in tcphead.get_options():
         if option.get_kind() != ImpactPacket.TCPOption.TCPOPT_MAXSEG:
             # Bad practice, but seems like the only possible way.
             tcphead._TCP__option_list[i] = nop
         i += 1
     # Recalculate the ipheader length
     iphead.set_ip_len(0)
     packet = encode(eth)
     if s.verbosity > 9:
         s.logfile.write("Syn packet sent: " + str(eth) + "\n")
     send(target, self, packet)
Example #2
0
    def build_reply(self, packet, path, personality, cb_ip_id, cb_tcp_seq, cb_tcp_ts):
        """Function creates a reply according to the personality of the device
        Args:
            packet : intercepted packet
            path : length of path in the virtual network
            personality : personality description of the device
            cb_ipid, cb_tcp_seq, cb_tcp_ts : callback functions for IP ID, TCP SEQ and TCP TS generation
        Return
            reply ip packet
        """
        # fingerprint fields R, DF, T, TG, W, S, A, F, O, RD, Q & CC

        # tcp packet
        tcp_pkt = packet.child()
        reply_tcp = ImpactPacket.TCP()
        reply_tcp.set_th_sport(tcp_pkt.get_th_dport())
        reply_tcp.set_th_dport(tcp_pkt.get_th_sport())
        reply_tcp.set_th_flags(0)
        reply_tcp.auto_checksum = 1

        # ip packet
        reply_ip = ImpactPacket.IP()
        reply_ip.set_ip_v(4)
        reply_ip.set_ip_p(6)
        reply_ip.set_ip_rf(False)
        reply_ip.set_ip_df(False)
        reply_ip.set_ip_mf(False)
        reply_ip.set_ip_src(packet.get_ip_dst())
        reply_ip.set_ip_dst(packet.get_ip_src())
        reply_ip.set_ip_id(cb_ip_id())
        reply_ip.auto_checksum = 1

        # check DF
        if 'DF' in personality:
            if personality['DF'] == 'N':
                reply_ip.set_ip_df(False)
            elif personality['DF'] == 'Y':
                reply_ip.set_ip_df(True)
            else:
                raise Exception('Unsupported Ti:DF=%s', personality['DF'])

        # check T
        ttl = 0x7f
        if 'T' in personality:
            try:
                ttl = personality['T'].split('-')
                # using minimum ttl
                ttl = int(ttl[0], 16)
            except BaseException:
                raise Exception('Unsupported Ti:T=%s', personality['T'])

        # check TG
        if 'TG' in personality:
            try:
                ttl = int(personality['TG'], 16)
            except BaseException:
                raise Exception('Unsupported Ti:TG=%s', personality['TG'])

        delta_ttl = ttl - path
        if delta_ttl < 1:
            logger.debug('Reply packet dropped: TTL reached 0 within virtual network.')
            return None
        reply_ip.set_ip_ttl(delta_ttl)

        # check W
        win = 0
        if 'W' in personality:
            try:
                win = int(personality['W'], 16)
            except BaseException:
                raise Exception('Unsupported Ti:W=%s', personality['W'])
        reply_tcp.set_th_win(win)

        # check CC
        if 'CC' in personality:
            if personality['CC'] == 'N':
                reply_tcp.reset_ECE()
                reply_tcp.reset_CWR()
            elif personality['CC'] == 'Y':
                reply_tcp.set_ECE()
                reply_tcp.reset_CWR()
            elif personality['CC'] == 'S':
                reply_tcp.set_ECE()
                reply_tcp.set_CWR()
            elif personality['CC'] == 'O':
                reply_tcp.reset_ECE()
                reply_tcp.set_CWR()

        # check S
        if 'S' in personality:
            if personality['S'] == 'Z':
                reply_tcp.set_th_seq(0)
            elif personality['S'] == 'A':
                reply_tcp.set_th_seq(tcp_pkt.get_th_ack())
            elif personality['S'] == 'A+':
                reply_tcp.set_th_seq(tcp_pkt.get_th_ack() + 1)
            elif personality['S'] == 'O':
                seq = cb_tcp_seq()
                reply_tcp.set_th_seq(seq)
            else:
                raise Exception('Unsupported Ti:S=%s', personality['S'])

        # check A
        if 'A' in personality:
            if personality['A'] == 'Z':
                reply_tcp.set_th_ack(0)
            elif personality['A'] == 'S':
                reply_tcp.set_th_ack(tcp_pkt.get_th_seq())
            elif personality['A'] == 'S+':
                reply_tcp.set_th_ack(tcp_pkt.get_th_seq() + 1)
            elif personality['A'] == 'O':
                temp = random.randint(1, 10)
                reply_tcp.set_th_ack(temp)
            else:
                try:
                    temp = int(personality['A'], 16)
                    reply_tcp.set_th_ack(temp)
                except BaseException:
                    raise Exception('Unsupported Ti:A=%s', personality['A'])

        # check O
        if 'O' in personality:
            options = personality['O']
            i = 0
            while i < len(options):
                opt = options[i]
                i += 1
                if opt == 'L':
                    reply_tcp.add_option(ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_EOL))
                if opt == 'N':
                    reply_tcp.add_option(ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_NOP))
                if opt == 'S':
                    reply_tcp.add_option(ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_SACK_PERMITTED))
                if opt == 'T':
                    opt = ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_TIMESTAMP)
                    if options[i] == '1':
                        ts = cb_tcp_ts()
                        opt.set_ts(ts)
                    if options[i + 1] == '1':
                        opt.set_ts_echo(0xffffffff)
                    reply_tcp.add_option(opt)
                    i += 2
                if opt == 'M':
                    maxseg, i = self.get_value(options, i)
                    reply_tcp.add_option(ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_MAXSEG, maxseg))
                if opt == 'W':
                    window, i = self.get_value(options, i)
                    reply_tcp.add_option(ImpactPacket.TCPOption(ImpactPacket.TCPOption.TCPOPT_WINDOW, window))

        # check F
        if 'F' in personality:
            if 'E' in personality['F']:
                reply_tcp.set_ECE()
            if 'U' in personality['F']:
                reply_tcp.set_URG()
            if 'A' in personality['F']:
                reply_tcp.set_ACK()
            if 'P' in personality['F']:
                reply_tcp.set_PSH()
            if 'R' in personality['F']:
                reply_tcp.set_RST()
            if 'S' in personality['F']:
                reply_tcp.set_SYN()
            if 'F' in personality['F']:
                reply_tcp.set_FIN()

        # check Q
        if 'Q' in personality:
            if 'R' in personality['Q']:
                reply_tcp.set_flags(0x800)
            if 'U' in personality['Q']:
                reply_tcp.set_th_urp(0xffff)

        # check RD
        if 'RD' in personality:
            try:
                crc = int(personality['RD'], 16)
                if crc != 0:
                    data = 'TCP Port is closed\x00'
                    data += self.compensate(data, crc)
                    pkt_data = ImpactPacket.Data(data)
                    reply_tcp.contains(pkt_data)
            except BaseException:
                raise Exception('Unsupported Ti:RD=%s', personality['RD'])

        reply_tcp.calculate_checksum()
        reply_ip.contains(reply_tcp)
        return reply_ip