diff --git a/nxc/protocols/smb/kerberos.py b/nxc/protocols/smb/kerberos.py index e8795a85..e71338df 100644 --- a/nxc/protocols/smb/kerberos.py +++ b/nxc/protocols/smb/kerberos.py @@ -1,5 +1,4 @@ import datetime -import logging import struct import random from six import b @@ -7,224 +6,226 @@ from six import b from pyasn1.codec.der import decoder, encoder from pyasn1.type.univ import noValue -from impacket.krb5.asn1 import AP_REQ, AS_REP, TGS_REQ, Authenticator, TGS_REP, seq_set, seq_set_iter, PA_FOR_USER_ENC, \ - Ticket as TicketAsn1, EncTGSRepPart, PA_PAC_OPTIONS +from impacket.krb5.asn1 import AP_REQ, AS_REP, TGS_REQ, Authenticator, TGS_REP, \ + seq_set, seq_set_iter, PA_FOR_USER_ENC, Ticket as TicketAsn1, EncTGSRepPart, \ + PA_PAC_OPTIONS from impacket.krb5.types import Principal, KerberosTime, Ticket from impacket.krb5.kerberosv5 import sendReceive, getKerberosTGT from impacket.krb5.ccache import CCache from impacket.krb5.crypto import Key, _enctype_table, _HMACMD5 from impacket.krb5 import constants -def kerberos_login_with_S4U(domain, hostname, username, password, nthash, lmhash, aesKey, kdcHost, impersonate, spn, useCache, no_s4u2proxy = False): - logger = logging.getLogger("nxc") - TGT = None - if useCache: - domain, user, tgt, _ = CCache.parseFile(domain, username, f"cifs/{hostname}") - if TGT is None: +from nxc.logger import nxc_logger + +def kerberos_login_with_S4U(domain, hostname, username, password, nthash, lmhash, aesKey, kdcHost, impersonate, spn, use_cache, no_s4u2proxy = False): + my_tgt = None + if use_cache: + domain, _, tgt, _ = CCache.parseFile(domain, username, f"cifs/{hostname}") + if my_tgt is None: raise - TGT = tgt["KDC_REP"] + my_tgt = tgt["KDC_REP"] cipher = tgt["cipher"] - sessionKey = tgt["sessionKey"] - if TGT is None: - userName = Principal(username, type=constants.PrincipalNameType.NT_PRINCIPAL.value) - logger.debug("Getting TGT for user") - tgt, cipher, _, sessionKey = getKerberosTGT(userName, password, domain, + session_key = tgt["sessionKey"] + if my_tgt is None: + principal = Principal(username, type=constants.PrincipalNameType.NT_PRINCIPAL.value) + nxc_logger.debug("Getting TGT for user") + tgt, cipher, _, session_key = getKerberosTGT(principal, password, domain, lmhash, nthash, aesKey, kdcHost) - TGT = decoder.decode(tgt, asn1Spec=AS_REP())[0] - decodedTGT=TGT + my_tgt = decoder.decode(tgt, asn1Spec=AS_REP())[0] + decoded_tgt=my_tgt # Extract the ticket from the TGT ticket = Ticket() - ticket.from_asn1(decodedTGT["ticket"]) + ticket.from_asn1(decoded_tgt["ticket"]) - apReq = AP_REQ() - apReq["pvno"] = 5 - apReq["msg-type"] = int(constants.ApplicationTagNumbers.AP_REQ.value) + ap_req = AP_REQ() + ap_req["pvno"] = 5 + ap_req["msg-type"] = int(constants.ApplicationTagNumbers.AP_REQ.value) opts = list() - apReq["ap-options"] = constants.encodeFlags(opts) - seq_set(apReq, "ticket", ticket.to_asn1) + ap_req["ap-options"] = constants.encodeFlags(opts) + seq_set(ap_req, "ticket", ticket.to_asn1) authenticator = Authenticator() authenticator["authenticator-vno"] = 5 - authenticator["crealm"] = str(decodedTGT["crealm"]) + authenticator["crealm"] = str(decoded_tgt["crealm"]) - clientName = Principal() - clientName.from_asn1(decodedTGT, "crealm", "cname") + client_name = Principal() + client_name.from_asn1(decoded_tgt, "crealm", "cname") - seq_set(authenticator, "cname", clientName.components_to_asn1) + seq_set(authenticator, "cname", client_name.components_to_asn1) now = datetime.datetime.utcnow() authenticator["cusec"] = now.microsecond authenticator["ctime"] = KerberosTime.to_asn1(now) - encodedAuthenticator = encoder.encode(authenticator) + encoded_authenticator = encoder.encode(authenticator) # Key Usage 7 # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes # TGS authenticator subkey), encrypted with the TGS session # key (Section 5.5.1) - encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7, encodedAuthenticator, None) + encrypted_encoded_authenticator = cipher.encrypt(session_key, 7, encoded_authenticator, None) - apReq["authenticator"] = noValue - apReq["authenticator"]["etype"] = cipher.enctype - apReq["authenticator"]["cipher"] = encryptedEncodedAuthenticator + ap_req["authenticator"] = noValue + ap_req["authenticator"]["etype"] = cipher.enctype + ap_req["authenticator"]["cipher"] = encrypted_encoded_authenticator - encodedApReq = encoder.encode(apReq) + encoded_ap_req = encoder.encode(ap_req) - tgsReq = TGS_REQ() + tgs_req = TGS_REQ() - tgsReq["pvno"] = 5 - tgsReq["msg-type"] = int(constants.ApplicationTagNumbers.TGS_REQ.value) + tgs_req["pvno"] = 5 + tgs_req["msg-type"] = int(constants.ApplicationTagNumbers.TGS_REQ.value) - tgsReq["padata"] = noValue - tgsReq["padata"][0] = noValue - tgsReq["padata"][0]["padata-type"] = int(constants.PreAuthenticationDataTypes.PA_TGS_REQ.value) - tgsReq["padata"][0]["padata-value"] = encodedApReq + tgs_req["padata"] = noValue + tgs_req["padata"][0] = noValue + tgs_req["padata"][0]["padata-type"] = int(constants.PreAuthenticationDataTypes.PA_TGS_REQ.value) + tgs_req["padata"][0]["padata-value"] = encoded_ap_req # In the S4U2self KRB_TGS_REQ/KRB_TGS_REP protocol extension, a service # requests a service ticket to itself on behalf of a user. The user is - # identified to the KDC by the user"s name and realm. - clientName = Principal(impersonate, type=constants.PrincipalNameType.NT_PRINCIPAL.value) + # identified to the KDC by the user's name and realm. + client_name = Principal(impersonate, type=constants.PrincipalNameType.NT_PRINCIPAL.value) - S4UByteArray = struct.pack("