コード例 #1
0
        private static NativeHelpers.SECURITY_LOGON_TYPE GetTokenLogonType(SafeNativeHandle hToken)
        {
            UInt64 tokenLuidId;

            using (SafeMemoryBuffer tokenInfo = GetTokenInformation(hToken, NativeHelpers.TokenInformationClass.TokenStatistics))
            {
                NativeHelpers.TOKEN_STATISTICS stats = (NativeHelpers.TOKEN_STATISTICS)Marshal.PtrToStructure(
                    tokenInfo.DangerousGetHandle(), typeof(NativeHelpers.TOKEN_STATISTICS));
                tokenLuidId = (UInt64)stats.AuthenticationId;
            }

            // Default to Network, if we weren't able to get the actual type treat it as an error and assume
            // we don't want to run a process with the token
            NativeHelpers.SECURITY_LOGON_TYPE logonType = NativeHelpers.SECURITY_LOGON_TYPE.Network;
            UInt32 sessionCount;
            SafeLsaMemoryBuffer sessionPtr;
            UInt32 res = NativeMethods.LsaEnumerateLogonSessions(out sessionCount, out sessionPtr);

            if (res != 0)
            {
                throw new Win32Exception((int)NativeMethods.LsaNtStatusToWinError(res), "LsaEnumerateLogonSession() failed");
            }
            using (sessionPtr)
            {
                for (IntPtr p = sessionPtr.DangerousGetHandle();
                     p != IntPtr.Add(sessionPtr.DangerousGetHandle(), (int)(IntPtr.Size * sessionCount));
                     p = IntPtr.Add(p, Marshal.SizeOf(typeof(NativeHelpers.LUID))))
                {
                    SafeLsaMemoryBuffer sessionDataPtr;
                    res = NativeMethods.LsaGetLogonSessionData(p, out sessionDataPtr);
                    if (res != 0)
                    {
                        continue;
                    }

                    using (sessionDataPtr)
                    {
                        NativeHelpers.SECURITY_LOGON_SESSION_DATA sessionData = (NativeHelpers.SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(
                            sessionDataPtr.DangerousGetHandle(), typeof(NativeHelpers.SECURITY_LOGON_SESSION_DATA));
                        UInt64 sessionId = (UInt64)sessionData.LogonId;
                        if (sessionId == tokenLuidId)
                        {
                            logonType = sessionData.LogonType;
                            break;
                        }
                    }
                }
            }

            return(logonType);
        }
コード例 #2
0
ファイル: Ansible.Become.cs プロジェクト: zorgzerg/ansible
        private static SafeNativeHandle GetPrimaryTokenForUser(SecurityIdentifier sid, List <string> requiredPrivileges = null)
        {
            // According to CreateProcessWithTokenW we require a token with
            //  TOKEN_QUERY, TOKEN_DUPLICATE and TOKEN_ASSIGN_PRIMARY
            // Also add in TOKEN_IMPERSONATE so we can get an impersonated token
            TokenAccessLevels dwAccess = TokenAccessLevels.Query |
                                         TokenAccessLevels.Duplicate |
                                         TokenAccessLevels.AssignPrimary |
                                         TokenAccessLevels.Impersonate;

            foreach (SafeNativeHandle hToken in TokenUtil.EnumerateUserTokens(sid, dwAccess))
            {
                // Filter out any Network logon tokens, using become with that is useless when S4U
                // can give us a Batch logon
                NativeHelpers.SECURITY_LOGON_TYPE tokenLogonType = GetTokenLogonType(hToken);
                if (tokenLogonType == NativeHelpers.SECURITY_LOGON_TYPE.Network)
                {
                    continue;
                }

                // Check that the required privileges are on the token
                if (requiredPrivileges != null)
                {
                    List <string> actualPrivileges = TokenUtil.GetTokenPrivileges(hToken).Select(x => x.Name).ToList();
                    int           missing          = requiredPrivileges.Where(x => !actualPrivileges.Contains(x)).Count();
                    if (missing > 0)
                    {
                        continue;
                    }
                }

                // Duplicate the token to convert it to a primary token with the access level required.
                try
                {
                    return(TokenUtil.DuplicateToken(hToken, TokenAccessLevels.MaximumAllowed, SecurityImpersonationLevel.Anonymous,
                                                    TokenType.Primary));
                }
                catch (Process.Win32Exception)
                {
                    continue;
                }
            }

            return(null);
        }
コード例 #3
0
        private static SafeNativeHandle GetPrimaryTokenForUser(SecurityIdentifier sid,
                                                               List <string> requiredPrivileges = null, bool mostPrivileges = false)
        {
            // According to CreateProcessWithTokenW we require a token with
            //  TOKEN_QUERY, TOKEN_DUPLICATE and TOKEN_ASSIGN_PRIMARY
            // Also add in TOKEN_IMPERSONATE so we can get an impersonated token
            TokenAccessLevels dwAccess = TokenAccessLevels.Query |
                                         TokenAccessLevels.Duplicate |
                                         TokenAccessLevels.AssignPrimary |
                                         TokenAccessLevels.Impersonate;

            SafeNativeHandle userToken = null;
            int privilegeCount         = 0;

            foreach (SafeNativeHandle hToken in TokenUtil.EnumerateUserTokens(sid, dwAccess))
            {
                // Filter out any Network logon tokens, using become with that is useless when S4U
                // can give us a Batch logon
                NativeHelpers.SECURITY_LOGON_TYPE tokenLogonType = GetTokenLogonType(hToken);
                if (tokenLogonType == NativeHelpers.SECURITY_LOGON_TYPE.Network)
                {
                    continue;
                }

                List <string> actualPrivileges = TokenUtil.GetTokenPrivileges(hToken).Select(x => x.Name).ToList();

                // If the token has less or the same number of privileges than the current token, skip it.
                if (mostPrivileges && privilegeCount >= actualPrivileges.Count)
                {
                    continue;
                }

                // Check that the required privileges are on the token
                if (requiredPrivileges != null)
                {
                    int missing = requiredPrivileges.Where(x => !actualPrivileges.Contains(x)).Count();
                    if (missing > 0)
                    {
                        continue;
                    }
                }

                // Duplicate the token to convert it to a primary token with the access level required.
                try
                {
                    userToken = TokenUtil.DuplicateToken(hToken, TokenAccessLevels.MaximumAllowed,
                                                         SecurityImpersonationLevel.Anonymous, TokenType.Primary);
                    privilegeCount = actualPrivileges.Count;
                }
                catch (Process.Win32Exception)
                {
                    continue;
                }

                // If we don't care about getting the token with the most privileges, escape the loop as we already
                // have a token.
                if (!mostPrivileges)
                {
                    break;
                }
            }

            return(userToken);
        }
コード例 #4
0
        private static SafeNativeHandle GetPrimaryTokenForUser(SecurityIdentifier sid, List <string> requiredPrivileges = null)
        {
            NativeHelpers.ProcessAccessFlags accessFlags = NativeHelpers.ProcessAccessFlags.PROCESS_QUERY_INFORMATION;
            // According to CreateProcessWithTokenW we require a token with
            //  TOKEN_QUERY, TOKEN_DUPLICATE and TOKEN_ASSIGN_PRIMARY
            // Also add in TOKEN_IMPERSONATE so we can get an impersonated token
            TokenAccessLevels dwAccess = TokenAccessLevels.Query |
                                         TokenAccessLevels.Duplicate |
                                         TokenAccessLevels.AssignPrimary |
                                         TokenAccessLevels.Impersonate;

            foreach (System.Diagnostics.Process process in System.Diagnostics.Process.GetProcesses())
            {
                using (process)
                {
                    using (SafeNativeHandle hProcess = NativeMethods.OpenProcess(accessFlags, false, (UInt32)process.Id))
                    {
                        if (hProcess.IsInvalid)
                        {
                            continue;
                        }

                        SafeNativeHandle hToken;
                        NativeMethods.OpenProcessToken(hProcess, dwAccess, out hToken);
                        if (hToken.IsInvalid)
                        {
                            continue;
                        }

                        using (hToken)
                        {
                            if (!sid.Equals(GetTokenUserSID(hToken)))
                            {
                                continue;
                            }

                            // Filter out any Network logon tokens, using become with that is useless when S4U
                            // can give us a Batch logon
                            NativeHelpers.SECURITY_LOGON_TYPE tokenLogonType = GetTokenLogonType(hToken);
                            if (tokenLogonType == NativeHelpers.SECURITY_LOGON_TYPE.Network)
                            {
                                continue;
                            }

                            // Check that the required privileges are on the token
                            if (requiredPrivileges != null)
                            {
                                List <string> actualPrivileges = GetTokenPrivileges(hToken);
                                int           missing          = requiredPrivileges.Where(x => !actualPrivileges.Contains(x)).Count();
                                if (missing > 0)
                                {
                                    continue;
                                }
                            }

                            SafeNativeHandle dupToken;
                            if (!NativeMethods.DuplicateTokenEx(hToken, TokenAccessLevels.MaximumAllowed,
                                                                IntPtr.Zero, NativeHelpers.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                                                                NativeHelpers.TOKEN_TYPE.TokenPrimary, out dupToken))
                            {
                                continue;
                            }

                            return(dupToken);
                        }
                    }
                }
            }

            return(null);
        }