Beispiel #1
0
 def m2i(self, pkt, s):
     family = None
     if pkt.type == 1:  # A
         family = socket.AF_INET
     elif pkt.type in [2, 5, 12]:  # NS, CNAME, PTR
         if hasattr(pkt, "_orig_s") and pkt._orig_s:
             if orb(s[0]) & 0xc0:
                 s = dns_get_str(s, 0, pkt)[0]
             else:
                 s = dns_get_str(pkt._orig_s, pkt._orig_p, _internal=True)[0]  # noqa: E501
         else:
             s = dns_get_str(s, 0)[0]
     elif pkt.type == 16:  # TXT
         ret_s = list()
         tmp_s = s
         # RDATA contains a list of strings, each are prepended with
         # a byte containing the size of the following string.
         while tmp_s:
             tmp_len = orb(tmp_s[0]) + 1
             if tmp_len > len(tmp_s):
                 warning("DNS RR TXT prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s)))  # noqa: E501
             ret_s.append(tmp_s[1:tmp_len])
             tmp_s = tmp_s[tmp_len:]
         s = ret_s
     elif pkt.type == 28:  # AAAA
         family = socket.AF_INET6
     if family is not None:
         s = inet_ntop(family, s)
     return s
Beispiel #2
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt and len(_pkt) >= 2:
         version = orb(_pkt[0])
         if version == 0x04:  # OpenFlow 1.3
             from scapy.contrib.openflow3 import OpenFlow3
             return OpenFlow3.dispatch_hook(_pkt, *args, **kargs)
         elif version == 0x01:  # OpenFlow 1.0
             # port 6653 has been allocated by IANA, port 6633 should no
             # longer be used
             # OpenFlow function may be called with a None
             # self in OFPPacketField
             of_type = orb(_pkt[1])
             if of_type == 1:
                 err_type = orb(_pkt[9])
                 # err_type is a short int, but last byte is enough
                 if err_type == 255:
                     err_type = 65535
                 return ofp_error_cls[err_type]
             elif of_type == 16:
                 mp_type = orb(_pkt[9])
                 if mp_type == 255:
                     mp_type = 65535
                 return ofp_stats_request_cls[mp_type]
             elif of_type == 17:
                 mp_type = orb(_pkt[9])
                 if mp_type == 255:
                     mp_type = 65535
                 return ofp_stats_reply_cls[mp_type]
             else:
                 return ofpt_cls[of_type]
         else:
             warning("Unknown OpenFlow packet")
     return _UnknownOpenFlow
Beispiel #3
0
def in6_getAddrType(addr):
    naddr = inet_pton(socket.AF_INET6, addr)
    paddr = inet_ntop(socket.AF_INET6, naddr)  # normalize
    addrType = 0
    # _Assignable_ Global Unicast Address space
    # is defined in RFC 3513 as those in 2000::/3
    if ((orb(naddr[0]) & 0xE0) == 0x20):
        addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL)
        if naddr[:2] == b' \x02':  # Mark 6to4 @
            addrType |= IPV6_ADDR_6TO4
    elif orb(naddr[0]) == 0xff:  # multicast
        addrScope = paddr[3]
        if addrScope == '2':
            addrType = (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST)
        elif addrScope == 'e':
            addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST)
        else:
            addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST)
    elif ((orb(naddr[0]) == 0xfe) and ((int(paddr[2], 16) & 0xC) == 0x8)):
        addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL)
    elif paddr == "::1":
        addrType = IPV6_ADDR_LOOPBACK
    elif paddr == "::":
        addrType = IPV6_ADDR_UNSPECIFIED
    else:
        # Everything else is global unicast (RFC 3513)
        # Even old deprecated (RFC3879) Site-Local addresses
        addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

    return addrType
Beispiel #4
0
 def pre_dissect(self, s):
     # Get the frame check sequence
     sty = orb(s[0])
     ty = orb(s[1]) >> 2
     fc = struct.unpack("!H", s[2:4])[0]
     length = 12 + 6 * ((ty != 1 or sty in [0x8, 0x9, 0xa, 0xb, 0xe, 0xf]) + (ty in [0, 2]) + (ty == 2 and fc & 3 == 3))  # noqa: E501
     return s[:length] + s[-4:] + s[length:-4]
Beispiel #5
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     """
     If the TLS class was called on raw SSLv2 data, we want to return an
     SSLv2 record instance. We acknowledge the risk of SSLv2 packets with a
     msglen of 0x1403, 0x1503, 0x1603 or 0x1703 which will never be casted
     as SSLv2 records but TLS ones instead, but hey, we can't be held
     responsible for low-minded extensibility choices.
     """
     if _pkt and len(_pkt) >= 2:
         byte0 = orb(_pkt[0])
         byte1 = orb(_pkt[1])
         if (byte0 not in _tls_type) or (byte1 != 3):
             from scapy.layers.tls.record_sslv2 import SSLv2
             return SSLv2
         else:
             s = kargs.get("tls_session", None)
             if s and _tls_version_check(s.tls_version, 0x0304):
                 if s.rcs and not isinstance(s.rcs.cipher, Cipher_NULL):
                     from scapy.layers.tls.record_tls13 import TLS13
                     return TLS13
     if _pkt and len(_pkt) < 5:
             # Layer detected as TLS but too small to be a real packet (len<5).  # noqa: E501
             # Those packets appear when sessions are interrupted or to flush buffers.  # noqa: E501
             # Scapy should not try to decode them
         return conf.raw_layer
     return TLS
Beispiel #6
0
def obfuscate(pay, secret, session_id, version, seq):
    '''

    Obfuscation methodology from section 3.7
    https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.7

    '''

    pad = b""
    curr_pad = b""

    # pad length must equal the payload to obfuscate.
    # pad = {MD5_1 [,MD5_2 [ ... ,MD5_n]]}

    while len(pad) < len(pay):

        msg = hashlib.md5()
        msg.update(struct.pack('!I', session_id))
        msg.update(secret.encode())
        msg.update(struct.pack('!BB', version, seq))
        msg.update(curr_pad)
        curr_pad = msg.digest()
        pad += curr_pad

    # Obf/Unobfuscation via XOR operation between plaintext and pad

    return b"".join(chb(orb(pad[i]) ^ orb(pay[i])) for i in range(len(pay)))
Beispiel #7
0
def _tzsp_guess_next_tag(payload):
    """
    :return: class representing the next tag, Raw on error, None on missing payload  # noqa: E501
    """

    if not payload:
        warning('missing payload')
        return None

    tag_type = orb(payload[0])

    try:
        tag_class_definition = _TZSP_TAG_CLASSES[tag_type]

    except KeyError:

        return _tzsp_handle_unknown_tag(payload, tag_type)

    if type(tag_class_definition) is not dict:
        return tag_class_definition

    try:
        length = orb(payload[1])
    except IndexError:
        length = None

    if not length:
        warning('no tag length given - packet to short')
        return Raw

    try:
        return tag_class_definition[length]
    except KeyError:
        warning('invalid tag length {} for tag type {}'.format(length, tag_type))  # noqa: E501
        return Raw
Beispiel #8
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt and len(_pkt) >= 4:
         if orb(_pkt[0]) in [0x12, 0x16, 0x17]:
             return IGMP
         elif orb(_pkt[0]) == 0x11 and len(_pkt) < 12:
             return IGMP
     return IGMPv3
Beispiel #9
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt:
         c = orb(_pkt[0])
         if c in [1, 2] and len(_pkt) >= 5:
             t = orb(_pkt[4])
             return cls.registered_methods.get(t, cls)
     return cls
Beispiel #10
0
def OpenFlow(self, payload):
    if self is None or self.dport == 6653 or self.dport == 6633 or self.sport == 6653 or self.sport == 6633:  # noqa: E501
        # port 6653 has been allocated by IANA, port 6633 should no longer be used  # noqa: E501
        # OpenFlow function may be called with None self in OFPPacketField
        of_type = orb(payload[1])
        if of_type == 1:
            err_type = orb(payload[9])
            # err_type is a short int, but last byte is enough
            if err_type == 255:
                err_type = 65535
            return ofp_error_cls[err_type]
        elif of_type == 16:
            mp_type = orb(payload[9])
            if mp_type == 255:
                mp_type = 65535
            return ofp_stats_request_cls[mp_type]
        elif of_type == 17:
            mp_type = orb(payload[9])
            if mp_type == 255:
                mp_type = 65535
            return ofp_stats_reply_cls[mp_type]
        else:
            return ofpt_cls[of_type]
    else:
        return TCP_guess_payload_class_copy(self, payload)
Beispiel #11
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt and len(_pkt) >= 4:
         from scapy.contrib.igmpv3 import IGMPv3
         if orb(_pkt[0]) in [0x22, 0x30, 0x31, 0x32]:
             return IGMPv3
         if orb(_pkt[0]) == 0x11 and len(_pkt) >= 12:
             return IGMPv3
     return IGMP
Beispiel #12
0
def dns_get_str(s, p, pkt=None, _internal=False):
    """This function decompresses a string s, from the character p.
    params:
     - s: the string to decompress
     - p: start index of the string
     - pkt: (optional) an InheritOriginDNSStrPacket packet

    returns: (decoded_string, end_index, left_string)
    """
    # The _internal parameter is reserved for scapy. It indicates
    # that the string provided is the full dns packet, and thus
    # will be the same than pkt._orig_str. The "Cannot decompress"
    # error will not be prompted if True.
    max_length = len(s)
    name = b""  # The result = the extracted name
    burned = 0  # The "burned" data, used to determine the remaining bytes
    q = None  # Will contain the index after the pointer, to be returned
    processed_pointers = [p]  # Used to check for decompression loops
    while True:
        if abs(p) >= max_length:
            warning("DNS RR prematured end (ofs=%i, len=%i)" % (p, len(s)))
            break
        cur = orb(s[p])  # current value of the string at p
        p += 1  # p is now pointing to the value of the pointer
        burned += 1
        if cur & 0xc0:  # Label pointer
            if q is None:
                # p will follow the pointer, whereas q will not
                q = p + 1
            if p >= max_length:
                warning("DNS incomplete jump token at (ofs=%i)" % p)
                break
            p = ((cur & ~0xc0) << 8) + orb(s[p]) - 12  # Follow the pointer
            burned += 1
            if pkt and hasattr(pkt, "_orig_s") and pkt._orig_s:
                # There should not be a loop as pkt is None
                name += dns_get_str(pkt._orig_s, p, None, _internal=True)[0]
                if burned == max_length:
                    break
            elif p in processed_pointers:
                warning("DNS decompression loop detected")
                break
            elif not _internal:
                raise Scapy_Exception("DNS message can't be compressed" +
                                      "at this point!")
            processed_pointers.append(p)
            continue
        elif cur > 0:  # Label
            name += s[p:p + cur] + b"."
            p += cur
            burned += cur
        else:
            break
    if q is not None:
        # Return the real end index (not the one we followed)
        p = q
    # name, end_index, remaining
    return name, p, s[burned:]
Beispiel #13
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt and len(_pkt) >= 1:
         if (orb(_pkt[0]) >> 5) & 0x7 == 2:
             from . import gtp_v2
             return gtp_v2.GTPHeader
     if _pkt and len(_pkt) >= 8:
         _gtp_type = orb(_pkt[1:2])
         return GTPforcedTypes.get(_gtp_type, GTPHeader)
     return cls
Beispiel #14
0
 def do_dec(cls, s, context=None, safe=False):
     l, s, t = cls.check_type_check_len(s)
     x = 0
     if s:
         if orb(s[0]) & 0x80:  # negative int
             x = -1
         for c in s:
             x <<= 8
             x |= orb(c)
     return cls.asn1_object(x), t
Beispiel #15
0
    def decrypt(self, sa, esp, key, icv_size=None):
        """
        Decrypt an ESP packet

        @param sa:         the SecurityAssociation associated with the ESP packet.
        @param esp:        an encrypted ESP packet
        @param key:        the secret key used for encryption
        @param icv_size:   the length of the icv used for integrity check

        @return:    a valid ESP packet encrypted with this algorithm
        @raise IPSecIntegrityError: if the integrity check fails with an AEAD
                                    algorithm
        """
        if icv_size is None:
            icv_size = self.icv_size if self.is_aead else 0

        iv = esp.data[:self.iv_size]
        data = esp.data[self.iv_size:len(esp.data) - icv_size]
        icv = esp.data[len(esp.data) - icv_size:]

        if self.cipher:
            mode_iv = self._format_mode_iv(sa=sa, iv=iv)
            cipher = self.new_cipher(key, mode_iv, icv)
            decryptor = cipher.decryptor()

            if self.is_aead:
                # Tag value check is done during the finalize method
                decryptor.authenticate_additional_data(
                    struct.pack('!LL', esp.spi, esp.seq)
                )

            try:
                data = decryptor.update(data) + decryptor.finalize()
            except InvalidTag as err:
                raise IPSecIntegrityError(err)

        # extract padlen and nh
        padlen = orb(data[-2])
        nh = orb(data[-1])

        # then use padlen to determine data and padding
        data = data[:len(data) - padlen - 2]
        padding = data[len(data) - padlen - 2: len(data) - 2]

        return _ESPPlain(spi=esp.spi,
                        seq=esp.seq,
                        iv=iv,
                        data=data,
                        padding=padding,
                        padlen=padlen,
                        nh=nh,
                        icv=icv)
Beispiel #16
0
    def i2m(self, pkt, x):
        if any((orb(y) >= 0xc0) for y in x):
            # The value has already been processed. Do not process it again
            return x

        if not x or x == b".":
            return b"\x00"

        # Truncate chunks that cannot be encoded (more than 63 bytes..)
        x = b"".join(chb(len(y)) + y for y in (k[:63] for k in x.split(b".")))
        if orb(x[-1]) != 0 and (orb(x[-2]) < 0xc0):
            x += b"\x00"
        return x
Beispiel #17
0
def BER_len_dec(s):
    tmp_len = orb(s[0])
    if not tmp_len & 0x80:
        return tmp_len, s[1:]
    tmp_len &= 0x7f
    if len(s) <= tmp_len:
        raise BER_Decoding_Error(
            "BER_len_dec: Got %i bytes while expecting %i" %
            (len(s) - 1, tmp_len),
            remaining=s
        )
    ll = 0
    for c in s[1:tmp_len + 1]:
        ll <<= 8
        ll |= orb(c)
    return ll, s[tmp_len + 1:]
Beispiel #18
0
 def guess_payload_class(self, payload):
     # type is a 7-bit bitfield spanning bits 1..7 -> div 2
     try:
         lldpdu_tlv_type = orb(payload[0]) // 2
         return LLDPDU_CLASS_TYPES.get(lldpdu_tlv_type, conf.raw_layer)
     except IndexError:
         return conf.raw_layer
Beispiel #19
0
def parse_data_pkt(pkt, tk):
    """Extract data from a WPA packet @pkt with temporal key @tk"""
    TSC, TA, data = parse_TKIP_hdr(pkt)
    TK = [orb(x) for x in tk]

    rc4_key = gen_TKIP_RC4_key(TSC, TA, TK)
    return ARC4_decrypt(rc4_key, data)
Beispiel #20
0
def in6_getRandomizedIfaceId(ifaceid, previous=None):
    """
    Implements the interface ID generation algorithm described in RFC 3041.
    The function takes the Modified EUI-64 interface identifier generated
    as described in RFC 4291 and an optional previous history value (the
    first element of the output of this function). If no previous interface
    identifier is provided, a random one is generated. The function returns
    a tuple containing the randomized interface identifier and the history
    value (for possible future use). Input and output values are provided in
    a "printable" format as depicted below.

    ex:
    >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3')
    ('4c61:76ff:f46a:a5f3', 'd006:d540:db11:b092')
    >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3',
                                 previous='d006:d540:db11:b092')
    ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e')
    """

    s = b""
    if previous is None:
        d = b"".join(chb(x) for x in range(256))
        for _ in range(8):
            s += chb(random.choice(d))
        previous = s
    s = inet_pton(socket.AF_INET6, "::" + ifaceid)[8:] + previous
    import hashlib
    s = hashlib.md5(s).digest()
    s1, s2 = s[:8], s[8:]
    s1 = chb(orb(s1[0]) | 0x04) + s1[1:]
    s1 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s1)[20:]
    s2 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s2)[20:]
    return (s1, s2)
Beispiel #21
0
def _tls_del_pad(p):
    """
    Provided with a just decrypted TLSCiphertext (now a TLSPlaintext instance)
    p, the function removes the trailing padding found in p.data. It also
    performs some sanity checks on the padding (length, content, ...). False
    is returned if one of the check fails. Otherwise, True is returned,
    indicating that p.data and p.len have been updated.
    """

    if p.len < 1:
        warning("Message format is invalid (padding)")
        return False

    padlen = orb(p.data[-1])
    padsize = padlen + 1

    if p.len < padsize:
        warning("Invalid padding length")
        return False

    if p.data[-padsize:] != chb(padlen) * padsize:
        warning("Padding content is invalid %s", repr(p.data[-padsize:]))
        return False

    p.data = p.data[:-padsize]
    p.len -= padsize

    return True
Beispiel #22
0
    def guess_payload_class(self, payload):
        pl_type = orb(payload[_SDEntry.TYPE_PAYLOAD_I])

        if (pl_type in _SDEntry.TYPE_SRV):
            return (SDEntry_Service)
        elif (pl_type in _SDEntry.TYPE_EVTGRP):
            return (SDEntry_EventGroup)
Beispiel #23
0
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip, Net):
        ip = next(iter(ip))
    ip = inet_ntoa(inet_aton(ip))
    tmp = [orb(e) for e in inet_aton(ip)]
    if (tmp[0] & 0xf0) == 0xe0:  # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3])
    iff, _, gw = conf.route.route(ip)
    if ((iff == consts.LOOPBACK_INTERFACE) or (ip == conf.route.get_if_bcast(iff))):  # noqa: E501
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST) / ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface=iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Beispiel #24
0
    def compute_crc(pdu, init=0x555555):
        def swapbits(a):
            v = 0
            if a & 0x80 != 0:
                v |= 0x01
            if a & 0x40 != 0:
                v |= 0x02
            if a & 0x20 != 0:
                v |= 0x04
            if a & 0x10 != 0:
                v |= 0x08
            if a & 0x08 != 0:
                v |= 0x10
            if a & 0x04 != 0:
                v |= 0x20
            if a & 0x02 != 0:
                v |= 0x40
            if a & 0x01 != 0:
                v |= 0x80
            return v

        state = swapbits(init & 0xff) + (swapbits((init >> 8) & 0xff) << 8) + (swapbits((init >> 16) & 0xff) << 16)  # noqa: E501
        lfsr_mask = 0x5a6000
        for i in (orb(x) for x in pdu):
            for j in range(8):
                next_bit = (state ^ i) & 1
                i >>= 1
                state >>= 1
                if next_bit:
                    state |= 1 << 23
                    state ^= lfsr_mask
        return struct.pack("<L", state)[:-1]
Beispiel #25
0
 def post_build(self, p, pay):
     p += pay
     optionlen = self.optionlen
     if optionlen is None:
         optionlen = (len(self.options) + 3) // 4
         p = chb(optionlen & 0x2f | orb(p[0]) & 0xc0) + p[1:]
     return p
Beispiel #26
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if len(_pkt) >= 2:
         if (orb(_pkt[2]) & 0x80):  # Response
             return LLMNRResponse
         else:                  # Query
             return LLMNRQuery
     return cls
Beispiel #27
0
def _extract_dot15d4address(pkt, source=True):
    """This function extracts the source/destination address of a 6LoWPAN
    from its upper Dot15d4Data (802.15.4 data) layer.

    params:
     - source: if True, the address is the source one. Otherwise, it is the
               destination.
    returns: the packed & processed address
    """
    underlayer = pkt.underlayer
    while underlayer is not None and not isinstance(underlayer, Dot15d4Data):  # noqa: E501
        underlayer = underlayer.underlayer
    if type(underlayer) == Dot15d4Data:
        addr = underlayer.src_addr if source else underlayer.dest_addr
        if underlayer.underlayer.fcf_destaddrmode == 3:
            tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(">Q", addr)  # noqa: E501
            # Turn off the bit 7.
            tmp_ip = tmp_ip[0:8] + struct.pack("B", (orb(tmp_ip[8]) ^ 0x2)) + tmp_ip[9:16]  # noqa: E501
        elif underlayer.underlayer.fcf_destaddrmode == 2:
            tmp_ip = LINK_LOCAL_PREFIX[0:8] + \
                b"\x00\x00\x00\xff\xfe\x00" + \
                struct.pack(">Q", addr)[6:]
        return tmp_ip
    else:
        # Most of the times, it's necessary the IEEE 802.15.4 data to extract this address  # noqa: E501
        raise Exception('Unimplemented: IP Header is contained into IEEE 802.15.4 frame, in this case it\'s not available.')  # noqa: E501
Beispiel #28
0
def isis_str2area(s):
    if len(s) == 0:
        return ""

    numbytes = len(s[1:])
    fmt = "%02X" + (".%02X%02X" * (numbytes // 2)) + ("" if (numbytes % 2) == 0 else ".%02X")  # noqa: E501
    return fmt % tuple(orb(x) for x in s)
Beispiel #29
0
 def __init__(self, name, default, default_readable=True, context=None,
              implicit_tag=None, explicit_tag=None):
     if default is not None and default_readable:
         default = b"".join(binrepr(orb(x)).zfill(8).encode("utf8") for x in default)  # noqa: E501
     ASN1F_field.__init__(self, name, default, context=context,
                          implicit_tag=implicit_tag,
                          explicit_tag=explicit_tag)
Beispiel #30
0
    def m2i(self, pkt, m):
        """
        Try to parse one of the TLS subprotocols (ccs, alert, handshake or
        application_data). This is used inside a loop managed by .getfield().
        """
        cls = Raw
        if pkt.type == 22:
            if len(m) >= 1:
                msgtype = orb(m[0])
                cls = _tls_handshake_cls.get(msgtype, Raw)
        elif pkt.type == 20:
            cls = TLSChangeCipherSpec
        elif pkt.type == 21:
            cls = TLSAlert
        elif pkt.type == 23:
            cls = TLSApplicationData

        if cls is Raw:
            return Raw(m)
        else:
            try:
                return cls(m, tls_session=pkt.tls_session)
            except Exception:
                if conf.debug_dissector:
                    raise
                return Raw(m)
Beispiel #31
0
 def m2i(self, pkt, x):
     list = []
     v = struct.unpack("!H", x[4:6])[0]
     list.append(v)
     flags = orb(x[6])
     v = (flags & 0x80) >> 7
     list.append(v)
     v = (flags & 0x40) >> 7
     list.append(v)
     return list
Beispiel #32
0
 def getfield(self, pkt, s):
     value = 0
     for offset, curbyte in enumerate(s):
         curbyte = orb(curbyte)
         value += (curbyte & 127) * (128**offset)
         if curbyte & 128 == 0:
             return s[offset + 1:], value
         if offset > 2:
             raise Scapy_Exception("%s: malformed length field" %
                                   self.__class__.__name__)
Beispiel #33
0
 def guess_payload_class(self, payload):
     if len(payload) >= 1:
         if not self.s:
             return MPLS
         ip_version = (orb(payload[0]) >> 4) & 0xF
         if ip_version == 4:
             return IP
         elif ip_version == 6:
             return IPv6
     return Padding
    def m2i(self, pkt, m):
        cls = Raw
        if len(m) >= 1:
            msgtype = orb(m[0])
            cls = _sslv2_handshake_cls.get(msgtype, Raw)

        if cls is Raw:
            return Raw(m)
        else:
            return cls(m, tls_session=pkt.tls_session)
Beispiel #35
0
 def guess_payload_class(self, payload):
     if self.NextExtHdr == 0:
         sub_proto = orb(payload[0])
         if sub_proto >= 0x45 and sub_proto <= 0x4e:
             return IP
         elif (sub_proto & 0xf0) == 0x60:
             return IPv6
         else:
             return PPP
     return GTPHeader.guess_payload_class(self, payload)
Beispiel #36
0
 def dispatch_hook(cls, _pkt=None, *_, **kargs):
     if _pkt:
         cmd = orb(_pkt[0])
     elif "type" in kargs:
         cmd = kargs["type"]
         if isinstance(cmd, six.string_types):
             cmd = cls.fields_desc[0].s2i[cmd]
     else:
         return cls
     return SPECIFIC_CLASSES.get(cmd, cls)
Beispiel #37
0
    def read_packet(self, size=MTU):
        # type: (int) -> Optional[BasePacket]
        """return a single packet read from the file or None if filters apply

        raise EOFError when no more packets are available
        """
        line = self.f.readline()
        line = line.lstrip()
        if len(line) < 16:
            raise EOFError

        is_log_file_format = orb(line[0]) == orb(b"(")

        if is_log_file_format:
            t, intf, f = line.split()
            idn, data = f.split(b'#')
            le = None
            t = float(t[1:-1])
        else:
            h, data = line.split(b']')
            intf, idn, le = h.split()
            t = None

        if self.ifilter is not None and \
                intf.decode('ASCII') not in self.ifilter:
            return None

        data = data.replace(b' ', b'')
        data = data.strip()

        pkt = CAN(identifier=int(idn, 16), data=binascii.unhexlify(data))
        if le is not None:
            pkt.length = int(le[1:])
        else:
            pkt.length = len(pkt.data)

        if len(idn) > 3:
            pkt.flags = 0b100

        if t is not None:
            pkt.time = t

        return pkt
Beispiel #38
0
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt:
         first_byte = orb(_pkt[0])
         if first_byte == 0xff:
             return HDLC
         # See RFC 1661 section 2
         # <https://tools.ietf.org/html/rfc1661#section-2>
         if first_byte & 0x01:
             return PPP_
     return cls
Beispiel #39
0
def _LSAGuessPayloadClass(p, **kargs):
    """ Guess the correct LSA class for a given payload """
    # This is heavily based on scapy-cdp.py by Nicolas Bareil and Arnaud Ebalard

    cls = conf.raw_layer
    if len(p) >= 4:
        typ = orb(p[3])
        clsname = _OSPF_LSclasses.get(typ, "Raw")
        cls = globals()[clsname]
    return cls(p, **kargs)
Beispiel #40
0
 def supported_responses(self):
     # type: () -> List[EcuResponse]
     supported_resps = list()
     all_responses = [p for p in self.__result_packets.values()
                      if orb(bytes(p)[0]) & 0x40]
     for resp in all_responses:
         states = list(set([t.state for t in self.results_with_response
                            if t.resp == resp]))
         supported_resps.append(EcuResponse(state=states, responses=resp))
     return supported_resps
Beispiel #41
0
 def getfield(self, pkt, s):
     if pkt.tls_session.consider_read_padding():
         # This should work with SSLv3 and also TLS versions.
         # Note that we need to retrieve pkt.padlen beforehand,
         # because it's possible that the padding is followed by some data
         # from another TLS record (hence the last byte from s would not be
         # the last byte from the current record padding).
         tmp_len = orb(s[pkt.padlen - 1])
         return s[tmp_len:], self.m2i(pkt, s[:tmp_len])
     return s, None
Beispiel #42
0
    def decompressSourceAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.sourceAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.sac == 0:
            if self.sam == 0x0:
                pass
            elif self.sam == 0x1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[
                    16 - source_addr_mode2(self):16]
            elif self.sam == 0x2:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + \
                    tmp_ip[16 - source_addr_mode2(self):16]
            elif self.sam == 0x3:  # EXTRACT ADDRESS FROM Dot15d4
                underlayer = self.underlayer
                if underlayer is not None:
                    while underlayer is not None and not isinstance(
                            underlayer, Dot15d4Data):
                        underlayer = underlayer.underlayer
                    assert type(underlayer) == Dot15d4Data
                    if underlayer.underlayer.fcf_srcaddrmode == 3:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(
                            ">Q", underlayer.src_addr)
                        # Turn off the bit 7.
                        tmp_ip = tmp_ip[0:8] + struct.pack(
                            "B", (orb(tmp_ip[8]) ^ 0x2)) + tmp_ip[9:16]
                    elif underlayer.underlayer.fcf_srcaddrmode == 2:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + \
                            b"\x00\x00\x00\xff\xfe\x00" + \
                            struct.pack(">Q", underlayer.src_addr)[6:]
                else:
                    payload = packet.payload
                    # Most of the times, it's necessary the IEEE 802.15.4 data to extract this address
                    raise Exception(
                        'Unimplemented: IP Header is contained into IEEE 802.15.4 frame, in this case it\'s not available.'
                    )
            else:
                warning("Unknown source address compression mode !")
        else:  # self.sac == 1:
            if self.sam == 0x0:
                pass
            elif self.sam == 0x2:
                # TODO: take context IID
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + \
                    tmp_ip[16 - source_addr_mode2(self):16]
            elif self.sam == 0x3:
                tmp_ip = LINK_LOCAL_PREFIX[
                    0:8] + b"\x00" * 8  # TODO: CONTEXT ID
            else:
                print(self.sam)
                raise Exception('Unimplemented')
        self.sourceAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.sourceAddr
Beispiel #43
0
    def m2i(self, pkt, x):
        opt = []
        while x:
            o = orb(x[0])
            if o == 255:
                opt.append("end")
                x = x[1:]
                continue
            if o == 0:
                opt.append("pad")
                x = x[1:]
                continue
            if len(x) < 2 or len(x) < orb(x[1]) + 2:
                opt.append(x)
                break
            elif o in DHCPOptions:
                f = DHCPOptions[o]

                if isinstance(f, str):
                    olen = orb(x[1])
                    opt.append((f, x[2:olen + 2]))
                    x = x[olen + 2:]
                else:
                    olen = orb(x[1])
                    lval = [f.name]
                    try:
                        left = x[2:olen + 2]
                        while left:
                            left, val = f.getfield(pkt, left)
                            lval.append(val)
                    except Exception:
                        opt.append(x)
                        break
                    else:
                        otuple = tuple(lval)
                    opt.append(otuple)
                    x = x[olen + 2:]
            else:
                olen = orb(x[1])
                opt.append((o, x[2:olen + 2]))
                x = x[olen + 2:]
        return opt
Beispiel #44
0
def in6_get_common_plen(a, b):
    # type: (str, str) -> int
    """
    Return common prefix length of IPv6 addresses a and b.
    """
    def matching_bits(byte1, byte2):
        # type: (int, int) -> int
        for i in range(8):
            cur_mask = 0x80 >> i
            if (byte1 & cur_mask) != (byte2 & cur_mask):
                return i
        return 8

    tmpA = inet_pton(socket.AF_INET6, a)
    tmpB = inet_pton(socket.AF_INET6, b)
    for i in range(16):
        mbits = matching_bits(orb(tmpA[i]), orb(tmpB[i]))
        if mbits != 8:
            return 8 * i + mbits
    return 128
Beispiel #45
0
 def do_dec(cls, s, context=None, safe=False):
     # /!\ the unused_bits information is lost after this decoding
     l, s, t = cls.check_type_check_len(s)
     if len(s) > 0:
         unused_bits = orb(s[0])
         if safe and unused_bits > 7:
             raise BER_Decoding_Error(
                 "BERcodec_BIT_STRING: too many unused_bits advertised",
                 remaining=s
             )
         s = "".join(binrepr(orb(x)).zfill(8) for x in s[1:])
         if unused_bits > 0:
             s = s[:-unused_bits]
         return cls.tag.asn1_object(s), t
     else:
         raise BER_Decoding_Error(
             "BERcodec_BIT_STRING found no content "
             "(not even unused_bits byte)",
             remaining=s
         )
Beispiel #46
0
def _sdentry_class(payload, **kargs):
    TYPE_PAYLOAD_I = 0
    pl_type = orb(payload[TYPE_PAYLOAD_I])
    cls = None

    if pl_type in SDENTRY_TYPE_SRV:
        cls = SDEntry_Service
    elif pl_type in SDENTRY_TYPE_EVTGRP:
        cls = SDEntry_EventGroup

    return cls(payload, **kargs)
Beispiel #47
0
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        """
        Returns the right parameter set class.
        """

        cls = conf.raw_layer
        if _pkt is not None:
            ptype = orb(_pkt[0])
            return globals().get(_param_set_cls.get(ptype), conf.raw_layer)

        return cls
Beispiel #48
0
def dns_encode(x, check_built=False):
    """Encodes a bytes string into the DNS format

    :param x: the string
    :param check_built: detect already-built strings and ignore them
    :returns: the encoded bytes string
    """
    if not x or x == b".":
        return b"\x00"

    if check_built and b"." not in x and (orb(x[-1]) == 0 or
                                          (orb(x[-2]) & 0xc0) == 0xc0):
        # The value has already been processed. Do not process it again
        return x

    # Truncate chunks that cannot be encoded (more than 63 bytes..)
    x = b"".join(chb(len(y)) + y for y in (k[:63] for k in x.split(b".")))
    if x[-1:] != b"\x00":
        x += b"\x00"
    return x
Beispiel #49
0
 def m2i(self, pkt, val):
     ret = []
     for v in val:
         byte = orb(v)
         left = byte >> 4
         right = byte & 0xf
         if left == 0xf:
             ret += [TBCD_TO_ASCII[right]]
         else:
             ret += [TBCD_TO_ASCII[right], TBCD_TO_ASCII[left]]
     return "".join(ret)
 def dispatch_hook(cls, _pkt=None, *args, **kargs):
     if _pkt:
         _id = orb(_pkt[0])
         if _id == 221:
             oui_a = orb(_pkt[2])
             oui_b = orb(_pkt[3])
             oui_c = orb(_pkt[4])
             if oui_a == 0x00 and oui_b == 0x50 and oui_c == 0xf2:
                 # MS OUI
                 type_ = orb(_pkt[5])
                 if type_ == 0x01:
                     # MS WPA IE
                     return Dot11EltMicrosoftWPA
                 else:
                     return Dot11EltVendorSpecific
             else:
                 return Dot11EltVendorSpecific
         else:
             return cls.registered_ies.get(_id, cls)
     return cls
Beispiel #51
0
 def m2i(self, pkt, val):
     ret = []
     for v in val:
         byte = orb(v)
         left = byte >> 4
         right = byte & 0xf
         if left == 0xf:
             ret.append(TBCD_TO_ASCII[right:right + 1])
         else:
             ret += [TBCD_TO_ASCII[right:right + 1], TBCD_TO_ASCII[left:left + 1]]
     return b"".join(ret)
Beispiel #52
0
 def guess_payload_class(self, payload):
     # Snooped from Wireshark
     # https://github.com/boundary/wireshark/blob/07eade8124fd1d5386161591b52e177ee6ea849f/epan/dissectors/packet-gtp.c#L8195  # noqa: E501
     if self.gtp_type == 255:
         sub_proto = orb(payload[0])
         if sub_proto >= 0x45 and sub_proto <= 0x4e:
             return IP
         elif (sub_proto & 0xf0) == 0x60:
             return IPv6
         else:
             return PPP
     return GTPHeader.guess_payload_class(self, payload)
Beispiel #53
0
def IE_Dispatcher(s):
    """Choose the correct Information Element class."""
    if len(s) < 1:
        return Raw(s)
    # Get the IE type
    ietype = orb(s[0])
    cls = ietypecls.get(ietype, Raw)

    # if ietype greater than 128 are TLVs
    if cls == Raw and ietype & 128 == 128:
        cls = IE_NotImplementedTLV
    return cls(s)
Beispiel #54
0
 def _check_len(self, pkt):
     """Check for odd packet length and pad according to Cisco spec.
     This padding is only used for checksum computation.  The original
     packet should not be altered."""
     if len(pkt) % 2:
         last_chr = pkt[-1]
         if last_chr <= b'\x80':
             return pkt[:-1] + b'\x00' + last_chr
         else:
             return pkt[:-1] + b'\xff' + chb(orb(last_chr) - 1)
     else:
         return pkt
Beispiel #55
0
    def getfield(self, pkt, s):
        if not s:
            return None

        prefix = orb(s[0])
        # if prefix is invalid value ( 0 > prefix > 32 ) then break
        if prefix > 32 or prefix < 0:
            warning("Invalid prefix value: %d (0x%x)", prefix, prefix)
            return s, []

        route_len = 5 + (prefix + 7) // 8
        return s[route_len:], self.m2i(pkt, s[:route_len])
Beispiel #56
0
    def dispatch_hook(cls, _pkt=None, *_, **kargs):
        code = None
        if _pkt:
            code = orb(_pkt[0])
        elif "code" in kargs:
            code = kargs["code"]
            if isinstance(code, six.string_types):
                code = cls.fields_desc[0].s2i[code]

        if code in (1, 2):
            return PPP_CHAP_ChallengeResponse
        return cls
Beispiel #57
0
def BER_id_enc(n):
    if n < 256:
        # low-tag-number
        return chb(n)
    else:
        # high-tag-number
        s = BER_num_enc(n)
        tag = orb(s[0])             # first byte, as an int
        tag &= 0x07                 # reset every bit from 8 to 4
        tag <<= 5                   # move back the info bits on top
        tag |= 0x1f                 # pad with 1s every bit from 5 to 1
        return chb(tag) + s[1:]
Beispiel #58
0
def OpenFlow(self, payload):
    if self is None or self.dport == 6653 or self.dport == 6633 or self.sport == 6653 or self.sport == 6633:
        # port 6653 has been allocated by IANA, port 6633 should no longer be used
        # OpenFlow function may be called with None self in OFPPacketField
        of_type = orb(payload[1])
        if of_type == 1:
            err_type = orb(payload[9])
            # err_type is a short int, but last byte is enough
            if err_type == 255: err_type = 65535
            return ofp_error_cls[err_type]
        elif of_type == 16:
            mp_type = orb(payload[9])
            if mp_type == 255: mp_type = 65535
            return ofp_stats_request_cls[mp_type]
        elif of_type == 17:
            mp_type = orb(payload[9])
            if mp_type == 255: mp_type = 65535
            return ofp_stats_reply_cls[mp_type]
        else:
            return ofpt_cls[of_type]
    else:
        return TCP_guess_payload_class_copy(self, payload)
Beispiel #59
0
    def guess_payload_class(self, payload):
        pl_type = orb(payload[2])

        return {
            _SDOption.CFG_TYPE: SDOption_Config,
            self.LOADBALANCE_TYPE: SDOption_LoadBalance,
            self.IP4_ENDPOINT_TYPE: SDOption_IP4_EndPoint,
            self.IP4_MCAST_TYPE: SDOption_IP4_Multicast,
            self.IP4_SDENDPOINT_TYPE: SDOption_IP4_SD_EndPoint,
            self.IP6_ENDPOINT_TYPE: SDOption_IP6_EndPoint,
            self.IP6_MCAST_TYPE: SDOption_IP6_Multicast,
            self.IP6_SDENDPOINT_TYPE: SDOption_IP6_SD_EndPoint
        }.get(pl_type, Raw)
Beispiel #60
0
 def m2i(self, pkt, s):
     ret_s = b""
     tmp_s = s
     while tmp_s:
         tmp_len = orb(tmp_s[0]) + 1
         if tmp_len > len(tmp_s):
             warning("APN prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s)))  # noqa: E501
         ret_s += tmp_s[1:tmp_len]
         tmp_s = tmp_s[tmp_len:]
         if len(tmp_s):
             ret_s += b"."
     s = ret_s
     return s