#!/usr/bin/env python # Copyright (c) 2003-2012 CORE Security Technologies # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # $Id: dcerpc.py 917 2013-11-10 20:47:57Z bethus $ # # Partial C706.pdf + [MS-RPCE] implementation # # ToDo: # [ ] Take out all the security provider stuff out of here (e.g. RPC_C_AUTHN_WINNT) # and put it elsewhere. This will make the coder cleaner and easier to add # more SSP (e.g. NETLOGON) # from structure import Structure,pack,unpack # MS/RPC Constants MSRPC_REQUEST = 0x00 MSRPC_PING = 0x01 MSRPC_RESPONSE = 0x02 MSRPC_FAULT = 0x03 MSRPC_WORKING = 0x04 MSRPC_NOCALL = 0x05 MSRPC_REJECT = 0x06 MSRPC_ACK = 0x07 MSRPC_CL_CANCEL = 0x08 MSRPC_FACK = 0x09 MSRPC_CANCELACK = 0x0A MSRPC_BIND = 0x0B MSRPC_BINDACK = 0x0C MSRPC_BINDNAK = 0x0D MSRPC_ALTERCTX = 0x0E MSRPC_ALTERCTX_R= 0x0F MSRPC_AUTH3 = 0x10 MSRPC_SHUTDOWN = 0x11 MSRPC_CO_CANCEL = 0x12 MSRPC_ORPHANED = 0x13 # MS/RPC Packet Flags MSRPC_FIRSTFRAG = 0x01 MSRPC_LASTFRAG = 0x02 # For PDU types bind, bind_ack, alter_context, and # alter_context_resp, this flag MUST be interpreted as PFC_SUPPORT_HEADER_SIGN MSRPC_SUPPORT_SIGN = 0x04 #For the #remaining PDU types, this flag MUST be interpreted as PFC_PENDING_CANCEL. MSRPC_PENDING_CANCEL= 0x04 MSRPC_NOTAFRAG = 0x04 MSRPC_RECRESPOND = 0x08 MSRPC_NOMULTIPLEX = 0x10 MSRPC_NOTFORIDEMP = 0x20 MSRPC_NOTFORBCAST = 0x40 MSRPC_NOUUID = 0x80 # Auth Types - Security Providers RPC_C_AUTHN_NONE = 0x00 RPC_C_AUTHN_GSS_NEGOTIATE = 0x09 RPC_C_AUTHN_WINNT = 0x0A RPC_C_AUTHN_GSS_SCHANNEL = 0x0E RPC_C_AUTHN_GSS_KERBEROS = 0x10 RPC_C_AUTHN_NETLOGON = 0x44 RPC_C_AUTHN_DEFAULT = 0xFF # Auth Levels RPC_C_AUTHN_LEVEL_NONE = 1 RPC_C_AUTHN_LEVEL_CONNECT = 2 RPC_C_AUTHN_LEVEL_CALL = 3 RPC_C_AUTHN_LEVEL_PKT = 4 RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5 RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6 #Reasons for rejection of a context element, included in bind_ack result reason rpc_provider_reason = { 0 : 'reason_not_specified', 1 : 'abstract_syntax_not_supported', 2 : 'proposed_transfer_syntaxes_not_supported', 3 : 'local_limit_exceeded', 4 : 'protocol_version_not_specified', 8 : 'authentication_type_not_recognized', 9 : 'invalid_checksum' } MSRPC_CONT_RESULT_ACCEPT = 0 MSRPC_CONT_RESULT_USER_REJECT = 1 MSRPC_CONT_RESULT_PROV_REJECT = 2 #Results of a presentation context negotiation rpc_cont_def_result = { 0 : 'acceptance', 1 : 'user_rejection', 2 : 'provider_rejection' } #status codes, references: #http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/rpc_return_values.asp #http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/common_return_values.asp #winerror.h #http://www.opengroup.org/onlinepubs/9629399/apdxn.htm rpc_status_codes = { 0x00000005L : 'rpc_s_access_denied', 0x00000008L : 'Authentication type not recognized', 0x000006D8L : 'rpc_fault_cant_perform', 0x000006C6L : 'rpc_x_invalid_bound', # the arrays bound are invalid 0x000006E4L : 'rpc_s_cannot_support: The requested operation is not supported.', # some operation is not supported 0x000006F7L : 'rpc_x_bad_stub_data', # the stub data is invalid, doesn't match with the IDL definition 0x1C010001L : 'nca_s_comm_failure', # unable to get response from server: 0x1C010002L : 'nca_s_op_rng_error', # bad operation number in call 0x1C010003L : 'nca_s_unk_if', # unknown interface 0x1C010006L : 'nca_s_wrong_boot_time', # client passed server wrong server boot time 0x1C010009L : 'nca_s_you_crashed', # a restarted server called back a client 0x1C01000BL : 'nca_s_proto_error', # someone messed up the protocol 0x1C010013L : 'nca_s_out_args_too_big ', # output args too big 0x1C010014L : 'nca_s_server_too_busy', # server is too busy to handle call 0x1C010015L : 'nca_s_fault_string_too_long', # string argument longer than declared max len 0x1C010017L : 'nca_s_unsupported_type ', # no implementation of generic operation for object 0x1C000001L : 'nca_s_fault_int_div_by_zero', 0x1C000002L : 'nca_s_fault_addr_error ', 0x1C000003L : 'nca_s_fault_fp_div_zero', 0x1C000004L : 'nca_s_fault_fp_underflow', 0x1C000005L : 'nca_s_fault_fp_overflow', 0x1C000006L : 'nca_s_fault_invalid_tag', 0x1C000007L : 'nca_s_fault_invalid_bound ', 0x1C000008L : 'nca_s_rpc_version_mismatch', 0x1C000009L : 'nca_s_unspec_reject ', 0x1C00000AL : 'nca_s_bad_actid', 0x1C00000BL : 'nca_s_who_are_you_failed', 0x1C00000CL : 'nca_s_manager_not_entered ', 0x1C00000DL : 'nca_s_fault_cancel', 0x1C00000EL : 'nca_s_fault_ill_inst', 0x1C00000FL : 'nca_s_fault_fp_error', 0x1C000010L : 'nca_s_fault_int_overflow', 0x1C000012L : 'nca_s_fault_unspec', 0x1C000013L : 'nca_s_fault_remote_comm_failure ', 0x1C000014L : 'nca_s_fault_pipe_empty ', 0x1C000015L : 'nca_s_fault_pipe_closed', 0x1C000016L : 'nca_s_fault_pipe_order ', 0x1C000017L : 'nca_s_fault_pipe_discipline', 0x1C000018L : 'nca_s_fault_pipe_comm_error', 0x1C000019L : 'nca_s_fault_pipe_memory', 0x1C00001AL : 'nca_s_fault_context_mismatch ', 0x1C00001BL : 'nca_s_fault_remote_no_memory ', 0x1C00001CL : 'nca_s_invalid_pres_context_id', 0x1C00001DL : 'nca_s_unsupported_authn_level', 0x1C00001FL : 'nca_s_invalid_checksum ', 0x1C000020L : 'nca_s_invalid_crc', 0x1C000021L : 'nca_s_fault_user_defined', 0x1C000022L : 'nca_s_fault_tx_open_failed', 0x1C000023L : 'nca_s_fault_codeset_conv_error', 0x1C000024L : 'nca_s_fault_object_not_found ', 0x1C000025L : 'nca_s_fault_no_client_stub' } class Exception(Exception): pass # Context Item class CtxItem(Structure): structure = ( ('ContextID',' 0 else 0)'), ('pduData',':'), ('_pad', '_-pad','(4 - ((self._SIZE + len(self["pduData"])) & 3) & 3)'), ('pad', ':'), ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'), ('sec_trailer',':'), ('auth_dataLen','_-auth_data','self["auth_len"]'), ('auth_data',':'), ) def __init__(self, data = None, alignment = 0): Structure.__init__(self,data, alignment) if data is None: self['ver_major'] = 5 self['ver_minor'] = 0 self['flags'] = MSRPC_FIRSTFRAG | MSRPC_LASTFRAG self['type'] = MSRPC_REQUEST self.__frag_len_set = 0 self['auth_len'] = 0 self['pduData'] = '' self['auth_data'] = '' self['sec_trailer'] = '' self['pad'] = '' def get_header_size(self): return self._SIZE def get_packet(self): if self['auth_data'] != '': self['auth_len'] = len(self['auth_data']) # The sec_trailer structure MUST be 4-byte aligned with respect to # the beginning of the PDU. Padding octets MUST be used to align the # sec_trailer structure if its natural beginning is not already 4-byte aligned ##self['pad'] = '\xAA' * (4 - ((self._SIZE + len(self['pduData'])) & 3) & 3) return self.getData() class MSRPCRequestHeader(MSRPCHeader): _SIZE = 24 commonHdr = MSRPCHeader.commonHdr + ( ('alloc_hint',' 0 else 0'), ('sec_trailer',':'), ('auth_dataLen','_-auth_data','self["auth_len"]'), ('auth_data',':'), ) def __init__(self, data = None, alignment = 0): self.__ctx_items = [] Structure.__init__(self,data,alignment) if data is None: self['Pad'] = '' self['ctx_items'] = '' self['sec_trailer'] = '' self['auth_data'] = '' def getCtxItems(self): return self.__ctx_items def getCtxItem(self,index): return self.__ctx_items[index-1] def fromString(self, data): Structure.fromString(self,data) # Parse the ctx_items data = self['ctx_items'] for i in range(self['ctx_num']): item = CtxItemResult(data) self.__ctx_items.append(item) data = data[len(item):] class MSRPCBindNak(Structure): structure = ( ('RejectedReason','