class IODWriteReq(Block): """IODWrite request block""" fields_desc = [ BlockHeader, ShortField("seqNum", 0), UUIDField("ARUUID", None), XIntField("API", 0), XShortField("slotNumber", 0), XShortField("subslotNumber", 0), StrFixedLenField("padding", "", length=2), XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), LenField("recordDataLength", None, fmt="I"), StrFixedLenField("RWPadding", "", length=24), ] # default block_type value block_type = 0x0008 def payload_length(self): return self.recordDataLength def get_response(self): """Generate the response block of this request. Careful: it only sets the fields which can be set from the request """ res = IODWriteRes() for field in ["seqNum", "ARUUID", "API", "slotNumber", "subslotNumber", "index"]: res.setfieldval(field, self.getfieldval(field)) return res
class NEGOEX_MESSAGE_HEADER(Packet): fields_desc = [ StrFixedLenField("Signature", "NEGOEXTS", length=8), LEIntEnumField( "MessageType", 0, { 0x0: "INITIATOR_NEGO", 0x01: "ACCEPTOR_NEGO", 0x02: "INITIATOR_META_DATA", 0x03: "ACCEPTOR_META_DATA", 0x04: "CHALENGE", 0x05: "AP_REQUEST", 0x06: "VERIFY", 0x07: "ALERT" }), LEIntField("SequenceNum", 0), LEIntField("cbHeaderLength", None), LEIntField("cbMessageLength", None), UUIDField("ConversationId", None), ] def post_build(self, pkt, pay): if self.cbHeaderLength is None: pkt = pkt[16:] + struct.pack("<I", len(pkt)) + pkt[20:] if self.cbMessageLength is None: pkt = pkt[20:] + struct.pack("<I", len(pkt) + len(pay)) + pkt[24:] return pkt + pay
class OBJREF_CUSTOM(Packet): name = "objetref stanDard" fields_desc = [ UUIDField('clsid', str('0001' * 8), uuid_fmt=UUIDField.FORMAT_BE), IntField('cbExtension', 0), IntField('reserved', 0), ]
class IODWriteMultipleReq(Block): """IODWriteMultiple request""" fields_desc = [ BlockHeader, ShortField("seqNum", 0), UUIDField("ARUUID", None), XIntField("API", 0xffffffff), XShortField("slotNumber", 0xffff), XShortField("subslotNumber", 0xffff), StrFixedLenField("padding", "", length=2), XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), FieldLenField("recordDataLength", None, fmt="I", length_of="blocks"), StrFixedLenField("RWPadding", "", length=24), FieldListField("blocks", [], PadFieldWithLen(PacketField("", None, IODWriteReq), 4), length_from=lambda pkt: pkt.recordDataLength) ] # default values block_type = 0x0008 index = 0xe040 API = 0xffffffff slotNumber = 0xffff subslotNumber = 0xffff def post_build(self, p, pay): # patch the update of block_length, as requests field must not be # included. block_length is always 60 if self.block_length is None: p = p[:2] + struct.pack("!H", 60) + p[4:] # Remove the final padding added in requests fld, val = self.getfield_and_val("blocks") if fld.i2count(self, val) > 0: length = len(val[-1]) pad = fld.field.padlen(length) if pad > 0: p = p[:-pad] # also reduce the recordDataLength accordingly if self.recordDataLength is None: val = struct.unpack("!I", p[36:40])[0] val -= pad p = p[:36] + struct.pack("!I", val) + p[40:] return Packet.post_build(self, p, pay) def get_response(self): """Generate the response block of this request. Careful: it only sets the fields which can be set from the request """ res = IODWriteMultipleRes() for field in ["seqNum", "ARUUID", "API", "slotNumber", "subslotNumber", "index"]: res.setfieldval(field, self.getfieldval(field)) # append all block response res_blocks = [] for block in self.getfieldval("blocks"): res_blocks.append(block.get_response()) res.setfieldval("blocks", res_blocks) return res
class OBJREF_HANDLER(Packet): name = "objetref stanDard" fields_desc = [ PacketField('std', None, STDOBJREF), UUIDField('clsid', str('0001' * 8), uuid_fmt=UUIDField.FORMAT_BE), PacketField('saResAddr', None, DualStringArray), ]
class IODWriteMultipleRes(Block): """IODWriteMultiple response""" fields_desc = [ BlockHeader, ShortField("seqNum", 0), UUIDField("ARUUID", None), XIntField("API", 0xffffffff), XShortField("slotNumber", 0xffff), XShortField("subslotNumber", 0xffff), StrFixedLenField("padding", "", length=2), XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), FieldLenField("recordDataLength", None, fmt="I", length_of="blocks"), XShortField("additionalValue1", 0), XShortField("additionalValue2", 0), IntEnumField("status", 0, ["OK"]), StrFixedLenField("RWPadding", "", length=16), FieldListField("blocks", [], PacketField("", None, IODWriteRes), length_from=lambda pkt: pkt.recordDataLength) ] # default values block_type = 0x8008 index = 0xe040 def post_build(self, p, pay): # patch the update of block_length, as requests field must not be # included. block_length is always 60 if self.block_length is None: p = p[:2] + struct.pack("!H", 60) + p[4:] return Packet.post_build(self, p, pay)
class EIR_CompleteList128BitServiceUUIDs(EIR_Element): name = "Complete list of 128-bit service UUIDs" fields_desc = [ FieldListField("svc_uuids", None, UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV), length_from=EIR_Element.length_from) ]
class ARBlockReq(Block): """Application relationship block request""" fields_desc = [ BlockHeader, XShortEnumField("ARType", 1, AR_TYPE), UUIDField("ARUUID", None), ShortField("SessionKey", 0), MACField("CMInitiatorMacAdd", None), UUIDField("CMInitiatorObjectUUID", None), # ARProperties BitField("ARProperties_PullModuleAlarmAllowed", 0, 1), BitEnumField("ARProperties_StartupMode", 0, 1, ["Legacy", "Advanced"]), BitField("ARProperties_reserved_3", 0, 6), BitField("ARProperties_reserved_2", 0, 12), BitField("ARProperties_AcknowledgeCompanionAR", 0, 1), BitEnumField("ARProperties_CompanionAR", 0, 2, ["Single_AR", "First_AR", "Companion_AR", "reserved"]), BitEnumField("ARProperties_DeviceAccess", 0, 1, ["ExpectedSubmodule", "Controlled_by_IO_device_app"]), BitField("ARProperties_reserved_1", 0, 3), BitEnumField("ARProperties_ParametrizationServer", 0, 1, ["External_PrmServer", "CM_Initator"]), BitField("ARProperties_SupervisorTakeoverAllowed", 0, 1), BitEnumField("ARProperties_State", 1, 3, {1: "Active"}), ShortField("CMInitiatorActivityTimeoutFactor", 1000), ShortField("CMInitiatorUDPRTPort", 0x8892), FieldLenField("StationNameLength", None, fmt="H", length_of="CMInitiatorStationName"), StrLenField("CMInitiatorStationName", "", length_from=lambda pkt: pkt.StationNameLength), ] # default block_type value block_type = 0x0101 def get_response(self): """Generate the response block of this request. Careful: it only sets the fields which can be set from the request """ res = ARBlockRes() for field in ["ARType", "ARUUID", "SessionKey"]: res.setfieldval(field, self.getfieldval(field)) return res
class SyntaxId(Packet): name = "syntax Id" fields_desc = [ UUIDField('interfaceUUID', str('0001' * 8), uuid_fmt=UUIDField.FORMAT_BE), ShortField('versionMajor', 0), ShortField('versionMinor', 0), ] def extract_padding(self, p): return b"", p
class IBeacon_Data(Packet): """ iBeacon broadcast data frame. Composed on top of an Apple_BLE_Submessage. """ name = "iBeacon data" fields_desc = [ UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_BE), ShortField("major", None), ShortField("minor", None), SignedByteField("tx_power", None), ]
class IODControlReq(Block): """IODControl request block""" fields_desc = [ BlockHeader, StrFixedLenField("padding", "", length=2), UUIDField("ARUUID", None), ShortField("SessionKey", 0), XShortField("AlarmSequenceNumber", 0), # ControlCommand BitField("ControlCommand_reserved", 0, 9), BitField("ControlCommand_PrmBegin", 0, 1), BitField("ControlCommand_ReadyForRT_CLASS_3", 0, 1), BitField("ControlCommand_ReadyForCompanion", 0, 1), BitField("ControlCommand_Done", 0, 1), BitField("ControlCommand_Release", 0, 1), BitField("ControlCommand_ApplicationReady", 0, 1), BitField("ControlCommand_PrmEnd", 0, 1), XShortField("ControlBlockProperties", 0) ] def post_build(self, p, pay): # Try to find the right block type if self.block_type is None: if self.ControlCommand_PrmBegin: p = struct.pack("!H", 0x0118) + p[2:] elif self.ControlCommand_ReadyForRT_CLASS_3: p = struct.pack("!H", 0x0117) + p[2:] elif self.ControlCommand_ReadyForCompanion: p = struct.pack("!H", 0x0116) + p[2:] elif self.ControlCommand_Release: p = struct.pack("!H", 0x0114) + p[2:] elif self.ControlCommand_ApplicationReady: if self.AlarmSequenceNumber > 0: p = struct.pack("!H", 0x0113) + p[2:] else: p = struct.pack("!H", 0x0112) + p[2:] elif self.ControlCommand_PrmEnd: if self.AlarmSequenceNumber > 0: p = struct.pack("!H", 0x0111) + p[2:] else: p = struct.pack("!H", 0x0110) + p[2:] return Block.post_build(self, p, pay) def get_response(self): """Generate the response block of this request. Careful: it only sets the fields which can be set from the request """ res = IODControlRes() for field in ["ARUUID", "SessionKey", "AlarmSequenceNumber"]: res.setfieldval(field, self.getfieldval(field)) res.block_type = self.block_type + 0x8000 return res
class ARBlockRes(Block): """Application relationship block response""" fields_desc = [ BlockHeader, XShortEnumField("ARType", 1, AR_TYPE), UUIDField("ARUUID", None), ShortField("SessionKey", 0), MACField("CMResponderMacAdd", None), ShortField("CMResponderUDPRTPort", 0x8892), ] # default block_type value block_type = 0x8101
class RequestSubDataLE(Packet): name = 'RequestSubData' fields_desc = [ LEShortField('versionMajor', 0), LEShortField('versionMinor', 0), LEIntField('flags', 0), LEIntField('reserved', 0), UUIDField('subUuid', str('0001' * 8), uuid_fmt=UUIDField.FORMAT_LE), StrField('subdata', ''), ] def extract_padding(self, p): return b"", p
class DceRpc(Packet): """DCE/RPC packet""" name = "DCE/RPC" fields_desc = [ ByteField("version", 4), ByteEnumField("type", 0, DCE_RPC_TYPE), FlagsField("flags1", 0, 8, DCE_RPC_FLAGS1), FlagsField("flags2", 0, 8, DCE_RPC_FLAGS2), BitEnumField("endianness", 0, 4, ["big", "little"]), BitEnumField("encoding", 0, 4, ["ASCII", "EBCDIC"]), ByteEnumField("float", 0, ["IEEE", "VAX", "CRAY", "IBM"]), ByteField("DataRepr_reserved", 0), XByteField("serial_high", 0), EndiannessField(UUIDField("object_uuid", None), endianess_from=dce_rpc_endianess), EndiannessField(UUIDField("interface_uuid", None), endianess_from=dce_rpc_endianess), EndiannessField(UUIDField("activity", None), endianess_from=dce_rpc_endianess), EndiannessField(IntField("boot_time", 0), endianess_from=dce_rpc_endianess), EndiannessField(IntField("interface_version", 1), endianess_from=dce_rpc_endianess), EndiannessField(IntField("sequence_num", 0), endianess_from=dce_rpc_endianess), EndiannessField(ShortField("opnum", 0), endianess_from=dce_rpc_endianess), EndiannessField(XShortField("interface_hint", 0xffff), endianess_from=dce_rpc_endianess), EndiannessField(XShortField("activity_hint", 0xffff), endianess_from=dce_rpc_endianess), EndiannessField(LenField("frag_len", None, fmt="H"), endianess_from=dce_rpc_endianess), EndiannessField(ShortField("frag_num", 0), endianess_from=dce_rpc_endianess), ByteEnumField("auth", 0, ["none"]), # TODO other auth ? XByteField("serial_low", 0), ]
class SMBNegotiate_Response_Extended_Security(_SMBNegotiate_Response): name = "SMB Negotiate Extended Security Response (SMB)" WordCount = 0x11 fields_desc = SMBNegotiate_Response_NoSecurity.fields_desc[:12] + [ LEFieldLenField("ByteCount", None, length_of="SecurityBlob", adjust=lambda _, x: x + 16), UUIDField("GUID", None, uuid_fmt=UUIDField.FORMAT_LE), PacketLenField("SecurityBlob", None, GSSAPI_BLOB, length_from=lambda x: x.ByteCount - 16) ]
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 OpcDaRequestLE(Packet): name = "OpcDaRequest" fields_desc = [ LEIntField('allocHint', 0), LEShortField('contextId', 0), LEShortField('opNum', 0), UUIDField('uuid', str('0001' * 8), uuid_fmt=UUIDField.FORMAT_LE), PacketLenField('subData', None, RequestSubDataLE, length_from=lambda pkt: pkt.allocHint), PacketField('authentication', None, AuthentificationProtocol), ] def extract_padding(self, p): return b"", p
class OpcDaRequest(Packet): # DCE 1.1 RPC - 12.6.4.9 name = "OpcDaRequest" fields_desc = [ IntField('allocHint', 0), ShortField('contextId', 0), ShortField('opNum', 0), ConditionalField( UUIDField('uuid', str('0001' * 8), uuid_fmt=UUIDField.FORMAT_BE), lambda pkt: OpcDaHeaderMessage in pkt.firstlayer() and pkt.firstlayer()[OpcDaHeaderMessage].pfc_flags & 'objectUuid' ), PacketLenField('stubData', None, RequestStubData, length_from=lambda pkt: _opc_stubdata_length(pkt)), PacketField('authentication', None, AuthentificationProtocol), ] def extract_padding(self, p): return b"", p
class IODWriteRes(Block): """IODWrite response block""" fields_desc = [ BlockHeader, ShortField("seqNum", 0), UUIDField("ARUUID", None), XIntField("API", 0), XShortField("slotNumber", 0), XShortField("subslotNumber", 0), StrFixedLenField("padding", "", length=2), XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), LenField("recordDataLength", None, fmt="I"), XShortField("additionalValue1", 0), XShortField("additionalValue2", 0), IntEnumField("status", 0, ["OK"]), StrFixedLenField("RWPadding", "", length=16), ] # default block_type value block_type = 0x8008
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 IODControlRes(Block): """IODControl response block""" fields_desc = [ BlockHeader, StrFixedLenField("padding", "", length=2), UUIDField("ARUUID", None), ShortField("SessionKey", 0), XShortField("AlarmSequenceNumber", 0), # ControlCommand BitField("ControlCommand_reserved", 0, 9), BitField("ControlCommand_PrmBegin", 0, 1), BitField("ControlCommand_ReadyForRT_CLASS_3", 0, 1), BitField("ControlCommand_ReadyForCompanion", 0, 1), BitField("ControlCommand_Done", 1, 1), BitField("ControlCommand_Release", 0, 1), BitField("ControlCommand_ApplicationReady", 0, 1), BitField("ControlCommand_PrmEnd", 0, 1), XShortField("ControlBlockProperties", 0) ] # default block_type value block_type = 0x8110
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), ]