From c13534a1a179f23b40f980942adeed64012055b1 Mon Sep 17 00:00:00 2001 From: michael-dev Date: Wed, 19 Apr 2023 08:47:56 +0200 Subject: [PATCH] Currently asktgt ignores /changepw when /certificate is used. Fix this by adding support for /changepw with /certificates. Can be used to change the ad user password of a user using smartcard / certificate authentication. Tested with Windows 10 + Windows Server 2019. --- Rubeus/Commands/Asktgt.cs | 2 +- Rubeus/lib/Ask.cs | 4 ++-- Rubeus/lib/krb_structures/AS_REQ.cs | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Rubeus/Commands/Asktgt.cs b/Rubeus/Commands/Asktgt.cs index 6cdb16f6..f4e88e55 100644 --- a/Rubeus/Commands/Asktgt.cs +++ b/Rubeus/Commands/Asktgt.cs @@ -255,7 +255,7 @@ public void Execute(Dictionary arguments) else if (String.IsNullOrEmpty(certificate)) Ask.TGT(user, domain, hash, encType, outfile, ptt, dc, luid, true, opsec, servicekey, changepw, pac, proxyUrl, service); else - Ask.TGT(user, domain, certificate, password, encType, outfile, ptt, dc, luid, true, verifyCerts, servicekey, getCredentials, proxyUrl, service); + Ask.TGT(user, domain, certificate, password, encType, outfile, ptt, dc, luid, true, verifyCerts, servicekey, getCredentials, proxyUrl, service, changepw); return; } diff --git a/Rubeus/lib/Ask.cs b/Rubeus/lib/Ask.cs index 21d15d17..7669cc22 100644 --- a/Rubeus/lib/Ask.cs +++ b/Rubeus/lib/Ask.cs @@ -186,7 +186,7 @@ public static X509Certificate2 FindCertificate(string certificate, string storeP } } - public static byte[] TGT(string userName, string domain, string certFile, string certPass, Interop.KERB_ETYPE etype, string outfile, bool ptt, string domainController = "", LUID luid = new LUID(), bool describe = false, bool verifyCerts = false, string servicekey = "", bool getCredentials = false, string proxyUrl = null, string service = null) { + public static byte[] TGT(string userName, string domain, string certFile, string certPass, Interop.KERB_ETYPE etype, string outfile, bool ptt, string domainController = "", LUID luid = new LUID(), bool describe = false, bool verifyCerts = false, string servicekey = "", bool getCredentials = false, string proxyUrl = null, string service = null, bool changepw = false) { try { X509Certificate2 cert = FindCertificate(certFile, certPass); @@ -206,7 +206,7 @@ public static X509Certificate2 FindCertificate(string certificate, string storeP Console.WriteLine("[*] Using PKINIT with etype {0} and subject: {1} ", etype, cert.Subject); Console.WriteLine("[*] Building AS-REQ (w/ PKINIT preauth) for: '{0}\\{1}'", domain, userName); - AS_REQ pkinitASREQ = AS_REQ.NewASReq(userName, domain, cert, agreement, etype, verifyCerts, service); + AS_REQ pkinitASREQ = AS_REQ.NewASReq(userName, domain, cert, agreement, etype, verifyCerts, service, changepw); return InnerTGT(pkinitASREQ, etype, outfile, ptt, domainController, luid, describe, true, false, servicekey, getCredentials, proxyUrl); } catch (KerberosErrorException ex) { diff --git a/Rubeus/lib/krb_structures/AS_REQ.cs b/Rubeus/lib/krb_structures/AS_REQ.cs index 8b1e6534..b8f20fb7 100755 --- a/Rubeus/lib/krb_structures/AS_REQ.cs +++ b/Rubeus/lib/krb_structures/AS_REQ.cs @@ -159,7 +159,7 @@ public static AS_REQ NewASReq(string userName, string domain, string keyString, } //TODO: Insert DHKeyPair parameter also. - public static AS_REQ NewASReq(string userName, string domain, X509Certificate2 cert, KDCKeyAgreement agreement, Interop.KERB_ETYPE etype, bool verifyCerts = false, string service = null) { + public static AS_REQ NewASReq(string userName, string domain, X509Certificate2 cert, KDCKeyAgreement agreement, Interop.KERB_ETYPE etype, bool verifyCerts = false, string service = null, bool changepw = false) { // build a new AS-REQ for the given userName, domain, and etype, w/ PA-ENC-TIMESTAMP // used for "legit" AS-REQs w/ pre-auth @@ -198,11 +198,16 @@ public static AS_REQ NewASReq(string userName, string domain, X509Certificate2 c req.req_body.sname.name_string.Add(part); } } - else + else if (!changepw) { req.req_body.sname.name_string.Add("krbtgt"); req.req_body.sname.name_string.Add(domain); } + else + { + req.req_body.sname.name_string.Add("kadmin"); + req.req_body.sname.name_string.Add("changepw"); + } // add in our encryption type req.req_body.etypes.Add(etype);