Coverage for /private/tmp/im/impacket/impacket/dcerpc/v5/dcom/oaut.py : 72%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # Author: Alberto Solino (@agsolino) # # Description: # [MS-OAUT]: OLE Automation Protocol Implementation # This was used as a way to test the DCOM runtime. Further # testing is needed to verify it is working as expected # # Best way to learn how to use these calls is to grab the protocol standard # so you understand what the call does, and then read the test case located # at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC # # Since DCOM is like an OO RPC, instead of helper functions you will see the # classes described in the standards developed. # There are test cases for them too. #
MInterfacePointer, MInterfacePointer_ARRAY, BYTE_ARRAY, PPMInterfacePointer DOUBLE, HRESULT, PSHORT, PLONG, PLONGLONG, PFLOAT, PDOUBLE, PHRESULT, CHAR, ULONGLONG, INT, UINT, PCHAR, PUSHORT, \ PULONG, PULONGLONG, PINT, PUINT, NULL NDRUniConformantVaryingArray, NDR
DCERPCException.__init__(self, error_string, error_code, packet)
if self.error_code in hresult_errors.ERROR_MESSAGES: error_msg_short = hresult_errors.ERROR_MESSAGES[self.error_code][0] error_msg_verbose = hresult_errors.ERROR_MESSAGES[self.error_code][1] return 'OAUT SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) else: return 'OAUT SessionError: unknown error code: 0x%x' % (self.error_code)
################################################################################ # CONSTANTS ################################################################################ # 1.9 Standards Assignments
# 2.2.2 IID
# 2.2.3 LPOLESTR
# 2.2.4 REFIID
# 2.2.25 DATE ('Data', DATE), )
# 2.2.27 VARIANT_BOOL
('Data', VARIANT_BOOL), )
# 3.1.4.4 IDispatch::Invoke (Opnum 6) # dwFlags
################################################################################ # STRUCTURES ################################################################################ # 2.2.26 DECIMAL ('wReserved',WORD), ('scale',BYTE), ('sign',BYTE), ('Hi32',ULONG), ('Lo64',ULONGLONG), )
('Data', DECIMAL), )
# 2.2.7 VARIANT Type Constants
# 2.2.8 SAFEARRAY Feature Constants # [v1_enum] type ('Data', '<L'), )
# 2.2.10 CALLCONV Calling Convention Constants # [v1_enum] type ('Data', '<L'), )
# 2.2.12 FUNCKIND Function Access Constants # [v1_enum] type ('Data', '<L'), )
# 2.2.14 INVOKEKIND Function Invocation Constants # [v1_enum] type ('Data', '<L'), )
# 2.2.17 TYPEKIND Type Kind Constants # [v1_enum] type ('Data', '<L'), )
# 2.2.23 BSTR # 2.2.23.1 FLAGGED_WORD_BLOB
('cBytes',ULONG), ('clSize',ULONG), ('asData',USHORT_ARRAY), ) else:
if key == 'asData': value = '' for letter in self.fields['asData']['Data']: value += pack('<H', letter).decode('utf-16le') return value else: return NDRSTRUCT.__getitem__(self,key)
if msg is None: msg = self.__class__.__name__ ind = ' '*indent if msg != '': print("%s" % (msg)) value = '' print('%sasData: %s' % (ind,self['asData']), end=' ')
# 2.2.23.2 BSTR Type Definition ('Data', FLAGGED_WORD_BLOB), )
('Data', BSTR), )
# 2.2.24 CURRENCY ('int64', LONGLONG), )
('Data', CURRENCY), )
# 2.2.28.2 BRECORD # 2.2.28.2.1 _wireBRECORD ('fFlags', LONGLONG), ('clSize', LONGLONG), ('pRecInfo', MInterfacePointer), ('pRecord', BYTE_ARRAY), )
('Data', _wireBRECORD), )
# 2.2.30 SAFEARRAY # 2.2.30.1 SAFEARRAYBOUND ('cElements', ULONG), ('lLbound', LONG), )
('Data', SAFEARRAYBOUND), )
# 2.2.30.2 SAFEARR_BSTR
('Data', BSTR_ARRAY), )
('Size', ULONG), ('aBstr', PBSTR_ARRAY), )
# 2.2.30.3 SAFEARR_UNKNOWN ('Size', ULONG), ('apUnknown', MInterfacePointer_ARRAY), )
# 2.2.30.4 SAFEARR_DISPATCH ('Size', ULONG), ('apDispatch', MInterfacePointer_ARRAY), )
# 2.2.30.6 SAFEARR_BRECORD
('Size', ULONG), ('aRecord', BRECORD_ARRAY), )
# 2.2.30.7 SAFEARR_HAVEIID ('Size', ULONG), ('apUnknown', MInterfacePointer_ARRAY), ('iid', IID), )
# 2.2.30.8 Scalar-Sized Arrays # 2.2.30.8.1 BYTE_SIZEDARR ('clSize', ULONG), ('pData', BYTE_ARRAY), )
# 2.2.30.8.2 WORD_SIZEDARR
('clSize', ULONG), ('pData', WORD_ARRAY), )
# 2.2.30.8.3 DWORD_SIZEDARR
('clSize', ULONG), ('pData', DWORD_ARRAY), )
# 2.2.30.8.4 HYPER_SIZEDARR
('clSize', ULONG), ('pData', HYPER_ARRAY), )
# 2.2.36 HREFTYPE
# 2.2.30.5 SAFEARR_VARIANT # In order to avoid the lack of forward declarations in Python # I declare the item in the constructor #item = VARIANT NDRUniConformantArray.__init__(self, data, isNDR64) self.item = VARIANT
('Data', VARIANT_ARRAY), )
# In order to avoid the lack of forward declarations in Python # I declare the item in the constructor #referent = ( # ('Data', VARIANT), #) NDRPOINTER.__init__(self, data, isNDR64) self.referent = ( ('Data', VARIANT),)
('Size', ULONG), ('aVariant', VARIANT_ARRAY), )
# 2.2.30.9 SAFEARRAYUNION ('tag', ULONG), ) SF_TYPE.SF_BSTR : ('BstrStr', SAFEARR_BSTR), SF_TYPE.SF_UNKNOWN : ('UnknownStr', SAFEARR_UNKNOWN), SF_TYPE.SF_DISPATCH : ('DispatchStr', SAFEARR_DISPATCH), SF_TYPE.SF_VARIANT : ('VariantStr', SAFEARR_VARIANT), SF_TYPE.SF_RECORD : ('RecordStr', SAFEARR_BRECORD), SF_TYPE.SF_HAVEIID : ('HaveIidStr', SAFEARR_HAVEIID), SF_TYPE.SF_I1 : ('ByteStr', BYTE_SIZEDARR), SF_TYPE.SF_I2 : ('WordStr', WORD_SIZEDARR), SF_TYPE.SF_I4 : ('LongStr', DWORD_SIZEDARR), SF_TYPE.SF_I8 : ('HyperStr', HYPER_SIZEDARR), }
# 2.2.30.10 SAFEARRAY
('Data', SAFEARRAYBOUND_ARRAY), )
('cDims', USHORT), ('fFeatures', USHORT), ('cbElements', ULONG), ('cLocks', ULONG), ('uArrayStructs', SAFEARRAYUNION), ('rgsabound', SAFEARRAYBOUND_ARRAY), )
('Data', SAFEARRAY), )
# 2.2.29 VARIANT # 2.2.29.1 _wireVARIANT )
('tag', ULONG), ) VARENUM.VT_I8 : ('llVal', LONGLONG), VARENUM.VT_I4 : ('lVal', LONG), VARENUM.VT_UI1 : ('bVal', BYTE), VARENUM.VT_I2 : ('iVal', SHORT), VARENUM.VT_R4 : ('fltVal', FLOAT), VARENUM.VT_R8 : ('dblVal', DOUBLE), VARENUM.VT_BOOL : ('boolVal', VARIANT_BOOL), VARENUM.VT_ERROR : ('scode', HRESULT), VARENUM.VT_CY : ('cyVal', CURRENCY), VARENUM.VT_DATE : ('date', DATE), VARENUM.VT_BSTR : ('bstrVal', BSTR), VARENUM.VT_UNKNOWN : ('punkVal', PMInterfacePointer), VARENUM.VT_DISPATCH : ('pdispVal', PMInterfacePointer), VARENUM.VT_ARRAY : ('parray', SAFEARRAY), VARENUM.VT_RECORD : ('brecVal', BRECORD), VARENUM.VT_RECORD_OR_VT_BYREF : ('brecVal', BRECORD), VARENUM.VT_UI1_OR_VT_BYREF : ('pbVal', BYTE), VARENUM.VT_I2_OR_VT_BYREF : ('piVal', PSHORT), VARENUM.VT_I4_OR_VT_BYREF : ('plVal', PLONG), VARENUM.VT_I8_OR_VT_BYREF : ('pllVal', PLONGLONG), VARENUM.VT_R4_OR_VT_BYREF : ('pfltVal', PFLOAT), VARENUM.VT_R8_OR_VT_BYREF : ('pdblVal', PDOUBLE), VARENUM.VT_BOOL_OR_VT_BYREF : ('pboolVal', PVARIANT_BOOL), VARENUM.VT_ERROR_OR_VT_BYREF : ('pscode', PHRESULT), VARENUM.VT_CY_OR_VT_BYREF : ('pcyVal', PCURRENCY), VARENUM.VT_DATE_OR_VT_BYREF : ('pdate', PDATE), VARENUM.VT_BSTR_OR_VT_BYREF : ('pbstrVal', PBSTR), VARENUM.VT_UNKNOWN_OR_VT_BYREF : ('ppunkVal', PPMInterfacePointer), VARENUM.VT_DISPATCH_OR_VT_BYREF: ('ppdispVal', PPMInterfacePointer), VARENUM.VT_ARRAY_OR_VT_BYREF : ('pparray', PSAFEARRAY), VARENUM.VT_VARIANT_OR_VT_BYREF : ('pvarVal', PVARIANT), VARENUM.VT_I1 : ('cVal', CHAR), VARENUM.VT_UI2 : ('uiVal', USHORT), VARENUM.VT_UI4 : ('ulVal', ULONG), VARENUM.VT_UI8 : ('ullVal', ULONGLONG), VARENUM.VT_INT : ('intVal', INT), VARENUM.VT_UINT : ('uintVal', UINT), VARENUM.VT_DECIMAL : ('decVal', DECIMAL), VARENUM.VT_I1_OR_VT_BYREF : ('pcVal', PCHAR), VARENUM.VT_UI2_OR_VT_BYREF : ('puiVal', PUSHORT), VARENUM.VT_UI4_OR_VT_BYREF : ('pulVal', PULONG), VARENUM.VT_UI8_OR_VT_BYREF : ('pullVal', PULONGLONG), VARENUM.VT_INT_OR_VT_BYREF : ('pintVal', PINT), VARENUM.VT_UINT_OR_VT_BYREF : ('puintVal', PUINT), VARENUM.VT_DECIMAL_OR_VT_BYREF : ('pdecVal', PDECIMAL), VARENUM.VT_EMPTY : ('empty', EMPTY), VARENUM.VT_NULL : ('null', EMPTY), }
('clSize',DWORD), ('rpcReserved',DWORD), ('vt',USHORT), ('wReserved1',USHORT), ('wReserved2',USHORT), ('wReserved3',USHORT), ('_varUnion',varUnion), )
return 8
('Data', wireVARIANTStr), )
('Data', VARIANT), )
# 2.2.32 DISPID
# 2.2.33 DISPPARAMS
('Data', DISPID_ARRAY), )
('rgvarg',PVARIANT_ARRAY), ('rgdispidNamedArgs', PDISPID_ARRAY), ('cArgs', UINT), ('cNamedArgs', UINT), )
# 2.2.34 EXCEPINFO ('wCode',WORD), ('wReserved', WORD), ('bstrSource', BSTR), ('bstrDescription', BSTR), ('bstrHelpFile', BSTR), ('dwHelpContext', DWORD), ('pvReserved', ULONG), ('pfnDeferredFillIn', ULONG), ('scode', HRESULT), )
# 2.2.35 MEMBERID
# 2.2.38 ARRAYDESC # In order to avoid the lack of forward declarations in Python # I declare the item in the constructor #structure = ( # ('tdescElem',TYPEDESC), # ('cDims',USHORT), # ('rgbounds',SAFEARRAYBOUND_ARRAY), #) NDRSTRUCT.__init__(self, data, isNDR64) self.structure = ( ('tdescElem',TYPEDESC), ('cDims',USHORT), ('rgbounds',SAFEARRAYBOUND_ARRAY), )
# 2.2.37 TYPEDESC ('tag', USHORT), ) # In order to avoid the lack of forward declarations in Python # I declare the item in the constructor #union = { # VARENUM.VT_PTR: ('lptdesc', tdUnion), # VARENUM.VT_SAFEARRAY: ('lptdesc', tdUnion), # VARENUM.VT_CARRAY: ('lpadesc', ARRAYDESC), # VARENUM.VT_USERDEFINED: ('hreftype', HREFTYPE), #} NDRUNION.__init__(self,None, isNDR64=isNDR64, topLevel=topLevel) self.union = { VARENUM.VT_PTR: ('lptdesc', PTYPEDESC), VARENUM.VT_SAFEARRAY: ('lptdesc', PTYPEDESC), VARENUM.VT_CARRAY: ('lpadesc', ARRAYDESC), VARENUM.VT_USERDEFINED: ('hreftype', HREFTYPE), 'default': None, }
('vtType',tdUnion), ('vt', VARENUM), )
return 4
('Data', TYPEDESC), ) ret = NDRPOINTER.__init__(self,None, isNDR64=isNDR64, topLevel = False) # We're forcing the pointer not to be topLevel if data is None: self.fields['ReferentID'] = random.randint(1,65535) else: self.fromString(data)
# 2.2.48 SCODE
('Data', SCODE_ARRAY), )
# 2.2.39 PARAMDESCEX ('cBytes',ULONG), ('varDefaultValue',VARIANT), )
('Data', PARAMDESCEX), )
# 2.2.40 PARAMDESC ('pparamdescex',PPARAMDESCEX), ('wParamFlags',USHORT), )
# 2.2.41 ELEMDESC ('tdesc',TYPEDESC), ('paramdesc',PARAMDESC), )
('Data', ELEMDESC_ARRAY), )
# 2.2.42 FUNCDESC ('memid',MEMBERID), ('lReserved1',PSCODE_ARRAY), ('lprgelemdescParam',PELEMDESC_ARRAY), ('funckind',FUNCKIND), ('invkind',INVOKEKIND), ('callconv',CALLCONV), ('cParams',SHORT), ('cParamsOpt',SHORT), ('oVft',SHORT), ('cReserved2',SHORT), ('elemdescFunc',ELEMDESC), ('wFuncFlags',WORD), )
('Data', FUNCDESC), ) # 2.2.44 TYPEATTR ('guid',GUID), ('lcid',LCID), ('dwReserved1',DWORD), ('dwReserved2',DWORD), ('dwReserved3',DWORD), ('lpstrReserved4',LPOLESTR), ('cbSizeInstance',ULONG), ('typeKind',TYPEKIND), ('cFuncs',WORD), ('cVars',WORD), ('cImplTypes',WORD), ('cbSizeVft',WORD), ('cbAlignment',WORD), ('wTypeFlags',WORD), ('wMajorVerNum',WORD), ('wMinorVerNum',WORD), ('tdescAlias',TYPEDESC), ('dwReserved5',DWORD), ('dwReserved6',WORD), )
('Data', TYPEATTR), )
################################################################################ # RPC CALLS ################################################################################ # 3.1.4.1 IDispatch::GetTypeInfoCount (Opnum 3) ('pwszMachineName', LPWSTR), )
('pctinfo', ULONG), ('ErrorCode', error_status_t), )
# 3.1.4.2 IDispatch::GetTypeInfo (Opnum 4) ('iTInfo', ULONG), ('lcid', DWORD), )
('ppTInfo', PMInterfacePointer), ('ErrorCode', error_status_t), )
# 3.1.4.3 IDispatch::GetIDsOfNames (Opnum 5) ('riid', REFIID), ('rgszNames', OLESTR_ARRAY), ('cNames', UINT), ('lcid', LCID), )
('rgDispId', DISPID_ARRAY), ('ErrorCode', error_status_t), )
# 3.1.4.4 IDispatch::Invoke (Opnum 6) ('dispIdMember', DISPID), ('riid', REFIID), ('lcid', LCID), ('dwFlags', DWORD), ('pDispParams', DISPPARAMS), ('cVarRef', UINT), ('rgVarRefIdx', UINT_ARRAY), ('rgVarRef', VARIANT_ARRAY), )
('pVarResult', VARIANT), ('pExcepInfo', EXCEPINFO), ('pArgErr', UINT), ('ErrorCode', error_status_t), )
# 3.7.4.1 ITypeInfo::GetTypeAttr (Opnum 3) )
('ppTypeAttr', PTYPEATTR), ('pReserved', DWORD), ('ErrorCode', error_status_t), )
# 3.7.4.2 ITypeInfo::GetTypeComp (Opnum 4) )
('ppTComp', PMInterfacePointer), ('ErrorCode', error_status_t), )
# 3.7.4.3 ITypeInfo::GetFuncDesc (Opnum 5) ('index', UINT), )
('ppFuncDesc', LPFUNCDESC), ('pReserved', DWORD), ('ErrorCode', error_status_t), )
# 3.7.4.5 ITypeInfo::GetNames (Opnum 7) ('memid', MEMBERID), ('cMaxNames', UINT), )
('rgBstrNames', BSTR_ARRAY_CV), ('pcNames', UINT), ('ErrorCode', error_status_t), )
# 3.7.4.8 ITypeInfo::GetDocumentation (Opnum 12) ('memid', MEMBERID), ('refPtrFlags', DWORD), )
('pBstrName', BSTR), ('pBstrDocString', BSTR), ('pdwHelpContext', DWORD), ('ErrorCode', error_status_t), )
################################################################################ # OPNUMs and their corresponding structures ################################################################################ }
################################################################################ # HELPER FUNCTIONS AND INTERFACES ################################################################################ # 4.8.5 Enumerating All Methods in an Interface # INPUT: IDispatch pointer from the automation server # CALL IDispatch::GetTypeInfoCount and OBTAIN pcTInfo # COMMENT see Section 3.1.4.1 for information on pcTInfo i # IF pcTInfo = 0 THEN # PRINT Automation Server does not support type information for this object # ELSE # CALL IDispatch::GetTypeInfo with correct LocaleID and OBTAIN ITypeInfo pointer # CALL ITypeInfo::GetDocumentation(MEMBERID_NIL, 1, &BstrName, NULL, NULL, NULL) # PRINT Name of the Interface is BstrName # CALL ITypeInfo::GetTypeAttr and OBTAIN TYPEATTR pointer # # FOR X = 0 to TYPEATTR:: cFuncs -1 # CALL ITypeInfo::GetFuncDesc with X and OBTAIN FUNCDESC pointer # CALL ITypeInfo::GetNames with FUNCDESC::memid and appropriate values for # rgBstrNames, cMaxNames and pcNames # COMMENT see Section 3.7.4.5 for more information regarding the parameters # to ITypeinfo::GetNames # IF pcNames > 0 THEN # PRINT Name of the method is rgBstrNames[0] # PRINT Parameters to above method are following # FOR Y = 1 to pcNames -1 # PRINT rgBstrNames[Y] # END FOR # END IF # END FOR i # ENDIF methods = dict() typeInfoCount = iInterface.GetTypeInfoCount() if typeInfoCount['pctinfo'] == 0: LOG.error('Automation Server does not support type information for this object') return {} iTypeInfo = iInterface.GetTypeInfo() iTypeAttr = iTypeInfo.GetTypeAttr() for x in range(iTypeAttr['ppTypeAttr']['cFuncs']): funcDesc = iTypeInfo.GetFuncDesc(x) names = iTypeInfo.GetNames(funcDesc['ppFuncDesc']['memid'], 255) print(names['rgBstrNames'][0]['asData']) funcDesc.dump() print('='*80) if names['pcNames'] > 0: name = names['rgBstrNames'][0]['asData'] methods[name] = {} for param in range(1, names['pcNames']): methods[name][names['rgBstrNames'][param]['asData']] = '' if funcDesc['ppFuncDesc']['elemdescFunc'] != NULL: methods[name]['ret'] = funcDesc['ppFuncDesc']['elemdescFunc']['tdesc']['vt']
return methods
if string == NULL: return string
if string[-1:] != '\x00': return string + '\x00' else: return string
IRemUnknown2.__init__(self,interface) self._iid = IID_ITypeComp
IRemUnknown2.__init__(self,interface) self._iid = IID_ITypeInfo
request = ITypeInfo_GetTypeAttr() resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return resp
request = ITypeInfo_GetTypeComp() resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return ITypeComp(INTERFACE(self.get_cinstance(), ''.join(resp['ppTComp']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
request = ITypeInfo_GetFuncDesc() request['index'] = index resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return resp
request = ITypeInfo_GetNames() request['memid'] = memid request['cMaxNames'] = cMaxNames resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return resp
request = ITypeInfo_GetDocumentation() request['memid'] = memid request['refPtrFlags'] = refPtrFlags resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return resp
request = IDispatch_GetTypeInfoCount() resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return resp
request = IDispatch_GetTypeInfo() request['iTInfo'] = 0 request['lcid'] = 0 resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return ITypeInfo(INTERFACE(self.get_cinstance(), ''.join(resp['ppTInfo']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
request = IDispatch_GetIDsOfNames() request['riid'] = IID_NULL for name in rgszNames: tmpName = LPOLESTR() tmpName['Data'] = checkNullString(name) request['rgszNames'].append(tmpName) request['cNames'] = len(rgszNames) request['lcid'] = lcid resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) IDs = list() for id in resp['rgDispId']: IDs.append(id)
return IDs
request = IDispatch_Invoke() request['dispIdMember'] = dispIdMember request['riid'] = IID_NULL request['lcid'] = lcid request['dwFlags'] = dwFlags request['pDispParams'] = pDispParams request['cVarRef'] = cVarRef request['rgVarRefIdx'] = rgVarRefIdx request['rgVarRef'] = rgVarRefIdx resp = self.request(request, iid = self._iid, uuid = self.get_iPid()) return resp |