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-LSAT] Interface implementation 

11# 

12# Best way to learn how to use these calls is to grab the protocol standard 

13# so you understand what the call does, and then read the test case located 

14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC 

15# 

16# Some calls have helper functions, which makes it even easier to use. 

17# They are located at the end of this file. 

18# Helper functions start with "h"<name of the call>. 

19# There are test cases for them too. 

20# 

21# Author: 

22# Alberto Solino (@agsolino) 

23# 

24from impacket import nt_errors 

25from impacket.dcerpc.v5.dtypes import ULONG, LONG, PRPC_SID, RPC_UNICODE_STRING, LPWSTR, PRPC_UNICODE_STRING, NTSTATUS, \ 

26 NULL 

27from impacket.dcerpc.v5.enum import Enum 

28from impacket.dcerpc.v5.lsad import LSAPR_HANDLE, PLSAPR_TRUST_INFORMATION_ARRAY 

29from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRENUM, NDRPOINTER, NDRUniConformantArray 

30from impacket.dcerpc.v5.rpcrt import DCERPCException 

31from impacket.dcerpc.v5.samr import SID_NAME_USE 

32from impacket.uuid import uuidtup_to_bin 

33 

34MSRPC_UUID_LSAT = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AB','0.0')) 

35 

36class DCERPCSessionError(DCERPCException): 

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

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

39 

40 def __str__( self ): 

41 key = self.error_code 

42 if key in nt_errors.ERROR_MESSAGES: 42 ↛ 47line 42 didn't jump to line 47, because the condition on line 42 was never false

43 error_msg_short = nt_errors.ERROR_MESSAGES[key][0] 

44 error_msg_verbose = nt_errors.ERROR_MESSAGES[key][1] 

45 return 'LSAT SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 

46 else: 

47 return 'LSAT SessionError: unknown error code: 0x%x' % self.error_code 

48 

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

50# CONSTANTS 

51################################################################################ 

52# 2.2.10 ACCESS_MASK 

53POLICY_LOOKUP_NAMES = 0x00000800 

54 

55################################################################################ 

56# STRUCTURES 

57################################################################################ 

58# 2.2.12 LSAPR_REFERENCED_DOMAIN_LIST 

59class LSAPR_REFERENCED_DOMAIN_LIST(NDRSTRUCT): 

60 structure = ( 

61 ('Entries', ULONG), 

62 ('Domains', PLSAPR_TRUST_INFORMATION_ARRAY), 

63 ('MaxEntries', ULONG), 

64 ) 

65 

66class PLSAPR_REFERENCED_DOMAIN_LIST(NDRPOINTER): 

67 referent = ( 

68 ('Data', LSAPR_REFERENCED_DOMAIN_LIST), 

69 ) 

70 

71# 2.2.14 LSA_TRANSLATED_SID 

72class LSA_TRANSLATED_SID(NDRSTRUCT): 

73 structure = ( 

74 ('Use', SID_NAME_USE), 

75 ('RelativeId', ULONG), 

76 ('DomainIndex', LONG), 

77 ) 

78 

79# 2.2.15 LSAPR_TRANSLATED_SIDS 

80class LSA_TRANSLATED_SID_ARRAY(NDRUniConformantArray): 

81 item = LSA_TRANSLATED_SID 

82 

83class PLSA_TRANSLATED_SID_ARRAY(NDRPOINTER): 

84 referent = ( 

85 ('Data', LSA_TRANSLATED_SID_ARRAY), 

86 ) 

87 

88class LSAPR_TRANSLATED_SIDS(NDRSTRUCT): 

89 structure = ( 

90 ('Entries', ULONG), 

91 ('Sids', PLSA_TRANSLATED_SID_ARRAY), 

92 ) 

93 

94# 2.2.16 LSAP_LOOKUP_LEVEL 

95class LSAP_LOOKUP_LEVEL(NDRENUM): 

96 class enumItems(Enum): 

97 LsapLookupWksta = 1 

98 LsapLookupPDC = 2 

99 LsapLookupTDL = 3 

100 LsapLookupGC = 4 

101 LsapLookupXForestReferral = 5 

102 LsapLookupXForestResolve = 6 

103 LsapLookupRODCReferralToFullDC = 7 

104 

105# 2.2.17 LSAPR_SID_INFORMATION 

106class LSAPR_SID_INFORMATION(NDRSTRUCT): 

107 structure = ( 

108 ('Sid', PRPC_SID), 

109 ) 

110 

111# 2.2.18 LSAPR_SID_ENUM_BUFFER 

112class LSAPR_SID_INFORMATION_ARRAY(NDRUniConformantArray): 

113 item = LSAPR_SID_INFORMATION 

114 

115class PLSAPR_SID_INFORMATION_ARRAY(NDRPOINTER): 

116 referent = ( 

117 ('Data', LSAPR_SID_INFORMATION_ARRAY), 

118 ) 

119 

120class LSAPR_SID_ENUM_BUFFER(NDRSTRUCT): 

121 structure = ( 

122 ('Entries', ULONG), 

123 ('SidInfo', PLSAPR_SID_INFORMATION_ARRAY), 

124 ) 

125 

126# 2.2.19 LSAPR_TRANSLATED_NAME 

127class LSAPR_TRANSLATED_NAME(NDRSTRUCT): 

128 structure = ( 

129 ('Use', SID_NAME_USE), 

130 ('Name', RPC_UNICODE_STRING), 

131 ('DomainIndex', LONG), 

132 ) 

133 

134# 2.2.20 LSAPR_TRANSLATED_NAMES 

135class LSAPR_TRANSLATED_NAME_ARRAY(NDRUniConformantArray): 

136 item = LSAPR_TRANSLATED_NAME 

137 

138class PLSAPR_TRANSLATED_NAME_ARRAY(NDRPOINTER): 

139 referent = ( 

140 ('Data', LSAPR_TRANSLATED_NAME_ARRAY), 

141 ) 

142 

143class LSAPR_TRANSLATED_NAMES(NDRSTRUCT): 

144 structure = ( 

145 ('Entries', ULONG), 

146 ('Names', PLSAPR_TRANSLATED_NAME_ARRAY), 

147 ) 

148 

149# 2.2.21 LSAPR_TRANSLATED_NAME_EX 

150class LSAPR_TRANSLATED_NAME_EX(NDRSTRUCT): 

151 structure = ( 

152 ('Use', SID_NAME_USE), 

153 ('Name', RPC_UNICODE_STRING), 

154 ('DomainIndex', LONG), 

155 ('Flags', ULONG), 

156 ) 

157 

158# 2.2.22 LSAPR_TRANSLATED_NAMES_EX 

159class LSAPR_TRANSLATED_NAME_EX_ARRAY(NDRUniConformantArray): 

160 item = LSAPR_TRANSLATED_NAME_EX 

161 

162class PLSAPR_TRANSLATED_NAME_EX_ARRAY(NDRPOINTER): 

163 referent = ( 

164 ('Data', LSAPR_TRANSLATED_NAME_EX_ARRAY), 

165 ) 

166 

167class LSAPR_TRANSLATED_NAMES_EX(NDRSTRUCT): 

168 structure = ( 

169 ('Entries', ULONG), 

170 ('Names', PLSAPR_TRANSLATED_NAME_EX_ARRAY), 

171 ) 

172 

173# 2.2.23 LSAPR_TRANSLATED_SID_EX 

174class LSAPR_TRANSLATED_SID_EX(NDRSTRUCT): 

175 structure = ( 

176 ('Use', SID_NAME_USE), 

177 ('RelativeId', ULONG), 

178 ('DomainIndex', LONG), 

179 ('Flags', ULONG), 

180 ) 

181 

182# 2.2.24 LSAPR_TRANSLATED_SIDS_EX 

183class LSAPR_TRANSLATED_SID_EX_ARRAY(NDRUniConformantArray): 

184 item = LSAPR_TRANSLATED_SID_EX 

185 

186class PLSAPR_TRANSLATED_SID_EX_ARRAY(NDRPOINTER): 

187 referent = ( 

188 ('Data', LSAPR_TRANSLATED_SID_EX_ARRAY), 

189 ) 

190 

191class LSAPR_TRANSLATED_SIDS_EX(NDRSTRUCT): 

192 structure = ( 

193 ('Entries', ULONG), 

194 ('Sids', PLSAPR_TRANSLATED_SID_EX_ARRAY), 

195 ) 

196 

197# 2.2.25 LSAPR_TRANSLATED_SID_EX2 

198class LSAPR_TRANSLATED_SID_EX2(NDRSTRUCT): 

199 structure = ( 

200 ('Use', SID_NAME_USE), 

201 ('Sid', PRPC_SID), 

202 ('DomainIndex', LONG), 

203 ('Flags', ULONG), 

204 ) 

205 

206# 2.2.26 LSAPR_TRANSLATED_SIDS_EX2 

207class LSAPR_TRANSLATED_SID_EX2_ARRAY(NDRUniConformantArray): 

208 item = LSAPR_TRANSLATED_SID_EX2 

209 

210class PLSAPR_TRANSLATED_SID_EX2_ARRAY(NDRPOINTER): 

211 referent = ( 

212 ('Data', LSAPR_TRANSLATED_SID_EX2_ARRAY), 

213 ) 

214 

215class LSAPR_TRANSLATED_SIDS_EX2(NDRSTRUCT): 

216 structure = ( 

217 ('Entries', ULONG), 

218 ('Sids', PLSAPR_TRANSLATED_SID_EX2_ARRAY), 

219 ) 

220 

221class RPC_UNICODE_STRING_ARRAY(NDRUniConformantArray): 

222 item = RPC_UNICODE_STRING 

223 

224################################################################################ 

225# RPC CALLS 

226################################################################################ 

227# 3.1.4.4 LsarGetUserName (Opnum 45) 

228class LsarGetUserName(NDRCALL): 

229 opnum = 45 

230 structure = ( 

231 ('SystemName', LPWSTR), 

232 ('UserName', PRPC_UNICODE_STRING), 

233 ('DomainName', PRPC_UNICODE_STRING), 

234 ) 

235 

236class LsarGetUserNameResponse(NDRCALL): 

237 structure = ( 

238 ('UserName', PRPC_UNICODE_STRING), 

239 ('DomainName', PRPC_UNICODE_STRING), 

240 ('ErrorCode', NTSTATUS), 

241 ) 

242 

243# 3.1.4.5 LsarLookupNames4 (Opnum 77) 

244class LsarLookupNames4(NDRCALL): 

245 opnum = 77 

246 structure = ( 

247 ('Count', ULONG), 

248 ('Names', RPC_UNICODE_STRING_ARRAY), 

249 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

250 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

251 ('MappedCount', ULONG), 

252 ('LookupOptions', ULONG), 

253 ('ClientRevision', ULONG), 

254 ) 

255 

256class LsarLookupNames4Response(NDRCALL): 

257 structure = ( 

258 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

259 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

260 ('MappedCount', ULONG), 

261 ('ErrorCode', NTSTATUS), 

262 ) 

263 

264# 3.1.4.6 LsarLookupNames3 (Opnum 68) 

265class LsarLookupNames3(NDRCALL): 

266 opnum = 68 

267 structure = ( 

268 ('PolicyHandle', LSAPR_HANDLE), 

269 ('Count', ULONG), 

270 ('Names', RPC_UNICODE_STRING_ARRAY), 

271 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

272 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

273 ('MappedCount', ULONG), 

274 ('LookupOptions', ULONG), 

275 ('ClientRevision', ULONG), 

276 ) 

277 

278class LsarLookupNames3Response(NDRCALL): 

279 structure = ( 

280 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

281 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

282 ('MappedCount', ULONG), 

283 ('ErrorCode', NTSTATUS), 

284 ) 

285 

286# 3.1.4.7 LsarLookupNames2 (Opnum 58) 

287class LsarLookupNames2(NDRCALL): 

288 opnum = 58 

289 structure = ( 

290 ('PolicyHandle', LSAPR_HANDLE), 

291 ('Count', ULONG), 

292 ('Names', RPC_UNICODE_STRING_ARRAY), 

293 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX), 

294 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

295 ('MappedCount', ULONG), 

296 ('LookupOptions', ULONG), 

297 ('ClientRevision', ULONG), 

298 ) 

299 

300class LsarLookupNames2Response(NDRCALL): 

301 structure = ( 

302 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

303 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX), 

304 ('MappedCount', ULONG), 

305 ('ErrorCode', NTSTATUS), 

306 ) 

307 

308# 3.1.4.8 LsarLookupNames (Opnum 14) 

309class LsarLookupNames(NDRCALL): 

310 opnum = 14 

311 structure = ( 

312 ('PolicyHandle', LSAPR_HANDLE), 

313 ('Count', ULONG), 

314 ('Names', RPC_UNICODE_STRING_ARRAY), 

315 ('TranslatedSids', LSAPR_TRANSLATED_SIDS), 

316 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

317 ('MappedCount', ULONG), 

318 ) 

319 

320class LsarLookupNamesResponse(NDRCALL): 

321 structure = ( 

322 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

323 ('TranslatedSids', LSAPR_TRANSLATED_SIDS), 

324 ('MappedCount', ULONG), 

325 ('ErrorCode', NTSTATUS), 

326 ) 

327 

328# 3.1.4.9 LsarLookupSids3 (Opnum 76) 

329class LsarLookupSids3(NDRCALL): 

330 opnum = 76 

331 structure = ( 

332 ('SidEnumBuffer', LSAPR_SID_ENUM_BUFFER), 

333 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

334 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

335 ('MappedCount', ULONG), 

336 ('LookupOptions', ULONG), 

337 ('ClientRevision', ULONG), 

338 ) 

339 

340class LsarLookupSids3Response(NDRCALL): 

341 structure = ( 

342 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

343 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

344 ('MappedCount', ULONG), 

345 ('ErrorCode', NTSTATUS), 

346 ) 

347 

348# 3.1.4.10 LsarLookupSids2 (Opnum 57) 

349class LsarLookupSids2(NDRCALL): 

350 opnum = 57 

351 structure = ( 

352 ('PolicyHandle', LSAPR_HANDLE), 

353 ('SidEnumBuffer', LSAPR_SID_ENUM_BUFFER), 

354 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

355 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

356 ('MappedCount', ULONG), 

357 ('LookupOptions', ULONG), 

358 ('ClientRevision', ULONG), 

359 ) 

360 

361class LsarLookupSids2Response(NDRCALL): 

362 structure = ( 

363 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

364 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

365 ('MappedCount', ULONG), 

366 ('ErrorCode', NTSTATUS), 

367 ) 

368 

369# 3.1.4.11 LsarLookupSids (Opnum 15) 

370class LsarLookupSids(NDRCALL): 

371 opnum = 15 

372 structure = ( 

373 ('PolicyHandle', LSAPR_HANDLE), 

374 ('SidEnumBuffer', LSAPR_SID_ENUM_BUFFER), 

375 ('TranslatedNames', LSAPR_TRANSLATED_NAMES), 

376 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

377 ('MappedCount', ULONG), 

378 ) 

379 

380class LsarLookupSidsResponse(NDRCALL): 

381 structure = ( 

382 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

383 ('TranslatedNames', LSAPR_TRANSLATED_NAMES), 

384 ('MappedCount', ULONG), 

385 ('ErrorCode', NTSTATUS), 

386 ) 

387 

388################################################################################ 

389# OPNUMs and their corresponding structures 

390################################################################################ 

391OPNUMS = { 

392 14 : (LsarLookupNames, LsarLookupNamesResponse), 

393 15 : (LsarLookupSids, LsarLookupSidsResponse), 

394 45 : (LsarGetUserName, LsarGetUserNameResponse), 

395 57 : (LsarLookupSids2, LsarLookupSids2Response), 

396 58 : (LsarLookupNames2, LsarLookupNames2Response), 

397 68 : (LsarLookupNames3, LsarLookupNames3Response), 

398 76 : (LsarLookupSids3, LsarLookupSids3Response), 

399 77 : (LsarLookupNames4, LsarLookupNames4Response), 

400} 

401 

402################################################################################ 

403# HELPER FUNCTIONS 

404################################################################################ 

405def hLsarGetUserName(dce, userName = NULL, domainName = NULL): 

406 request = LsarGetUserName() 

407 request['SystemName'] = NULL 

408 request['UserName'] = userName 

409 request['DomainName'] = domainName 

410 return dce.request(request) 

411 

412def hLsarLookupNames4(dce, names, lookupLevel = LSAP_LOOKUP_LEVEL.LsapLookupWksta, lookupOptions=0x00000000, clientRevision=0x00000001): 

413 request = LsarLookupNames4() 

414 request['Count'] = len(names) 

415 for name in names: 

416 itemn = RPC_UNICODE_STRING() 

417 itemn['Data'] = name 

418 request['Names'].append(itemn) 

419 request['TranslatedSids']['Sids'] = NULL 

420 request['LookupLevel'] = lookupLevel 

421 request['LookupOptions'] = lookupOptions 

422 request['ClientRevision'] = clientRevision 

423 

424 return dce.request(request) 

425 

426def hLsarLookupNames3(dce, policyHandle, names, lookupLevel = LSAP_LOOKUP_LEVEL.LsapLookupWksta, lookupOptions=0x00000000, clientRevision=0x00000001): 

427 request = LsarLookupNames3() 

428 request['PolicyHandle'] = policyHandle 

429 request['Count'] = len(names) 

430 for name in names: 

431 itemn = RPC_UNICODE_STRING() 

432 itemn['Data'] = name 

433 request['Names'].append(itemn) 

434 request['TranslatedSids']['Sids'] = NULL 

435 request['LookupLevel'] = lookupLevel 

436 request['LookupOptions'] = lookupOptions 

437 request['ClientRevision'] = clientRevision 

438 

439 return dce.request(request) 

440 

441def hLsarLookupNames2(dce, policyHandle, names, lookupLevel = LSAP_LOOKUP_LEVEL.LsapLookupWksta, lookupOptions=0x00000000, clientRevision=0x00000001): 

442 request = LsarLookupNames2() 

443 request['PolicyHandle'] = policyHandle 

444 request['Count'] = len(names) 

445 for name in names: 

446 itemn = RPC_UNICODE_STRING() 

447 itemn['Data'] = name 

448 request['Names'].append(itemn) 

449 request['TranslatedSids']['Sids'] = NULL 

450 request['LookupLevel'] = lookupLevel 

451 request['LookupOptions'] = lookupOptions 

452 request['ClientRevision'] = clientRevision 

453 

454 return dce.request(request) 

455 

456def hLsarLookupNames(dce, policyHandle, names, lookupLevel = LSAP_LOOKUP_LEVEL.LsapLookupWksta): 

457 request = LsarLookupNames() 

458 request['PolicyHandle'] = policyHandle 

459 request['Count'] = len(names) 

460 for name in names: 

461 itemn = RPC_UNICODE_STRING() 

462 itemn['Data'] = name 

463 request['Names'].append(itemn) 

464 request['TranslatedSids']['Sids'] = NULL 

465 request['LookupLevel'] = lookupLevel 

466 

467 return dce.request(request) 

468 

469def hLsarLookupSids2(dce, policyHandle, sids, lookupLevel = LSAP_LOOKUP_LEVEL.LsapLookupWksta, lookupOptions=0x00000000, clientRevision=0x00000001): 

470 request = LsarLookupSids2() 

471 request['PolicyHandle'] = policyHandle 

472 request['SidEnumBuffer']['Entries'] = len(sids) 

473 for sid in sids: 

474 itemn = LSAPR_SID_INFORMATION() 

475 itemn['Sid'].fromCanonical(sid) 

476 request['SidEnumBuffer']['SidInfo'].append(itemn) 

477 

478 request['TranslatedNames']['Names'] = NULL 

479 request['LookupLevel'] = lookupLevel 

480 request['LookupOptions'] = lookupOptions 

481 request['ClientRevision'] = clientRevision 

482 

483 return dce.request(request) 

484 

485def hLsarLookupSids(dce, policyHandle, sids, lookupLevel = LSAP_LOOKUP_LEVEL.LsapLookupWksta): 

486 request = LsarLookupSids() 

487 request['PolicyHandle'] = policyHandle 

488 request['SidEnumBuffer']['Entries'] = len(sids) 

489 for sid in sids: 

490 itemn = LSAPR_SID_INFORMATION() 

491 itemn['Sid'].fromCanonical(sid) 

492 request['SidEnumBuffer']['SidInfo'].append(itemn) 

493 

494 request['TranslatedNames']['Names'] = NULL 

495 request['LookupLevel'] = lookupLevel 

496 

497 return dce.request(request)