Beispiel #1
0
        /// <summary>
        /// Manually set the token privileges in 1 call. This can be used to
        /// enable/disable/remove privileges at the same time. Enable/Disable
        /// privileges function's return value can be used in state to undo the
        /// action of those functions.
        /// </summary>
        /// <param name="token">The current process to set the privilege state on</param>
        /// <param name="state">Dictionary<string, bool?> where the key is the privilege constant and the bool is the action; true == enable, false == disable, null == remove</string></param>
        /// <returns>Dictionary<string, bool?> of the previous state, can be used on a subsequent call to undo the action</string></returns>
        public static Dictionary <string, bool?> SetTokenPrivileges(SafeHandle token, Dictionary <string, bool?> state)
        {
            Helpers.LUID_AND_ATTRIBUTES[] privilegeAttr = new Helpers.LUID_AND_ATTRIBUTES[state.Count];
            int i = 0;

            foreach (KeyValuePair <string, bool?> entry in state)
            {
                if (!Advapi32.LookupPrivilegeValueW(null, entry.Key, out var luid))
                {
                    throw new Win32Exception(String.Format("LookupPrivilegeValue({0}) failed", entry.Key));
                }

                PrivilegeAttributes attributes;
                switch (entry.Value)
                {
                case true:
                    attributes = PrivilegeAttributes.Enabled;
                    break;

                case false:
                    attributes = PrivilegeAttributes.Disabled;
                    break;

                default:
                    attributes = PrivilegeAttributes.Removed;
                    break;
                }

                privilegeAttr[i].Luid       = luid;
                privilegeAttr[i].Attributes = attributes;
                i++;
            }

            return(AdjustTokenPrivileges(token, privilegeAttr));
        }
Beispiel #2
0
        /// <summary>
        /// Get the information for all privileges on the process token
        /// specified.
        /// </summary>
        /// <param name="token">The user token to get the privilege information</param>
        /// <returns>Dictionary<String, PrivilegeAttributes> the info on all the privileges on the process token</String></returns>
        public static Dictionary <String, PrivilegeAttributes> GetAllPrivilegeInfo(SafeHandle token)
        {
            Dictionary <String, PrivilegeAttributes> info = new Dictionary <String, PrivilegeAttributes>();

            IntPtr hToken = IntPtr.Zero;

            if (!Advapi32.OpenProcessToken(token, TokenAccessLevels.Query, out hToken))
            {
                throw new Win32Exception("OpenProcessToken() failed");
            }

            try
            {
                Advapi32.GetTokenInformation(hToken, TOKEN_PRIVILEGES, IntPtr.Zero, 0, out var tokenLength);

                Helpers.LUID_AND_ATTRIBUTES[] privileges;
                IntPtr privilegesPtr = Marshal.AllocHGlobal((int)tokenLength);
                try
                {
                    if (!Advapi32.GetTokenInformation(hToken, TOKEN_PRIVILEGES, privilegesPtr, tokenLength, out tokenLength))
                    {
                        throw new Win32Exception("GetTokenInformation() for TOKEN_PRIVILEGES failed");
                    }

                    Helpers.TOKEN_PRIVILEGES privilegeInfo = Marshal.PtrToStructure <Helpers.TOKEN_PRIVILEGES>(privilegesPtr);
                    privileges = new Helpers.LUID_AND_ATTRIBUTES[privilegeInfo.PrivilegeCount];
                    PtrToStructureArray(privileges, IntPtr.Add(privilegesPtr, Marshal.SizeOf(privilegeInfo.PrivilegeCount)));
                }
                finally
                {
                    Marshal.FreeHGlobal(privilegesPtr);
                }

                info = privileges.ToDictionary(p => GetPrivilegeName(p.Luid), p => p.Attributes);
            }
            finally
            {
                Kernel32.CloseHandle(hToken);
            }
            return(info);
        }
Beispiel #3
0
        private static Dictionary <string, bool?> AdjustTokenPrivileges(SafeHandle token, Helpers.LUID_AND_ATTRIBUTES[]?newState)
        {
            bool   disableAllPrivileges = true;
            IntPtr newStatePtr          = IntPtr.Zero;

            Helpers.LUID_AND_ATTRIBUTES[] oldStatePrivileges;

            if (newState != null)
            {
                disableAllPrivileges = false;

                // Need to manually marshal the bytes requires for newState as the constant size
                // of LUID_AND_ATTRIBUTES is set to 1 and can't be overridden at runtime, TOKEN_PRIVILEGES
                // always contains at least 1 entry so we need to calculate the extra size if there are
                // nore than 1 LUID_AND_ATTRIBUTES entry
                int tokenPrivilegesSize = Marshal.SizeOf(typeof(Helpers.TOKEN_PRIVILEGES));
                int luidAttrSize        = 0;
                if (newState.Length > 1)
                {
                    luidAttrSize = Marshal.SizeOf(typeof(Helpers.LUID_AND_ATTRIBUTES)) * (newState.Length - 1);
                }
                int    totalSize     = tokenPrivilegesSize + luidAttrSize;
                byte[] newStateBytes = new byte[totalSize];

                // get the first entry that includes the struct details
                Helpers.TOKEN_PRIVILEGES tokenPrivileges = new Helpers.TOKEN_PRIVILEGES()
                {
                    PrivilegeCount = (UInt32)newState.Length,
                    Privileges     = new Helpers.LUID_AND_ATTRIBUTES[1],
                };
                if (newState.Length > 0)
                {
                    tokenPrivileges.Privileges[0] = newState[0];
                }
                int offset = StructureToBytes(tokenPrivileges, newStateBytes, 0);

                // copy the remaining LUID_AND_ATTRIBUTES (if any)
                for (int i = 1; i < newState.Length; i++)
                {
                    offset += StructureToBytes(newState[i], newStateBytes, offset);
                }

                // finally create the pointer to the byte array we just created
                newStatePtr = Marshal.AllocHGlobal(newStateBytes.Length);
                Marshal.Copy(newStateBytes, 0, newStatePtr, newStateBytes.Length);
            }

            try
            {
                IntPtr hToken = IntPtr.Zero;
                if (!Advapi32.OpenProcessToken(token, TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, out hToken))
                {
                    throw new Win32Exception("OpenProcessToken() failed with Query and AdjustPrivileges");
                }
                try
                {
                    IntPtr oldStatePtr = Marshal.AllocHGlobal(0);
                    if (!Advapi32.AdjustTokenPrivileges(hToken, disableAllPrivileges, newStatePtr, 0, oldStatePtr, out var returnLength))
                    {
                        int errCode = Marshal.GetLastWin32Error();
                        if (errCode != (int)Win32ErrorCodes.ERROR_INSUFFICIENT_BUFFER)
                        {
                            throw new Win32Exception(errCode, "AdjustTokenPrivileges() failed to get old state size");
                        }
                    }

                    // resize the oldStatePtr based on the length returned from Windows
                    Marshal.FreeHGlobal(oldStatePtr);
                    oldStatePtr = Marshal.AllocHGlobal((int)returnLength);
                    try
                    {
                        bool res     = Advapi32.AdjustTokenPrivileges(hToken, disableAllPrivileges, newStatePtr, returnLength, oldStatePtr, out returnLength);
                        int  errCode = Marshal.GetLastWin32Error();

                        // even when res == true, ERROR_NOT_ALL_ASSIGNED may be set as the last error code
                        if (!res || errCode != (int)Win32ErrorCodes.ERROR_SUCCESS)
                        {
                            throw new Win32Exception(errCode, "AdjustTokenPrivileges() failed");
                        }

                        // Marshal the oldStatePtr to the struct
                        Helpers.TOKEN_PRIVILEGES oldState = Marshal.PtrToStructure <Helpers.TOKEN_PRIVILEGES>(oldStatePtr);
                        oldStatePrivileges = new Helpers.LUID_AND_ATTRIBUTES[oldState.PrivilegeCount];
                        PtrToStructureArray(oldStatePrivileges, IntPtr.Add(oldStatePtr, Marshal.SizeOf(oldState.PrivilegeCount)));
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(oldStatePtr);
                    }
                }
                finally
                {
                    Kernel32.CloseHandle(hToken);
                }
            }
            finally
            {
                if (newStatePtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(newStatePtr);
                }
            }

            return(oldStatePrivileges.ToDictionary(p => GetPrivilegeName(p.Luid), p => (bool?)p.Attributes.HasFlag(PrivilegeAttributes.Enabled)));
        }