Hide keyboard shortcuts

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-VDS]: Virtual Disk Service (VDS) Protocol 

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 NDRSTRUCT, NDRUniConformantVaryingArray, NDRENUM 

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

29from impacket.dcerpc.v5.dtypes import LPWSTR, ULONG, DWORD, SHORT, GUID 

30from impacket.dcerpc.v5.rpcrt import DCERPCException 

31from impacket.dcerpc.v5.enum import Enum 

32from impacket import hresult_errors 

33from impacket.uuid import string_to_bin 

34 

35class 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 'VDS SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 

44 else: 

45 return 'VDS SessionError: unknown error code: 0x%x' % (self.error_code) 

46 

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

48# CONSTANTS 

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

50# 1.9 Standards Assignments 

51CLSID_VirtualDiskService = string_to_bin('7D1933CB-86F6-4A98-8628-01BE94C9A575') 

52IID_IEnumVdsObject = string_to_bin('118610B7-8D94-4030-B5B8-500889788E4E') 

53IID_IVdsAdviseSink = string_to_bin('8326CD1D-CF59-4936-B786-5EFC08798E25') 

54IID_IVdsAsync = string_to_bin('D5D23B6D-5A55-4492-9889-397A3C2D2DBC') 

55IID_IVdsServiceInitialization = string_to_bin('4AFC3636-DB01-4052-80C3-03BBCB8D3C69') 

56IID_IVdsService = string_to_bin('0818A8EF-9BA9-40D8-A6F9-E22833CC771E') 

57IID_IVdsSwProvider = string_to_bin('9AA58360-CE33-4F92-B658-ED24B14425B8') 

58IID_IVdsProvider = string_to_bin('10C5E575-7984-4E81-A56B-431F5F92AE42') 

59 

60error_status_t = ULONG 

61 

62# 2.2.1.1.3 VDS_OBJECT_ID 

63VDS_OBJECT_ID = GUID 

64 

65################################################################################ 

66# STRUCTURES 

67################################################################################ 

68# 2.2.2.1.3.1 VDS_SERVICE_PROP 

69class VDS_SERVICE_PROP(NDRSTRUCT): 

70 structure = ( 

71 ('pwszVersion',LPWSTR), 

72 ('ulFlags',ULONG), 

73 ) 

74 

75class OBJECT_ARRAY(NDRUniConformantVaryingArray): 

76 item = PMInterfacePointer 

77 

78# 2.2.2.7.1.1 VDS_PROVIDER_TYPE 

79class VDS_PROVIDER_TYPE(NDRENUM): 

80 class enumItems(Enum): 

81 VDS_PT_UNKNOWN = 0 

82 VDS_PT_SOFTWARE = 1 

83 VDS_PT_HARDWARE = 2 

84 VDS_PT_VIRTUALDISK = 3 

85 VDS_PT_MAX = 4 

86 

87# 2.2.2.7.2.1 VDS_PROVIDER_PROP 

88class VDS_PROVIDER_PROP(NDRSTRUCT): 

89 structure = ( 

90 ('id',VDS_OBJECT_ID), 

91 ('pwszName',LPWSTR), 

92 ('guidVersionId',GUID), 

93 ('pwszVersion',LPWSTR), 

94 ('type',VDS_PROVIDER_TYPE), 

95 ('ulFlags',ULONG), 

96 ('ulStripeSizeFlags',ULONG), 

97 ('sRebuildPriority',SHORT), 

98 ) 

99 

100################################################################################ 

101# RPC CALLS 

102################################################################################ 

103 

104# 3.4.5.2.5.1 IVdsServiceInitialization::Initialize (Opnum 3) 

105class IVdsServiceInitialization_Initialize(DCOMCALL): 

106 opnum = 3 

107 structure = ( 

108 ('pwszMachineName', LPWSTR), 

109 ) 

110 

111class IVdsServiceInitialization_InitializeResponse(DCOMANSWER): 

112 structure = ( 

113 ('ErrorCode', error_status_t), 

114 ) 

115 

116# 3.4.5.2.4.1 IVdsService::IsServiceReady (Opnum 3) 

117class IVdsService_IsServiceReady(DCOMCALL): 

118 opnum = 3 

119 structure = ( 

120 ) 

121 

122class IVdsService_IsServiceReadyResponse(DCOMANSWER): 

123 structure = ( 

124 ('ErrorCode', error_status_t), 

125 ) 

126 

127# 3.4.5.2.4.2 IVdsService::WaitForServiceReady (Opnum 4) 

128class IVdsService_WaitForServiceReady(DCOMCALL): 

129 opnum = 4 

130 structure = ( 

131 ) 

132 

133class IVdsService_WaitForServiceReadyResponse(DCOMANSWER): 

134 structure = ( 

135 ('ErrorCode', error_status_t), 

136 ) 

137 

138# 3.4.5.2.4.3 IVdsService::GetProperties (Opnum 5) 

139class IVdsService_GetProperties(DCOMCALL): 

140 opnum = 5 

141 structure = ( 

142 ) 

143 

144class IVdsService_GetPropertiesResponse(DCOMANSWER): 

145 structure = ( 

146 ('pServiceProp', VDS_SERVICE_PROP), 

147 ('ErrorCode', error_status_t), 

148 ) 

149 

150# 3.4.5.2.4.4 IVdsService::QueryProviders (Opnum 6) 

151class IVdsService_QueryProviders(DCOMCALL): 

152 opnum = 6 

153 structure = ( 

154 ('masks', DWORD), 

155 ) 

156 

157class IVdsService_QueryProvidersResponse(DCOMANSWER): 

158 structure = ( 

159 ('ppEnum', PMInterfacePointer), 

160 ('ErrorCode', error_status_t), 

161 ) 

162 

163# 3.1.1.1 IEnumVdsObject Interface 

164# 3.4.5.2.1.1 IEnumVdsObject::Next (Opnum 3) 

165class IEnumVdsObject_Next(DCOMCALL): 

166 opnum = 3 

167 structure = ( 

168 ('celt', ULONG), 

169 ) 

170 

171class IEnumVdsObject_NextResponse(DCOMANSWER): 

172 structure = ( 

173 ('ppObjectArray', OBJECT_ARRAY), 

174 ('pcFetched', ULONG), 

175 ('ErrorCode', error_status_t), 

176 ) 

177# 3.4.5.2.14.1 IVdsProvider::GetProperties (Opnum 3) 

178class IVdsProvider_GetProperties(DCOMCALL): 

179 opnum = 3 

180 structure = ( 

181 ) 

182 

183class IVdsProvider_GetPropertiesResponse(DCOMANSWER): 

184 structure = ( 

185 ('pProviderProp', VDS_PROVIDER_PROP), 

186 ('ErrorCode', error_status_t), 

187 ) 

188 

189################################################################################ 

190# OPNUMs and their corresponding structures 

191################################################################################ 

192OPNUMS = { 

193} 

194 

195################################################################################ 

196# HELPER FUNCTIONS AND INTERFACES 

197################################################################################ 

198class IEnumVdsObject(IRemUnknown2): 

199 def Next(self, celt=0xffff): 

200 request = IEnumVdsObject_Next() 

201 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

202 request['ORPCthis']['flags'] = 0 

203 request['celt'] = celt 

204 try: 

205 resp = self.request(request, uuid = self.get_iPid()) 

206 except Exception as e: 

207 resp = e.get_packet() 

208 # If it is S_FALSE(1) means less items were returned 

209 if resp['ErrorCode'] != 1: 

210 raise 

211 interfaces = list() 

212 for interface in resp['ppObjectArray']: 

213 interfaces.append(IRemUnknown2(INTERFACE(self.get_cinstance(), ''.join(interface['abData']), self.get_ipidRemUnknown(), target = self.get_target()))) 

214 return interfaces 

215 

216class IVdsProvider(IRemUnknown2): 

217 def GetProperties(self): 

218 request = IVdsProvider_GetProperties() 

219 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

220 request['ORPCthis']['flags'] = 0 

221 resp = self.request(request, uuid = self.get_iPid()) 

222 return resp 

223 

224class IVdsServiceInitialization(IRemUnknown2): 

225 def __init__(self, interface): 

226 IRemUnknown2.__init__(self, interface) 

227 

228 def Initialize(self): 

229 request = IVdsServiceInitialization_Initialize() 

230 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

231 request['ORPCthis']['flags'] = 0 

232 request['pwszMachineName'] = '\x00' 

233 resp = self.request(request, uuid = self.get_iPid()) 

234 return resp 

235 

236class IVdsService(IRemUnknown2): 

237 def __init__(self, interface): 

238 IRemUnknown2.__init__(self, interface) 

239 

240 def IsServiceReady(self): 

241 request = IVdsService_IsServiceReady() 

242 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

243 request['ORPCthis']['flags'] = 0 

244 try: 

245 resp = self.request(request, uuid = self.get_iPid()) 

246 except Exception as e: 

247 resp = e.get_packet() 

248 return resp 

249 

250 def WaitForServiceReady(self): 

251 request = IVdsService_WaitForServiceReady() 

252 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

253 request['ORPCthis']['flags'] = 0 

254 resp = self.request(request, uuid = self.get_iPid()) 

255 return resp 

256 

257 def GetProperties(self): 

258 request = IVdsService_GetProperties() 

259 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

260 request['ORPCthis']['flags'] = 0 

261 resp = self.request(request, uuid = self.get_iPid()) 

262 return resp 

263 

264 def QueryProviders(self, masks): 

265 request = IVdsService_QueryProviders() 

266 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

267 request['ORPCthis']['flags'] = 0 

268 request['masks'] = masks 

269 resp = self.request(request, uuid = self.get_iPid()) 

270 return IEnumVdsObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))