1# Copyright (c) 2003-2018 CORE Security Technologies 2# 3# This software is provided under under a slightly modified version 4# of the Apache Software License. See the accompanying LICENSE file 5# for more information. 6# 7# Author: Alberto Solino (@agsolino) 8# 9# Description: 10# [MS-BKRP] Interface implementation 11# 12# Best way to learn how to use these calls is to grab the protocol standard 13# so you understand what the call does, and then read the test case located 14# at https://github.com/CoreSecurity/impacket/tree/master/impacket/testcases/SMB_RPC 15# 16# Some calls have helper functions, which makes it even easier to use. 17# They are located at the end of this file. 18# Helper functions start with "h"<name of the call>. 19# There are test cases for them too. 20# 21# ToDo: 22# [ ] 2.2.2 Client-Side-Wrapped Secret 23 24from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER, NDRUniConformantArray 25from impacket.dcerpc.v5.dtypes import DWORD, NTSTATUS, GUID, RPC_SID, NULL 26from impacket.dcerpc.v5.rpcrt import DCERPCException 27from impacket import system_errors 28from impacket.uuid import uuidtup_to_bin, string_to_bin 29from impacket.structure import Structure 30 31MSRPC_UUID_BKRP = uuidtup_to_bin(('3dde7c30-165d-11d1-ab8f-00805f14db40', '1.0')) 32 33class DCERPCSessionError(DCERPCException): 34 def __init__(self, error_string=None, error_code=None, packet=None): 35 DCERPCException.__init__(self, error_string, error_code, packet) 36 37 def __str__( self ): 38 key = self.error_code 39 if system_errors.ERROR_MESSAGES.has_key(key): 40 error_msg_short = system_errors.ERROR_MESSAGES[key][0] 41 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] 42 return 'BKRP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 43 else: 44 return 'BKRP SessionError: unknown error code: 0x%x' % self.error_code 45 46################################################################################ 47# CONSTANTS 48################################################################################ 49 50BACKUPKEY_BACKUP_GUID = string_to_bin("7F752B10-178E-11D1-AB8F-00805F14DB40") 51BACKUPKEY_RESTORE_GUID_WIN2K = string_to_bin("7FE94D50-178E-11D1-AB8F-00805F14DB40") 52BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID = string_to_bin("018FF48A-EABA-40C6-8F6D-72370240E967") 53BACKUPKEY_RESTORE_GUID = string_to_bin("47270C64-2FC7-499B-AC5B-0E37CDCE899A") 54 55################################################################################ 56# STRUCTURES 57################################################################################ 58class BYTE_ARRAY(NDRUniConformantArray): 59 item = 'c' 60 61class PBYTE_ARRAY(NDRPOINTER): 62 referent = ( 63 ('Data', BYTE_ARRAY), 64 ) 65 66# 2.2.4.1 Rc4EncryptedPayload Structure 67class Rc4EncryptedPayload(Structure): 68 structure = ( 69 ('R3', '32s=""'), 70 ('MAC', '20s=""'), 71 ('SID', ':', RPC_SID), 72 ('Secret', ':'), 73 ) 74 75# 2.2.4 Secret Wrapped with Symmetric Key 76class WRAPPED_SECRET(Structure): 77 structure = ( 78 ('SIGNATURE', '<L=1'), 79 ('Payload_Length', '<L=0'), 80 ('Ciphertext_Length', '<L=0'), 81 ('GUID_of_Wrapping_Key', '16s=""'), 82 ('R2', '68s=""'), 83 ('_Rc4EncryptedPayload', '_-Rc4EncryptedPayload', 'self["Payload_Length"]'), 84 ('Rc4EncryptedPayload', ':'), 85 ) 86 87################################################################################ 88# RPC CALLS 89################################################################################ 90# 3.1.4.1 BackuprKey(Opnum 0) 91class BackuprKey(NDRCALL): 92 opnum = 0 93 structure = ( 94 ('pguidActionAgent', GUID), 95 ('pDataIn', BYTE_ARRAY), 96 ('cbDataIn', DWORD), 97 ('dwParam', DWORD), 98 ) 99 100class BackuprKeyResponse(NDRCALL): 101 structure = ( 102 ('ppDataOut', PBYTE_ARRAY), 103 ('pcbDataOut', DWORD), 104 ('ErrorCode', NTSTATUS), 105 ) 106 107################################################################################ 108# OPNUMs and their corresponding structures 109################################################################################ 110OPNUMS = { 111 0 : (BackuprKey, BackuprKeyResponse), 112} 113 114################################################################################ 115# HELPER FUNCTIONS 116################################################################################ 117def hBackuprKey(dce, pguidActionAgent, pDataIn, dwParam=0): 118 request = BackuprKey() 119 request['pguidActionAgent'] = pguidActionAgent 120 request['pDataIn'] = pDataIn 121 if pDataIn == NULL: 122 request['cbDataIn'] = 0 123 else: 124 request['cbDataIn'] = len(pDataIn) 125 request['dwParam'] = dwParam 126 return dce.request(request) 127 128