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# Kerberos Credential Cache format implementation 

11# based on file format described at: 

12# https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/ccache.txt 

13# Pretty lame and quick implementation, not a fun thing to do 

14# Contribution is welcome to make it the right way 

15# 

16from __future__ import division 

17from __future__ import print_function 

18from datetime import datetime 

19from struct import pack, unpack, calcsize 

20from six import b 

21 

22from pyasn1.codec.der import decoder, encoder 

23from pyasn1.type.univ import noValue 

24from binascii import hexlify 

25 

26from impacket.structure import Structure 

27from impacket.krb5 import crypto, constants, types 

28from impacket.krb5.asn1 import AS_REP, seq_set, TGS_REP, EncTGSRepPart, EncASRepPart, Ticket, KRB_CRED, \ 

29 EncKrbCredPart, KrbCredInfo, seq_set_iter 

30from impacket.krb5.types import KerberosTime 

31from impacket import LOG 

32 

33DELTA_TIME = 1 

34 

35class Header(Structure): 

36 structure = ( 

37 ('tag','!H=0'), 

38 ('taglen','!H=0'), 

39 ('_tagdata','_-tagdata','self["taglen"]'), 

40 ('tagdata',':'), 

41 ) 

42 

43class DeltaTime(Structure): 

44 structure = ( 

45 ('time_offset','!L=0'), 

46 ('usec_offset','!L=0'), 

47 ) 

48 

49class CountedOctetString(Structure): 

50 structure = ( 

51 ('length','!L=0'), 

52 ('_data','_-data','self["length"]'), 

53 ('data',':'), 

54 ) 

55 

56 def prettyPrint(self, indent=''): 

57 return "%s%s" % (indent, hexlify(self['data'])) 

58 

59class KeyBlock(Structure): 

60 structure = ( 

61 ('keytype','!H=0'), 

62 ('etype','!H=0'), 

63 ('keylen','!H=0'), 

64 ('_keyvalue','_-keyvalue','self["keylen"]'), 

65 ('keyvalue',':'), 

66 ) 

67 

68 def prettyPrint(self): 

69 return "Key: (0x%x)%s" % (self['keytype'], hexlify(self['keyvalue'])) 

70 

71class Times(Structure): 

72 structure = ( 

73 ('authtime','!L=0'), 

74 ('starttime','!L=0'), 

75 ('endtime','!L=0'), 

76 ('renew_till','!L=0'), 

77 ) 

78 def prettyPrint(self, indent = ''): 

79 print(("%sAuth : %s" % (indent, datetime.fromtimestamp(self['authtime']).isoformat()))) 

80 print(("%sStart: %s" % (indent, datetime.fromtimestamp(self['starttime']).isoformat()))) 

81 print(("%sEnd : %s" % (indent, datetime.fromtimestamp(self['endtime']).isoformat()))) 

82 print(("%sRenew: %s" % (indent, datetime.fromtimestamp(self['renew_till']).isoformat()))) 

83 

84class Address(Structure): 

85 structure = ( 

86 ('addrtype','!H=0'), 

87 ('addrdata',':', CountedOctetString), 

88 ) 

89 

90class AuthData(Structure): 

91 structure = ( 

92 ('authtype','!H=0'), 

93 ('authdata',':', CountedOctetString), 

94 ) 

95 

96class Principal: 

97 class PrincipalHeader(Structure): 

98 structure = ( 

99 ('name_type','!L=0'), 

100 ('num_components','!L=0'), 

101 ) 

102 def __init__(self, data=None): 

103 self.components = [] 

104 self.realm = None 

105 if data is not None: 

106 self.header = self.PrincipalHeader(data) 

107 data = data[len(self.header):] 

108 self.realm = CountedOctetString(data) 

109 data = data[len(self.realm):] 

110 self.components = [] 

111 for component in range(self.header['num_components']): 

112 comp = CountedOctetString(data) 

113 data = data[len(comp):] 

114 self.components.append(comp) 

115 else: 

116 self.header = self.PrincipalHeader() 

117 

118 def __len__(self): 

119 totalLen = len(self.header) + len(self.realm) 

120 for i in self.components: 

121 totalLen += len(i) 

122 return totalLen 

123 

124 def getData(self): 

125 data = self.header.getData() + self.realm.getData() 

126 for component in self.components: 

127 data += component.getData() 

128 return data 

129 

130 def __str__(self): 

131 return self.getData() 

132 

133 def prettyPrint(self): 

134 principal = b'' 

135 for component in self.components: 

136 if isinstance(component['data'], bytes) is not True: 

137 component = b(component['data']) 

138 else: 

139 component = component['data'] 

140 principal += component + b'/' 

141 

142 principal = principal[:-1] 

143 if isinstance(self.realm['data'], bytes): 

144 realm = self.realm['data'] 

145 else: 

146 realm = b(self.realm['data']) 

147 principal += b'@' + realm 

148 return principal 

149 

150 def fromPrincipal(self, principal): 

151 self.header['name_type'] = principal.type 

152 self.header['num_components'] = len(principal.components) 

153 octetString = CountedOctetString() 

154 octetString['length'] = len(principal.realm) 

155 octetString['data'] = principal.realm 

156 self.realm = octetString 

157 self.components = [] 

158 for c in principal.components: 

159 octetString = CountedOctetString() 

160 octetString['length'] = len(c) 

161 octetString['data'] = c 

162 self.components.append(octetString) 

163 

164 def toPrincipal(self): 

165 return types.Principal(self.prettyPrint(), type=self.header['name_type']) 

166 

167class Credential: 

168 class CredentialHeader(Structure): 

169 structure = ( 

170 ('client',':', Principal), 

171 ('server',':', Principal), 

172 ('key',':', KeyBlock), 

173 ('time',':', Times), 

174 ('is_skey','B=0'), 

175 ('tktflags','!L=0'), 

176 ('num_address','!L=0'), 

177 ) 

178 

179 def __init__(self, data=None): 

180 self.addresses = () 

181 self.authData = () 

182 self.header = None 

183 self.ticket = None 

184 self.secondTicket = None 

185 

186 if data is not None: 

187 self.header = self.CredentialHeader(data) 

188 data = data[len(self.header):] 

189 self.addresses = [] 

190 for address in range(self.header['num_address']): 

191 ad = Address(data) 

192 data = data[len(ad):] 

193 self.addresses.append(ad) 

194 num_authdata = unpack('!L', data[:4])[0] 

195 data = data[calcsize('!L'):] 

196 for authdata in range(num_authdata): 

197 ad = AuthData(data) 

198 data = data[len(ad):] 

199 self.authData.append(ad) 

200 self.ticket = CountedOctetString(data) 

201 data = data[len(self.ticket):] 

202 self.secondTicket = CountedOctetString(data) 

203 data = data[len( self.secondTicket):] 

204 else: 

205 self.header = self.CredentialHeader() 

206 

207 def __getitem__(self, key): 

208 return self.header[key] 

209 

210 def __setitem__(self, item, value): 

211 self.header[item] = value 

212 

213 def getServerPrincipal(self): 

214 return self.header['server'].prettyPrint() 

215 

216 def __len__(self): 

217 totalLen = len(self.header) 

218 for i in self.addresses: 

219 totalLen += len(i) 

220 totalLen += calcsize('!L') 

221 for i in self.authData: 

222 totalLen += len(i) 

223 totalLen += len(self.ticket) 

224 totalLen += len(self.secondTicket) 

225 return totalLen 

226 

227 def dump(self): 

228 self.header.dump() 

229 

230 def getData(self): 

231 data = self.header.getData() 

232 for i in self.addresses: 

233 data += i.getData() 

234 data += pack('!L', len(self.authData)) 

235 for i in self.authData: 

236 data += i.getData() 

237 data += self.ticket.getData() 

238 data += self.secondTicket.getData() 

239 return data 

240 

241 def __str__(self): 

242 return self.getData() 

243 

244 def prettyPrint(self, indent=''): 

245 print(("%sClient: %s" % (indent, self.header['client'].prettyPrint()))) 

246 print(("%sServer: %s" % (indent, self.header['server'].prettyPrint()))) 

247 print(("%s%s" % (indent, self.header['key'].prettyPrint()))) 

248 print(("%sTimes: " % indent)) 

249 self.header['time'].prettyPrint('\t\t') 

250 print(("%sSubKey: %s" % (indent, self.header['is_skey']))) 

251 print(("%sFlags: 0x%x" % (indent, self.header['tktflags']))) 

252 print(("%sAddresses: %d" % (indent, self.header['num_address']))) 

253 for address in self.addresses: 

254 address.prettyPrint('\t\t') 

255 print(("%sAuth Data: %d" % (indent, len(self.authData)))) 

256 for ad in self.authData: 

257 ad.prettyPrint('\t\t') 

258 print(("%sTicket: %s" % (indent, self.ticket.prettyPrint()))) 

259 print(("%sSecond Ticket: %s" % (indent, self.secondTicket.prettyPrint()))) 

260 

261 def toTGT(self): 

262 tgt_rep = AS_REP() 

263 tgt_rep['pvno'] = 5 

264 tgt_rep['msg-type'] = int(constants.ApplicationTagNumbers.AS_REP.value) 

265 tgt_rep['crealm'] = self['server'].realm['data'] 

266 

267 # Fake EncryptedData 

268 tgt_rep['enc-part'] = noValue 

269 tgt_rep['enc-part']['etype'] = 1 

270 tgt_rep['enc-part']['cipher'] = '' 

271 seq_set(tgt_rep, 'cname', self['client'].toPrincipal().components_to_asn1) 

272 ticket = types.Ticket() 

273 ticket.from_asn1(self.ticket['data']) 

274 seq_set(tgt_rep,'ticket', ticket.to_asn1) 

275 

276 cipher = crypto._enctype_table[self['key']['keytype']]() 

277 

278 tgt = dict() 

279 tgt['KDC_REP'] = encoder.encode(tgt_rep) 

280 tgt['cipher'] = cipher 

281 tgt['sessionKey'] = crypto.Key(cipher.enctype, self['key']['keyvalue']) 

282 return tgt 

283 

284 def toTGS(self, newSPN=None): 

285 tgs_rep = TGS_REP() 

286 tgs_rep['pvno'] = 5 

287 tgs_rep['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REP.value) 

288 tgs_rep['crealm'] = self['server'].realm['data'] 

289 

290 # Fake EncryptedData 

291 tgs_rep['enc-part'] = noValue 

292 tgs_rep['enc-part']['etype'] = 1 

293 tgs_rep['enc-part']['cipher'] = '' 

294 seq_set(tgs_rep, 'cname', self['client'].toPrincipal().components_to_asn1) 

295 ticket = types.Ticket() 

296 ticket.from_asn1(self.ticket['data']) 

297 if newSPN is not None: 

298 if newSPN.upper() != str(ticket.service_principal).upper(): 

299 LOG.debug('Changing sname from %s to %s and hoping for the best' % (ticket.service_principal, newSPN) ) 

300 ticket.service_principal = types.Principal(newSPN, type=int(ticket.service_principal.type)) 

301 seq_set(tgs_rep,'ticket', ticket.to_asn1) 

302 

303 cipher = crypto._enctype_table[self['key']['keytype']]() 

304 

305 tgs = dict() 

306 tgs['KDC_REP'] = encoder.encode(tgs_rep) 

307 tgs['cipher'] = cipher 

308 tgs['sessionKey'] = crypto.Key(cipher.enctype, self['key']['keyvalue']) 

309 return tgs 

310 

311class CCache: 

312 class MiniHeader(Structure): 

313 structure = ( 

314 ('file_format_version','!H=0x0504'), 

315 ('headerlen','!H=12'), 

316 ) 

317 

318 def __init__(self, data = None): 

319 self.headers = None 

320 self.principal = None 

321 self.credentials = [] 

322 self.miniHeader = None 

323 if data is not None: 

324 miniHeader = self.MiniHeader(data) 

325 data = data[len(miniHeader.getData()):] 

326 

327 headerLen = miniHeader['headerlen'] 

328 

329 self.headers = [] 

330 while headerLen > 0: 

331 header = Header(data) 

332 self.headers.append(header) 

333 headerLen -= len(header) 

334 data = data[len(header):] 

335 

336 # Now the primary_principal 

337 self.principal = Principal(data) 

338 

339 data = data[len(self.principal):] 

340 

341 # Now let's parse the credentials 

342 self.credentials = [] 

343 while len(data) > 0: 

344 cred = Credential(data) 

345 if cred['server'].prettyPrint().find(b'krb5_ccache_conf_data') < 0: 

346 self.credentials.append(cred) 

347 data = data[len(cred.getData()):] 

348 

349 def getData(self): 

350 data = self.MiniHeader().getData() 

351 for header in self.headers: 

352 data += header.getData() 

353 data += self.principal.getData() 

354 for credential in self.credentials: 

355 data += credential.getData() 

356 return data 

357 

358 def getCredential(self, server, anySPN=True): 

359 for c in self.credentials: 

360 if c['server'].prettyPrint().upper() == b(server.upper()) or c['server'].prettyPrint().upper().split(b'@')[0] == b(server.upper())\ 

361 or c['server'].prettyPrint().upper().split(b'@')[0] == b(server.upper().split('@')[0]): 

362 LOG.debug('Returning cached credential for %s' % c['server'].prettyPrint().upper().decode('utf-8')) 

363 return c 

364 LOG.debug('SPN %s not found in cache' % server.upper()) 

365 if anySPN is True: 

366 LOG.debug('AnySPN is True, looking for another suitable SPN') 

367 for c in self.credentials: 

368 # Let's search for any TGT/TGS that matches the server w/o the SPN's service type/port, returns 

369 # the first one 

370 if c['server'].prettyPrint().find(b'/') >=0: 

371 # Let's take the port out for comparison 

372 cachedSPN = (c['server'].prettyPrint().upper().split(b'/')[1].split(b'@')[0].split(b':')[0] + b'@' + c['server'].prettyPrint().upper().split(b'/')[1].split(b'@')[1]) 

373 searchSPN = '%s@%s' % (server.upper().split('/')[1].split('@')[0].split(':')[0], 

374 server.upper().split('/')[1].split('@')[1]) 

375 if cachedSPN == b(searchSPN): 

376 LOG.debug('Returning cached credential for %s' % c['server'].prettyPrint().upper().decode('utf-8')) 

377 return c 

378 

379 return None 

380 

381 def toTimeStamp(self, dt, epoch=datetime(1970,1,1)): 

382 td = dt - epoch 

383 # return td.total_seconds() 

384 return int((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) // 1e6) 

385 

386 def reverseFlags(self, flags): 

387 result = 0 

388 if isinstance(flags, str): 

389 flags = flags[1:-2] 

390 for i,j in enumerate(reversed(flags)): 

391 if j != 0: 

392 result += j << i 

393 return result 

394 

395 def fromTGT(self, tgt, oldSessionKey, sessionKey): 

396 self.headers = [] 

397 header = Header() 

398 header['tag'] = 1 

399 header['taglen'] = 8 

400 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00' 

401 self.headers.append(header) 

402 

403 decodedTGT = decoder.decode(tgt, asn1Spec = AS_REP())[0] 

404 

405 tmpPrincipal = types.Principal() 

406 tmpPrincipal.from_asn1(decodedTGT, 'crealm', 'cname') 

407 self.principal = Principal() 

408 self.principal.fromPrincipal(tmpPrincipal) 

409 

410 # Now let's add the credential 

411 cipherText = decodedTGT['enc-part']['cipher'] 

412 

413 cipher = crypto._enctype_table[decodedTGT['enc-part']['etype']] 

414 

415 # Key Usage 3 

416 # AS-REP encrypted part (includes TGS session key or 

417 # application session key), encrypted with the client key 

418 # (Section 5.4.2) 

419 plainText = cipher.decrypt(oldSessionKey, 3, cipherText) 

420 

421 encASRepPart = decoder.decode(plainText, asn1Spec = EncASRepPart())[0] 

422 credential = Credential() 

423 server = types.Principal() 

424 server.from_asn1(encASRepPart, 'srealm', 'sname') 

425 tmpServer = Principal() 

426 tmpServer.fromPrincipal(server) 

427 

428 credential['client'] = self.principal 

429 credential['server'] = tmpServer 

430 credential['is_skey'] = 0 

431 

432 credential['key'] = KeyBlock() 

433 credential['key']['keytype'] = int(encASRepPart['key']['keytype']) 

434 credential['key']['keyvalue'] = encASRepPart['key']['keyvalue'].asOctets() 

435 credential['key']['keylen'] = len(credential['key']['keyvalue']) 

436 

437 credential['time'] = Times() 

438 credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['authtime'])) 

439 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['starttime'])) 

440 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['endtime'])) 

441 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['renew-till'])) 

442 

443 flags = self.reverseFlags(encASRepPart['flags']) 

444 credential['tktflags'] = flags 

445 

446 credential['num_address'] = 0 

447 credential.ticket = CountedOctetString() 

448 credential.ticket['data'] = encoder.encode(decodedTGT['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True)) 

449 credential.ticket['length'] = len(credential.ticket['data']) 

450 credential.secondTicket = CountedOctetString() 

451 credential.secondTicket['data'] = b'' 

452 credential.secondTicket['length'] = 0 

453 self.credentials.append(credential) 

454 

455 def fromTGS(self, tgs, oldSessionKey, sessionKey): 

456 self.headers = [] 

457 header = Header() 

458 header['tag'] = 1 

459 header['taglen'] = 8 

460 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00' 

461 self.headers.append(header) 

462 

463 decodedTGS = decoder.decode(tgs, asn1Spec = TGS_REP())[0] 

464 

465 tmpPrincipal = types.Principal() 

466 tmpPrincipal.from_asn1(decodedTGS, 'crealm', 'cname') 

467 self.principal = Principal() 

468 self.principal.fromPrincipal(tmpPrincipal) 

469 

470 # Now let's add the credential 

471 cipherText = decodedTGS['enc-part']['cipher'] 

472 

473 cipher = crypto._enctype_table[decodedTGS['enc-part']['etype']] 

474 

475 # Key Usage 8 

476 # TGS-REP encrypted part (includes application session 

477 # key), encrypted with the TGS session key (Section 5.4.2) 

478 plainText = cipher.decrypt(oldSessionKey, 8, cipherText) 

479 

480 encTGSRepPart = decoder.decode(plainText, asn1Spec = EncTGSRepPart())[0] 

481 

482 credential = Credential() 

483 server = types.Principal() 

484 server.from_asn1(encTGSRepPart, 'srealm', 'sname') 

485 tmpServer = Principal() 

486 tmpServer.fromPrincipal(server) 

487 

488 credential['client'] = self.principal 

489 credential['server'] = tmpServer 

490 credential['is_skey'] = 0 

491 

492 credential['key'] = KeyBlock() 

493 credential['key']['keytype'] = int(encTGSRepPart['key']['keytype']) 

494 credential['key']['keyvalue'] = encTGSRepPart['key']['keyvalue'].asOctets() 

495 credential['key']['keylen'] = len(credential['key']['keyvalue']) 

496 

497 credential['time'] = Times() 

498 credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['authtime'])) 

499 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['starttime'])) 

500 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['endtime'])) 

501 # After KB4586793 for CVE-2020-17049 this timestamp may be omitted 

502 if encTGSRepPart['renew-till'].hasValue(): 

503 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['renew-till'])) 

504 

505 flags = self.reverseFlags(encTGSRepPart['flags']) 

506 credential['tktflags'] = flags 

507 

508 credential['num_address'] = 0 

509 

510 credential.ticket = CountedOctetString() 

511 credential.ticket['data'] = encoder.encode(decodedTGS['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True)) 

512 credential.ticket['length'] = len(credential.ticket['data']) 

513 credential.secondTicket = CountedOctetString() 

514 credential.secondTicket['data'] = b'' 

515 credential.secondTicket['length'] = 0 

516 self.credentials.append(credential) 

517 

518 @classmethod 

519 def loadFile(cls, fileName): 

520 f = open(fileName,'rb') 

521 data = f.read() 

522 f.close() 

523 return cls(data) 

524 

525 def saveFile(self, fileName): 

526 f = open(fileName,'wb+') 

527 f.write(self.getData()) 

528 f.close() 

529 

530 def prettyPrint(self): 

531 print(("Primary Principal: %s" % self.principal.prettyPrint())) 

532 print("Credentials: ") 

533 for i, credential in enumerate(self.credentials): 

534 print(("[%d]" % i)) 

535 credential.prettyPrint('\t') 

536 

537 @classmethod 

538 def loadKirbiFile(cls, fileName): 

539 f = open(fileName, 'rb') 

540 data = f.read() 

541 f.close() 

542 ccache = cls() 

543 ccache.fromKRBCRED(data) 

544 return ccache 

545 

546 def saveKirbiFile(self, fileName): 

547 f = open(fileName, 'wb+') 

548 f.write(self.toKRBCRED()) 

549 f.close() 

550 

551 def fromKRBCRED(self, encodedKrbCred): 

552 

553 krbCred = decoder.decode(encodedKrbCred, asn1Spec=KRB_CRED())[0] 

554 encKrbCredPart = decoder.decode(krbCred['enc-part']['cipher'], asn1Spec=EncKrbCredPart())[0] 

555 krbCredInfo = encKrbCredPart['ticket-info'][0] 

556 

557 self.setDefaultHeader() 

558 

559 tmpPrincipal = types.Principal() 

560 tmpPrincipal.from_asn1(krbCredInfo, 'prealm', 'pname') 

561 self.principal = Principal() 

562 self.principal.fromPrincipal(tmpPrincipal) 

563 

564 credential = Credential() 

565 server = types.Principal() 

566 server.from_asn1(krbCredInfo, 'srealm', 'sname') 

567 tmpServer = Principal() 

568 tmpServer.fromPrincipal(server) 

569 

570 credential['client'] = self.principal 

571 credential['server'] = tmpServer 

572 credential['is_skey'] = 0 

573 

574 credential['key'] = KeyBlock() 

575 credential['key']['keytype'] = int(krbCredInfo['key']['keytype']) 

576 credential['key']['keyvalue'] = str(krbCredInfo['key']['keyvalue']) 

577 credential['key']['keylen'] = len(credential['key']['keyvalue']) 

578 

579 credential['time'] = Times() 

580 

581 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['starttime'])) 

582 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['endtime'])) 

583 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['renew-till'])) 

584 

585 flags = self.reverseFlags(krbCredInfo['flags']) 

586 credential['tktflags'] = flags 

587 

588 credential['num_address'] = 0 

589 credential.ticket = CountedOctetString() 

590 credential.ticket['data'] = encoder.encode( 

591 krbCred['tickets'][0].clone(tagSet=Ticket.tagSet, cloneValueFlag=True) 

592 ) 

593 credential.ticket['length'] = len(credential.ticket['data']) 

594 credential.secondTicket = CountedOctetString() 

595 credential.secondTicket['data'] = '' 

596 credential.secondTicket['length'] = 0 

597 

598 self.credentials.append(credential) 

599 

600 def toKRBCRED(self): 

601 principal = self.principal 

602 credential = self.credentials[0] 

603 

604 krbCredInfo = KrbCredInfo() 

605 

606 krbCredInfo['key'] = noValue 

607 krbCredInfo['key']['keytype'] = credential['key']['keytype'] 

608 krbCredInfo['key']['keyvalue'] = credential['key']['keyvalue'] 

609 

610 krbCredInfo['prealm'] = principal.realm.fields['data'] 

611 

612 krbCredInfo['pname'] = noValue 

613 krbCredInfo['pname']['name-type'] = principal.header['name_type'] 

614 seq_set_iter(krbCredInfo['pname'], 'name-string', (principal.components[0].fields['data'],)) 

615 

616 krbCredInfo['flags'] = credential['tktflags'] 

617 

618 krbCredInfo['starttime'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['starttime'])) 

619 krbCredInfo['endtime'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['endtime'])) 

620 krbCredInfo['renew-till'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['renew_till'])) 

621 

622 krbCredInfo['srealm'] = credential['server'].realm.fields['data'] 

623 

624 krbCredInfo['sname'] = noValue 

625 krbCredInfo['sname']['name-type'] = credential['server'].header['name_type'] 

626 seq_set_iter(krbCredInfo['sname'], 'name-string', 

627 (credential['server'].components[0].fields['data'], credential['server'].realm.fields['data'])) 

628 

629 encKrbCredPart = EncKrbCredPart() 

630 seq_set_iter(encKrbCredPart, 'ticket-info', (krbCredInfo,)) 

631 

632 krbCred = KRB_CRED() 

633 krbCred['pvno'] = 5 

634 krbCred['msg-type'] = 22 

635 

636 krbCred['enc-part'] = noValue 

637 krbCred['enc-part']['etype'] = 0 

638 krbCred['enc-part']['cipher'] = encoder.encode(encKrbCredPart) 

639 

640 ticket = decoder.decode(credential.ticket['data'], asn1Spec=Ticket())[0] 

641 seq_set_iter(krbCred, 'tickets', (ticket,)) 

642 

643 encodedKrbCred = encoder.encode(krbCred) 

644 

645 return encodedKrbCred 

646 

647 def setDefaultHeader(self): 

648 self.headers = [] 

649 header = Header() 

650 header['tag'] = 1 

651 header['taglen'] = 8 

652 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00' 

653 self.headers.append(header) 

654 

655 

656 

657if __name__ == '__main__': 657 ↛ 658line 657 didn't jump to line 658, because the condition on line 657 was never true

658 import os 

659 ccache = CCache.loadFile(os.getenv('KRB5CCNAME')) 

660 ccache.prettyPrint()