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# 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#

25 from __future__ import division

26 from __future__ import print_function

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

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

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

30 from impacket.dcerpc.v5.enum import Enum

31 from impacket.dcerpc.v5.rpcrt import DCERPCException

32 from impacket import hresult_errors

33 from impacket.uuid import string_to_bin

34

35 class DCERPCSessionError(DCERPCException):

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

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

38

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

46

47################################################################################

48# CONSTANTS

49################################################################################

50# 1.9 Standards Assignments

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

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

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

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

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

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

57

58# 2.2.1.1 VSS_ID

59 class VSS_ID(NDRSTRUCT):

60 structure = (

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

62 )

63

64 def getAlignment(self):

65 return 2

66

67#2.2.1.2 VSS_PWSZ

68 VSS_PWSZ = WSTR

69

70# 2.2.1.3 VSS_TIMESTAMP

71 VSS_TIMESTAMP = LONGLONG

72

73 error_status_t = LONG

74################################################################################

75# STRUCTURES

76################################################################################

77# 2.2.2.1 VSS_OBJECT_TYPE Enumeration

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

86

87# 2.2.2.2 VSS_MGMT_OBJECT_TYPE Enumeration

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

94

95# 2.2.2.3 VSS_VOLUME_SNAPSHOT_ATTRIBUTES Enumeration

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

103

104# 2.2.2.4 VSS_SNAPSHOT_STATE Enumeration

105 class VSS_SNAPSHOT_STATE(NDRENUM):

106 class enumItems(Enum):

107 VSS_SS_UNKNOWN = 0x01

108 VSS_SS_CREATED = 0x0c

109

110# 2.2.2.5 VSS_PROVIDER_TYPE Enumeration

111 class VSS_PROVIDER_TYPE(NDRENUM):

112 class enumItems(Enum):

113 VSS_PROV_UNKNOWN = 0

114

115# 2.2.3.7 VSS_VOLUME_PROP Structure

116 class VSS_VOLUME_PROP(NDRSTRUCT):

117 structure = (

118 ('m_pwszVolumeName', VSS_PWSZ),

119 ('m_pwszVolumeDisplayName', VSS_PWSZ),

120 )

121

122# 2.2.3.5 VSS_MGMT_OBJECT_UNION Union

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

132

133# 2.2.3.6 VSS_MGMT_OBJECT_PROP Structure

134 class VSS_MGMT_OBJECT_PROP(NDRSTRUCT):

135 structure = (

136 ('Type', VSS_MGMT_OBJECT_TYPE),

137 ('Obj', VSS_MGMT_OBJECT_UNION),

138 )

139

140################################################################################

141# RPC CALLS

142################################################################################

143# 3.1.3 IVssEnumMgmtObject Details

144

145# 3.1.3.1 Next (Opnum 3)

146 class IVssEnumMgmtObject_Next(DCOMCALL):

147 opnum = 3

148 structure = (

149 ('celt', ULONG),

150 )

151

152 class IVssEnumMgmtObject_NextResponse(DCOMANSWER):

153 structure = (

154 ('rgelt', VSS_MGMT_OBJECT_PROP),

155 ('pceltFetched', ULONG),

156 ('ErrorCode', error_status_t),

157 )

158

159# 3.1.2.1 Next (Opnum 3)

160 class IVssEnumObject_Next(DCOMCALL):

161 opnum = 3

162 structure = (

163 ('celt', ULONG),

164 )

165

166 class IVssEnumObject_NextResponse(DCOMANSWER):

167 structure = (

168 ('rgelt', VSS_MGMT_OBJECT_PROP),

169 ('pceltFetched', ULONG),

170 ('ErrorCode', error_status_t),

171 )

172

173 class GetProviderMgmtInterface(DCOMCALL):

174 opnum = 3

175 structure = (

176 ('ProviderId', VSS_ID),

177 ('InterfaceId', VSS_ID),

178 )

179

180 class GetProviderMgmtInterfaceResponse(DCOMANSWER):

181 structure = (

182 ('ppItf', PMInterfacePointer),

183 ('ErrorCode', error_status_t),

184 )

185

186 class QueryVolumesSupportedForSnapshots(DCOMCALL):

187 opnum = 4

188 structure = (

189 ('ProviderId', VSS_ID),

190 ('IContext', LONG),

191 )

192

193 class QueryVolumesSupportedForSnapshotsResponse(DCOMANSWER):

194 structure = (

195 ('ppEnum', PMInterfacePointer),

196 ('ErrorCode', error_status_t),

197 )

198

199 class QuerySnapshotsByVolume(DCOMCALL):

200 opnum = 5

201 structure = (

202 ('pwszVolumeName', VSS_PWSZ),

203 ('ProviderId', VSS_ID),

204 )

205

206 class QuerySnapshotsByVolumeResponse(DCOMANSWER):

207 structure = (

208 ('ppEnum', PMInterfacePointer),

209 ('ErrorCode', error_status_t),

210 )

211

212# 3.1.4.4.5 QueryDiffAreasForVolume (Opnum 6)

213 class QueryDiffAreasForVolume(DCOMCALL):

214 opnum = 6

215 structure = (

216 ('pwszVolumeName', VSS_PWSZ),

217 )

218

219 class QueryDiffAreasForVolumeResponse(DCOMANSWER):

220 structure = (

221 ('ppEnum', PMInterfacePointer),

222 ('ErrorCode', error_status_t),

223 )

224

225# 3.1.4.4.6 QueryDiffAreasOnVolume (Opnum 7)

226 class QueryDiffAreasOnVolume(DCOMCALL):

227 opnum = 7

228 structure = (

229 ('pwszVolumeName', VSS_PWSZ),

230 )

231

232 class QueryDiffAreasOnVolumeResponse(DCOMANSWER):

233 structure = (

234 ('ppEnum', PMInterfacePointer),

235 ('ErrorCode', error_status_t),

236 )

237

238

239################################################################################

240# OPNUMs and their corresponding structures

241################################################################################

242 OPNUMS = {

243}

244

245################################################################################

246# HELPER FUNCTIONS AND INTERFACES

247################################################################################

248 class IVssEnumMgmtObject(IRemUnknown2):

249 def __init__(self, interface):

250 IRemUnknown2.__init__(self, interface)

251 self._iid = IID_IVssEnumMgmtObject

252

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

260

261 class IVssEnumObject(IRemUnknown2):

262 def __init__(self, interface):

263 IRemUnknown2.__init__(self, interface)

264 self._iid = IID_IVssEnumObject

265

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

274

275 class IVssSnapshotMgmt(IRemUnknown2):

276 def __init__(self, interface):

277 IRemUnknown2.__init__(self, interface)

278 self._iid = IID_IVssSnapshotMgmt

279

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

289

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

299

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

318

319 class IVssDifferentialSoftwareSnapshotMgmt(IRemUnknown2):

320 def __init__(self, interface):

321 IRemUnknown2.__init__(self, interface)

322 self._iid = IID_IVssDifferentialSoftwareSnapshotMgmt

323

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

332

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