def sendBindType1(self, iface_uuid, auth_data): bind = MSRPCBind() item = CtxItem() item['AbstractSyntax'] = iface_uuid item['TransferSyntax'] = self.transfer_syntax item['ContextID'] = 0 item['TransItems'] = 1 bind.addCtxItem(item) packet = MSRPCHeader() packet['type'] = rpcrt.MSRPC_BIND packet['pduData'] = bind.getData() packet['call_id'] = 0 sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT sec_trailer['auth_ctx_id'] = 79231 pad = (4 - (len(packet.get_packet()) % 4)) % 4 if pad != 0: packet['pduData'] += b'\xFF' * pad sec_trailer['auth_pad_len'] = pad packet['sec_trailer'] = sec_trailer packet['auth_data'] = auth_data self._transport.send(packet.get_packet()) s = self._transport.recv() if s != 0: resp = MSRPCHeader(s) else: return 0 #mmm why not None? if resp['type'] == rpcrt.MSRPC_BINDACK or resp['type'] == rpcrt.MSRPC_ALTERCTX_R: bindResp = MSRPCBindAck(resp.getData()) elif resp['type'] == rpcrt.MSRPC_BINDNAK or resp['type'] == rpcrt.MSRPC_FAULT: if resp['type'] == rpcrt.MSRPC_FAULT: resp = MSRPCRespHeader(resp.getData()) status_code = unpack('<L', resp['pduData'][:4])[0] else: resp = MSRPCBindNak(resp['pduData']) status_code = resp['RejectedReason'] if status_code in rpc_status_codes: raise DCERPCException(error_code = status_code) elif status_code in rpc_provider_reason: raise DCERPCException("Bind context rejected: %s" % rpc_provider_reason[status_code]) else: raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code) else: raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type']) self.set_max_tfrag(bindResp['max_rfrag']) return bindResp
def sendBindType3(self, auth_data): sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_PKT_PRIVACY sec_trailer['auth_ctx_id'] = 79231 auth3 = MSRPCHeader() auth3['type'] = rpcrt.MSRPC_AUTH3 # pad (4 bytes): Can be set to any arbitrary value when set and MUST be # ignored on receipt. The pad field MUST be immediately followed by a # sec_trailer structure whose layout, location, and alignment are as # specified in section 2.2.2.11 auth3['pduData'] = b' ' auth3['sec_trailer'] = sec_trailer auth3['auth_data'] = auth_data auth3['call_id'] = 0 self._transport.send(auth3.get_packet(), forceWriteAndx=1)
def bind_ntlm_authinfo(dcerpc, iface_uuid): # Build MSRPCBind information bind = MSRPCBind() item = CtxItem() item['AbstractSyntax'] = iface_uuid item['TransferSyntax'] = uuidtup_to_bin( ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')) item['ContextID'] = 0 item['TransItems'] = 1 bind.addCtxItem(item) # Build NTLM Authentication Negociate auth = ntlm.NTLMAuthNegotiate() auth['flags'] = ntlm.NTLMSSP_NEGOTIATE_UNICODE # Build Security Trailer sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT sec_trailer['auth_ctx_id'] = 0xb0b0d0ba # Build MSRPC Header packet = MSRPCHeader() packet['type'] = MSRPC_BIND packet['call_id'] = 1 packet['flags'] = 0x03 packet['pduData'] = str(bind) packet['sec_trailer'] = sec_trailer packet['auth_data'] = str(auth) # Send MSRPC request dcerpc._transport.send(packet.get_packet()) # Receive MSRPC response s = dcerpc._transport.recv() if s == 0: print "Failed to retrieve a Bind response!" return 0 resp = MSRPCHeader(s) return resp
def rpc_out_read_pkt(self, handle_rts=False): while True: response_data = b'' # Let's receive common RPC header and no more # # C706 # 12.4 Common Fields # Header encodings differ between connectionless and connection-oriented PDUs. # However, certain fields use common sets of values with a consistent # interpretation across the two protocols. # # This MUST recv MSRPCHeader._SIZE bytes, and not MSRPCRespHeader._SIZE bytes! # while len(response_data) < MSRPCHeader._SIZE: response_data += self.rpc_out_recv1(MSRPCHeader._SIZE - len(response_data)) response_header = MSRPCHeader(response_data) # frag_len contains the full length of the packet for both # MSRPC and RTS frag_len = response_header['frag_len'] # Receiving the full pkt and no more while len(response_data) < frag_len: response_data += self.rpc_out_recv1(frag_len - len(response_data)) # We need to do the Flow Control procedures # # 3.2.1.1.4 # This protocol specifies that only RPC PDUs are subject to the flow control abstract data # model. RTS PDUs and the HTTP request and response headers are not subject to flow control. if response_header['type'] != MSRPC_RTS: self.flow_control(frag_len) if handle_rts is True and response_header['type'] == MSRPC_RTS: self.handle_out_of_sequence_rts(response_data) else: return response_data
def __init__(self, data=None, alignment=0): MSRPCHeader.__init__(self, data, alignment) self['type'] = MSRPC_RTS self['flags'] = PFC_FIRST_FRAG | PFC_LAST_FRAG self['auth_length'] = 0 self['call_id'] = 0