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

21from impacket import nt_errors 

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

23 NULL 

24from impacket.dcerpc.v5.enum import Enum 

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

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

27from impacket.dcerpc.v5.rpcrt import DCERPCException 

28from impacket.dcerpc.v5.samr import SID_NAME_USE 

29from impacket.uuid import uuidtup_to_bin 

30 

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

32 

33class DCERPCSessionError(DCERPCException): 

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

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

36 

37 def __str__( self ): 

38 key = self.error_code 

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

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

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

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

43 else: 

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

45 

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

47# CONSTANTS 

48################################################################################ 

49# 2.2.10 ACCESS_MASK 

50POLICY_LOOKUP_NAMES = 0x00000800 

51 

52################################################################################ 

53# STRUCTURES 

54################################################################################ 

55# 2.2.12 LSAPR_REFERENCED_DOMAIN_LIST 

56class LSAPR_REFERENCED_DOMAIN_LIST(NDRSTRUCT): 

57 structure = ( 

58 ('Entries', ULONG), 

59 ('Domains', PLSAPR_TRUST_INFORMATION_ARRAY), 

60 ('MaxEntries', ULONG), 

61 ) 

62 

63class PLSAPR_REFERENCED_DOMAIN_LIST(NDRPOINTER): 

64 referent = ( 

65 ('Data', LSAPR_REFERENCED_DOMAIN_LIST), 

66 ) 

67 

68# 2.2.14 LSA_TRANSLATED_SID 

69class LSA_TRANSLATED_SID(NDRSTRUCT): 

70 structure = ( 

71 ('Use', SID_NAME_USE), 

72 ('RelativeId', ULONG), 

73 ('DomainIndex', LONG), 

74 ) 

75 

76# 2.2.15 LSAPR_TRANSLATED_SIDS 

77class LSA_TRANSLATED_SID_ARRAY(NDRUniConformantArray): 

78 item = LSA_TRANSLATED_SID 

79 

80class PLSA_TRANSLATED_SID_ARRAY(NDRPOINTER): 

81 referent = ( 

82 ('Data', LSA_TRANSLATED_SID_ARRAY), 

83 ) 

84 

85class LSAPR_TRANSLATED_SIDS(NDRSTRUCT): 

86 structure = ( 

87 ('Entries', ULONG), 

88 ('Sids', PLSA_TRANSLATED_SID_ARRAY), 

89 ) 

90 

91# 2.2.16 LSAP_LOOKUP_LEVEL 

92class LSAP_LOOKUP_LEVEL(NDRENUM): 

93 class enumItems(Enum): 

94 LsapLookupWksta = 1 

95 LsapLookupPDC = 2 

96 LsapLookupTDL = 3 

97 LsapLookupGC = 4 

98 LsapLookupXForestReferral = 5 

99 LsapLookupXForestResolve = 6 

100 LsapLookupRODCReferralToFullDC = 7 

101 

102# 2.2.17 LSAPR_SID_INFORMATION 

103class LSAPR_SID_INFORMATION(NDRSTRUCT): 

104 structure = ( 

105 ('Sid', PRPC_SID), 

106 ) 

107 

108# 2.2.18 LSAPR_SID_ENUM_BUFFER 

109class LSAPR_SID_INFORMATION_ARRAY(NDRUniConformantArray): 

110 item = LSAPR_SID_INFORMATION 

111 

112class PLSAPR_SID_INFORMATION_ARRAY(NDRPOINTER): 

113 referent = ( 

114 ('Data', LSAPR_SID_INFORMATION_ARRAY), 

115 ) 

116 

117class LSAPR_SID_ENUM_BUFFER(NDRSTRUCT): 

118 structure = ( 

119 ('Entries', ULONG), 

120 ('SidInfo', PLSAPR_SID_INFORMATION_ARRAY), 

121 ) 

122 

123# 2.2.19 LSAPR_TRANSLATED_NAME 

124class LSAPR_TRANSLATED_NAME(NDRSTRUCT): 

125 structure = ( 

126 ('Use', SID_NAME_USE), 

127 ('Name', RPC_UNICODE_STRING), 

128 ('DomainIndex', LONG), 

129 ) 

130 

131# 2.2.20 LSAPR_TRANSLATED_NAMES 

132class LSAPR_TRANSLATED_NAME_ARRAY(NDRUniConformantArray): 

133 item = LSAPR_TRANSLATED_NAME 

134 

135class PLSAPR_TRANSLATED_NAME_ARRAY(NDRPOINTER): 

136 referent = ( 

137 ('Data', LSAPR_TRANSLATED_NAME_ARRAY), 

138 ) 

139 

140class LSAPR_TRANSLATED_NAMES(NDRSTRUCT): 

141 structure = ( 

142 ('Entries', ULONG), 

143 ('Names', PLSAPR_TRANSLATED_NAME_ARRAY), 

144 ) 

145 

146# 2.2.21 LSAPR_TRANSLATED_NAME_EX 

147class LSAPR_TRANSLATED_NAME_EX(NDRSTRUCT): 

148 structure = ( 

149 ('Use', SID_NAME_USE), 

150 ('Name', RPC_UNICODE_STRING), 

151 ('DomainIndex', LONG), 

152 ('Flags', ULONG), 

153 ) 

154 

155# 2.2.22 LSAPR_TRANSLATED_NAMES_EX 

156class LSAPR_TRANSLATED_NAME_EX_ARRAY(NDRUniConformantArray): 

157 item = LSAPR_TRANSLATED_NAME_EX 

158 

159class PLSAPR_TRANSLATED_NAME_EX_ARRAY(NDRPOINTER): 

160 referent = ( 

161 ('Data', LSAPR_TRANSLATED_NAME_EX_ARRAY), 

162 ) 

163 

164class LSAPR_TRANSLATED_NAMES_EX(NDRSTRUCT): 

165 structure = ( 

166 ('Entries', ULONG), 

167 ('Names', PLSAPR_TRANSLATED_NAME_EX_ARRAY), 

168 ) 

169 

170# 2.2.23 LSAPR_TRANSLATED_SID_EX 

171class LSAPR_TRANSLATED_SID_EX(NDRSTRUCT): 

172 structure = ( 

173 ('Use', SID_NAME_USE), 

174 ('RelativeId', ULONG), 

175 ('DomainIndex', LONG), 

176 ('Flags', ULONG), 

177 ) 

178 

179# 2.2.24 LSAPR_TRANSLATED_SIDS_EX 

180class LSAPR_TRANSLATED_SID_EX_ARRAY(NDRUniConformantArray): 

181 item = LSAPR_TRANSLATED_SID_EX 

182 

183class PLSAPR_TRANSLATED_SID_EX_ARRAY(NDRPOINTER): 

184 referent = ( 

185 ('Data', LSAPR_TRANSLATED_SID_EX_ARRAY), 

186 ) 

187 

188class LSAPR_TRANSLATED_SIDS_EX(NDRSTRUCT): 

189 structure = ( 

190 ('Entries', ULONG), 

191 ('Sids', PLSAPR_TRANSLATED_SID_EX_ARRAY), 

192 ) 

193 

194# 2.2.25 LSAPR_TRANSLATED_SID_EX2 

195class LSAPR_TRANSLATED_SID_EX2(NDRSTRUCT): 

196 structure = ( 

197 ('Use', SID_NAME_USE), 

198 ('Sid', PRPC_SID), 

199 ('DomainIndex', LONG), 

200 ('Flags', ULONG), 

201 ) 

202 

203# 2.2.26 LSAPR_TRANSLATED_SIDS_EX2 

204class LSAPR_TRANSLATED_SID_EX2_ARRAY(NDRUniConformantArray): 

205 item = LSAPR_TRANSLATED_SID_EX2 

206 

207class PLSAPR_TRANSLATED_SID_EX2_ARRAY(NDRPOINTER): 

208 referent = ( 

209 ('Data', LSAPR_TRANSLATED_SID_EX2_ARRAY), 

210 ) 

211 

212class LSAPR_TRANSLATED_SIDS_EX2(NDRSTRUCT): 

213 structure = ( 

214 ('Entries', ULONG), 

215 ('Sids', PLSAPR_TRANSLATED_SID_EX2_ARRAY), 

216 ) 

217 

218class RPC_UNICODE_STRING_ARRAY(NDRUniConformantArray): 

219 item = RPC_UNICODE_STRING 

220 

221################################################################################ 

222# RPC CALLS 

223################################################################################ 

224# 3.1.4.4 LsarGetUserName (Opnum 45) 

225class LsarGetUserName(NDRCALL): 

226 opnum = 45 

227 structure = ( 

228 ('SystemName', LPWSTR), 

229 ('UserName', PRPC_UNICODE_STRING), 

230 ('DomainName', PRPC_UNICODE_STRING), 

231 ) 

232 

233class LsarGetUserNameResponse(NDRCALL): 

234 structure = ( 

235 ('UserName', PRPC_UNICODE_STRING), 

236 ('DomainName', PRPC_UNICODE_STRING), 

237 ('ErrorCode', NTSTATUS), 

238 ) 

239 

240# 3.1.4.5 LsarLookupNames4 (Opnum 77) 

241class LsarLookupNames4(NDRCALL): 

242 opnum = 77 

243 structure = ( 

244 ('Count', ULONG), 

245 ('Names', RPC_UNICODE_STRING_ARRAY), 

246 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

247 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

248 ('MappedCount', ULONG), 

249 ('LookupOptions', ULONG), 

250 ('ClientRevision', ULONG), 

251 ) 

252 

253class LsarLookupNames4Response(NDRCALL): 

254 structure = ( 

255 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

256 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

257 ('MappedCount', ULONG), 

258 ('ErrorCode', NTSTATUS), 

259 ) 

260 

261# 3.1.4.6 LsarLookupNames3 (Opnum 68) 

262class LsarLookupNames3(NDRCALL): 

263 opnum = 68 

264 structure = ( 

265 ('PolicyHandle', LSAPR_HANDLE), 

266 ('Count', ULONG), 

267 ('Names', RPC_UNICODE_STRING_ARRAY), 

268 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

269 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

270 ('MappedCount', ULONG), 

271 ('LookupOptions', ULONG), 

272 ('ClientRevision', ULONG), 

273 ) 

274 

275class LsarLookupNames3Response(NDRCALL): 

276 structure = ( 

277 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

278 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX2), 

279 ('MappedCount', ULONG), 

280 ('ErrorCode', NTSTATUS), 

281 ) 

282 

283# 3.1.4.7 LsarLookupNames2 (Opnum 58) 

284class LsarLookupNames2(NDRCALL): 

285 opnum = 58 

286 structure = ( 

287 ('PolicyHandle', LSAPR_HANDLE), 

288 ('Count', ULONG), 

289 ('Names', RPC_UNICODE_STRING_ARRAY), 

290 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX), 

291 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

292 ('MappedCount', ULONG), 

293 ('LookupOptions', ULONG), 

294 ('ClientRevision', ULONG), 

295 ) 

296 

297class LsarLookupNames2Response(NDRCALL): 

298 structure = ( 

299 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

300 ('TranslatedSids', LSAPR_TRANSLATED_SIDS_EX), 

301 ('MappedCount', ULONG), 

302 ('ErrorCode', NTSTATUS), 

303 ) 

304 

305# 3.1.4.8 LsarLookupNames (Opnum 14) 

306class LsarLookupNames(NDRCALL): 

307 opnum = 14 

308 structure = ( 

309 ('PolicyHandle', LSAPR_HANDLE), 

310 ('Count', ULONG), 

311 ('Names', RPC_UNICODE_STRING_ARRAY), 

312 ('TranslatedSids', LSAPR_TRANSLATED_SIDS), 

313 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

314 ('MappedCount', ULONG), 

315 ) 

316 

317class LsarLookupNamesResponse(NDRCALL): 

318 structure = ( 

319 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

320 ('TranslatedSids', LSAPR_TRANSLATED_SIDS), 

321 ('MappedCount', ULONG), 

322 ('ErrorCode', NTSTATUS), 

323 ) 

324 

325# 3.1.4.9 LsarLookupSids3 (Opnum 76) 

326class LsarLookupSids3(NDRCALL): 

327 opnum = 76 

328 structure = ( 

329 ('SidEnumBuffer', LSAPR_SID_ENUM_BUFFER), 

330 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

331 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

332 ('MappedCount', ULONG), 

333 ('LookupOptions', ULONG), 

334 ('ClientRevision', ULONG), 

335 ) 

336 

337class LsarLookupSids3Response(NDRCALL): 

338 structure = ( 

339 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

340 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

341 ('MappedCount', ULONG), 

342 ('ErrorCode', NTSTATUS), 

343 ) 

344 

345# 3.1.4.10 LsarLookupSids2 (Opnum 57) 

346class LsarLookupSids2(NDRCALL): 

347 opnum = 57 

348 structure = ( 

349 ('PolicyHandle', LSAPR_HANDLE), 

350 ('SidEnumBuffer', LSAPR_SID_ENUM_BUFFER), 

351 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

352 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

353 ('MappedCount', ULONG), 

354 ('LookupOptions', ULONG), 

355 ('ClientRevision', ULONG), 

356 ) 

357 

358class LsarLookupSids2Response(NDRCALL): 

359 structure = ( 

360 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

361 ('TranslatedNames', LSAPR_TRANSLATED_NAMES_EX), 

362 ('MappedCount', ULONG), 

363 ('ErrorCode', NTSTATUS), 

364 ) 

365 

366# 3.1.4.11 LsarLookupSids (Opnum 15) 

367class LsarLookupSids(NDRCALL): 

368 opnum = 15 

369 structure = ( 

370 ('PolicyHandle', LSAPR_HANDLE), 

371 ('SidEnumBuffer', LSAPR_SID_ENUM_BUFFER), 

372 ('TranslatedNames', LSAPR_TRANSLATED_NAMES), 

373 ('LookupLevel', LSAP_LOOKUP_LEVEL), 

374 ('MappedCount', ULONG), 

375 ) 

376 

377class LsarLookupSidsResponse(NDRCALL): 

378 structure = ( 

379 ('ReferencedDomains', PLSAPR_REFERENCED_DOMAIN_LIST), 

380 ('TranslatedNames', LSAPR_TRANSLATED_NAMES), 

381 ('MappedCount', ULONG), 

382 ('ErrorCode', NTSTATUS), 

383 ) 

384 

385################################################################################ 

386# OPNUMs and their corresponding structures 

387################################################################################ 

388OPNUMS = { 

389 14 : (LsarLookupNames, LsarLookupNamesResponse), 

390 15 : (LsarLookupSids, LsarLookupSidsResponse), 

391 45 : (LsarGetUserName, LsarGetUserNameResponse), 

392 57 : (LsarLookupSids2, LsarLookupSids2Response), 

393 58 : (LsarLookupNames2, LsarLookupNames2Response), 

394 68 : (LsarLookupNames3, LsarLookupNames3Response), 

395 76 : (LsarLookupSids3, LsarLookupSids3Response), 

396 77 : (LsarLookupNames4, LsarLookupNames4Response), 

397} 

398 

399################################################################################ 

400# HELPER FUNCTIONS 

401################################################################################ 

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

403 request = LsarGetUserName() 

404 request['SystemName'] = NULL 

405 request['UserName'] = userName 

406 request['DomainName'] = domainName 

407 return dce.request(request) 

408 

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

410 request = LsarLookupNames4() 

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

412 for name in names: 

413 itemn = RPC_UNICODE_STRING() 

414 itemn['Data'] = name 

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

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

417 request['LookupLevel'] = lookupLevel 

418 request['LookupOptions'] = lookupOptions 

419 request['ClientRevision'] = clientRevision 

420 

421 return dce.request(request) 

422 

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

424 request = LsarLookupNames3() 

425 request['PolicyHandle'] = policyHandle 

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

427 for name in names: 

428 itemn = RPC_UNICODE_STRING() 

429 itemn['Data'] = name 

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

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

432 request['LookupLevel'] = lookupLevel 

433 request['LookupOptions'] = lookupOptions 

434 request['ClientRevision'] = clientRevision 

435 

436 return dce.request(request) 

437 

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

439 request = LsarLookupNames2() 

440 request['PolicyHandle'] = policyHandle 

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

442 for name in names: 

443 itemn = RPC_UNICODE_STRING() 

444 itemn['Data'] = name 

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

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

447 request['LookupLevel'] = lookupLevel 

448 request['LookupOptions'] = lookupOptions 

449 request['ClientRevision'] = clientRevision 

450 

451 return dce.request(request) 

452 

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

454 request = LsarLookupNames() 

455 request['PolicyHandle'] = policyHandle 

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

457 for name in names: 

458 itemn = RPC_UNICODE_STRING() 

459 itemn['Data'] = name 

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

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

462 request['LookupLevel'] = lookupLevel 

463 

464 return dce.request(request) 

465 

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

467 request = LsarLookupSids2() 

468 request['PolicyHandle'] = policyHandle 

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

470 for sid in sids: 

471 itemn = LSAPR_SID_INFORMATION() 

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

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

474 

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

476 request['LookupLevel'] = lookupLevel 

477 request['LookupOptions'] = lookupOptions 

478 request['ClientRevision'] = clientRevision 

479 

480 return dce.request(request) 

481 

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

483 request = LsarLookupSids() 

484 request['PolicyHandle'] = policyHandle 

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

486 for sid in sids: 

487 itemn = LSAPR_SID_INFORMATION() 

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

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

490 

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

492 request['LookupLevel'] = lookupLevel 

493 

494 return dce.request(request)