class TLS_Ext_EncryptedServerName(TLS_Ext_PrettyPacketList): name = "TLS Extension - Encrypted Server Name" fields_desc = [ ShortEnumField("type", 0xffce, _tls_ext), ShortField("len", None), EnumField("cipher", None, _tls_cipher_suites), ShortEnumField("key_exchange_group", None, _tls_named_groups), FieldLenField("key_exchange_len", None, length_of="key_exchange", fmt="H"), XStrLenField("key_exchange", "", length_from=lambda pkt: pkt.key_exchange_len), FieldLenField("record_digest_len", None, length_of="record_digest"), XStrLenField("record_digest", "", length_from=lambda pkt: pkt.record_digest_len), FieldLenField("encrypted_sni_len", None, length_of="encrypted_sni", fmt="H"), XStrLenField("encrypted_sni", "", length_from=lambda pkt: pkt.encrypted_sni_len) ]
class SSLv2ClientHello(_SSLv2Handshake): """ SSLv2 ClientHello. """ name = "SSLv2 Handshake - Client Hello" fields_desc = [ByteEnumField("msgtype", 1, _sslv2_handshake_type), _TLSVersionField("version", 0x0002, _tls_version), FieldLenField("cipherslen", None, fmt="!H", length_of="ciphers"), FieldLenField("sidlen", None, fmt="!H", length_of="sid"), FieldLenField("challengelen", None, fmt="!H", length_of="challenge"), XStrLenField("sid", b"", length_from=lambda pkt:pkt.sidlen), _SSLv2CipherSuitesField("ciphers", [SSL_CK_DES_192_EDE3_CBC_WITH_MD5], _tls_cipher_suites, length_from=lambda pkt: pkt.cipherslen), XStrLenField("challenge", b"", length_from=lambda pkt:pkt.challengelen)] def tls_session_update(self, msg_str): super(SSLv2ClientHello, self).tls_session_update(msg_str) self.tls_session.advertised_tls_version = self.version self.tls_session.sslv2_common_cs = self.ciphers self.tls_session.sslv2_challenge = self.challenge
class AH(Packet): """ Authentication Header See https://tools.ietf.org/rfc/rfc4302.txt """ name = 'AH' def __get_icv_len(self): """ Compute the size of the ICV based on the payloadlen field. Padding size is included as it can only be known from the authentication algorithm provided by the Security Association. """ # payloadlen = length of AH in 32-bit words (4-byte units), minus "2" # payloadlen = 3 32-bit word fixed fields + ICV + padding - 2 # ICV = (payloadlen + 2 - 3 - padding) in 32-bit words return (self.payloadlen - 1) * 4 fields_desc = [ ByteEnumField('nh', None, IP_PROTOS), ByteField('payloadlen', None), ShortField('reserved', None), XIntField('spi', 0x0), IntField('seq', 0), XStrLenField('icv', None, length_from=__get_icv_len), # Padding len can only be known with the SecurityAssociation.auth_algo XStrLenField('padding', None, length_from=lambda x: 0), ] overload_fields = { IP: { 'proto': socket.IPPROTO_AH }, IPv6: { 'nh': socket.IPPROTO_AH }, IPv6ExtHdrHopByHop: { 'nh': socket.IPPROTO_AH }, IPv6ExtHdrDestOpt: { 'nh': socket.IPPROTO_AH }, IPv6ExtHdrRouting: { 'nh': socket.IPPROTO_AH }, }
class EAP_FAST(EAP): """ RFC 4851 - "The Flexible Authentication via Secure Tunneling Extensible Authentication Protocol Method (EAP-FAST)" """ name = "EAP-FAST" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="data", adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), ByteEnumField("type", 43, eap_types), BitField('L', 0, 1), BitField('M', 0, 1), BitField('S', 0, 1), BitField('reserved', 0, 2), BitField('version', 0, 3), ConditionalField(IntField('message_len', 0), lambda pkt: pkt.L == 1), XStrLenField('data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 ]
class PPP_CHAP_ChallengeResponse(PPP_CHAP): fields_desc = [ ByteEnumField("code", 1, _PPP_chaptypes), XByteField("id", 0), FieldLenField("len", None, fmt="!H", length_of="value", adjust=lambda p, x: x + len(p.optional_name) + 5), FieldLenField("value_size", None, fmt="B", length_of="value"), XStrLenField("value", b"\0" * 8, length_from=lambda p: p.value_size), StrLenField("optional_name", "", length_from=lambda p: p.len - p.value_size - 5) ] def answers(self, other): return isinstance(other, PPP_CHAP_ChallengeResponse) and other.code == 1\ and self.code == 2 and self.id == other.id def mysummary(self): if self.code == 1: return self.sprintf( "CHAP challenge=0x%PPP_CHAP_ChallengeResponse.value% " + "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%") elif self.code == 2: return self.sprintf( "CHAP response=0x%PPP_CHAP_ChallengeResponse.value% " + "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%") else: return PPP_CHAP.mysummary(self)
class LLDPDUGenericOrganisationSpecific(LLDPDU): ORG_UNIQUE_CODE_PNO = 0x000ecf ORG_UNIQUE_CODE_IEEE_802_1 = 0x0080c2 ORG_UNIQUE_CODE_IEEE_802_3 = 0x00120f ORG_UNIQUE_CODE_TIA_TR_41_MED = 0x0012bb ORG_UNIQUE_CODE_HYTEC = 0x30b216 ORG_UNIQUE_CODES = { ORG_UNIQUE_CODE_PNO: "PROFIBUS International (PNO)", ORG_UNIQUE_CODE_IEEE_802_1: "IEEE 802.1", ORG_UNIQUE_CODE_IEEE_802_3: "IEEE 802.3", ORG_UNIQUE_CODE_TIA_TR_41_MED: "TIA TR-41 Committee . Media Endpoint Discovery", # noqa: E501 ORG_UNIQUE_CODE_HYTEC: "Hytec Geraetebau GmbH" } fields_desc = [ BitEnumField('_type', 127, 7, LLDPDU.TYPES), BitFieldLenField( '_length', None, 9, length_of='data', adjust=lambda pkt, x: len(pkt.data) + 4), # noqa: E501 ThreeBytesEnumField('org_code', 0, ORG_UNIQUE_CODES), ByteField('subtype', 0x00), XStrLenField('data', '', length_from=lambda pkt: 0 if pkt._length is None else pkt._length - 4) ]
class NEGOEX_CHECKSUM(Packet): fields_desc = [ LELongField("cbHeaderLength", 20), LELongEnumField("ChecksumScheme", 1, {1: "CHECKSUM_SCHEME_RFC3961"}), LELongEnumField("ChecksumType", None, _checksum_types), XStrLenField("ChecksumValue", b"", length_from=_checksum_size) ]
class EAP_MD5(EAP): """ RFC 3748 - "Extensible Authentication Protocol (EAP)" """ name = "EAP-MD5" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="optional_name", adjust=lambda p, x: x + 6 + (p.value_size or 0)), ByteEnumField("type", 4, eap_types), FieldLenField("value_size", None, fmt="B", length_of="value"), XStrLenField("value", '', length_from=lambda p: p.value_size), XStrLenField("optional_name", '', length_from=lambda p: 0 if p.len is None or p.value_size is None else (p.len - p.value_size - 6)) # noqa: E501 ]
class _RadiusAttrHexStringVal(_SpecificRadiusAttr): """ Implements a RADIUS attribute which value field is a string that will be as a hex string. """ __slots__ = ["val"] def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields): # noqa: E501 super(_RadiusAttrHexStringVal, self).__init__(_pkt, post_transform, _internal, _underlayer) self.fields["type"] = self.val name_parts = self.__class__.__name__.split('RadiusAttr_') if len(name_parts) < 2: raise Scapy_Exception("Invalid class name: {}".format( self.__class__.__name__)) self.name = name_parts[1].replace('_', '-') fields_desc = [ ByteEnumField("type", 24, _radius_attribute_types), FieldLenField("len", None, "value", "B", adjust=lambda p, x: len(p.value) + 2), XStrLenField("value", "", length_from=lambda p: p.len - 2 if p.len else 0) # noqa: E501 ]
class SMB2_Preauth_Integrity_Capabilities(Packet): name = "SMB2 Preauth Integrity Capabilities" fields_desc = [ # According to the spec, this field value must be greater than 0 # (cf Section 2.2.3.1.1 of MS-SMB2.pdf) FieldLenField("HashAlgorithmCount", 1, fmt="<H", count_of="HashAlgorithms"), FieldLenField("SaltLength", 0, fmt="<H", length_of="Salt"), FieldListField( "HashAlgorithms", [0x0001], LEShortEnumField( "", 0x0, { # As for today, no other hash algorithm is described by the spec 0x0001: "SHA-512", }), count_from=lambda pkt: pkt.HashAlgorithmCount), XStrLenField("Salt", "", length_from=lambda pkt: pkt.SaltLength), ] def default_payload_class(self, payload): return conf.padding_layer
class TLS_Ext_Cookie(TLS_Ext_Unknown): name = "TLS Extension - Cookie" fields_desc = [ShortEnumField("type", 0x2c, _tls_ext), ShortField("len", None), FieldLenField("cookielen", None, length_of="cookie"), XStrLenField("cookie", "", length_from=lambda pkt: pkt.cookielen)]
class EAP_PEAP(EAP): """ draft-josefsson-pppext-eap-tls-eap-05.txt - "Protected EAP Protocol (PEAP)" """ name = "PEAP" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="tls_data", adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), ByteEnumField("type", 25, eap_types), BitField("L", 0, 1), BitField("M", 0, 1), BitField("S", 0, 1), BitField("reserved", 0, 3), BitField("version", 1, 2), ConditionalField(IntField("tls_message_len", 0), lambda pkt: pkt.L == 1), # noqa: E501 XStrLenField("tls_data", "", length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 ]
class PPP_CHAP_ChallengeResponse(PPP_CHAP): fields_desc = [ ByteEnumField("code", 1, _PPP_chaptypes), XByteField("id", 0), FieldLenField( "len", None, fmt="!H", length_of="value", adjust=lambda pkt, val: val + len(pkt.optional_name) + 5, ), FieldLenField("value_size", None, fmt="B", length_of="value"), XStrLenField("value", b'\x00\x00\x00\x00\x00\x00\x00\x00', length_from=lambda pkt: pkt.value_size), StrLenField("optional_name", "", length_from=lambda pkt: pkt.len - pkt.value_size - 5), ] def answers(self, other): return isinstance(other, PPP_CHAP_ChallengeResponse) \ and other.code == 1 and self.code == 2 and self.id == other.id def mysummary(self): if self.code == 1: return self.sprintf( "CHAP challenge=0x%PPP_CHAP_ChallengeResponse.value% " "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%" ) elif self.code == 2: return self.sprintf( "CHAP response=0x%PPP_CHAP_ChallengeResponse.value% " "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%" ) else: return super(PPP_CHAP_ChallengeResponse, self).mysummary()
class EAP_TLS(EAP): """ RFC 5216 - "The EAP-TLS Authentication Protocol" """ name = "EAP-TLS" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="tls_data", adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), ByteEnumField("type", 13, eap_types), BitField('L', 0, 1), BitField('M', 0, 1), BitField('S', 0, 1), BitField('reserved', 0, 5), ConditionalField(IntField('tls_message_len', 0), lambda pkt: pkt.L == 1), # noqa: E501 XStrLenField('tls_data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 ]
class EAP_TTLS(EAP): """ RFC 5281 - "Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0)" """ name = "EAP-TTLS" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="data", adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), ByteEnumField("type", 21, eap_types), BitField("L", 0, 1), BitField("M", 0, 1), BitField("S", 0, 1), BitField("reserved", 0, 2), BitField("version", 0, 3), ConditionalField(IntField("message_len", 0), lambda pkt: pkt.L == 1), XStrLenField("data", "", length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 ]
class LEAP(EAP): """ Cisco LEAP (Lightweight EAP) https://freeradius.org/rfc/leap.txt """ name = "Cisco LEAP" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), ShortField("len", None), ByteEnumField("type", 17, eap_types), ByteField('version', 1), XByteField('unused', 0), FieldLenField( "count", None, "challenge_response", "B", adjust=lambda p, x: len(p.challenge_response)), # noqa: E501 XStrLenField("challenge_response", "", length_from=lambda p: 0 or p.count), # noqa: E501 StrLenField("username", "", length_from=lambda p: p.len - (8 + (0 or p.count))) # noqa: E501 ]
class SMB2_Compression_Capabilities(Packet): name = "SMB2 Compression Capabilities" fields_desc = [ FieldLenField( "CompressionAlgorithmCount", 0, fmt="<H", count_of="CompressionAlgorithms" ), ShortField("Padding", 0x0), IntEnumField("Flags", 0x0, { 0x00000000: "SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE", 0x00000001: "SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED", }), FieldListField( "CompressionAlgorithms", None, LEShortEnumField("", 0x0, SMB2_COMPRESSION_ALGORITHMS), count_from=lambda pkt: pkt.CompressionAlgorithmCount, ), # Pad the whole packet on 8 bytes XStrLenField( "Padding2", "", length_from=lambda pkt: (8 - (2 + 2 + 4 + pkt.CompressionAlgorithmCount * 2)) % 8 ), ]
class MKABasicParamSet(Packet): """ Basic Parameter Set (802.1X-2010, section 11.11). """ ######################################################################### # # IEEE 802.1X-2010 standard # Section 11.11 ######################################################################### # name = "Basic Parameter Set" fields_desc = [ ByteField("mka_version_id", 0), ByteField("key_server_priority", 0), BitField("key_server", 0, 1), BitField("macsec_desired", 0, 1), BitField("macsec_capability", 0, 2), BitField("param_set_body_len", 0, 12), PacketField("SCI", MACsecSCI(), MACsecSCI), XStrFixedLenField("actor_member_id", "", length=12), XIntField("actor_message_number", 0), XIntField("algorithm_agility", 0), PadField(XStrLenField("cak_name", "", length_from=lambda pkt: (pkt.param_set_body_len - 28)), 4, padwith=b"\x00") ] def extract_padding(self, s): return "", s
class TZSPTagUnknown(_TZSPTag): """ unknown tag type dummy """ fields_desc = [ ByteField('type', 0xff), FieldLenField('len', None, length_of='data', fmt='b'), XStrLenField('data', '', length_from=lambda pkt: pkt.len) ]
class SMBSession_Setup_AndX_Request(Packet): name = "Session Setup AndX Request (CIFS)" fields_desc = [ ByteField("WordCount", 13), ByteEnumField("AndXCommand", 0x75, SMB_COM), ByteField("AndXReserved", 0), LEShortField("AndXOffset", 96), LEShortField("MaxBufferSize", 2920), LEShortField("MaxMPXCount", 50), LEShortField("VCNumber", 0), LEIntField("SessionKey", 0), LEFieldLenField("OEMPasswordLength", None, length_of="OEMPassword"), LEFieldLenField("UnicodePasswordLength", None, length_of="UnicodePassword"), LEIntField("Reserved", 0), FlagsField("ServerCapabilities", 0x05, -32, _SMB_ServerCapabilities), LEShortField("ByteCount", 35), XStrLenField("OEMPassword", "Pass", length_from=lambda x: x.OEMPasswordLength), XStrLenField("UnicodePassword", "Pass", length_from=lambda x: x.UnicodePasswordLength), ReversePadField(StrNullField("AccountName", "GUEST"), 2, b"\0"), _SMBStrNullField("PrimaryDomain", ""), _SMBStrNullField("NativeOS", "Windows 4.0"), _SMBStrNullField("NativeLanMan", "Windows 4.0"), # Off spec? ByteField("WordCount2", 4), ByteEnumField("AndXCommand2", 0xFF, {0xFF: "SMB_COM_NONE"}), ByteField("Reserved6", 0), LEShortField("AndXOffset2", 0), LEShortField("Flags3", 0x2), LEShortField("PasswordLength", 0x1), LEShortField("ByteCount2", 18), ByteField("Password", 0), StrNullField("Path", "\\\\WIN2K\\IPC$"), StrNullField("Service", "IPC") ]
class TLS_Ext_Cookie(TLS_Ext_Unknown): name = "TLS Extension - Cookie" fields_desc = [ShortEnumField("type", 0x2c, _tls_ext), ShortField("len", None), FieldLenField("cookielen", None, length_of="cookie"), XStrLenField("cookie", "", length_from=lambda pkt: pkt.cookielen)] def build(self): fval = self.getfieldval("cookie") if fval is None or fval == b"": self.cookie = os.urandom(32) return TLS_Ext_Unknown.build(self)
class MAVLink(Raw): ''' MAVLink message scapy layer. ''' name = 'MAVLink' fields_desc = [ ByteEnumField('magic', None, {0x55: '(0x55) MAVLink v0.9', 0xfe: '(0xfe) MAVLink v1.0', 0xfd: '(0xfd) MAVLink v2.0'}), ByteField('length', None), ConditionalField(XByteField('incompat_flags', None), lambda pkt: pkt.magic == 0xfd), ConditionalField(XByteField('compat_flags', None), lambda pkt: pkt.magic == 0xfd), ByteField('sequence', None), XByteField('sysid', None), XByteField('compid', None), MAVLinkMessageID('msgid', None), ConditionalField(XStrLenField('raw_data', None, length_from=lambda pkt: pkt.length), lambda pkt: pkt.msgid not in MESSAGES.keys()), ConditionalField(MAVLinkMessage('message', None, msgid=lambda pkt: pkt.msgid, length_from=lambda pkt: pkt.length), lambda pkt: pkt.msgid in MESSAGES.keys()), LEShortField('crc', None), ConditionalField(StrFixedLenField('signature', None, length=13), lambda pkt: pkt.magic == 0xfd and (pkt.incompat_flags & 0x01) > 0x00), ] def __init__(self, _pkt=b'', index=0, **kwargs): Raw.__init__(self, _pkt, index, kwargs) def extract_padding(self, s): return None, s def pre_dissect(self, s): offset = 0 while offset < len(s) and s[offset] not in [0x55, 0xfe, 0xfd]: offset += 1 if offset > 0 and self.underlayer is not None: self.underlayer.add_payload(Padding(s[:offset])) return s[offset:] def dissect(self, s): s = self.pre_dissect(s) s = self.do_dissect(s) s = self.post_dissect(s) payl, pad = self.extract_padding(s) self.do_dissect_payload(payl) if pad and conf.padding: if pad[0] in [0x55, 0xfe, 0xfd]: if self.underlayer is not None: self.underlayer.add_payload(MAVLink(pad)) else: self.add_payload(MAVLink(pad)) else: if self.underlayer is not None: self.underlayer.add_payload(Padding(pad)) else: self.add_payload(Padding(pad))
class SMB2_Preauth_Integrity_Capabilities(Packet): name = "SMB2 Preauth Integrity Capabilities" fields_desc = [ # According to the spec, this field value must be greater than 0 # (cf Section 2.2.3.1.1 of MS-SMB2.pdf) FieldLenField( "HashAlgorithmCount", 1, fmt="<H", count_of="HashAlgorithms" ), FieldLenField("SaltLength", 0, fmt="<H", length_of="Salt"), FieldListField("HashAlgorithms", [0x0001], LEShortEnumField("", 0x0, { # As for today, no other hash algorithm is described by the spec 0x0001: "SHA-512", }), count_from=lambda pkt: pkt.HashAlgorithmCount), XStrLenField("Salt", "", length_from=lambda pkt: pkt.SaltLength), # Pad the whole packet on 8 bytes XStrLenField( "Padding", "", length_from=lambda pkt: (8 - (4 + pkt.HashAlgorithmCount * 2 + pkt.SaltLength)) % 8 ), ]
class SMB2_Encryption_Capabilities(Packet): name = "SMB2 Encryption Capabilities" fields_desc = [ # According to the spec, this field value must be greater than 0 # (cf Section 2.2.3.1.2 of MS-SMB2.pdf) FieldLenField("CipherCount", 1, fmt="<H", count_of="Ciphers"), FieldListField("Ciphers", [0x0001], LEShortEnumField("", 0x0, { 0x0001: "AES-128-CCM", 0x0002: "AES-128-GCM", }), count_from=lambda pkt: pkt.CipherCount), # Pad the whole packet on 8 bytes XStrLenField( "Padding", "", length_from=lambda pkt: (8 - (2 + pkt.CipherCount * 2)) % 8 ), ]
class EAP_PWD(EAP): """ RFC 5931 - "Extensible Authentication Protocol (EAP)" """ name = "EAP-pwd" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="pwd_data", adjust=lambda pkt, x: len(pkt.value) + 2), ByteEnumField("type", 52, eap_types), BitField('L', 0, 1), BitField('M', 0, 1), BitField('pwd_type', 0, 5), ConditionalField(IntField("message_len", 0), lambda pkt: pkt.L == 1), # payload must be subtracted from header length (5) XStrLenField("pwd_data", "", length_from=lambda \ pkt: 0 if pkt.len is None else pkt.len - 5) ]
class SMB2_Negociate_Protocol_Response_Header(Packet): name = "SMB2 Negociate Protocol Response Header" fields_desc = [ XLEShortField("StructureSize", 0), FlagsField("SecurityMode", 0, 16, { 0x7: "Signing Required", 0x8: "Signing Enabled", }), LEShortEnumField("Dialect", 0x0, SMB_DIALECTS), FieldLenField( "NegociateCount", 0x0, fmt="<H", count_of="NegociateContexts" ), UUIDField("ServerGUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), # Capabilities FlagsField("Capabilities", 0, 32, SMB2_CAPABILITIES), LEIntField("MaxTransactionSize", 0), LEIntField("MaxReadSize", 0), LEIntField("MaxWriteSize", 0), # TODO FIXME XLongField("SystemTime", 0), XLongField("ServerStartTime", 0), XLEShortField("SecurityBufferOffset", 0), FieldLenField( "SecurityBufferLength", 0, fmt="<H", length_of="SecurityBuffer" ), XLEIntField("NegociateContextOffset", 0), # TODO FIXME XStrLenField( "SecurityBuffer", None, length_from=lambda pkt: pkt.SecurityBufferLength ), PacketListField( "NegociateContexts", [], SMB2_Negociate_Context, count_from=lambda pkt: pkt.NegociateCount ), ]
class RTPSSubMessage_ACKNACK(EPacket): """ 0...2...........7...............15.............23...............31 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ACKNACK | flags | octetsToNextHeader | +---------------+---------------+---------------+---------------+ | EntityId readerEntityId | +---------------+---------------+---------------+---------------+ | EntityId writerEntityId | +---------------+---------------+---------------+---------------+ | | + SequenceNumberSet readerSNState + | | +---------------+---------------+---------------+---------------+ | Counter count | +---------------+---------------+---------------+---------------+ """ name = "RTPS ACKNACK (0x06)" fields_desc = [ XByteField("submessageId", 0x06), XByteField("submessageFlags", 0x00), EField(ShortField("octetsToNextHeader", 0)), EnumField( "reader_id", default=b"\x00\x00\x00\x00", fmt="4s", enum=_rtps_reserved_entity_ids, ), EnumField( "writer_id", default=b"\x00\x00\x00\x00", fmt="4s", enum=_rtps_reserved_entity_ids, ), XStrLenField( "readerSNState", 0, length_from=lambda pkt: pkt.octetsToNextHeader - 8 - 4 ), XNBytesField("count", 0, 4), ]
class SSLv2ServerHello(_SSLv2Handshake): """ SSLv2 ServerHello. """ name = "SSLv2 Handshake - Server Hello" fields_desc = [ ByteEnumField("msgtype", 4, _sslv2_handshake_type), ByteField("sid_hit", 0), ByteEnumField("certtype", 1, {1: "x509_cert"}), _TLSVersionField("version", 0x0002, _tls_version), FieldLenField("certlen", None, fmt="!H", length_of="cert"), FieldLenField("cipherslen", None, fmt="!H", length_of="ciphers"), FieldLenField("connection_idlen", None, fmt="!H", length_of="connection_id"), _SSLv2CertDataField("cert", b"", length_from=lambda pkt: pkt.certlen), _SSLv2CipherSuitesField( "ciphers", [], _tls_cipher_suites, length_from=lambda pkt: pkt.cipherslen), # noqa: E501 XStrLenField("connection_id", b"", length_from=lambda pkt: pkt.connection_idlen) ] def tls_session_update(self, msg_str): """ XXX Something should be done about the session ID here. """ super(SSLv2ServerHello, self).tls_session_update(msg_str) s = self.tls_session client_cs = s.sslv2_common_cs css = [cs for cs in client_cs if cs in self.ciphers] s.sslv2_common_cs = css s.sslv2_connection_id = self.connection_id s.tls_version = self.version if self.cert is not None: s.server_certs = [self.cert]
class AV_PAIR(Packet): name = "NTLM AV Pair" fields_desc = [ LEShortEnumField( 'AvId', 0, { 0x0000: "MsvAvEOL", 0x0001: "MsvAvNbComputerName", 0x0002: "MsvAvNbDomainName", 0x0003: "MsvAvDnsComputerName", 0x0004: "MsvAvDnsDomainName", 0x0005: "MsvAvDnsTreeName", 0x0006: "MsvAvFlags", 0x0007: "MsvAvTimestamp", 0x0008: "MsvAvSingleHost", 0x0009: "MsvAvTargetName", 0x000A: "MsvAvChannelBindings", }), FieldLenField('AvLen', None, length_of="Value", fmt="<H"), MultipleTypeField([ (LEIntEnumField( 'Value', 1, { 0x0001: "constrained", 0x0002: "MIC integrity", 0x0004: "SPN from untrusted source" }), lambda pkt: pkt.AvId == 0x0006), (UTCTimeField("Value", None, epoch=[1601, 1, 1, 0, 0, 0], custom_scaling=1e7, fmt="<Q"), lambda pkt: pkt.AvId == 0x0007), (PacketField('Value', Single_Host_Data(), Single_Host_Data), lambda pkt: pkt.AvId == 0x0008), (XStrLenField('Value', b"", length_from=lambda pkt: pkt.AvLen), lambda pkt: pkt.AvId == 0x000A), ], StrLenFieldUtf16('Value', b"", length_from=lambda pkt: pkt.AvLen)) ] def default_payload_class(self, payload): return conf.padding_layer
class SSLv2ClientMasterKey(_SSLv2Handshake): """ SSLv2 ClientMasterKey. """ __slots__ = ["decryptedkey"] name = "SSLv2 Handshake - Client Master Key" fields_desc = [ByteEnumField("msgtype", 2, _sslv2_handshake_type), _SSLv2CipherSuiteField("cipher", None, _tls_cipher_suites), FieldLenField("clearkeylen", None, fmt="!H", length_of="clearkey"), FieldLenField("encryptedkeylen", None, fmt="!H", length_of="encryptedkey"), FieldLenField("keyarglen", None, fmt="!H", length_of="keyarg"), XStrLenField("clearkey", "", length_from=lambda pkt: pkt.clearkeylen), _SSLv2EncryptedKeyField("encryptedkey", "", length_from=lambda pkt: pkt.encryptedkeylen), XStrLenField("keyarg", "", length_from=lambda pkt: pkt.keyarglen)] def __init__(self, *args, **kargs): """ When post_building, the packets fields are updated (this is somewhat non-standard). We might need these fields later, but calling __str__ on a new packet (i.e. not dissected from a raw string) applies post_build to an object different from the original one... unless we hackishly always set self.explicit to 1. """ self.decryptedkey = kargs.pop("decryptedkey", b"") super(SSLv2ClientMasterKey, self).__init__(*args, **kargs) self.explicit = 1 def pre_dissect(self, s): clearkeylen = struct.unpack("!H", s[4:6])[0] encryptedkeylen = struct.unpack("!H", s[6:8])[0] encryptedkeystart = 10 + clearkeylen encryptedkey = s[encryptedkeystart:encryptedkeystart + encryptedkeylen] if self.tls_session.server_rsa_key: self.decryptedkey = \ self.tls_session.server_rsa_key.decrypt(encryptedkey) else: self.decryptedkey = None return s def post_build(self, pkt, pay): cs_val = None if self.cipher is None: common_cs = self.tls_session.sslv2_common_cs cs_vals = get_usable_ciphersuites(common_cs, "SSLv2") if len(cs_vals) == 0: warning("No known common cipher suite between SSLv2 Hellos.") cs_val = 0x0700c0 cipher = b"\x07\x00\xc0" else: cs_val = cs_vals[0] # XXX choose the best one cipher = struct.pack(">BH", cs_val >> 16, cs_val & 0x00ffff) cs_cls = _tls_cipher_suites_cls[cs_val] self.cipher = cs_val else: cipher = pkt[1:4] cs_val = struct.unpack("!I", b"\x00" + cipher)[0] if cs_val not in _tls_cipher_suites_cls: warning("Unknown ciphersuite %d from ClientMasterKey" % cs_val) cs_cls = None else: cs_cls = _tls_cipher_suites_cls[cs_val] if cs_cls: if (self.encryptedkey == b"" and len(self.tls_session.server_certs) > 0): # else, the user is responsible for export slicing & encryption key = randstring(cs_cls.cipher_alg.key_len) if self.clearkey == b"" and cs_cls.kx_alg.export: self.clearkey = key[:-5] if self.decryptedkey == b"": if cs_cls.kx_alg.export: self.decryptedkey = key[-5:] else: self.decryptedkey = key pubkey = self.tls_session.server_certs[0].pubKey self.encryptedkey = pubkey.encrypt(self.decryptedkey) if self.keyarg == b"" and cs_cls.cipher_alg.type == "block": self.keyarg = randstring(cs_cls.cipher_alg.block_size) clearkey = self.clearkey or b"" if self.clearkeylen is None: self.clearkeylen = len(clearkey) clearkeylen = struct.pack("!H", self.clearkeylen) encryptedkey = self.encryptedkey or b"" if self.encryptedkeylen is None: self.encryptedkeylen = len(encryptedkey) encryptedkeylen = struct.pack("!H", self.encryptedkeylen) keyarg = self.keyarg or b"" if self.keyarglen is None: self.keyarglen = len(keyarg) keyarglen = struct.pack("!H", self.keyarglen) s = (chb(pkt[0]) + cipher + clearkeylen + encryptedkeylen + keyarglen + clearkey + encryptedkey + keyarg) return s + pay def tls_session_update(self, msg_str): super(SSLv2ClientMasterKey, self).tls_session_update(msg_str) s = self.tls_session cs_val = self.cipher if cs_val not in _tls_cipher_suites_cls: warning("Unknown cipher suite %d from ClientMasterKey" % cs_val) cs_cls = None else: cs_cls = _tls_cipher_suites_cls[cs_val] tls_version = s.tls_version or 0x0002 connection_end = s.connection_end wcs_seq_num = s.wcs.seq_num s.pwcs = writeConnState(ciphersuite=cs_cls, connection_end=connection_end, seq_num=wcs_seq_num, tls_version=tls_version) rcs_seq_num = s.rcs.seq_num s.prcs = readConnState(ciphersuite=cs_cls, connection_end=connection_end, seq_num=rcs_seq_num, tls_version=tls_version) if self.decryptedkey is not None: s.master_secret = self.clearkey + self.decryptedkey s.compute_sslv2_km_and_derive_keys() if s.pwcs.cipher.type == "block": s.pwcs.cipher.iv = self.keyarg if s.prcs.cipher.type == "block": s.prcs.cipher.iv = self.keyarg s.triggered_prcs_commit = True s.triggered_pwcs_commit = True