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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
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-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#
22from __future__ import division
23from __future__ import print_function
24from impacket.dcerpc.v5.ndr import NDRENUM, NDRSTRUCT, NDRUNION
25from impacket.dcerpc.v5.dcomrt import PMInterfacePointer, INTERFACE, DCOMCALL, DCOMANSWER, IRemUnknown2
26from impacket.dcerpc.v5.dtypes import LONG, LONGLONG, ULONG, WSTR
27from impacket.dcerpc.v5.enum import Enum
28from impacket.dcerpc.v5.rpcrt import DCERPCException
29from impacket import hresult_errors
30from impacket.uuid import string_to_bin
32class DCERPCSessionError(DCERPCException):
33 def __init__(self, error_string=None, error_code=None, packet=None):
34 DCERPCException.__init__(self, error_string, error_code, packet)
36 def __str__( self ):
37 if self.error_code in hresult_errors.ERROR_MESSAGES:
38 error_msg_short = hresult_errors.ERROR_MESSAGES[self.error_code][0]
39 error_msg_verbose = hresult_errors.ERROR_MESSAGES[self.error_code][1]
40 return 'SCMP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
41 else:
42 return 'SCMP SessionError: unknown error code: 0x%x' % self.error_code
44################################################################################
45# CONSTANTS
46################################################################################
47# 1.9 Standards Assignments
48CLSID_ShadowCopyProvider = string_to_bin('0b5a2c52-3eb9-470a-96e2-6c6d4570e40f')
49IID_IVssSnapshotMgmt = string_to_bin('FA7DF749-66E7-4986-A27F-E2F04AE53772')
50IID_IVssEnumObject = string_to_bin('AE1C7110-2F60-11d3-8A39-00C04F72D8E3')
51IID_IVssDifferentialSoftwareSnapshotMgmt = string_to_bin('214A0F28-B737-4026-B847-4F9E37D79529')
52IID_IVssEnumMgmtObject = string_to_bin('01954E6B-9254-4e6e-808C-C9E05D007696')
53IID_ShadowCopyProvider = string_to_bin('B5946137-7B9F-4925-AF80-51ABD60B20D5')
55# 2.2.1.1 VSS_ID
56class VSS_ID(NDRSTRUCT):
57 structure = (
58 ('Data','16s=b""'),
59 )
61 def getAlignment(self):
62 return 2
64#2.2.1.2 VSS_PWSZ
65VSS_PWSZ = WSTR
67# 2.2.1.3 VSS_TIMESTAMP
68VSS_TIMESTAMP = LONGLONG
70error_status_t = LONG
71################################################################################
72# STRUCTURES
73################################################################################
74# 2.2.2.1 VSS_OBJECT_TYPE Enumeration
75class VSS_OBJECT_TYPE(NDRENUM):
76 class enumItems(Enum):
77 VSS_OBJECT_UNKNOWN = 0
78 VSS_OBJECT_NONE = 1
79 VSS_OBJECT_SNAPSHOT_SET = 2
80 VSS_OBJECT_SNAPSHOT = 3
81 VSS_OBJECT_PROVIDER = 4
82 VSS_OBJECT_TYPE_COUNT = 5
84# 2.2.2.2 VSS_MGMT_OBJECT_TYPE Enumeration
85class VSS_MGMT_OBJECT_TYPE(NDRENUM):
86 class enumItems(Enum):
87 VSS_MGMT_OBJECT_UNKNOWN = 0
88 VSS_MGMT_OBJECT_VOLUME = 1
89 VSS_MGMT_OBJECT_DIFF_VOLUME = 2
90 VSS_MGMT_OBJECT_DIFF_AREA = 3
92# 2.2.2.3 VSS_VOLUME_SNAPSHOT_ATTRIBUTES Enumeration
93class VSS_VOLUME_SNAPSHOT_ATTRIBUTES(NDRENUM):
94 class enumItems(Enum):
95 VSS_VOLSNAP_ATTR_PERSISTENT = 0x01
96 VSS_VOLSNAP_ATTR_NO_AUTORECOVERY = 0x02
97 VSS_VOLSNAP_ATTR_CLIENT_ACCESSIBLE = 0x04
98 VSS_VOLSNAP_ATTR_NO_AUTO_RELEASE = 0x08
99 VSS_VOLSNAP_ATTR_NO_WRITERS = 0x10
101# 2.2.2.4 VSS_SNAPSHOT_STATE Enumeration
102class VSS_SNAPSHOT_STATE(NDRENUM):
103 class enumItems(Enum):
104 VSS_SS_UNKNOWN = 0x01
105 VSS_SS_CREATED = 0x0c
107# 2.2.2.5 VSS_PROVIDER_TYPE Enumeration
108class VSS_PROVIDER_TYPE(NDRENUM):
109 class enumItems(Enum):
110 VSS_PROV_UNKNOWN = 0
112# 2.2.3.7 VSS_VOLUME_PROP Structure
113class VSS_VOLUME_PROP(NDRSTRUCT):
114 structure = (
115 ('m_pwszVolumeName', VSS_PWSZ),
116 ('m_pwszVolumeDisplayName', VSS_PWSZ),
117 )
119# 2.2.3.5 VSS_MGMT_OBJECT_UNION Union
120class VSS_MGMT_OBJECT_UNION(NDRUNION):
121 commonHdr = (
122 ('tag', ULONG),
123 )
124 union = {
125 VSS_MGMT_OBJECT_TYPE.VSS_MGMT_OBJECT_VOLUME: ('Vol', VSS_VOLUME_PROP),
126 #VSS_MGMT_OBJECT_DIFF_VOLUME: ('DiffVol', VSS_DIFF_VOLUME_PROP),
127 #VSS_MGMT_OBJECT_DIFF_AREA: ('DiffArea', VSS_DIFF_AREA_PROP),
128 }
130# 2.2.3.6 VSS_MGMT_OBJECT_PROP Structure
131class VSS_MGMT_OBJECT_PROP(NDRSTRUCT):
132 structure = (
133 ('Type', VSS_MGMT_OBJECT_TYPE),
134 ('Obj', VSS_MGMT_OBJECT_UNION),
135 )
137################################################################################
138# RPC CALLS
139################################################################################
140# 3.1.3 IVssEnumMgmtObject Details
142# 3.1.3.1 Next (Opnum 3)
143class IVssEnumMgmtObject_Next(DCOMCALL):
144 opnum = 3
145 structure = (
146 ('celt', ULONG),
147 )
149class IVssEnumMgmtObject_NextResponse(DCOMANSWER):
150 structure = (
151 ('rgelt', VSS_MGMT_OBJECT_PROP),
152 ('pceltFetched', ULONG),
153 ('ErrorCode', error_status_t),
154 )
156# 3.1.2.1 Next (Opnum 3)
157class IVssEnumObject_Next(DCOMCALL):
158 opnum = 3
159 structure = (
160 ('celt', ULONG),
161 )
163class IVssEnumObject_NextResponse(DCOMANSWER):
164 structure = (
165 ('rgelt', VSS_MGMT_OBJECT_PROP),
166 ('pceltFetched', ULONG),
167 ('ErrorCode', error_status_t),
168 )
170class GetProviderMgmtInterface(DCOMCALL):
171 opnum = 3
172 structure = (
173 ('ProviderId', VSS_ID),
174 ('InterfaceId', VSS_ID),
175 )
177class GetProviderMgmtInterfaceResponse(DCOMANSWER):
178 structure = (
179 ('ppItf', PMInterfacePointer),
180 ('ErrorCode', error_status_t),
181 )
183class QueryVolumesSupportedForSnapshots(DCOMCALL):
184 opnum = 4
185 structure = (
186 ('ProviderId', VSS_ID),
187 ('IContext', LONG),
188 )
190class QueryVolumesSupportedForSnapshotsResponse(DCOMANSWER):
191 structure = (
192 ('ppEnum', PMInterfacePointer),
193 ('ErrorCode', error_status_t),
194 )
196class QuerySnapshotsByVolume(DCOMCALL):
197 opnum = 5
198 structure = (
199 ('pwszVolumeName', VSS_PWSZ),
200 ('ProviderId', VSS_ID),
201 )
203class QuerySnapshotsByVolumeResponse(DCOMANSWER):
204 structure = (
205 ('ppEnum', PMInterfacePointer),
206 ('ErrorCode', error_status_t),
207 )
209# 3.1.4.4.5 QueryDiffAreasForVolume (Opnum 6)
210class QueryDiffAreasForVolume(DCOMCALL):
211 opnum = 6
212 structure = (
213 ('pwszVolumeName', VSS_PWSZ),
214 )
216class QueryDiffAreasForVolumeResponse(DCOMANSWER):
217 structure = (
218 ('ppEnum', PMInterfacePointer),
219 ('ErrorCode', error_status_t),
220 )
222# 3.1.4.4.6 QueryDiffAreasOnVolume (Opnum 7)
223class QueryDiffAreasOnVolume(DCOMCALL):
224 opnum = 7
225 structure = (
226 ('pwszVolumeName', VSS_PWSZ),
227 )
229class QueryDiffAreasOnVolumeResponse(DCOMANSWER):
230 structure = (
231 ('ppEnum', PMInterfacePointer),
232 ('ErrorCode', error_status_t),
233 )
236################################################################################
237# OPNUMs and their corresponding structures
238################################################################################
239OPNUMS = {
240}
242################################################################################
243# HELPER FUNCTIONS AND INTERFACES
244################################################################################
245class IVssEnumMgmtObject(IRemUnknown2):
246 def __init__(self, interface):
247 IRemUnknown2.__init__(self, interface)
248 self._iid = IID_IVssEnumMgmtObject
250 def Next(self, celt):
251 request = IVssEnumMgmtObject_Next()
252 request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
253 request['ORPCthis']['flags'] = 0
254 request['celt'] = celt
255 resp = self.request(request, self._iid, uuid = self.get_iPid())
256 return resp
258class IVssEnumObject(IRemUnknown2):
259 def __init__(self, interface):
260 IRemUnknown2.__init__(self, interface)
261 self._iid = IID_IVssEnumObject
263 def Next(self, celt):
264 request = IVssEnumObject_Next()
265 request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
266 request['ORPCthis']['flags'] = 0
267 request['celt'] = celt
268 dce = self.connect()
269 resp = dce.request(request, self._iid, uuid = self.get_iPid())
270 return resp
272class IVssSnapshotMgmt(IRemUnknown2):
273 def __init__(self, interface):
274 IRemUnknown2.__init__(self, interface)
275 self._iid = IID_IVssSnapshotMgmt
277 def GetProviderMgmtInterface(self, providerId = IID_ShadowCopyProvider, interfaceId = IID_IVssDifferentialSoftwareSnapshotMgmt):
278 req = GetProviderMgmtInterface()
279 classInstance = self.get_cinstance()
280 req['ORPCthis'] = classInstance.get_ORPCthis()
281 req['ORPCthis']['flags'] = 0
282 req['ProviderId'] = providerId
283 req['InterfaceId'] = interfaceId
284 resp = self.request(req, self._iid, uuid = self.get_iPid())
285 return IVssDifferentialSoftwareSnapshotMgmt(INTERFACE(classInstance, ''.join(resp['ppItf']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
287 def QueryVolumesSupportedForSnapshots(self, providerId, iContext):
288 req = QueryVolumesSupportedForSnapshots()
289 classInstance = self.get_cinstance()
290 req['ORPCthis'] = classInstance.get_ORPCthis()
291 req['ORPCthis']['flags'] = 0
292 req['ProviderId'] = providerId
293 req['IContext'] = iContext
294 resp = self.request(req, self._iid, uuid = self.get_iPid())
295 return IVssEnumMgmtObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(),target = self.get_target()))
297 def QuerySnapshotsByVolume(self, volumeName, providerId = IID_ShadowCopyProvider):
298 req = QuerySnapshotsByVolume()
299 classInstance = self.get_cinstance()
300 req['ORPCthis'] = classInstance.get_ORPCthis()
301 req['ORPCthis']['flags'] = 0
302 req['pwszVolumeName'] = volumeName
303 req['ProviderId'] = providerId
304 try:
305 resp = self.request(req, self._iid, uuid = self.get_iPid())
306 except DCERPCException as e:
307 print(e)
308 from impacket.winregistry import hexdump
309 data = e.get_packet()
310 hexdump(data)
311 kk = QuerySnapshotsByVolumeResponse(data)
312 kk.dump()
313 #resp.dump()
314 return IVssEnumObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
316class IVssDifferentialSoftwareSnapshotMgmt(IRemUnknown2):
317 def __init__(self, interface):
318 IRemUnknown2.__init__(self, interface)
319 self._iid = IID_IVssDifferentialSoftwareSnapshotMgmt
321 def QueryDiffAreasOnVolume(self, pwszVolumeName):
322 req = QueryDiffAreasOnVolume()
323 classInstance = self.get_cinstance()
324 req['ORPCthis'] = classInstance.get_ORPCthis()
325 req['ORPCthis']['flags'] = 0
326 req['pwszVolumeName'] = pwszVolumeName
327 resp = self.request(req, self._iid, uuid = self.get_iPid())
328 return IVssEnumMgmtObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))
330 def QueryDiffAreasForVolume(self, pwszVolumeName):
331 req = QueryDiffAreasForVolume()
332 classInstance = self.get_cinstance()
333 req['ORPCthis'] = classInstance.get_ORPCthis()
334 req['ORPCthis']['flags'] = 0
335 req['pwszVolumeName'] = pwszVolumeName
336 resp = self.request(req, self._iid, uuid = self.get_iPid())
337 return IVssEnumMgmtObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))