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

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

## 184 statements

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#

22 from __future__ import division

23 from __future__ import print_function

24 from impacket.dcerpc.v5.ndr import NDRENUM, NDRSTRUCT, NDRUNION

25 from impacket.dcerpc.v5.dcomrt import PMInterfacePointer, INTERFACE, DCOMCALL, DCOMANSWER, IRemUnknown2

26 from impacket.dcerpc.v5.dtypes import LONG, LONGLONG, ULONG, WSTR

27 from impacket.dcerpc.v5.enum import Enum

28 from impacket.dcerpc.v5.rpcrt import DCERPCException

29 from impacket import hresult_errors

30 from impacket.uuid import string_to_bin

31

32 class DCERPCSessionError(DCERPCException):

33 def __init__(self, error_string=None, error_code=None, packet=None):

34 DCERPCException.__init__(self, error_string, error_code, packet)

35

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

43

44################################################################################

45# CONSTANTS

46################################################################################

47# 1.9 Standards Assignments

48 CLSID_ShadowCopyProvider = string_to_bin('0b5a2c52-3eb9-470a-96e2-6c6d4570e40f')

49 IID_IVssSnapshotMgmt = string_to_bin('FA7DF749-66E7-4986-A27F-E2F04AE53772')

50 IID_IVssEnumObject = string_to_bin('AE1C7110-2F60-11d3-8A39-00C04F72D8E3')

51 IID_IVssDifferentialSoftwareSnapshotMgmt = string_to_bin('214A0F28-B737-4026-B847-4F9E37D79529')

52 IID_IVssEnumMgmtObject = string_to_bin('01954E6B-9254-4e6e-808C-C9E05D007696')

53 IID_ShadowCopyProvider = string_to_bin('B5946137-7B9F-4925-AF80-51ABD60B20D5')

54

55# 2.2.1.1 VSS_ID

56 class VSS_ID(NDRSTRUCT):

57 structure = (

58 ('Data','16s=b""'),

59 )

60

61 def getAlignment(self):

62 return 2

63

64#2.2.1.2 VSS_PWSZ

65 VSS_PWSZ = WSTR

66

67# 2.2.1.3 VSS_TIMESTAMP

68 VSS_TIMESTAMP = LONGLONG

69

70 error_status_t = LONG

71################################################################################

72# STRUCTURES

73################################################################################

74# 2.2.2.1 VSS_OBJECT_TYPE Enumeration

75 class 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

83

84# 2.2.2.2 VSS_MGMT_OBJECT_TYPE Enumeration

85 class 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

91

92# 2.2.2.3 VSS_VOLUME_SNAPSHOT_ATTRIBUTES Enumeration

93 class 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

100

101# 2.2.2.4 VSS_SNAPSHOT_STATE Enumeration

102 class VSS_SNAPSHOT_STATE(NDRENUM):

103 class enumItems(Enum):

104 VSS_SS_UNKNOWN = 0x01

105 VSS_SS_CREATED = 0x0c

106

107# 2.2.2.5 VSS_PROVIDER_TYPE Enumeration

108 class VSS_PROVIDER_TYPE(NDRENUM):

109 class enumItems(Enum):

110 VSS_PROV_UNKNOWN = 0

111

112# 2.2.3.7 VSS_VOLUME_PROP Structure

113 class VSS_VOLUME_PROP(NDRSTRUCT):

114 structure = (

115 ('m_pwszVolumeName', VSS_PWSZ),

116 ('m_pwszVolumeDisplayName', VSS_PWSZ),

117 )

118

119# 2.2.3.5 VSS_MGMT_OBJECT_UNION Union

120 class 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 }

129

130# 2.2.3.6 VSS_MGMT_OBJECT_PROP Structure

131 class VSS_MGMT_OBJECT_PROP(NDRSTRUCT):

132 structure = (

133 ('Type', VSS_MGMT_OBJECT_TYPE),

134 ('Obj', VSS_MGMT_OBJECT_UNION),

135 )

136

137################################################################################

138# RPC CALLS

139################################################################################

140# 3.1.3 IVssEnumMgmtObject Details

141

142# 3.1.3.1 Next (Opnum 3)

143 class IVssEnumMgmtObject_Next(DCOMCALL):

144 opnum = 3

145 structure = (

146 ('celt', ULONG),

147 )

148

149 class IVssEnumMgmtObject_NextResponse(DCOMANSWER):

150 structure = (

151 ('rgelt', VSS_MGMT_OBJECT_PROP),

152 ('pceltFetched', ULONG),

153 ('ErrorCode', error_status_t),

154 )

155

156# 3.1.2.1 Next (Opnum 3)

157 class IVssEnumObject_Next(DCOMCALL):

158 opnum = 3

159 structure = (

160 ('celt', ULONG),

161 )

162

163 class IVssEnumObject_NextResponse(DCOMANSWER):

164 structure = (

165 ('rgelt', VSS_MGMT_OBJECT_PROP),

166 ('pceltFetched', ULONG),

167 ('ErrorCode', error_status_t),

168 )

169

170 class GetProviderMgmtInterface(DCOMCALL):

171 opnum = 3

172 structure = (

173 ('ProviderId', VSS_ID),

174 ('InterfaceId', VSS_ID),

175 )

176

177 class GetProviderMgmtInterfaceResponse(DCOMANSWER):

178 structure = (

179 ('ppItf', PMInterfacePointer),

180 ('ErrorCode', error_status_t),

181 )

182

183 class QueryVolumesSupportedForSnapshots(DCOMCALL):

184 opnum = 4

185 structure = (

186 ('ProviderId', VSS_ID),

187 ('IContext', LONG),

188 )

189

190 class QueryVolumesSupportedForSnapshotsResponse(DCOMANSWER):

191 structure = (

192 ('ppEnum', PMInterfacePointer),

193 ('ErrorCode', error_status_t),

194 )

195

196 class QuerySnapshotsByVolume(DCOMCALL):

197 opnum = 5

198 structure = (

199 ('pwszVolumeName', VSS_PWSZ),

200 ('ProviderId', VSS_ID),

201 )

202

203 class QuerySnapshotsByVolumeResponse(DCOMANSWER):

204 structure = (

205 ('ppEnum', PMInterfacePointer),

206 ('ErrorCode', error_status_t),

207 )

208

209# 3.1.4.4.5 QueryDiffAreasForVolume (Opnum 6)

210 class QueryDiffAreasForVolume(DCOMCALL):

211 opnum = 6

212 structure = (

213 ('pwszVolumeName', VSS_PWSZ),

214 )

215

216 class QueryDiffAreasForVolumeResponse(DCOMANSWER):

217 structure = (

218 ('ppEnum', PMInterfacePointer),

219 ('ErrorCode', error_status_t),

220 )

221

222# 3.1.4.4.6 QueryDiffAreasOnVolume (Opnum 7)

223 class QueryDiffAreasOnVolume(DCOMCALL):

224 opnum = 7

225 structure = (

226 ('pwszVolumeName', VSS_PWSZ),

227 )

228

229 class QueryDiffAreasOnVolumeResponse(DCOMANSWER):

230 structure = (

231 ('ppEnum', PMInterfacePointer),

232 ('ErrorCode', error_status_t),

233 )

234

235

236################################################################################

237# OPNUMs and their corresponding structures

238################################################################################

239 OPNUMS = {

240}

241

242################################################################################

243# HELPER FUNCTIONS AND INTERFACES

244################################################################################

245 class IVssEnumMgmtObject(IRemUnknown2):

246 def __init__(self, interface):

247 IRemUnknown2.__init__(self, interface)

248 self._iid = IID_IVssEnumMgmtObject

249

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

257

258 class IVssEnumObject(IRemUnknown2):

259 def __init__(self, interface):

260 IRemUnknown2.__init__(self, interface)

261 self._iid = IID_IVssEnumObject

262

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

271

272 class IVssSnapshotMgmt(IRemUnknown2):

273 def __init__(self, interface):

274 IRemUnknown2.__init__(self, interface)

275 self._iid = IID_IVssSnapshotMgmt

276

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()))

286

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()))

296

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()))

315

316 class IVssDifferentialSoftwareSnapshotMgmt(IRemUnknown2):

317 def __init__(self, interface):

318 IRemUnknown2.__init__(self, interface)

319 self._iid = IID_IVssDifferentialSoftwareSnapshotMgmt

320

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()))

329

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()))