Exemple #1
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)
Exemple #2
0
 def post_build(self, p, pay):
     if self.length is None:
         tmp_len = len(p)
         tmp_pay = p[:2] + chb((tmp_len >> 8) & 0xff)
         p = tmp_pay + chb(tmp_len & 0xff) + p[4:]
     p += pay
     return p
Exemple #3
0
 def post_build(self, pkt, pay):
     if self.len is None:
         # len should be a FieldLenField but has an unsupported
         # format (14 bits)
         flags = orb(pkt[0]) & 0xc0
         length = len(self.value)
         pkt = chb(flags + (length >> 8)) + chb(length % 256) + pkt[2:]
     return pkt + pay
Exemple #4
0
 def post_build(self, pkt, pay):
     if self.descs_count is None:
         # descs_count should be a FieldLenField but has an
         # unsupported format (14 bits)
         flags = orb(pkt[0]) & 0xc0
         count = len(self.descs_list)
         pkt = chb(flags + (count >> 8)) + chb(count % 256) + pkt[2:]
     return pkt + pay
Exemple #5
0
    def post_build(self, p, pay):
        p += pay

        if self.keysize is None:
            keysize = len(self.authdata)
            p = p[:6] + chb((keysize >> 8) & 0xff) + chb(keysize & 0xff) + p[8:]  # noqa: E501

        return p
Exemple #6
0
    def get_raw(self):
        raw = ''
        raw += chb((self.length & 0xFF00) >> 8)
        raw += chb(self.length & 0xFF)

        if self.content != '':
            raw += self.content
        return raw
Exemple #7
0
    def post_build(self, p, pay):
        p += pay

        if self.len is None:
            l = len(p)
            p = p[:2] + chb((l >> 8) & 0xff) + chb(l & 0xff) + p[4:]

        return p
Exemple #8
0
    def post_build(self, p, pay):
        p += pay

        if self.len is None:
            l = len(p)
            p = p[:2] + chb((l >> 8) & 0xff) + chb(l & 0xff) + p[4:]

        return p
Exemple #9
0
 def post_build(self, pkt, pay):
     if self.descs_count is None:
         # descs_count should be a FieldLenField but has an
         # unsupported format (14 bits)
         flags = orb(pkt[0]) & 0xc0
         count = len(self.descs_list)
         pkt = chb(flags + (count >> 8)) + chb(count % 256) + pkt[2:]
     return pkt + pay
Exemple #10
0
 def post_build(self, p, pay):
     # type: (bytes, bytes) -> bytes
     p += pay
     if self.payload_len is None:
         pay_len = len(pay)
         p = p[:4] + chb((pay_len >> 8)
                         & 0xff) + chb(pay_len & 0xff) + p[6:]  # noqa: E501
     return p
Exemple #11
0
    def post_build(self, p, pay):
        p += pay

        if self.keysize is None:
            keysize = len(self.authdata)
            p = p[:6] + chb((keysize >> 8) & 0xff) + chb(keysize & 0xff) + p[8:]

        return p
Exemple #12
0
 def post_build(self, pkt, pay):
     if self.len is None:
         # len should be a FieldLenField but has an unsupported
         # format (14 bits)
         flags = orb(pkt[0]) & 0xc0
         length = len(self.value)
         pkt = chb(flags + (length >> 8)) + chb(length % 256) + pkt[2:]
     return pkt + pay
Exemple #13
0
    def decompressDestAddr(self, packet):
        # https://tools.ietf.org/html/rfc6282#section-3.1.1
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.dst)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                # Address fully carried
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[
                    0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[
                        -2:]  # noqa: E501
            elif self.dam == 3:
                tmp_ip = _extract_upperaddress(self, source=False)

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                # reserved
                pass
            elif self.dam == 0x3:
                # should use context IID + encapsulating header
                tmp_ip = _extract_upperaddress(self, source=False)
            elif self.dam not in [0x1, 0x2]:
                # https://tools.ietf.org/html/rfc6282#page-9
                # Should use context information: unimplemented
                pass
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                # Address fully carried
                pass
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - dest_addr_size(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - dest_addr_size(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                # https://tools.ietf.org/html/rfc6282#page-10
                # https://github.com/wireshark/wireshark/blob/f54611d1104d85a425e52c7318c522ed249916b6/epan/dissectors/packet-6lowpan.c#L2149-L2166
                # Format: ffXX:XXLL:PPPP:PPPP:PPPP:PPPP:XXXX:XXXX
                # P and L should be retrieved from context
                P = b"\x00" * 16
                L = b"\x00"
                X = tmp_ip[-6:]
                tmp_ip = b"\xff" + X[:2] + L + P[:8] + X[2:6]
            else:  # all the others values: reserved
                pass

        self.dst = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.dst
Exemple #14
0
 def post_build(self, p, pay):
     p += pay
     if self.Length is None:
         l = len(p)
         p = p[:6] + chb((l >> 8) & 0xff) + chb(l & 0xff) + p[8:]
     if self.chksum is None:
         ck = checksum(p)
         p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
     return p
Exemple #15
0
    def post_build(self, p, pay):
        p += pay

        if self.len is None:
            tmp_len = len(p)
            tmp_p = p[:2] + chb((tmp_len >> 8) & 0xff)
            p = tmp_p + chb(tmp_len & 0xff) + p[4:]

        return p
Exemple #16
0
    def post_build(self, p, pay):
        p += pay

        if self.len is None:
            tmp_len = len(p)
            tmp_p = p[:2] + chb((tmp_len >> 8) & 0xff)
            p = tmp_p + chb(tmp_len & 0xff) + p[4:]

        return p
Exemple #17
0
 def post_build(self, p, pay):
     p += pay
     if self.Length is None:
         l = len(p)
         p = p[:6] + chb((l >> 8) & 0xff) + chb(l & 0xff) + p[8:]
     if self.chksum is None:
         ck = checksum(p)
         p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
     return p
Exemple #18
0
    def decompressDestinyAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[-2:]  # noqa: E501
            """else: #self.dam == 3
                raise Exception('Unimplemented')"""

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                raise Exception('Reserved')
            elif self.dam == 0x3:
                underlayer = self.underlayer
                while underlayer is not None and not isinstance(underlayer, Dot15d4Data):  # noqa: E501
                    underlayer = underlayer.underlayer
                if type(underlayer) == Dot15d4Data:
                    if underlayer.underlayer.fcf_destaddrmode == 3:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(">Q", underlayer.dest_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", underlayer.dest_addr)[6:]
                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
            elif self.dam not in [0x1, 0x2]:
                warning("Unknown destiny address compression mode !")
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                raise Exception("unimplemented")
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                raise Exception("Unimplemented: I didnt understand the 6lowpan specification")  # noqa: E501
            else:  # all the others values
                raise Exception("Reserved value by specification.")

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.destinyAddr
Exemple #19
0
    def decompressDestinyAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[-2:]  # noqa: E501
            """else: #self.dam == 3
                raise Exception('Unimplemented')"""

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                raise Exception('Reserved')
            elif self.dam == 0x3:
                underlayer = self.underlayer
                while underlayer is not None and not isinstance(underlayer, Dot15d4Data):  # noqa: E501
                    underlayer = underlayer.underlayer
                if type(underlayer) == Dot15d4Data:
                    if underlayer.underlayer.fcf_destaddrmode == 3:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(">Q", underlayer.dest_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", underlayer.dest_addr)[6:]
                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
            elif self.dam not in [0x1, 0x2]:
                warning("Unknown destiny address compression mode !")
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                raise Exception("unimplemented")
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                raise Exception("Unimplemented: I didnt understand the 6lowpan specification")  # noqa: E501
            else:  # all the others values
                raise Exception("Reserved value by specification.")

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.destinyAddr
Exemple #20
0
 def load_winpcapy():
     """This functions calls Winpcap/Npcap pcap_findalldevs function,
     and extracts and parse all the data scapy will need to use it:
      - the Interface List
      - the IPv4 addresses
      - the IPv6 addresses
     This data is stored in their respective conf.cache_* subfields:
         conf.cache_iflist
         conf.cache_ipaddrs
         conf.cache_in6_getifaddr
     """
     err = create_string_buffer(PCAP_ERRBUF_SIZE)
     devs = POINTER(pcap_if_t)()
     if_list = []
     ip_addresses = {}
     ip6_addresses = []
     if pcap_findalldevs(byref(devs), err) < 0:
         return
     try:
         p = devs
         # Iterate through the different interfaces
         while p:
             if_list.append(plain_str(p.contents.name))
             a = p.contents.addresses
             while a:
                 # IPv4 address
                 if a.contents.addr.contents.sa_family == socket.AF_INET:  # noqa: E501
                     ap = a.contents.addr
                     val = cast(ap, POINTER(sockaddr_in))
                     if_raw_addr = b"".join(
                         chb(x) for x in
                         val.contents.sin_addr[:4])  # noqa: E501
                     if if_raw_addr != b'\x00\x00\x00\x00':
                         ip_addresses[plain_str(
                             p.contents.name
                         )] = if_raw_addr  # noqa: E501
                 # IPv6 address
                 if a.contents.addr.contents.sa_family == socket.AF_INET6:  # noqa: E501
                     ap = a.contents.addr
                     val = cast(ap, POINTER(sockaddr_in6))
                     addr = inet_ntop(socket.AF_INET6, b"".join(
                         chb(x) for x in
                         val.contents.sin6_addr[:]))  # noqa: E501
                     scope = scapy.utils6.in6_getscope(addr)
                     ip6_addresses.append(
                         (addr, scope,
                          plain_str(p.contents.name)))  # noqa: E501
                 a = a.contents.next
             p = p.contents.next
         conf.cache_iflist = if_list
         conf.cache_ipaddrs = ip_addresses
         conf.cache_in6_getifaddr = ip6_addresses
     except Exception:
         raise
     finally:
         pcap_freealldevs(devs)
Exemple #21
0
 def post_build(self, p, pay):
     p += pay
     if self.Length is None:
         tmp_len = len(p)
         tmp_p = p[:6] + chb((tmp_len >> 8) & 0xff) + chb(tmp_len & 0xff)
         p = tmp_p + p[8:]
     if self.chksum is None:
         ck = checksum(p)
         p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
     return p
Exemple #22
0
 def post_build(self, p, pay):
     p += pay
     if self.Length is None:
         tmp_len = len(p)
         tmp_p = p[:6] + chb((tmp_len >> 8) & 0xff) + chb(tmp_len & 0xff)
         p = tmp_p + p[8:]
     if self.chksum is None:
         ck = checksum(p)
         p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
     return p
Exemple #23
0
 def enc(cls, s):
     # /!\ this is DER encoding (bit strings are only zero-bit padded)
     s = raw(s)
     if len(s) % 8 == 0:
         unused_bits = 0
     else:
         unused_bits = 8 - len(s) % 8
         s += b"0" * unused_bits
     s = b"".join(chb(int(b"".join(chb(y) for y in x), 2)) for x in zip(*[iter(s)] * 8))  # noqa: E501
     s = chb(unused_bits) + s
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemple #24
0
def BER_len_enc(ll, size=0):
    if ll <= 127 and size == 0:
        return chb(ll)
    s = b""
    while ll or size > 0:
        s = chb(ll & 0xff) + s
        ll >>= 8
        size -= 1
    if len(s) > 127:
        raise BER_Exception("BER_len_enc: Length too long (%i) to be encoded [%r]" % (len(s), s))  # noqa: E501
    return chb(len(s) | 0x80) + s
Exemple #25
0
 def post_build(self, p, pay):
     if self.chksum is None:
         if isinstance(self.underlayer, IP):
             ck = in4_chksum(112, self.underlayer, p)
         elif isinstance(self.underlayer, IPv6):
             ck = in6_chksum(112, self.underlayer, p)
         else:
             warning("No IP(v6) layer to compute checksum on VRRP. Leaving null")  # noqa: E501
             ck = 0
         p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:]
     return p
Exemple #26
0
 def i2m(self, pkt, val):
     if not isinstance(val, bytes):
         val = bytes_encode(val)
     ret_string = b""
     for i in range(0, len(val), 2):
         tmp = val[i:i + 2]
         if len(tmp) == 2:
             ret_string += chb(int(tmp[::-1], 16))
         else:
             ret_string += chb(int(b"F" + tmp[:1], 16))
     return ret_string
Exemple #27
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:]
Exemple #28
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:]
 def post_build(self, p, pay):
     if self.chksum is None:
         if isinstance(self.underlayer, IP):
             ck = in4_chksum(112, self.underlayer, p)
         elif isinstance(self.underlayer, IPv6):
             ck = in6_chksum(112, self.underlayer, p)
         else:
             warning("No IP(v6) layer to compute checksum on VRRP. "
                     "Leaving null")
             ck = 0
         p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:]
     return p
Exemple #30
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 = orb(pkt[-1])
         if last_chr <= 0x80:
             return pkt[:-1] + b'\x00' + chb(last_chr)
         else:
             return pkt[:-1] + b'\xff' + chb(orb(last_chr) - 1)
     else:
         return pkt
Exemple #31
0
 def enc(cls, s):
     # /!\ this is DER encoding (bit strings are only zero-bit padded)
     s = raw(s)
     if len(s) % 8 == 0:
         unused_bits = 0
     else:
         unused_bits = 8 - len(s) % 8
         s += b"0" * unused_bits
     s = b"".join(chb(int(b"".join(chb(y) for y in x), 2))
                  for x in zip(*[iter(s)] * 8))
     s = chb(unused_bits) + s
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemple #32
0
    def post_build(self, p, pay):
        """Called implicitly before a packet is sent to compute and place IGMP checksum.

        Parameters:
          self    The instantiation of an IGMP class
          p       The IGMP message in hex in network byte order
          pay     Additional payload for the IGMP message
        """
        p += pay
        if self.chksum is None:
            ck = checksum(p)
            p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
        return p
Exemple #33
0
 def post_build(self, p, pay):
     ihl = self.ihl
     p += b"\0" * ((-len(p)) % 4)  # pad IP options if needed
     if ihl is None:
         ihl = len(p) // 4
         p = chb(((self.version & 0xf) << 4) | ihl & 0x0f) + p[1:]
     if self.len is None:
         tmp_len = len(p) + len(pay)
         p = p[:2] + struct.pack("!H", tmp_len) + p[4:]
     if self.chksum is None:
         ck = checksum(p)
         p = p[:10] + chb(ck >> 8) + chb(ck & 0xff) + p[12:]
     return p + pay
    def generate(self, req):
        if not self.is_valid(req):
            return _ObdResponseGenerator._generate_invalid(req)

        payload = _ObdResponseGenerator.\
            generate_packet_with_random_values(OBD_DTC)

        byte_string = chb(req.service + 0x40) + chb(self.count)
        for _ in range(self.count):
            byte_string += bytes(payload)

        packet = OBD(byte_string)
        return packet
Exemple #35
0
    def post_build(self, p, pay):
        """Called implicitly before a packet is sent to compute and place IGMP checksum.  # noqa: E501

        Parameters:
          self    The instantiation of an IGMP class
          p       The IGMP message in hex in network byte order
          pay     Additional payload for the IGMP message
        """
        p += pay
        if self.chksum is None:
            ck = checksum(p)
            p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
        return p
Exemple #36
0
def customPRF512(key, amac, smac, anonce, snonce):
    """Source https://stackoverflow.com/questions/12018920/"""
    A = b"Pairwise key expansion"
    B = b"".join(sorted([amac, smac]) + sorted([anonce, snonce]))

    blen = 64
    i = 0
    R = b''
    while i <= ((blen * 8 + 159) // 160):
        hmacsha1 = hmac.new(key, A + chb(0x00) + B + chb(i), hashlib.sha1)
        i += 1
        R = R + hmacsha1.digest()
    return R[:blen]
Exemple #37
0
 def enc(cls, _s):
     # type: (AnyStr) -> bytes
     # /!\ this is DER encoding (bit strings are only zero-bit padded)
     s = bytes_encode(_s)
     if len(s) % 8 == 0:
         unused_bits = 0
     else:
         unused_bits = 8 - len(s) % 8
         s += b"0" * unused_bits
     s = b"".join(chb(int(b"".join(chb(y) for y in x), 2))
                  for x in zip(*[iter(s)] * 8))
     s = chb(unused_bits) + s
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemple #38
0
def BER_len_enc(ll, size=0):
    if ll <= 127 and size == 0:
        return chb(ll)
    s = b""
    while ll or size > 0:
        s = chb(ll & 0xff) + s
        ll >>= 8
        size -= 1
    if len(s) > 127:
        raise BER_Exception(
            "BER_len_enc: Length too long (%i) to be encoded [%r]" %
            (len(s), s)
        )
    return chb(len(s) | 0x80) + s
Exemple #39
0
    def decompressDestinyAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[
                    0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[
                        -2:]  # noqa: E501
            elif self.dam == 3:
                # TODO May need some extra changes, we are copying
                # (self.m == 0 and self.dac == 1)
                tmp_ip = _extract_upperaddress(self, source=False)

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                raise Exception('Reserved')
            elif self.dam == 0x3:
                tmp_ip = _extract_upperaddress(self, source=False)
            elif self.dam not in [0x1, 0x2]:
                warning("Unknown destiny address compression mode !")
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                raise Exception("unimplemented")
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                # See https://tools.ietf.org/html/rfc6282#page-9
                raise Exception(
                    "Unimplemented: I didn't understand the 6lowpan specification"
                )  # noqa: E501
            else:  # all the others values
                raise Exception("Reserved value by specification.")

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.destinyAddr
Exemple #40
0
 def enc(cls, i):
     s = []
     while True:
         s.append(i & 0xff)
         if -127 <= i < 0:
             break
         if 128 <= i <= 255:
             s.append(0)
         i >>= 8
         if not i:
             break
     s = [chb(hash(c)) for c in s]
     s.append(BER_len_enc(len(s)))
     s.append(chb(hash(cls.tag)))
     s.reverse()
     return b"".join(s)
Exemple #41
0
 def next(self):
     c = pcap_next_ex(self.pcap, byref(self.header), byref(self.pkt_data))  # noqa: E501
     if not c > 0:
         return
     ts = self.header.contents.ts.tv_sec + float(self.header.contents.ts.tv_usec) / 1000000  # noqa: E501
     pkt = b"".join(chb(i) for i in self.pkt_data[:self.header.contents.len])  # noqa: E501
     return ts, pkt
Exemple #42
0
def _scan_id_service(socket, timeout, service_class, id_numbers, verbose):
    """ Queries certain PIDs and stores their return value

    Args:
        socket: is the ISOTPSocket, over which the OBD-Services communicate.
                the id 0x7df acts as a broadcast address for all obd-supporting ECUs.
        timeout: only required for the OBD Simulator, since it might tell it
                 supports a PID, while it actually doesn't and won't respond to this PID.
                 If this happens with a real ECU, it is an implementation error.
        service_class: specifies, which OBD-Service should be queried.
        id_numbers: a set of PIDs, which should be queried by the method.
        verbose: specifies, whether the sr1()-method gives feedback or not.

    This method queries the specified id_numbers and stores their responses in a dictionary, which is then returned.
    """

    data = dict()

    for id_number in id_numbers:
        id_byte = chb(id_number)
        # assemble request packet
        pkt = OBD() / service_class(id_byte)
        resp = socket.sr1(pkt, timeout=timeout, verbose=verbose)

        if resp is not None:
            data[id_number] = bytes(resp)
    return data
Exemple #43
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)))
Exemple #44
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
Exemple #45
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
Exemple #46
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
Exemple #47
0
def in6_getRandomizedIfaceId(ifaceid, previous=None):
    # type: (str, Optional[str]) -> Tuple[str, str]
    """
    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:
        b_previous = bytes(RandBin(8))
    else:
        b_previous = inet_pton(socket.AF_INET6, "::" + previous)[8:]
    s = inet_pton(socket.AF_INET6, "::" + ifaceid)[8:] + b_previous
    import hashlib
    s = hashlib.md5(s).digest()
    s1, s2 = s[:8], s[8:]
    s1 = chb(orb(s1[0]) & (~0x04)) + s1[1:]  # set bit 6 to 0
    bs1 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s1)[20:]
    bs2 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s2)[20:]
    return (bs1, bs2)
Exemple #48
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
    def generate(self, req):
        if not self.is_valid(req):
            return _ObdResponseGenerator._generate_invalid(req)

        full_payload = b''

        for r in req.payload.requests:
            id_field_name = r.fields_desc[0].name
            one_id = r.getfieldval(id_field_name)
            try:
                class_name = _ObdResponseGeneratorId.get_class_name(
                    id_field_name, one_id)
                payload = _ObdResponseGenerator.\
                    generate_packet_with_random_values(class_name)
                full_payload += bytes(r) + bytes(payload)
            except NameError:
                # appears when PID/IID etc. not supported
                # do not respond, OBD spec conform
                print("{0} {1:#04x} not supported".format(
                    id_field_name.upper(), one_id))

        if len(full_payload) == 0:
            # if no payload, do not generate/send an empty answer
            return None

        packet = OBD(chb(req.service + 0x40) + full_payload)
        return packet
Exemple #50
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)))
Exemple #51
0
 def post_build(self, p, pay):
     # This just forces destaddrmode to None for Ack frames.
     if self.fcf_frametype == 2 and self.fcf_destaddrmode != 0:
         self.fcf_destaddrmode = 0
         return p[:1] + \
             chb((self.fcf_srcaddrmode << 6) + (self.fcf_framever << 4)) \
             + p[2:] + pay
     else:
         return p + pay
Exemple #52
0
def BER_num_enc(ll, size=1):
    x = []
    while ll or size > 0:
        x.insert(0, ll & 0x7f)
        if len(x) > 1:
            x[0] |= 0x80
        ll >>= 7
        size -= 1
    return b"".join(chb(k) for k in x)
Exemple #53
0
 def post_build(self, p, pay):
     if self.headerLen is None:
         headerLen = len(p)
         if isinstance(self.payload, (USBpcapTransferIsochronous,
                                      USBpcapTransferInterrupt,
                                      USBpcapTransferControl)):
             headerLen += len(self.payload) - len(self.payload.payload)
         p = chb(headerLen) + p[1:]
     return p + pay
Exemple #54
0
    def decompressDestinyAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[-2:]  # noqa: E501
            elif self.dam == 3:
                # TODO May need some extra changes, we are copying
                # (self.m == 0 and self.dac == 1)
                tmp_ip = _extract_dot15d4address(self, source=False)

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                raise Exception('Reserved')
            elif self.dam == 0x3:
                tmp_ip = _extract_dot15d4address(self, source=False)
            elif self.dam not in [0x1, 0x2]:
                warning("Unknown destiny address compression mode !")
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                raise Exception("unimplemented")
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                raise Exception("Unimplemented: I didn't understand the 6lowpan specification")  # noqa: E501
            else:  # all the others values
                raise Exception("Reserved value by specification.")

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.destinyAddr
Exemple #55
0
 def post_build(self, p, pay):
     p += pay
     if self.Length is None:
         if len(pay) > 2:
             l = len(pay)
         else:
             l = 0
         p = p[:1] + chb(l & 0x3f) + p[2:]
     if not isinstance(self.underlayer, BTLE):
         self.add_underlayer(BTLE)
     return p
Exemple #56
0
 def enc(cls, oid):
     oid = raw(oid)
     if oid:
         lst = [int(x) for x in oid.strip(b".").split(b".")]
     else:
         lst = list()
     if len(lst) >= 2:
         lst[1] += 40 * lst[0]
         del(lst[0])
     s = b"".join(BER_num_enc(k) for k in lst)
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemple #57
0
def _tls_add_pad(p, block_size):
    """
    Provided with cipher block size parameter and current TLSCompressed packet
    p (after MAC addition), the function adds required, deterministic padding
    to p.data before encryption step, as it is defined for TLS (i.e. not
    SSL and its allowed random padding). The function has no return value.
    """
    padlen = -p.len % block_size
    padding = chb(padlen) * (padlen + 1)
    p.len += len(padding)
    p.data += padding
Exemple #58
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
Exemple #59
0
 def build_GTK_KDE(self):
     """Build the Key Data Encapsulation for GTK
     KeyID: 0
     Ref: 802.11i p81
     """
     return b''.join([
         b'\xdd', # Type KDE
         chb(len(self.gtk_full) + 6),
         b'\x00\x0f\xac', # OUI
         b'\x01', # GTK KDE
         b'\x00\x00', # KeyID - Tx - Reserved x2
         self.gtk_full,
     ])
Exemple #60
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