Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/dcom/scmp.py : 59%

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
1# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
9# Description:
10# [MS-SCMP]: Shadow Copy Management Protocol Interface implementation
11# This was used as a way to test the DCOM runtime. Further
12# testing is needed to verify it is working as expected
13#
14# Best way to learn how to use these calls is to grab the protocol standard
15# so you understand what the call does, and then read the test case located
16# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
17#
18# Since DCOM is like an OO RPC, instead of helper functions you will see the
19# classes described in the standards developed.
20# There are test cases for them too.
21#
22# Author:
23# Alberto Solino (@agsolino)
24#
25from __future__ import division
26from __future__ import print_function
27from impacket.dcerpc.v5.ndr import NDRENUM, NDRSTRUCT, NDRUNION
28from impacket.dcerpc.v5.dcomrt import PMInterfacePointer, INTERFACE, DCOMCALL, DCOMANSWER, IRemUnknown2
29from impacket.dcerpc.v5.dtypes import LONG, LONGLONG, ULONG, WSTR
30from impacket.dcerpc.v5.enum import Enum
31from impacket.dcerpc.v5.rpcrt import DCERPCException
32from impacket import hresult_errors
33from impacket.uuid import string_to_bin
35class DCERPCSessionError(DCERPCException):
36 def __init__(self, error_string=None, error_code=None, packet=None):
37 DCERPCException.__init__(self, error_string, error_code, packet)
39 def __str__( self ):
40 if self.error_code in hresult_errors.ERROR_MESSAGES:
41 error_msg_short = hresult_errors.ERROR_MESSAGES[self.error_code][0]
42 error_msg_verbose = hresult_errors.ERROR_MESSAGES[self.error_code][1]
43 return 'SCMP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
44 else:
45 return 'SCMP SessionError: unknown error code: 0x%x' % self.error_code
47################################################################################
48# CONSTANTS
49################################################################################
50# 1.9 Standards Assignments
51CLSID_ShadowCopyProvider = string_to_bin('0b5a2c52-3eb9-470a-96e2-6c6d4570e40f')
52IID_IVssSnapshotMgmt = string_to_bin('FA7DF749-66E7-4986-A27F-E2F04AE53772')
53IID_IVssEnumObject = string_to_bin('AE1C7110-2F60-11d3-8A39-00C04F72D8E3')
54IID_IVssDifferentialSoftwareSnapshotMgmt = string_to_bin('214A0F28-B737-4026-B847-4F9E37D79529')
55IID_IVssEnumMgmtObject = string_to_bin('01954E6B-9254-4e6e-808C-C9E05D007696')
56IID_ShadowCopyProvider = string_to_bin('B5946137-7B9F-4925-AF80-51ABD60B20D5')
58# 2.2.1.1 VSS_ID
59class VSS_ID(NDRSTRUCT):
60 structure = (
61 ('Data','16s=b""'),
62 )
64 def getAlignment(self):
65 return 2
67#2.2.1.2 VSS_PWSZ
68VSS_PWSZ = WSTR
70# 2.2.1.3 VSS_TIMESTAMP
71VSS_TIMESTAMP = LONGLONG
73error_status_t = LONG
74################################################################################
75# STRUCTURES
76################################################################################
77# 2.2.2.1 VSS_OBJECT_TYPE Enumeration
78class VSS_OBJECT_TYPE(NDRENUM):
79 class enumItems(Enum):
80 VSS_OBJECT_UNKNOWN = 0
81 VSS_OBJECT_NONE = 1
82 VSS_OBJECT_SNAPSHOT_SET = 2
83 VSS_OBJECT_SNAPSHOT = 3
84 VSS_OBJECT_PROVIDER = 4
85 VSS_OBJECT_TYPE_COUNT = 5
87# 2.2.2.2 VSS_MGMT_OBJECT_TYPE Enumeration
88class VSS_MGMT_OBJECT_TYPE(NDRENUM):
89 class enumItems(Enum):
90 VSS_MGMT_OBJECT_UNKNOWN = 0
91 VSS_MGMT_OBJECT_VOLUME = 1
92 VSS_MGMT_OBJECT_DIFF_VOLUME = 2
93 VSS_MGMT_OBJECT_DIFF_AREA = 3
95# 2.2.2.3 VSS_VOLUME_SNAPSHOT_ATTRIBUTES Enumeration
96class VSS_VOLUME_SNAPSHOT_ATTRIBUTES(NDRENUM):
97 class enumItems(Enum):
98 VSS_VOLSNAP_ATTR_PERSISTENT = 0x01
99 VSS_VOLSNAP_ATTR_NO_AUTORECOVERY = 0x02
100 VSS_VOLSNAP_ATTR_CLIENT_ACCESSIBLE = 0x04
101 VSS_VOLSNAP_ATTR_NO_AUTO_RELEASE = 0x08
102 VSS_VOLSNAP_ATTR_NO_WRITERS = 0x10
104# 2.2.2.4 VSS_SNAPSHOT_STATE Enumeration
105class VSS_SNAPSHOT_STATE(NDRENUM):
106 class enumItems(Enum):
107 VSS_SS_UNKNOWN = 0x01
108 VSS_SS_CREATED = 0x0c
110# 2.2.2.5 VSS_PROVIDER_TYPE Enumeration
111class VSS_PROVIDER_TYPE(NDRENUM):
112 class enumItems(Enum):
113 VSS_PROV_UNKNOWN = 0
115# 2.2.3.7 VSS_VOLUME_PROP Structure
116class VSS_VOLUME_PROP(NDRSTRUCT):
117 structure = (
118 ('m_pwszVolumeName', VSS_PWSZ),
119 ('m_pwszVolumeDisplayName', VSS_PWSZ),
120 )
122# 2.2.3.5 VSS_MGMT_OBJECT_UNION Union
123class VSS_MGMT_OBJECT_UNION(NDRUNION):
124 commonHdr = (
125 ('tag', ULONG),
126 )
127 union = {
128 VSS_MGMT_OBJECT_TYPE.VSS_MGMT_OBJECT_VOLUME: ('Vol', VSS_VOLUME_PROP),
129 #VSS_MGMT_OBJECT_DIFF_VOLUME: ('DiffVol', VSS_DIFF_VOLUME_PROP),
130 #VSS_MGMT_OBJECT_DIFF_AREA: ('DiffArea', VSS_DIFF_AREA_PROP),
131 }
133# 2.2.3.6 VSS_MGMT_OBJECT_PROP Structure
134class VSS_MGMT_OBJECT_PROP(NDRSTRUCT):
135 structure = (
136 ('Type', VSS_MGMT_OBJECT_TYPE),
137 ('Obj', VSS_MGMT_OBJECT_UNION),
138 )
140################################################################################
141# RPC CALLS
142################################################################################
143# 3.1.3 IVssEnumMgmtObject Details
145# 3.1.3.1 Next (Opnum 3)
146class IVssEnumMgmtObject_Next(DCOMCALL):
147 opnum = 3
148 structure = (
149 ('celt', ULONG),
150 )
152class IVssEnumMgmtObject_NextResponse(DCOMANSWER):
153 structure = (
154 ('rgelt', VSS_MGMT_OBJECT_PROP),
155 ('pceltFetched', ULONG),
156 ('ErrorCode', error_status_t),
157 )
159# 3.1.2.1 Next (Opnum 3)
160class IVssEnumObject_Next(DCOMCALL):
161 opnum = 3
162 structure = (
163 ('celt', ULONG),
164 )
166class IVssEnumObject_NextResponse(DCOMANSWER):
167 structure = (
168 ('rgelt', VSS_MGMT_OBJECT_PROP),
169 ('pceltFetched', ULONG),
170 ('ErrorCode', error_status_t),
171 )
173class GetProviderMgmtInterface(DCOMCALL):
174 opnum = 3
175 structure = (
176 ('ProviderId', VSS_ID),
177 ('InterfaceId', VSS_ID),
178 )
180class GetProviderMgmtInterfaceResponse(DCOMANSWER):
181 structure = (
182 ('ppItf', PMInterfacePointer),
183 ('ErrorCode', error_status_t),
184 )
186class QueryVolumesSupportedForSnapshots(DCOMCALL):
187 opnum = 4
188 structure = (
189 ('ProviderId', VSS_ID),
190 ('IContext', LONG),
191 )
193class QueryVolumesSupportedForSnapshotsResponse(DCOMANSWER):
194 structure = (
195 ('ppEnum', PMInterfacePointer),
196 ('ErrorCode', error_status_t),
197 )
199class QuerySnapshotsByVolume(DCOMCALL):
200 opnum = 5
201 structure = (
202 ('pwszVolumeName', VSS_PWSZ),
203 ('ProviderId', VSS_ID),
204 )
206class QuerySnapshotsByVolumeResponse(DCOMANSWER):
207 structure = (
208 ('ppEnum', PMInterfacePointer),
209 ('ErrorCode', error_status_t),
210 )
212# 3.1.4.4.5 QueryDiffAreasForVolume (Opnum 6)
213class QueryDiffAreasForVolume(DCOMCALL):
214 opnum = 6
215 structure = (
216 ('pwszVolumeName', VSS_PWSZ),
217 )
219class QueryDiffAreasForVolumeResponse(DCOMANSWER):
220 structure = (
221 ('ppEnum', PMInterfacePointer),
222 ('ErrorCode', error_status_t),
223 )
225# 3.1.4.4.6 QueryDiffAreasOnVolume (Opnum 7)
226class QueryDiffAreasOnVolume(DCOMCALL):
227 opnum = 7
228 structure = (
229 ('pwszVolumeName', VSS_PWSZ),
230 )
232class QueryDiffAreasOnVolumeResponse(DCOMANSWER):
233 structure = (
234 ('ppEnum', PMInterfacePointer),
235 ('ErrorCode', error_status_t),
236 )
239################################################################################
240# OPNUMs and their corresponding structures
241################################################################################
242OPNUMS = {
243}
245################################################################################
246# HELPER FUNCTIONS AND INTERFACES
247################################################################################
248class IVssEnumMgmtObject(IRemUnknown2):
249 def __init__(self, interface):
250 IRemUnknown2.__init__(self, interface)
251 self._iid = IID_IVssEnumMgmtObject
253 def Next(self, celt):
254 request = IVssEnumMgmtObject_Next()
255 request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
256 request['ORPCthis']['flags'] = 0
257 request['celt'] = celt
258 resp = self.request(request, self._iid, uuid = self.get_iPid())
259 return resp
261class IVssEnumObject(IRemUnknown2):
262 def __init__(self, interface):
263 IRemUnknown2.__init__(self, interface)
264 self._iid = IID_IVssEnumObject
266 def Next(self, celt):
267 request = IVssEnumObject_Next()
268 request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
269 request['ORPCthis']['flags'] = 0
270 request['celt'] = celt
271 dce = self.connect()
272 resp = dce.request(request, self._iid, uuid = self.get_iPid())
273 return resp
275class IVssSnapshotMgmt(IRemUnknown2):
276 def __init__(self, interface):
277 IRemUnknown2.__init__(self, interface)
278 self._iid = IID_IVssSnapshotMgmt
280 def GetProviderMgmtInterface(self, providerId = IID_ShadowCopyProvider, interfaceId = IID_IVssDifferentialSoftwareSnapshotMgmt):
281 req = GetProviderMgmtInterface()
282 classInstance = self.get_cinstance()
283 req['ORPCthis'] = classInstance.get_ORPCthis()
284 req['ORPCthis']['flags'] = 0
285 req['ProviderId'] = providerId
286 req['InterfaceId'] = interfaceId
287 resp = self.request(req, self._iid, uuid = self.get_iPid())
288 return IVssDifferentialSoftwareSnapshotMgmt(INTERFACE(classInstance, ''.join(resp['ppItf']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
290 def QueryVolumesSupportedForSnapshots(self, providerId, iContext):
291 req = QueryVolumesSupportedForSnapshots()
292 classInstance = self.get_cinstance()
293 req['ORPCthis'] = classInstance.get_ORPCthis()
294 req['ORPCthis']['flags'] = 0
295 req['ProviderId'] = providerId
296 req['IContext'] = iContext
297 resp = self.request(req, self._iid, uuid = self.get_iPid())
298 return IVssEnumMgmtObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(),target = self.get_target()))
300 def QuerySnapshotsByVolume(self, volumeName, providerId = IID_ShadowCopyProvider):
301 req = QuerySnapshotsByVolume()
302 classInstance = self.get_cinstance()
303 req['ORPCthis'] = classInstance.get_ORPCthis()
304 req['ORPCthis']['flags'] = 0
305 req['pwszVolumeName'] = volumeName
306 req['ProviderId'] = providerId
307 try:
308 resp = self.request(req, self._iid, uuid = self.get_iPid())
309 except DCERPCException as e:
310 print(e)
311 from impacket.winregistry import hexdump
312 data = e.get_packet()
313 hexdump(data)
314 kk = QuerySnapshotsByVolumeResponse(data)
315 kk.dump()
316 #resp.dump()
317 return IVssEnumObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
319class IVssDifferentialSoftwareSnapshotMgmt(IRemUnknown2):
320 def __init__(self, interface):
321 IRemUnknown2.__init__(self, interface)
322 self._iid = IID_IVssDifferentialSoftwareSnapshotMgmt
324 def QueryDiffAreasOnVolume(self, pwszVolumeName):
325 req = QueryDiffAreasOnVolume()
326 classInstance = self.get_cinstance()
327 req['ORPCthis'] = classInstance.get_ORPCthis()
328 req['ORPCthis']['flags'] = 0
329 req['pwszVolumeName'] = pwszVolumeName
330 resp = self.request(req, self._iid, uuid = self.get_iPid())
331 return IVssEnumMgmtObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
333 def QueryDiffAreasForVolume(self, pwszVolumeName):
334 req = QueryDiffAreasForVolume()
335 classInstance = self.get_cinstance()
336 req['ORPCthis'] = classInstance.get_ORPCthis()
337 req['ORPCthis']['flags'] = 0
338 req['pwszVolumeName'] = pwszVolumeName
339 resp = self.request(req, self._iid, uuid = self.get_iPid())
340 return IVssEnumMgmtObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))