class SMB2_Header(Packet): name = "SMB2 Header" fields_desc = [ StrFixedLenField("Start", b"\xfeSMB", 4), LEShortField("HeaderLength", 0), LEShortField("CreditCharge", 0), LEShortField("ChannelSequence", 0), LEShortField("Unused", 0), ShortEnumField("Command", 0, {0x0000: "SMB2_COM_NEGOCIATE"}), LEShortField("CreditsRequested", 0), # XLEIntField("Flags", 0), FlagsField("Flags", 0, 32, { 24: "SMB2_FLAGS_SERVER_TO_REDIR", }), XLEIntField("ChainOffset", 0), LELongField("MessageID", 0), XLEIntField("ProcessID", 0), XLEIntField("TreeID", 0), XLELongField("SessionID", 0), XNBytesField("Signature", 0, 16), ] def guess_payload_class(self, payload): if self.Command == 0x0000: if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: return SMB2_Negociate_Protocol_Response_Header return SMB2_Negociate_Protocol_Request_Header return super(SMB2_Header, self).guess_payload_class(payload)
class Dot15d4AuxSecurityHeader(Packet): name = "802.15.4 Auxiliary Security Header" fields_desc = [ BitField("sec_sc_reserved", 0, 3), # Key Identifier Mode # 0: Key is determined implicitly from the originator and recipient(s) of the frame # noqa: E501 # 1: Key is determined explicitly from the the 1-octet Key Index subfield of the Key Identifier field # noqa: E501 # 2: Key is determined explicitly from the 4-octet Key Source and the 1-octet Key Index # noqa: E501 # 3: Key is determined explicitly from the 8-octet Key Source and the 1-octet Key Index # noqa: E501 BitEnumField("sec_sc_keyidmode", 0, 2, { 0: "Implicit", 1: "1oKeyIndex", 2: "4o-KeySource-1oKeyIndex", 3: "8o-KeySource-1oKeyIndex"} # noqa: E501 ), BitEnumField("sec_sc_seclevel", 0, 3, {0: "None", 1: "MIC-32", 2: "MIC-64", 3: "MIC-128", 4: "ENC", 5: "ENC-MIC-32", 6: "ENC-MIC-64", 7: "ENC-MIC-128"}), # noqa: E501 XLEIntField("sec_framecounter", 0x00000000), # 4 octets # Key Identifier (variable length): identifies the key that is used for cryptographic protection # noqa: E501 # Key Source : length of sec_keyid_keysource varies btwn 0, 4, and 8 bytes depending on sec_sc_keyidmode # noqa: E501 # 4 octets when sec_sc_keyidmode == 2 ConditionalField(XLEIntField("sec_keyid_keysource", 0x00000000), lambda pkt: pkt.getfieldval("sec_sc_keyidmode") == 2), # 8 octets when sec_sc_keyidmode == 3 ConditionalField(LELongField("sec_keyid_keysource", 0x0000000000000000), # noqa: E501 lambda pkt: pkt.getfieldval("sec_sc_keyidmode") == 3), # Key Index (1 octet): allows unique identification of different keys with the same originator # noqa: E501 ConditionalField(XByteField("sec_keyid_keyindex", 0xFF), lambda pkt: pkt.getfieldval("sec_sc_keyidmode") != 0), ]
class WireguardResponse(Packet): name = "Wireguard Response" fields_desc = [ XLEIntField("sender_index", 0), XLEIntField("receiver_index", 0), XStrFixedLenField("unencrypted_ephemeral", 0, 32), XStrFixedLenField("encrypted_nothing", 0, 16), XStrFixedLenField("mac1", 0, 16), XStrFixedLenField("mac2", 0, 16), ]
class Dot15d4AuxSecurityHeader(Packet): KEY_IDENTIFIER_MODE = { # Key is determined implicitly from the originator and recipient(s) of # the frame 0: "Implicit", # Key is determined explicitly from the the 1-octet Key Index subfield # of the Key Identifier field 1: "1oKeyIndex", # Key is determined explicitly from the 4-octet Key Source and the # 1-octet Key Index 2: "4o-KeySource-1oKeyIndex", # Key is determined explicitly from the 8-octet Key Source and the # 1-octet Key Index 3: "8o-KeySource-1oKeyIndex" } SEC_LEVEL = { 0: "None", 1: "MIC-32", 2: "MIC-64", 3: "MIC-128", 4: "ENC", 5: "ENC-MIC-32", 6: "ENC-MIC-64", 7: "ENC-MIC-128" } name = "802.15.4 Auxiliary Security Header" fields_desc = [ BitField("sec_sc_reserved", 0, 3), BitEnumField("sec_sc_keyidmode", 0, 2, KEY_IDENTIFIER_MODE), BitEnumField("sec_sc_seclevel", 0, 3, SEC_LEVEL), XLEIntField("sec_framecounter", 0x00000000), # Key Identifier (variable length): identifies the key that is used for # cryptographic protection. # Key Source : length of sec_keyid_keysource varies btwn 0, 4, and 8 # bytes depending on sec_sc_keyidmode. # 4 octets when sec_sc_keyidmode == 2 ConditionalField(XLEIntField("sec_keyid_keysource", 0), lambda pkt: pkt.getfieldval("sec_sc_keyidmode") == 2), # 8 octets when sec_sc_keyidmode == 3 ConditionalField(LELongField("sec_keyid_keysource", 0), lambda pkt: pkt.getfieldval("sec_sc_keyidmode") == 3), # Key Index (1 octet): allows unique identification of different keys # with the same originator. ConditionalField(XByteField("sec_keyid_keyindex", 0xFF), lambda pkt: pkt.getfieldval("sec_sc_keyidmode") != 0), ]
class ZigbearSecurityLayer(Packet): name = "Zigbear Security Header" fields_desc = [ # Message Info (1 octet) # Informational flags FlagsField("flags", 0, 6, ['public_key_request', 'reserved1', 'reserved2', 'reserved3', 'reserved4', 'reserved5']), # Message type BitEnumField("message_type", 0, 2, { 0: 'no_encryption', 1: 'public_key_transmission', 2: 'network_key_transmission', 3: 'symencrypted_data', }), # Frame counter (4 octets) XLEIntField("fc", 0), # provide frame freshness and prevent duplicate frames # Payload # Message Authentication Code (16 Byte CMAC for example) # For transmission of network key: Other key derived from shared key # Otherwise: tbd ConditionalField(BitField("mac", 0, 128), lambda pkt: pkt.getfieldval("message_type") > 1), # Can be 80 Bytes DER serialized ECDH public key from SECP224R1 # Can be the transmitted network key encrypted with a key derived from the shared key # Can be data encrpted with the network key StrField("data", "") ]
class Dot11FCS(Dot11): name = "802.11-FCS" fields_desc = Dot11.fields_desc + [ XLEIntField("fcs", None) ] # Automatically moved to the end of the packet # noqa: E501 def compute_fcs(self, s): return struct.pack("!I", crc32(s) & 0xffffffff)[::-1] def post_build(self, p, pay): # Switch payload and frame check sequence return p[:-4] + pay + (p[-4:] if self.fcs is not None else self.compute_fcs(p[:-4] + pay)) # noqa: E501 def post_dissect(self, s): self.raw_packet_cache = None # Reset packet to allow post_build return s 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]
class BTLE(Packet): name = "BT4LE" fields_desc = [ XLEIntField("access_addr", 0x8E89BED6), LEX3BytesField("crc", None) ] @staticmethod 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] def post_build(self, p, pay): # Switch payload and CRC crc = p[-3:] p = p[:-3] + pay p += crc if self.crc is not None else self.compute_crc(p[4:]) return p def post_dissect(self, s): self.raw_packet_cache = None # Reset packet to allow post_build return s def pre_dissect(self, s): # move crc return s[:4] + s[-3:] + s[4:-3] def hashret(self): return struct.pack("!L", self.access_addr)
class WireguardCookieReply(Packet): name = "Wireguard Cookie Reply" fields_desc = [ XLEIntField("receiver_index", 0), XStrFixedLenField("nonce", 0, 24), XStrFixedLenField("encrypted_cookie", 0, 32), ]
class WireguardTransport(Packet): name = "Wireguard Transport" fields_desc = [ XLEIntField("receiver_index", 0), XLELongField("counter", 0), XStrField("encrypted_encapsulated_packet", None) ]
class LL_ENC_REQ(Packet): name = 'LL_ENC_REQ' fields_desc = [ XLELongField("rand", 0), XLEShortField("ediv", 0), XLELongField("skdm", 0), XLEIntField("ivm", 0), ]
class ZCLMeteringGetProfile(Packet): name = "Metering Cluster: Get Profile Command (Server: Received)" fields_desc = [ # Interval Channel (8-bit Enumeration): 1 octet ByteField("Interval_Channel", 0), # 0 == Consumption Delivered ; 1 == Consumption Received # noqa: E501 # End Time (UTCTime): 4 octets XLEIntField("End_Time", 0x00000000), # NumberOfPeriods (Unsigned 8-bit Integer): 1 octet ByteField("NumberOfPeriods", 1), # Represents the number of intervals being requested. # noqa: E501 ]
class ZigbeeSecurityHeader(Packet): name = "Zigbee Security Header" fields_desc = [ # Security control (1 octet) FlagsField("reserved1", 0, 2, ['reserved1', 'reserved2']), BitField( "extended_nonce", 1, 1 ), # set to 1 if the sender address field is present (source) # noqa: E501 # Key identifier BitEnumField( "key_type", 1, 2, { 0: 'data_key', 1: 'network_key', 2: 'key_transport_key', 3: 'key_load_key' }), # Security level (3 bits) BitEnumField( "nwk_seclevel", 0, 3, { 0: "None", 1: "MIC-32", 2: "MIC-64", 3: "MIC-128", 4: "ENC", 5: "ENC-MIC-32", 6: "ENC-MIC-64", 7: "ENC-MIC-128" }), # Frame counter (4 octets) XLEIntField( "fc", 0 ), # provide frame freshness and prevent duplicate frames # noqa: E501 # Source address (0/8 octets) ConditionalField( dot15d4AddressField("source", 0, adjust=lambda pkt, x: 8), lambda pkt: pkt.extended_nonce), # noqa: E501 # Key sequence number (0/1 octet): only present when key identifier is 1 (network key) # noqa: E501 ConditionalField( ByteField("key_seqnum", 0), lambda pkt: pkt.getfieldval("key_type") == 1), # noqa: E501 # Payload # the length of the encrypted data is the payload length minus the MIC StrField("data", ""), # noqa: E501 # Message Integrity Code (0/variable in size), length depends on nwk_seclevel # noqa: E501 XStrField("mic", ""), ] def post_dissect(self, s): # Get the mic dissected correctly mic_length = util_mic_len(self) if mic_length > 0: # Slice "data" into "data + mic" _data, _mic = self.data[:-mic_length], self.data[-mic_length:] self.data, self.mic = _data, _mic return s
class WireguardInitiation(Packet): name = "Wireguard Initiation" fields_desc = [ XLEIntField("sender_index", 0), XStrFixedLenField("unencrypted_ephemeral", 0, 32), XStrFixedLenField("encrypted_static", 0, 48), XStrFixedLenField("encrypted_timestamp", 0, 28), XStrFixedLenField("mac1", 0, 16), XStrFixedLenField("mac2", 0, 16), ]
class SMB2_Header(Packet): name = "SMB2 Header" fields_desc = [ StrFixedLenField("Start", b"\xfeSMB", 4), LEShortField("HeaderLength", 0), LEShortField("CreditCharge", 0), LEShortField("ChannelSequence", 0), LEShortField("Unused", 0), ShortEnumField("Command", 0, {0x0000: "SMB2_COM_NEGOCIATE"}), LEShortField("CreditsRequested", 0), # XLEIntField("Flags", 0), FlagsField("Flags", 0, 32, { 24: "SMB2_FLAGS_SERVER_TO_REDIR", }), XLEIntField("ChainOffset", 0), LELongField("MessageID", 0), XLEIntField("ProcessID", 0), XLEIntField("TreeID", 0), XLELongField("SessionID", 0), XNBytesField("Signature", 0, 16), ]
class SMB2_Compression_Transform_Header(Packet): name = "SMB2 Compression Transform Header" fields_desc = [ StrFixedLenField("Start", b"\xfcSMB", 4), LEIntField("OriginalCompressedSegmentSize", 0x0), LEShortEnumField("CompressionAlgorithm", 0, SMB2_COMPRESSION_ALGORITHMS), ShortEnumField( "Flags", 0x0, { 0x0000: "SMB2_COMPRESSION_FLAG_NONE", 0x0001: "SMB2_COMPRESSION_FLAG_CHAINED", }), XLEIntField("Offset_or_Length", 0), ]
class SMB2_Negotiate_Protocol_Response(Packet): name = "SMB2 Negotiate Protocol Response" fields_desc = [ XLEShortField("StructureSize", 0), FlagsField("SecurityMode", 0, -16, { 0x1: "Signing Required", 0x2: "Signing Enabled", }), LEShortEnumField("DialectRevision", 0x0, SMB_DIALECTS), FieldLenField("NegotiateCount", None, fmt="<H", count_of="NegotiateContexts"), UUIDField("ServerGUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), # Capabilities FlagsField("Capabilities", 0, -32, SMB2_CAPABILITIES), LEIntField("MaxTransactionSize", 0), LEIntField("MaxReadSize", 0), LEIntField("MaxWriteSize", 0), UTCTimeField("SystemTime", None, fmt="<Q", epoch=[1601, 1, 1, 0, 0, 0], custom_scaling=1e7), UTCTimeField("ServerStartTime", None, fmt="<Q", epoch=[1601, 1, 1, 0, 0, 0], custom_scaling=1e7), XLEShortField("SecurityBlobOffset", 0), FieldLenField("SecurityBlobLength", None, fmt="<H", length_of="SecurityBlob"), XLEIntField("NegotiateContextOffset", 0), PacketLenField("SecurityBlob", None, GSSAPI_BLOB, length_from=lambda x: x.SecurityBlobLength), # Field only exists if Dialect is 0x0311 # Each negotiate context must be 8-byte aligned ConditionalField( FieldListField("NegotiateContexts", [], ReversePadField( PacketField("Context", None, SMB2_Negotiate_Context), 8), count_from=lambda pkt: pkt.NegotiateCount), lambda x: x.DialectRevision == 0x0311), ]
class BTLE_RF(Packet): name = "BTLE RF info header" fields_desc = [ ByteField("rf_channel", 0), _dbmField("signal", -256), _dbmField("noise", -256), ByteField("access_address_offenses", 0), XLEIntField("reference_access_address", 0), FlagsField("flags", 0, -16, [ "dewhitened", "sig_power_valid", "noise_power_valid", "decrypted", "reference_access_address_valid", "access_address_offenses_valid", "channel_aliased", "res1", "res2", "res3", "crc_checked", "crc_valid", "mic_checked", "mic_valid", "res4", "res5" ]) ]
class ENIPTCP(Packet): """Ethernet/IP packet over TCP""" name = "ENIPTCP" fields_desc = [ LEShortEnumField("commandId", None, _commandIdList), LEShortField("length", 0), XLEIntField("session", 0), LEIntEnumField("status", None, _statusList), LELongField("senderContext", 0), LEIntField("options", 0), MultipleTypeField( [ # List Services Reply (PacketField("commandSpecificData", ENIPListServicesReply, ENIPListServicesReply), lambda pkt: pkt.commandId == 0x4), # List Identity Reply (PacketField("commandSpecificData", ENIPListIdentityReply, ENIPListIdentityReply), lambda pkt: pkt.commandId == 0x63), # List Interfaces Reply (PacketField("commandSpecificData", ENIPListInterfacesReply, ENIPListInterfacesReply), lambda pkt: pkt.commandId == 0x64), # Register Session (PacketField("commandSpecificData", ENIPRegisterSession, ENIPRegisterSession), lambda pkt: pkt.commandId == 0x65), # Send RR Data (PacketField("commandSpecificData", ENIPSendRRData, ENIPSendRRData), lambda pkt: pkt.commandId == 0x6f), # Send Unit Data (PacketField("commandSpecificData", ENIPSendUnitData, ENIPSendUnitData), lambda pkt: pkt.commandId == 0x70), ], PacketField( "commandSpecificData", None, CommandSpecificData) # By default ), ] def post_build(self, pkt, pay): if self.length is None and pay: pkt = pkt[:2] + struct.pack("<H", len(pay)) + pkt[4:] return pkt + pay
class Zboss(Packet): name = "ZBOSS Dump" fields_desc = [ ByteField("Z", 'Z'), ByteField("B", 'B'), ByteField("O", 'O'), ByteField("S", 'S'), ByteField("S", 'S'), BitEnumField("zboss_dir", 0, 1, {0: "IN"}), BitEnumField("zboss_band", 0, 7, {0: "2.4GHz"}), ByteField("channel", 0), XLEIntField("trace_num", 0), ] def guess_payload_class(self, payload): return Dot15d4FCS
class BTLE_CONNECT_REQ(Packet): name = "BTLE connect request" fields_desc = [ BDAddrField("InitA", None), BDAddrField("AdvA", None), # LLDATA XLEIntField("AA", 0x00), LEX3BytesField("crc_init", 0x0), XByteField("win_size", 0x0), XLEShortField("win_offset", 0x0), XLEShortField("interval", 0x0), XLEShortField("latency", 0x0), XLEShortField("timeout", 0x0), BTLEChanMapField("chM", 0), BitField("SCA", 0, 3), BitField("hop", 0, 5), ]
class BTLE_RF(Packet): """Cooked BTLE link-layer pseudoheader. https://www.tcpdump.org/linktypes/LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR.html """ name = "BTLE RF info header" _TYPES = { 0: "ADV_OR_DATA_UNKNOWN_DIR", 1: "AUX_ADV", 2: "DATA_M_TO_S", 3: "DATA_S_TO_M", 4: "CONN_ISO_M_TO_S", 5: "CONN_ISO_S_TO_M", 6: "BROADCAST_ISO", 7: "RFU", } _PHY = { 0: "1M", 1: "2M", 2: "Coded", 3: "RFU", } fields_desc = [ ByteField("rf_channel", 0), SignedByteField("signal", -128), SignedByteField("noise", -128), ByteField("access_address_offenses", 0), XLEIntField("reference_access_address", 0), LEBitField("dewhitened", 0, 1), LEBitField("sig_power_valid", 0, 1), LEBitField("noise_power_valid", 0, 1), LEBitField("decrypted", 0, 1), LEBitField("reference_access_address_valid", 0, 1), LEBitField("access_address_offenses_valid", 0, 1), LEBitField("channel_aliased", 0, 1), LEBitEnumField("type", 0, 3, _TYPES), LEBitField("crc_checked", 0, 1), LEBitField("crc_valid", 0, 1), LEBitField("mic_checked", 0, 1), LEBitField("mic_valid", 0, 1), LEBitEnumField("phy", 0, 2, _PHY), ]
class BTLE_RF(Packet): """Cooked BTLE link-layer pseudoheader. http://www.whiterocker.com/bt/LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR.html """ name = "BTLE RF info header" fields_desc = [ ByteField("rf_channel", 0), SignedByteField("signal", -128), SignedByteField("noise", -128), ByteField("access_address_offenses", 0), XLEIntField("reference_access_address", 0), FlagsField("flags", 0, -16, [ "dewhitened", "sig_power_valid", "noise_power_valid", "decrypted", "reference_access_address_valid", "access_address_offenses_valid", "channel_aliased", "res1", "res2", "res3", "crc_checked", "crc_valid", "mic_checked", "mic_valid", "res4", "res5" ]) ]
class Join_Accept(Packet): name = "Join_Accept" dcflist = False fields_desc = [LEX3BytesField("JoinAppNonce", 0), LEX3BytesField("NetID", 0), XLEIntField("DevAddr", 0), DLsettings, XByteField("RxDelay", 0), ConditionalField(StrFixedLenField("CFList", b"\x00" * 16, 16), # noqa: E501 lambda pkt:(Join_Accept.dcflist is True))] # pylint: disable=R0201 def extract_padding(self, p): return "", p def __init__(self, packet=""): # CFList calculated with rest of packet len if len(packet) > 18: Join_Accept.dcflist = True super(Join_Accept, self).__init__(packet)
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 SMB2_Negociate_Protocol_Request_Header(Packet): name = "SMB2 Negociate Protocol Request Header" fields_desc = [ XLEShortField("StructureSize", 0), FieldLenField( "DialectCount", 0, fmt="<H", count_of="Dialects" ), # SecurityMode FlagsField("SecurityMode", 0, 16, { 0x7: "Signing Required", 0x8: "Signing Enabled", }), LEShortField("Reserved", 0), # Capabilities FlagsField("Capabilities", 0, 32, SMB2_CAPABILITIES), UUIDField("ClientGUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), XLEIntField("NegociateContextOffset", 0x0), FieldLenField( "NegociateCount", 0x0, fmt="<H", count_of="NegociateContexts" ), ShortField("Reserved2", 0), # Padding the dialects - the whole packet (from the # beginning) should be aligned on 8 bytes ; so the list of # dialects should be aligned on 6 bytes (because it starts # at PKT + 8 * N + 2 PadField(FieldListField( "Dialects", [0x0202], LEShortEnumField("", 0x0, SMB_DIALECTS), count_from=lambda pkt: pkt.DialectCount ), 6), PacketListField( "NegociateContexts", [], SMB2_Negociate_Context, count_from=lambda pkt: pkt.NegociateCount ), ]
class ZCLPricePublishPrice(Packet): name = "Price Cluster: Publish Price Command (Server: Generated)" fields_desc = [ XLEIntField( "provider_id", 0x00000000), # Unsigned 32-bit Integer (4 octets) # noqa: E501 # Rate Label is a UTF-8 encoded Octet String (0-12 octets). The first Octet indicates the length. # noqa: E501 StrLenField("rate_label", "", length_from=lambda pkt: int(pkt.rate_label[0]) ), # TODO verify # noqa: E501 XLEIntField( "issuer_event_id", 0x00000000), # Unsigned 32-bit Integer (4 octets) # noqa: E501 XLEIntField("current_time", 0x00000000), # UTCTime (4 octets) ByteField("unit_of_measure", 0), # 8 bits enumeration (1 octet) XLEShortField( "currency", 0x0000), # Unsigned 16-bit Integer (2 octets) # noqa: E501 ByteField("price_trailing_digit", 0), # 8-bit BitMap (1 octet) ByteField("number_of_price_tiers", 0), # 8-bit BitMap (1 octet) XLEIntField("start_time", 0x00000000), # UTCTime (4 octets) XLEShortField( "duration_in_minutes", 0x0000), # Unsigned 16-bit Integer (2 octets) # noqa: E501 XLEIntField("price", 0x00000000), # Unsigned 32-bit Integer (4 octets) ByteField("price_ratio", 0), # Unsigned 8-bit Integer (1 octet) XLEIntField( "generation_price", 0x00000000), # Unsigned 32-bit Integer (4 octets) # noqa: E501 ByteField("generation_price_ratio", 0), # Unsigned 8-bit Integer (1 octet) # noqa: E501 XLEIntField( "alternate_cost_delivered", 0x00000000), # Unsigned 32-bit Integer (4 octets) # noqa: E501 ByteField("alternate_cost_unit", 0), # 8-bit enumeration (1 octet) ByteField("alternate_cost_trailing_digit", 0), # 8-bit BitMap (1 octet) # noqa: E501 ByteField("number_of_block_thresholds", 0), # 8-bit BitMap (1 octet) ByteField("price_control", 0), # 8-bit BitMap (1 octet) ]
class SMB2_Negociate_Protocol_Request_Header(Packet): name = "SMB2 Negociate Protocol Request Header" fields_desc = [ XLEShortField("StructureSize", 0), FieldLenField( "DialectCount", None, fmt="<H", count_of="Dialects" ), # SecurityMode FlagsField("SecurityMode", 0, 16, { 0x7: "Signing Required", 0x8: "Signing Enabled", }), LEShortField("Reserved", 0), # Capabilities FlagsField("Capabilities", 0, 32, SMB2_CAPABILITIES), UUIDField("ClientGUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), XLEIntField("NegociateContextOffset", 0x0), FieldLenField( "NegociateCount", 0x0, fmt="<H", count_of="NegociateContexts" ), ShortField("Reserved2", 0), FieldListField( "Dialects", [0x0202], LEShortEnumField("", 0x0, SMB_DIALECTS), count_from=lambda pkt: pkt.DialectCount ), # The first negotiate context must be 8-byte aligned ReversePadField(PacketListField( "NegociateContexts", [], SMB2_Negociate_Context, count_from=lambda pkt: pkt.NegociateCount ), 8), ]
class SMB2_Negotiate_Protocol_Request(Packet): name = "SMB2 Negotiate Protocol Request" fields_desc = [ XLEShortField("StructureSize", 0), FieldLenField("DialectCount", None, fmt="<H", count_of="Dialects"), # SecurityMode FlagsField( "SecurityMode", 0, -16, { 0x01: "SMB2_NEGOTIATE_SIGNING_ENABLED", 0x02: "SMB2_NEGOTIATE_SIGNING_REQUIRED", }), LEShortField("Reserved", 0), # Capabilities FlagsField("Capabilities", 0, -32, SMB2_CAPABILITIES), UUIDField("ClientGUID", 0x0, uuid_fmt=UUIDField.FORMAT_LE), # XXX TODO If we ever want to properly dissect the offsets, we have # a _NTLMPayloadField in scapy/layers/ntlm.py that does precisely that XLEIntField("NegotiateContextOffset", 0x0), FieldLenField("NegotiateCount", None, fmt="<H", count_of="NegotiateContexts"), ShortField("Reserved2", 0), FieldListField("Dialects", [0x0202], LEShortEnumField("", 0x0, SMB_DIALECTS), count_from=lambda pkt: pkt.DialectCount), # Field only exists if Dialects contains 0x0311 # Each negotiate context must be 8-byte aligned ConditionalField( FieldListField("NegotiateContexts", [], ReversePadField( PacketField("Context", None, SMB2_Negotiate_Context), 8), count_from=lambda pkt: pkt.NegotiateCount), lambda x: 0x0311 in x.Dialects), ]
class SMB2_Header(Packet): name = "SMB2 Header" fields_desc = [ StrFixedLenField("Start", b"\xfeSMB", 4), LEShortField("StructureSize", 64), LEShortField("CreditCharge", 0), LEShortField("ChannelSequence", 0), LEShortField("Unused", 0), LEShortEnumField("Command", 0, SMB2_COM), LEShortField("CreditsRequested", 0), FlagsField( "Flags", 0, -32, { 0x00000001: "SMB2_FLAGS_SERVER_TO_REDIR", 0x00000002: "SMB2_FLAGS_ASYNC_COMMAND", 0x00000004: "SMB2_FLAGS_RELATED_OPERATIONS", 0x00000008: "SMB2_FLAGS_SIGNED", 0x10000000: "SMB2_FLAGS_DFS_OPERATIONS", 0x20000000: "SMB2_FLAGS_REPLAY_OPERATION", }), XLEIntField("NextCommand", 0), LELongField("MessageId", 0), LELongField("AsyncID", 0), LELongField("SessionId", 0), XNBytesField("Signature", 0, 16), ] def guess_payload_class(self, payload): if self.Command == 0x0000: # Negotiate if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: return SMB2_Negotiate_Protocol_Response return SMB2_Negotiate_Protocol_Request elif self.Command == 0x0001: # Setup if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR: return SMB2_Session_Setup_Response return SMB2_Session_Setup_Request return super(SMB2_Header, self).guess_payload_class(payload)
# # To build each Packet type, build a list of the fields normally, excluding # the present bitmask field. The code will then construct conditional # versions of each field and add the present field. # # See GPS_Fields as an example. _COMMON_GEOTAG_HEADERS = [ ByteField('geotag_ver', CURR_GEOTAG_VER), ByteField('geotag_pad', 0), LEShortField('geotag_len', None), ] _COMMON_GEOTAG_FOOTER = [ HCSIDescField("DescString", None), XLEIntField("AppId", None), HCSIAppField("AppData", None), HCSINullField("Extended"), ] # Conditional test for all HCSI Fields def _HCSITest(fname, fbit, pkt): if pkt.present is None: return pkt.getfieldval(fname) is not None return pkt.present & fbit class _Geotag_metaclass(Packet_metaclass): def __new__(cls, name, bases, dct): hcsi_fields = dct.get('hcsi_fields', [])