Exemple #1
0
def tcp_timestamp_test():
    p = Packet(tlspkt)
    (bef_tsval, _, _) = p.parse_timestamp()
    p.offset_timestamp(4, True)
    (after_tsval, _, _) = p.parse_timestamp()
    assert (bef_tsval + 4 == after_tsval)

    # Verify the TCP checksum
    before = p.get_tcp_cksum()
    p.update_cksum()
    after = p.get_tcp_cksum()
    assert (abs(after - before) == 4)
Exemple #2
0
 def __init__(self, opts):
     self.tuples = {}
     self.opts = opts
     self.log = logging.getLogger('cb.tcphijack.hijackmgr')
     self.tun = TwistedTUN(
         lambda x: self.traffic_to_client(Packet(x, read_only=False)), '',
         self.opts['tun_ip'], self.opts['tun_netmask'])
Exemple #3
0
    def drop(self):

        # If we don't have a hijack_tuple, then we can't release it.
        # This shouldn't happen, so we note this.
        #
        if not self.hijack_tuple:
            print 'WARNING: TCPHijack.drop() called on non-hijacked conn'
            return

        TCPHijack.hijack_manager.unregister_tuple(self.hijack_tuple)

        # Send a RST to the listener of the hijack
        # in case it hasn't dropped this flow yet
        if not self.next_seq is None:
            (fsrc, fsport, fdst, fdport) = self.flow_tuple
            rst = dpkt.ip.IP(src=fsrc,
                             dst=fdst,
                             p=dpkt.ip.IP_PROTO_TCP,
                             data=dpkt.tcp.TCP(sport=fsport,
                                               dport=fdport,
                                               flags=dpkt.tcp.TH_RST,
                                               seq=self.next_seq,
                                               ack=self.last_ack))
            rst.len += len(rst.data)

            self.traffic_from_client(Packet(str(rst), read_only=False),
                                     buffer=False)

        # TODO: This might be endian-specific.  Investigate.
        #
        dotted_quad = '.'.join(['%d' % ord(x) for x in self.hijack_tuple[0]])
        TCPHijack.free_srcs.free_src((dotted_quad, self.hijack_tuple[1]))
Exemple #4
0
    def tun_callback(rawpkt):
        """
        Callback when pkts arrive from the TUN

        Figure out which client should receive the packet, and forward
        it along along that client connection.
        """

        msg = VpnMsgWrapper.pkt_msg(rawpkt)
        
        pkt = Packet(rawpkt, read_only=True)

        des_ip = pkt.get_dst()

        # Lookup the client to which this pkt should be sent.
        #
        try:
            point = VpnServerState.CLIENTS[des_ip]
            point.transport.write(msg.pack())
        except KeyError:
            logging.getLogger('cb.vpn_dp').debug('no client, dropping')
            print 'no client, dropping'
Exemple #5
0
    def ack_synack(self, pkt):
        """
        ack_synack: Respond to a synack with an ack
        """

        (src, sport, dst, dport) = self.flow_tuple

        DEBUG and log_debug("tcphijack.ack_synack: %s" % str(self.flow_tuple))

        ack = dpkt.ip.IP(src=src,
                         dst=dst,
                         p=dpkt.ip.IP_PROTO_TCP,
                         data=dpkt.tcp.TCP(sport=sport,
                                           dport=dport,
                                           flags=dpkt.tcp.TH_ACK,
                                           seq=pkt.get_ack(),
                                           ack=pkt.get_seq() + 1))

        (tsv, tsr, index) = pkt.parse_timestamp()

        if not tsv is None:
            timestamp = pkt.buff[index:index + 10]
            opts = []
            (typ, length, tsval, tsecr) = struct.unpack('>BBII', timestamp)
            # Just reuse our original tsval, but do echo the engine's
            reply = struct.pack('>BBII', typ, length, tsecr, tsval)
            opts.append(reply)
            nop = struct.pack('>B', dpkt.tcp.TCP_OPT_NOP)
            opts.append(nop)
            opts.append(nop)
            ack.data.opts = ''.join(opts)
            ack.data.off = (20 + len(ack.data.opts)) >> 2

        ack.len += len(ack.data)
        self.traffic_from_client(Packet(str(ack), read_only=False),
                                 buffer=False)
Exemple #6
0
class VpnDpSrcProtocol(Protocol):
    """
    VPN source protocol: receive VPN messages from the clients
    and respond (typically by forwarding them through the TUN)
    """

    def __init__(self):
        self.log = logging.getLogger('cb.vpn_dp')

        self.log.debug('VpnDpSrcProtocol init')

        self._recv_buffer = ''
        self._opened_session = False
        self._client_ipaddr = None

    def dstAccept(self, _protocol):
        """
        accept method for new connections.

        (Is this method actually used?)
        """

        self.log.debug('VpnDpSrcProtocol dstAccept')

    def dataReceived(self, new_data):
        """
        Respond to data arriving from a client

        Parse the data into as many messages as possible (buffering
        any leftovers for later), and then process each message.
        """

        self.log.debug('dataReceived')

        self._recv_buffer += new_data

        try:
            (msgs, self._recv_buffer) = VpnMsgWrapper.recv_from_buffer(
                    self._recv_buffer)
        except BaseException, exc:
            # FIXME: recv_from_buffer can raise an exception.  If this happens,
            # we must drop the connection.
            #
            return

        for msg in msgs:
            msg_type = msg.get_msg_type()

            self.log.debug('dataReceived ' + str(msg))

            # TODO
            # should check that the msg makes sense, and the packet
            # we're about to forward isn't spoofed, forged, bogus...
            #
            if msg_type == cb.vpn.vpn_msg.FORWARD_PKT:

                msg_text = msg.get_msg_text()

                parsed_pkt = Packet(msg_text, read_only=True)
                src_ip = parsed_pkt.get_src()

                if src_ip != self._client_ipaddr:
                    self.log.warn('incorrect src for %d.%d.%d.%d' % (
                            ord(src_ip[0]), ord(src_ip[1]),
                            ord(src_ip[2]), ord(src_ip[3])))
                    # FIXME: bad packet == bad client; drop client
                else:
                    _written = VpnServerState.TUN.write(msg_text)

            elif msg_type == cb.vpn.vpn_msg.OPEN_SESSION:
                if self._opened_session:
                    self.log.warn('multiple OPEN_SESSION requests')
                    # FIXME: This client is bad, and should be dropped
                else:
                    self._opened_session = True

                    next_addr = VpnServerState.TUN_ADDR_POOL.alloc()

                    next_client_addr_str = str(next_addr)

                    # Smoosh the client ipaddr into binary, and then
                    # add the mapping from the binary ipaddr to ourselves for
                    # future error checking that src addrs are correct.
                    #
                    octets = next_client_addr_str.split('.')
                    ipaddr_binary = ''.join([chr(int(x)) for x in octets])

                    VpnServerState.CLIENTS[ipaddr_binary] = self
                    self._client_ipaddr = ipaddr_binary

                    self.log.info('assigning src_ip %s' %
                            (next_client_addr_str,))

                    info_msg = VpnMsgWrapper.info_msg(next_client_addr_str,
                            str(VpnServerState.TUN_NETWORK.netmask),
                            VpnServerState.DNS_SERVERS)

                    self.transport.write(info_msg.pack())

            elif msg_type == cb.vpn.vpn_msg.CLOSE_SESSION:
                self.log.info('CLOSE_SESSION request')
                # FIXME: actually close the session
            else:
                self.log.warn('unknown msg type (%d)' % (msg_type,))
Exemple #7
0
    def init_hijack(self, pkt, isn=None):
        """
        init_hijack: Initialize a hijack

        This function allocates an internal addr/port to use for
        communication with the kernel.  It then sends a syn packet
        to initiate a TCP connection with the kernel.
        """

        # FIXME: no longer have to guess in the symmetric case
        # GUESS THE TCP/IP OPTIONS
        opts = []

        # assume we're using SACK
        opts.append('\x04\x02')  # SACKOK

        # assume the MSS is 1460
        opts.append(struct.pack('>BBH', dpkt.tcp.TCP_OPT_MSS, 4, 1460))

        nop = struct.pack('>B', dpkt.tcp.TCP_OPT_NOP)

        (tsv, tsecr, index) = pkt.parse_timestamp()

        if not index is None:
            timestamp = pkt.buff[index:index + 10]
            if tsv:
                opts.append(timestamp)
                self.decoy_time = tsecr

        # for earlier kernels, we ignored window scale.  Don't ignore now.
        # guess the window scale size by looking at the initial window size
        scale = 1
        while pow(2, scale) * pkt.get_window() < 10000:
            scale += 1
        opts.append(struct.pack('>BBB', dpkt.tcp.TCP_OPT_WSCALE, 3, scale))

        while len(''.join(opts)) % 4 != 0:
            opts.append(nop)

        if isn is None:
            isn = pkt.get_seq() - 1

        # CREATE THE SYN PACKET
        syn = dpkt.ip.IP(src=self.flow_tuple[0],
                         dst=self.flow_tuple[2],
                         p=dpkt.ip.IP_PROTO_TCP,
                         data=dpkt.tcp.TCP(sport=self.flow_tuple[1],
                                           dport=self.flow_tuple[3],
                                           seq=isn,
                                           flags=dpkt.tcp.TH_SYN,
                                           opts=''.join(opts)))

        syn.data.off = (20 + len(syn.data.opts)) >> 2
        syn.len += len(syn.data)

        self.buffer = [pkt]

        if self.log.getEffectiveLevel() <= logging.DEBUG:
            DEBUG and log_debug("Sending to c2d_nat -> %s" %
                                cb.util.dpkt_util.dpkt_to_str(syn))

        self.traffic_from_client(Packet(str(syn), read_only=False),
                                 buffer=False)
Exemple #8
0
def tcp_cksum_test():
    p = Packet(tlspkt)
    before = p.get_tcp_cksum()
    p.update_cksum()
    after = p.get_tcp_cksum()
    assert (before == after)
Exemple #9
0
def tcp_attrib_test():
    p = Packet(tlspkt)
    assert (p.get_sport() == 443)
    assert (p.get_dport() == 59320)
    assert (p.get_tcp_cksum() == 0xb8b0)
    assert (p.thl == 32)
    assert (p.get_opts() == '\x01\x01\x08\x0a\x44\x4e\x98\x3d\x0b\x63\x5a\xdb')
    assert (p.get_payload_len() == 95)
    assert (p.get_seq() == 0xbdb8019a)
    assert (p.get_ack() == 0xa72449c8)
    assert (p.get_flags() == 0x18)

    old_seq = p.get_seq()
    p.set_seq(old_seq + 1)
    assert (p.get_seq() == old_seq + 1)
    assert (p.get_ack() == 0xa72449c8)
    old_ack = p.get_ack()
    p.set_ack(old_ack + 1)
    assert (p.get_ack() == old_ack + 1)
Exemple #10
0
def payload_test():
    p = Packet(tlspkt)
    payload = p.get_payload()
    assert (payload == tlspayload)
Exemple #11
0
def ip_attrib_test():
    p = Packet(tlspkt)
    assert (p.get_src() == '\x48\x0E\xCC\x67')
    assert (p.get_dst() == '\x80\x59\x50\xF8')
    assert (p.get_ip_cksum() == 0xc3a7)
    assert (p.protocol == 6)
Exemple #12
0
def tcp_test():
    p = Packet(tlspkt)
    assert (p.protocol == 6)
Exemple #13
0
def load_test():
    p = Packet(tlspkt)