Exemplo n.º 1
0
        static ProcessManager()
        {
            // In order to query information (OpenProcess) on some protected processes
            // like csrss, we need SeDebugPrivilege privilege.
            // After removing the depenecy on Performance Counter, we don't have a chance
            // to run the code in CLR performance counter to ask for this privilege.
            // So we will try to get the privilege here.
            // We could fail if the user account doesn't have right to do this, but that's fair.

            Interop.LUID luid = new Interop.LUID();
            if (!Interop.mincore.LookupPrivilegeValue(null, "SeDebugPrivilege", out luid))
            {
                return;
            }

            SafeTokenHandle tokenHandle = null;
            try
            {
                if (!Interop.mincore.OpenProcessToken(
                        Interop.mincore.GetCurrentProcess(),
                        TOKEN_ADJUST_PRIVILEGES,
                        out tokenHandle))
                {
                    return;
                }

                Interop.TokenPrivileges tp = new Interop.TokenPrivileges();
                tp.Luid = luid;
                tp.Attributes = Interop.SE_PRIVILEGE_ENABLED;

                // AdjustTokenPrivileges can return true even if it didn't succeed (when ERROR_NOT_ALL_ASSIGNED is returned).
                Interop.mincore.AdjustTokenPrivileges(tokenHandle, false, tp, 0, IntPtr.Zero, IntPtr.Zero);
            }
            finally
            {
                if (tokenHandle != null)
                {
                    tokenHandle.Dispose();
                }
            }
        }
Exemplo n.º 2
0
        public void Execute(Dictionary <string, string> arguments)
        {
            string user     = "";
            string domain   = "";
            string password = "";
            string hash     = "";
            string dc       = "";
            bool   ptt      = false;

            Interop.LUID       luid    = new Interop.LUID();
            Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;

            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("/dc"))
            {
                dc = arguments["/dc"];
            }

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

                string salt = String.Format("{0}{1}", domain.ToUpper(), user.ToLower());
                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;
                    }
                }
                hash = Crypto.KerberosPasswordHash(encType, password, salt);
            }

            else 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("/ptt"))
            {
                ptt = true;
            }

            if (arguments.ContainsKey("/luid"))
            {
                try
                {
                    luid = new Interop.LUID(arguments["/luid"]);
                }
                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 /password , or a [/des|/rc4|/aes128|/aes256] hash!\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
            {
                Ask.TGT(user, domain, hash, encType, ptt, dc, luid, true);
                return;
            }
        }
Exemplo n.º 3
0
        private static void SetPrivilege(string privilegeName, int attrib)
        {
            SafeTokenHandle hToken = null;
            Interop.LUID debugValue = new Interop.LUID();

            // this is only a "pseudo handle" to the current process - no need to close it later
            SafeProcessHandle processHandle = Interop.mincore.GetCurrentProcess();

            // get the process token so we can adjust the privilege on it.  We DO need to
            // close the token when we're done with it.
            if (!Interop.mincore.OpenProcessToken(processHandle, Interop.TOKEN_ADJUST_PRIVILEGES, out hToken))
            {
                throw new Win32Exception();
            }

            try
            {
                if (!Interop.mincore.LookupPrivilegeValue(null, privilegeName, out debugValue))
                {
                    throw new Win32Exception();
                }

                Interop.TokenPrivileges tkp = new Interop.TokenPrivileges();
                tkp.Luid = debugValue;
                tkp.Attributes = attrib;

                Interop.mincore.AdjustTokenPrivileges(hToken, false, tkp, 0, IntPtr.Zero, IntPtr.Zero);

                // AdjustTokenPrivileges can return true even if it failed to
                // set the privilege, so we need to use GetLastError
                if (Marshal.GetLastWin32Error() != Interop.ERROR_SUCCESS)
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
#if FEATURE_TRACESWITCH
                Debug.WriteLineIf(_processTracing.TraceVerbose, "Process - CloseHandle(processToken)");
#endif
                if (hToken != null)
                {
                    hToken.Dispose();
                }
            }
        }
Exemplo n.º 4
0
        public void Execute(Dictionary <string, string> arguments)
        {
            string altservice = "";

            Interop.LUID luid = new Interop.LUID();
            bool         ptt  = false;

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

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

            if (arguments.ContainsKey("/altservice"))
            {
                altservice = arguments["/altservice"];
            }
            else
            {
                Console.WriteLine("\r\n[X] An /altservice:SNAME or /altservice:SNAME/host needs to be supplied!\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);
                    LSA.SubstituteTGSSname(kirbi, altservice, ptt, luid);
                }
                else if (File.Exists(kirbi64))
                {
                    byte[]   kirbiBytes = File.ReadAllBytes(kirbi64);
                    KRB_CRED kirbi      = new KRB_CRED(kirbiBytes);
                    LSA.SubstituteTGSSname(kirbi, altservice, ptt, 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 /ticket:X needs to be supplied!\r\n");
                return;
            }
        }
Exemplo n.º 5
0
        internal unsafe AuthZSet(
            byte[] userSid,
            NetCred credentials,
            ContextOptions contextOptions,
            string flatUserAuthority,
            StoreCtx userStoreCtx,
            object userCtxBase)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "AuthZSet",
                                    "AuthZSet: SID={0}, authority={1}, storeCtx={2}",
                                    Utils.ByteArrayToString(userSid),
                                    flatUserAuthority,
                                    userStoreCtx.GetType());

            _userType       = userStoreCtx.OwningContext.ContextType;
            _userStoreCtx   = userStoreCtx;
            _credentials    = credentials;
            _contextOptions = contextOptions;

            // flatUserAuthority is flat domain name if userType == Domain,
            // flat host name if userType == LocalMachine
            _flatUserAuthority = flatUserAuthority;

            // Preload the PrincipalContext cache with the user's PrincipalContext
            _contexts[flatUserAuthority] = userStoreCtx.OwningContext;

            //
            // Get the SIDs of the groups to which the user belongs
            //

            IntPtr pClientContext = IntPtr.Zero;
            IntPtr pResManager    = IntPtr.Zero;
            IntPtr pBuffer        = IntPtr.Zero;

            try
            {
                Interop.LUID luid = default;

                _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid());
                _psUserSid    = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));

                bool f;
                int  lastError = 0;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager");

                // Create a resource manager
                f = Interop.Authz.AuthzInitializeResourceManager(
                    Interop.Authz.AUTHZ_RM_FLAG_NO_AUDIT,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    null,
                    out pResManager
                    );

                if (f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID");

                    // Construct a context for the user based on the user's SID
                    f = Interop.Authz.AuthzInitializeContextFromSid(
                        0,                                          // default flags
                        _psUserSid.DangerousGetHandle(),
                        pResManager,
                        IntPtr.Zero,
                        luid,
                        IntPtr.Zero,
                        out pClientContext
                        );

                    if (f)
                    {
                        int bufferSize = 0;

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx");

                        // Extract the group SIDs from the user's context.  Determine the size of the buffer we need.
                        f = Interop.Authz.AuthzGetInformationFromContext(
                            pClientContext,
                            2,                                            // AuthzContextInfoGroupsSids
                            0,
                            out bufferSize,
                            IntPtr.Zero
                            );
                        if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize);

                            Debug.Assert(bufferSize > 0);

                            // Set up the needed buffer
                            pBuffer = Marshal.AllocHGlobal(bufferSize);

                            // Extract the group SIDs from the user's context, into our buffer.0
                            f = Interop.Authz.AuthzGetInformationFromContext(
                                pClientContext,
                                2,                                            // AuthzContextInfoGroupsSids
                                bufferSize,
                                out bufferSize,
                                pBuffer
                                );

                            if (f)
                            {
                                // Marshall the native buffer into managed SID_AND_ATTR structures.
                                // The native buffer holds a TOKEN_GROUPS structure:
                                //
                                //        struct TOKEN_GROUPS {
                                //                DWORD GroupCount;
                                //                SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
                                //        };
                                //

                                // Extract TOKEN_GROUPS.GroupCount

                                Interop.TOKEN_GROUPS tokenGroups = (Interop.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(Interop.TOKEN_GROUPS));

                                uint groupCount = tokenGroups.GroupCount;

                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount);

                                // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling
                                // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR.
                                Interop.SID_AND_ATTRIBUTES[] groups = new Interop.SID_AND_ATTRIBUTES[groupCount];

                                IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(Interop.TOKEN_GROUPS)) - sizeof(Interop.SID_AND_ATTRIBUTES));

                                for (int i = 0; i < groupCount; i++)
                                {
                                    groups[i] = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure(currentItem, typeof(Interop.SID_AND_ATTRIBUTES));

                                    currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(Interop.SID_AND_ATTRIBUTES)));
                                }

                                _groupSidList = new SidList(groups);
                            }
                            else
                            {
                                lastError = Marshal.GetLastWin32Error();
                            }
                        }
                        else
                        {
                            lastError = Marshal.GetLastWin32Error();
                            Debug.Fail("With a zero-length buffer, this should have never succeeded");
                        }
                    }
                    else
                    {
                        lastError = Marshal.GetLastWin32Error();
                    }
                }
                else
                {
                    lastError = Marshal.GetLastWin32Error();
                }

                if (!f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError);

                    throw new PrincipalOperationException(
                              SR.Format(
                                  SR.AuthZFailedToRetrieveGroupList,
                                  lastError));
                }

                // Save off the buffer since it still holds the native SIDs referenced by SidList
                _psBuffer = new SafeMemoryPtr(pBuffer);
                pBuffer   = IntPtr.Zero;
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message);

                _psBuffer?.Dispose();
                _psUserSid?.Dispose();
                _psMachineSid?.Dispose();

                // We're on a platform that doesn't have the AuthZ library
                if (e is DllNotFoundException)
                {
                    throw new NotSupportedException(SR.AuthZNotSupported, e);
                }

                if (e is EntryPointNotFoundException)
                {
                    throw new NotSupportedException(SR.AuthZNotSupported, e);
                }

                throw;
            }
            finally
            {
                if (pClientContext != IntPtr.Zero)
                {
                    Interop.Authz.AuthzFreeContext(pClientContext);
                }

                if (pResManager != IntPtr.Zero)
                {
                    Interop.Authz.AuthzFreeResourceManager(pResManager);
                }

                if (pBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pBuffer);
                }
            }
        }