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

22from __future__ import division 

23from __future__ import print_function 

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

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

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

27from impacket.dcerpc.v5.rpcrt import DCERPCException 

28from impacket.dcerpc.v5.enum import Enum 

29from impacket import hresult_errors 

30from impacket.uuid import string_to_bin 

31 

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

41 else: 

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

43 

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

45# CONSTANTS 

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

47# 1.9 Standards Assignments 

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

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

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

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

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

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

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

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

56 

57error_status_t = ULONG 

58 

59# 2.2.1.1.3 VDS_OBJECT_ID 

60VDS_OBJECT_ID = GUID 

61 

62################################################################################ 

63# STRUCTURES 

64################################################################################ 

65# 2.2.2.1.3.1 VDS_SERVICE_PROP 

66class VDS_SERVICE_PROP(NDRSTRUCT): 

67 structure = ( 

68 ('pwszVersion',LPWSTR), 

69 ('ulFlags',ULONG), 

70 ) 

71 

72class OBJECT_ARRAY(NDRUniConformantVaryingArray): 

73 item = PMInterfacePointer 

74 

75# 2.2.2.7.1.1 VDS_PROVIDER_TYPE 

76class VDS_PROVIDER_TYPE(NDRENUM): 

77 class enumItems(Enum): 

78 VDS_PT_UNKNOWN = 0 

79 VDS_PT_SOFTWARE = 1 

80 VDS_PT_HARDWARE = 2 

81 VDS_PT_VIRTUALDISK = 3 

82 VDS_PT_MAX = 4 

83 

84# 2.2.2.7.2.1 VDS_PROVIDER_PROP 

85class VDS_PROVIDER_PROP(NDRSTRUCT): 

86 structure = ( 

87 ('id',VDS_OBJECT_ID), 

88 ('pwszName',LPWSTR), 

89 ('guidVersionId',GUID), 

90 ('pwszVersion',LPWSTR), 

91 ('type',VDS_PROVIDER_TYPE), 

92 ('ulFlags',ULONG), 

93 ('ulStripeSizeFlags',ULONG), 

94 ('sRebuildPriority',SHORT), 

95 ) 

96 

97################################################################################ 

98# RPC CALLS 

99################################################################################ 

100 

101# 3.4.5.2.5.1 IVdsServiceInitialization::Initialize (Opnum 3) 

102class IVdsServiceInitialization_Initialize(DCOMCALL): 

103 opnum = 3 

104 structure = ( 

105 ('pwszMachineName', LPWSTR), 

106 ) 

107 

108class IVdsServiceInitialization_InitializeResponse(DCOMANSWER): 

109 structure = ( 

110 ('ErrorCode', error_status_t), 

111 ) 

112 

113# 3.4.5.2.4.1 IVdsService::IsServiceReady (Opnum 3) 

114class IVdsService_IsServiceReady(DCOMCALL): 

115 opnum = 3 

116 structure = ( 

117 ) 

118 

119class IVdsService_IsServiceReadyResponse(DCOMANSWER): 

120 structure = ( 

121 ('ErrorCode', error_status_t), 

122 ) 

123 

124# 3.4.5.2.4.2 IVdsService::WaitForServiceReady (Opnum 4) 

125class IVdsService_WaitForServiceReady(DCOMCALL): 

126 opnum = 4 

127 structure = ( 

128 ) 

129 

130class IVdsService_WaitForServiceReadyResponse(DCOMANSWER): 

131 structure = ( 

132 ('ErrorCode', error_status_t), 

133 ) 

134 

135# 3.4.5.2.4.3 IVdsService::GetProperties (Opnum 5) 

136class IVdsService_GetProperties(DCOMCALL): 

137 opnum = 5 

138 structure = ( 

139 ) 

140 

141class IVdsService_GetPropertiesResponse(DCOMANSWER): 

142 structure = ( 

143 ('pServiceProp', VDS_SERVICE_PROP), 

144 ('ErrorCode', error_status_t), 

145 ) 

146 

147# 3.4.5.2.4.4 IVdsService::QueryProviders (Opnum 6) 

148class IVdsService_QueryProviders(DCOMCALL): 

149 opnum = 6 

150 structure = ( 

151 ('masks', DWORD), 

152 ) 

153 

154class IVdsService_QueryProvidersResponse(DCOMANSWER): 

155 structure = ( 

156 ('ppEnum', PMInterfacePointer), 

157 ('ErrorCode', error_status_t), 

158 ) 

159 

160# 3.1.1.1 IEnumVdsObject Interface 

161# 3.4.5.2.1.1 IEnumVdsObject::Next (Opnum 3) 

162class IEnumVdsObject_Next(DCOMCALL): 

163 opnum = 3 

164 structure = ( 

165 ('celt', ULONG), 

166 ) 

167 

168class IEnumVdsObject_NextResponse(DCOMANSWER): 

169 structure = ( 

170 ('ppObjectArray', OBJECT_ARRAY), 

171 ('pcFetched', ULONG), 

172 ('ErrorCode', error_status_t), 

173 ) 

174# 3.4.5.2.14.1 IVdsProvider::GetProperties (Opnum 3) 

175class IVdsProvider_GetProperties(DCOMCALL): 

176 opnum = 3 

177 structure = ( 

178 ) 

179 

180class IVdsProvider_GetPropertiesResponse(DCOMANSWER): 

181 structure = ( 

182 ('pProviderProp', VDS_PROVIDER_PROP), 

183 ('ErrorCode', error_status_t), 

184 ) 

185 

186################################################################################ 

187# OPNUMs and their corresponding structures 

188################################################################################ 

189OPNUMS = { 

190} 

191 

192################################################################################ 

193# HELPER FUNCTIONS AND INTERFACES 

194################################################################################ 

195class IEnumVdsObject(IRemUnknown2): 

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

197 request = IEnumVdsObject_Next() 

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

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

200 request['celt'] = celt 

201 try: 

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

203 except Exception as e: 

204 resp = e.get_packet() 

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

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

207 raise 

208 interfaces = list() 

209 for interface in resp['ppObjectArray']: 

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

211 return interfaces 

212 

213class IVdsProvider(IRemUnknown2): 

214 def GetProperties(self): 

215 request = IVdsProvider_GetProperties() 

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

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

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

219 return resp 

220 

221class IVdsServiceInitialization(IRemUnknown2): 

222 def __init__(self, interface): 

223 IRemUnknown2.__init__(self, interface) 

224 

225 def Initialize(self): 

226 request = IVdsServiceInitialization_Initialize() 

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

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

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

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

231 return resp 

232 

233class IVdsService(IRemUnknown2): 

234 def __init__(self, interface): 

235 IRemUnknown2.__init__(self, interface) 

236 

237 def IsServiceReady(self): 

238 request = IVdsService_IsServiceReady() 

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

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

241 try: 

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

243 except Exception as e: 

244 resp = e.get_packet() 

245 return resp 

246 

247 def WaitForServiceReady(self): 

248 request = IVdsService_WaitForServiceReady() 

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

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

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

252 return resp 

253 

254 def GetProperties(self): 

255 request = IVdsService_GetProperties() 

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

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

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

259 return resp 

260 

261 def QueryProviders(self, masks): 

262 request = IVdsService_QueryProviders() 

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

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

265 request['masks'] = masks 

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

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