internal static extern bool AdjustTokenPrivileges( SafeTokenHandle TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGE NewState, uint BufferLength, ref TOKEN_PRIVILEGE PreviousState, ref uint ReturnLength);
internal static extern bool AdjustTokenPrivileges( SafeTokenHandle TokenHandle, bool DisableAllPrivileges, TokenPrivileges NewState, int BufferLength, IntPtr PreviousState, IntPtr ReturnLength );
/// <summary> /// The function checks whether the primary access token of the process belongs /// to user account that is a member of the local Administrators group, even if /// it currently is not elevated. /// </summary> /// <returns> /// Returns true if the primary access token of the process belongs to user /// account that is a member of the local Administrators group. Returns false /// if the token does not. /// </returns> /// <exception cref="System.ComponentModel.Win32Exception"> /// When any native Windows API call fails, the function throws a Win32Exception /// with the last error code. /// </exception> public static bool IsUserInAdminGroup() { bool fInAdminGroup = false; SafeTokenHandle hTokenToCheck = null; // Open the access token of the current process for query and duplicate. SafeTokenHandle hToken = SafeTokenHandle.FromCurrentProcess(AccessTypes.TokenQuery | AccessTypes.TokenDuplicate); // Determine whether system is running Windows Vista or later operating // systems (major version >= 6) because they support linked tokens, but // previous versions (major version < 6) do not. if (Environment.OSVersion.Version.Major >= 6) { // Running Windows Vista or later (major version >= 6). // Determine token type: limited, elevated, or default. // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET. TOKEN_ELEVATION_TYPE elevType = hToken.GetInfo<TOKEN_ELEVATION_TYPE>(TOKEN_INFORMATION_CLASS.TokenElevationType); // If limited, get the linked elevated token for further check. if (elevType == TOKEN_ELEVATION_TYPE.Limited) { // Marshal the linked token value from native to .NET. IntPtr hLinkedToken = hToken.GetInfo<IntPtr>(TOKEN_INFORMATION_CLASS.TokenLinkedToken); hTokenToCheck = new SafeTokenHandle(hLinkedToken); } } // CheckTokenMembership requires an impersonation token. If we just got // a linked token, it already is an impersonation token. If we did not // get a linked token, duplicate the original into an impersonation // token for CheckTokenMembership. if (hTokenToCheck == null) { if (!NativeMethods.DuplicateToken(hToken, SECURITY_IMPERSONATION_LEVEL.Identification, out hTokenToCheck)) throw new Win32Exception(); } // Check if the token to be checked contains admin SID. WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle()); WindowsPrincipal principal = new WindowsPrincipal(id); fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator); return fInAdminGroup; }
public static extern bool OpenProcessToken(SafeProcessHandle ProcessHandle, int DesiredAccess, out SafeTokenHandle TokenHandle);
public static extern bool OpenProcessToken( IntPtr ProcessHandle, int DesiredAccess, out SafeTokenHandle TokenHandle);
public static extern bool OpenThreadToken( SafeThreadHandle ThreadHandle, TokenRights DesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, out SafeTokenHandle TokenHandle);
internal static partial bool OpenThreadToken( IntPtr ThreadHandle, TokenAccessLevels dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bOpenAsSelf, out SafeTokenHandle phThreadToken);
public static extern bool GetTokenInformation(SafeTokenHandle hToken, TokenInformationClass tokenInfoClass, IntPtr pTokenInfo, Int32 tokenInfoLength, out Int32 returnLength);
internal static extern bool OpenProcessToken(IntPtr ProcessToken, TokenAccessLevels DesiredAccess, ref SafeTokenHandle TokenHandle);
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
internal static partial bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, out SafeTokenHandle TokenHandle);
internal static extern int ImpersonateLoggedOnUser(SafeTokenHandle hToken);
public static extern bool SetThreadToken( IntPtr Thread, SafeTokenHandle Token);
internal static extern bool OpenProcessToken( #endif IntPtr ProcessToken, TokenAccessLevels DesiredAccess, out SafeTokenHandle TokenHandle);
public static extern bool PrivilegeCheck( SafeTokenHandle ClientToken, ref PRIVILEGE_SET RequiredPrivileges, [MarshalAs(UnmanagedType.Bool)] out bool pfResult);
/// <summary> /// Returns true if the given token has the specified privilege. The privilege may or may not be enabled. /// </summary> public static bool HasPrivilege(SafeTokenHandle token, Privileges privilege) { return(GetTokenPrivileges(token).Any(t => t.Privilege == privilege)); }
// From winnt.h: // // 1 1 1 1 1 1 // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---------------------------------------------------------------+ // | SubAuthorityCount |Reserved1 (SBZ)| Revision | // +---------------------------------------------------------------+ // | IdentifierAuthority[0] | // +---------------------------------------------------------------+ // | IdentifierAuthority[1] | // +---------------------------------------------------------------+ // | IdentifierAuthority[2] | // +---------------------------------------------------------------+ // | | // +- - - - - - - - SubAuthority[] - - - - - - - - -+ // | | // +---------------------------------------------------------------+ // // // typedef struct _SID // { // BYTE Revision; // BYTE SubAuthorityCount; // SID_IDENTIFIER_AUTHORITY IdentifierAuthority; // DWORD SubAuthority[ANYSIZE_ARRAY]; // } SID, *PISID; // // As a SID is variable in length it is a little more complicated to wrap. Using a flat buffer makes the most sense. // System.Security.Principal.SecurityIdentifier allows copying to/from a byte array. // // https://msdn.microsoft.com/en-us/library/system.security.principal.securityidentifier.aspx public static IEnumerable <PrivilegeSetting> GetTokenPrivileges(SafeTokenHandle token) { // Get the buffer size we need uint bytesNeeded; if (!Direct.GetTokenInformation( token, TOKEN_INFORMATION_CLASS.TokenPrivileges, EmptySafeHandle.Instance, 0, out bytesNeeded)) { WindowsError error = ErrorHelper.GetLastError(); if (error != WindowsError.ERROR_INSUFFICIENT_BUFFER) { throw ErrorHelper.GetIoExceptionForError(error); } } else { // Didn't need any space for output, let's assume there are no privileges return(Enumerable.Empty <PrivilegeSetting>()); } // Initialize the buffer and get the data var streamBuffer = new StreamBuffer(bytesNeeded); if (!Direct.GetTokenInformation( token, TOKEN_INFORMATION_CLASS.TokenPrivileges, streamBuffer, (uint)streamBuffer.Length, out bytesNeeded)) { throw ErrorHelper.GetIoExceptionForLastError(); } // Loop through and get our privileges BinaryReader reader = new BinaryReader(streamBuffer, Encoding.Unicode, leaveOpen: true); uint count = reader.ReadUInt32(); var privileges = new List <PrivilegeSetting>(); StringBuffer nameBuffer = StringBufferCache.Instance.Acquire(256); for (int i = 0; i < count; i++) { LUID luid = new LUID { LowPart = reader.ReadUInt32(), HighPart = reader.ReadUInt32(), }; uint length = nameBuffer.CharCapacity; if (!Direct.LookupPrivilegeNameW(IntPtr.Zero, ref luid, nameBuffer, ref length)) { throw ErrorHelper.GetIoExceptionForLastError(); } nameBuffer.Length = length; PrivilegeAttributes attributes = (PrivilegeAttributes)reader.ReadUInt32(); privileges.Add(new PrivilegeSetting(nameBuffer.ToString(), attributes)); nameBuffer.Length = 0; } StringBufferCache.Instance.Release(nameBuffer); return(privileges); }
private void Dispose( bool disposing ) { if ( this.disposed ) return; if ( this.threadHandle != null ) { this.threadHandle.Dispose(); this.threadHandle = null; } if ( this.isImpersonating ) { NativeMethods.RevertToSelf(); } this.disposed = true; }
internal static extern int OpenThreadToken(TokenAccessLevels dwDesiredAccess, WinSecurityContext OpenAs, out SafeTokenHandle phThreadToken);
internal static extern bool SetThreadToken(IntPtr ThreadHandle, SafeTokenHandle hToken);
internal static extern int SetThreadToken(SafeTokenHandle hToken);
internal static extern bool SetTokenInformation(SafeTokenHandle hToken, TOKEN_INFORMATION_CLASS informationClass, TOKEN_MANDATORY_LABEL tokenInformation, int tokenInformationLength);
private static extern bool LogonUser( string userName, string domain, string password, LogonType logonType, LogonProvider logonProvider, out SafeTokenHandle token);
public static extern bool GetTokenInformation( SafeTokenHandle hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr pTokenInfo, Int32 tokenInfoLength, out Int32 returnLength);
public static extern bool DuplicateToken( /* [in] */ SafeTokenHandle tokenHandle, /* [in] */ [MarshalAs(UnmanagedType.I4)] SecurityImpersonationLevel impersonationLevel, /* [out] */ out IntPtr duplicatedTokenHandle);
public static extern bool DuplicateToken(SafeTokenHandle ExistingTokenHandle, SecurityImpersonationLevel ImpersonationLevel, out SafeTokenHandle DuplicateTokenHandle);
public static extern bool OpenProcessToken( /* [in] */ IntPtr handle, /* [in] */ [MarshalAs(UnmanagedType.U4)] TokenAccessRights desiredAccess, /* [out] */ out SafeTokenHandle tokenHandle);
public static extern bool AdjustTokenPrivileges( SafeTokenHandle TokenHandle, bool DisableAllPrivileges, [MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, ref int ReturnLength);
/// <summary> /// The function checks whether the primary access token of the process belongs /// to user account that is a member of the local Administrators group, even if /// it currently is not elevated. /// </summary> /// <returns> /// Returns true if the primary access token of the process belongs to user /// account that is a member of the local Administrators group. Returns false /// if the token does not. /// </returns> /// <exception cref="System.ComponentModel.Win32Exception"> /// When any native Windows API call fails, the function throws a Win32Exception /// with the last error code. /// </exception> public static bool IsUserInAdminGroup() { bool fInAdminGroup = false; SafeTokenHandle hToken = null; SafeTokenHandle hTokenToCheck = null; IntPtr pElevationType = IntPtr.Zero; IntPtr pLinkedToken = IntPtr.Zero; int cbSize = 0; try { // Open the access token of the current process for query and duplicate. if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle, NativeMethods.TOKEN_QUERY | NativeMethods.TOKEN_DUPLICATE, out hToken)) { throw new Win32Exception(); } // Determine whether system is running Windows Vista or later operating // systems (major version >= 6) because they support linked tokens, but // previous versions (major version < 6) do not. if (Environment.OSVersion.Version.Major >= 6) { // Running Windows Vista or later (major version >= 6). // Determine token type: limited, elevated, or default. // Allocate a buffer for the elevation type information. cbSize = sizeof(TOKEN_ELEVATION_TYPE); pElevationType = Marshal.AllocHGlobal(cbSize); if (pElevationType == IntPtr.Zero) { throw new Win32Exception(); } // Retrieve token elevation type information. if (!NativeMethods.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType, cbSize, out cbSize)) { throw new Win32Exception(); } // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET. TOKEN_ELEVATION_TYPE elevType = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(pElevationType); // If limited, get the linked elevated token for further check. if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) { // Allocate a buffer for the linked token. cbSize = IntPtr.Size; pLinkedToken = Marshal.AllocHGlobal(cbSize); if (pLinkedToken == IntPtr.Zero) { throw new Win32Exception(); } // Get the linked token. if (!NativeMethods.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken, cbSize, out cbSize)) { throw new Win32Exception(); } // Marshal the linked token value from native to .NET. IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken); hTokenToCheck = new SafeTokenHandle(hLinkedToken); } } // CheckTokenMembership requires an impersonation token. If we just got // a linked token, it already is an impersonation token. If we did not // get a linked token, duplicate the original into an impersonation // token for CheckTokenMembership. if (hTokenToCheck == null) { if (!NativeMethods.DuplicateToken(hToken, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out hTokenToCheck)) { throw new Win32Exception(); } } // Check if the token to be checked contains admin SID. WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle()); WindowsPrincipal principal = new WindowsPrincipal(id); fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator); } finally { // Centralized cleanup for all allocated resources. if (hToken != null) { hToken.Close(); hToken = null; } if (hTokenToCheck != null) { hTokenToCheck.Close(); hTokenToCheck = null; } if (pElevationType != IntPtr.Zero) { Marshal.FreeHGlobal(pElevationType); pElevationType = IntPtr.Zero; } if (pLinkedToken != IntPtr.Zero) { Marshal.FreeHGlobal(pLinkedToken); pLinkedToken = IntPtr.Zero; } } return fInAdminGroup; }
internal int GetProcessIntegrityLevel(int id) { int IL = -1; SafeTokenHandle hToken = null; int cbTokenIL = 0; IntPtr pTokenIL = IntPtr.Zero; try { // Open the access token of the current process with TOKEN_QUERY. if (!NativeMethod.OpenProcessToken(Process.GetProcessById(id).Handle, NativeMethod.TOKEN_QUERY, out hToken)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Then we must query the size of the integrity level information // associated with the token. Note that we expect GetTokenInformation // to return false with the ERROR_INSUFFICIENT_BUFFER error code // because we've given it a null buffer. On exit cbTokenIL will tell // the size of the group information. if (!NativeMethod.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, IntPtr.Zero, 0, out cbTokenIL)) { int error = Marshal.GetLastWin32Error(); if (error != NativeMethod.ERROR_INSUFFICIENT_BUFFER) { // When the process is run on operating systems prior to // Windows Vista, GetTokenInformation returns false with the // ERROR_INVALID_PARAMETER error code because // TokenIntegrityLevel is not supported on those OS's. throw new Win32Exception(error); } } // Now we allocate a buffer for the integrity level information. pTokenIL = Marshal.AllocHGlobal(cbTokenIL); if (pTokenIL == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Now we ask for the integrity level information again. This may fail // if an administrator has added this account to an additional group // between our first call to GetTokenInformation and this one. if (!NativeMethod.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenIL, cbTokenIL, out cbTokenIL)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Marshal the TOKEN_MANDATORY_LABEL struct from native to .NET object. TOKEN_MANDATORY_LABEL tokenIL = (TOKEN_MANDATORY_LABEL) Marshal.PtrToStructure(pTokenIL, typeof(TOKEN_MANDATORY_LABEL)); // Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g. // S-1-16-0x1000 stands for low integrity level SID). There is one // and only one subauthority. IntPtr pIL = NativeMethod.GetSidSubAuthority(tokenIL.Label.Sid, 0); IL = Marshal.ReadInt32(pIL); } finally { // Centralized cleanup for all allocated resources. if (hToken != null) { hToken.Close(); hToken = null; } if (pTokenIL != IntPtr.Zero) { Marshal.FreeHGlobal(pTokenIL); pTokenIL = IntPtr.Zero; cbTokenIL = 0; } } return(IL); }
internal static extern bool OpenThreadToken(IntPtr ThreadHandle, TokenAccessLevels dwDesiredAccess, bool bOpenAsSelf, out SafeTokenHandle phThreadToken);
public static extern bool GetTokenInformation( /* [in] */ SafeTokenHandle token, /* [in] */ TokenInformationClass tokenInfoClass, /* [in] */ IntPtr tokenInformation, /* [in] */ int tokeInfoLength, /* [out] */ out int actualSize);
public TlsContents() { int error = 0; int cachingError = 0; bool success = true; if (processHandle.IsInvalid) { lock (syncRoot) { if (processHandle.IsInvalid) { SafeTokenHandle localProcessHandle; if (false == Interop.mincore.OpenProcessToken( Interop.mincore.GetCurrentProcess(), TokenAccessLevels.Duplicate, out localProcessHandle)) { cachingError = Marshal.GetLastWin32Error(); success = false; } processHandle = localProcessHandle; } } } try { // Make the sequence non-interruptible } finally { try { // // Open the thread token; if there is no thread token, get one from // the process token by impersonating self. // SafeTokenHandle threadHandleBefore = this.threadHandle; error = FCall.OpenThreadToken( TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, WinSecurityContext.Process, out this.threadHandle); unchecked { error &= ~(int)0x80070000; } if (error != 0) { if (success == true) { this.threadHandle = threadHandleBefore; if (error != Interop.mincore.Errors.ERROR_NO_TOKEN) { success = false; } Contract.Assert(this.isImpersonating == false, "Incorrect isImpersonating state"); if (success == true) { error = 0; if (false == Interop.mincore.DuplicateTokenEx( processHandle, TokenAccessLevels.Impersonate | TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, IntPtr.Zero, Interop.mincore.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, System.Security.Principal.TokenType.TokenImpersonation, ref this.threadHandle)) { error = Marshal.GetLastWin32Error(); success = false; } } if (success == true) { error = FCall.SetThreadToken(this.threadHandle); unchecked { error &= ~(int)0x80070000; } if (error != 0) { success = false; } } if (success == true) { this.isImpersonating = true; } } else { error = cachingError; } } else { success = true; } } finally { if (!success) { Dispose(); } } } if (error == Interop.mincore.Errors.ERROR_NOT_ENOUGH_MEMORY) { throw new OutOfMemoryException(); } else if (error == Interop.mincore.Errors.ERROR_ACCESS_DENIED || error == Interop.mincore.Errors.ERROR_CANT_OPEN_ANONYMOUS) { throw new UnauthorizedAccessException(); } else if (error != 0) { Contract.Assert(false, string.Format(CultureInfo.InvariantCulture, "WindowsIdentity.GetCurrentThreadToken() failed with unrecognized error code {0}", error)); throw new InvalidOperationException(); } }
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out SafeTokenHandle TokenHandle);
bool DuplicateTokenEx(SafeTokenHandle ExistingTokenHandle, TokenAccessLevels DesiredAccess, IntPtr TokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, System.Security.Principal.TokenType TokenType, ref SafeTokenHandle DuplicateTokenHandle);
public static extern bool GetTokenInformation(SafeTokenHandle TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength);
internal static extern bool OpenProcessToken(SafeProcessHandle ProcessHandle, int DesiredAccess, out SafeTokenHandle TokenHandle);
internal static partial bool OpenProcessToken( IntPtr ProcessToken, TokenAccessLevels DesiredAccess, out SafeTokenHandle TokenHandle);
private static extern bool LogonUser(string UserName, string Domain, string Password, int LogonType, int LogonProvider, out SafeTokenHandle SafeToken);
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
internal static extern bool DuplicateTokenEx(SafeTokenHandle ExistingTokenHandle, TokenAccessLevels DesiredAccess, IntPtr TokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TokenType TokenType, ref SafeTokenHandle DuplicateTokenHandle);
public Collection<PSObject> RunPowerShell(Dictionary<string, object> arguments, LoginViewModel clientId) { // Start with identity assigned by IIS Application Pool var poolIdentity = System.Security.Principal.WindowsIdentity.GetCurrent(); // TODO: remove, this is for initial testing //scriptPath = Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder, "TestScript.ps1"); Command command = new Command(scriptPath); if (arguments != null) { foreach (var argument in arguments) { command.Parameters.Add(argument.Key, argument.Value); } } if (debug) { command.Parameters.Add("debug"); } command.Parameters.Add("log", logger); // add the ndc context string ndcContext = log4net.NDC.Pop(); log4net.NDC.Push(ndcContext); command.Parameters.Add("ndcContext", ndcContext); try { logger.Debug("Application Pool identity is " + poolIdentity.Name + ", but we will impersonate " + clientId.UserName); if (System.Security.SecurityContext.IsWindowsIdentityFlowSuppressed()) { logger.Error("PowerShell calls will fail, because IsWindowsIdentityFlowSuppressed true"); } // A RunSpace defines the operating system environment, which references HKCU\Environment // We create it now before impersonating an identity that might not have HKCU\Environment access // TODO: it may be possible to improve performance by using a RunSpacePool using (PowerShell powerShell = PowerShell.Create()) { Runspace runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); powerShell.Runspace = runspace; Collection<PSObject> results; IntPtr handle; SafeTokenHandle _handle; /// Test: generate primary login token /// LOGON32_PROVIDER_DEFAULT = 0 /// logger.Debug("LogonUser call for " + clientId.UserNameNoDomain); bool logonSuccess = NativeMethods.LogonUser(clientId.UserNameNoDomain, clientId.DomainName, clientId.Password, (int) LogonType.Interactive, 0, out handle); _handle = new SafeTokenHandle(handle); if (!logonSuccess) { string errMsg = "LogonUser() for " + clientId.UserName + "failed - no handle for user credentials:" + Marshal.GetLastWin32Error(); throw new Win32Exception(errMsg); } // When 'using' block ends, the thread reverts back to previous Windows identity, // because under the hood WindowsImpersonationContext.Undo() is called by Dispose() try { using ( WindowsImpersonationContext wic = WindowsIdentity.Impersonate(_handle.DangerousGetHandle())) { // WindowsIdentity will have changed to match clientId var clientIdentity = System.Security.Principal.WindowsIdentity.GetCurrent(); logger.Debug("Application Pool identity is now " + clientIdentity.Name); powerShell.Commands.AddCommand(command); logger.Debug("Calling " + scriptPath); results = powerShell.Invoke(); } } // Back to the original identity finally { // dispose of the LogonUser handle _handle.Dispose(); // clean up RunSpace used by the PowerShell object runspace.Close(); runspace.Dispose(); } // The order is important here. Debug messages are flushed to the log *before* checking for errors // so the debug traces leading up to an error are not lost Collection<PSObject> filteredResults = new Collection<PSObject>(); foreach (PSObject result in results) { string output = result.BaseObject as string; if ((output != null) && output.StartsWith(DebugPrefix)) { if (debug) { logger.Info(output.Substring(DebugPrefix.Length)); } } else { filteredResults.Add(result); } } foreach (DebugRecord r in powerShell.Streams.Debug) { logger.Info(r.Message); } logger.Debug("Examining powershell error records"); foreach (ErrorRecord r in powerShell.Streams.Error) { // If the exception doesn't match a "to be ignored" exception, then throw it if (IgnoreExceptions.SingleOrDefault(i => i.Equals(r.Exception.GetType().FullName, StringComparison.InvariantCultureIgnoreCase)) == null) { logger.Error("Powershell reported exception:" + r.ErrorDetails); throw r.Exception; } } return filteredResults; } } catch (Exception e) { logger.Error(e); logger.Error(e.Message); logger.Error(e.StackTrace); throw; } }
internal static extern bool CreateProcessAsUser(SafeTokenHandle hToken, string lpApplicationName, string lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes, SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInformation);
/// <summary> /// 即使在还没有为当前用户提升权限的前提下,此函数检测拥有此进程的主访 /// 问令牌的用户是否是本地管理员组的成员。 /// </summary> /// <returns> /// 如果拥有主访问令牌的用户是管理员组成员则返回TRUE,反之则返回FALSE。 /// </returns> /// <exception cref="System.ComponentModel.Win32Exception"> /// 如果任何原生的Windows API函数出错,此函数会抛出一个包含最后错误代码的Win32Exception。 /// </exception> internal bool IsUserInAdminGroup() { bool fInAdminGroup = false; SafeTokenHandle hToken = null; SafeTokenHandle hTokenToCheck = null; IntPtr pElevationType = IntPtr.Zero; IntPtr pLinkedToken = IntPtr.Zero; int cbSize = 0; try { // 打开此进程的主访问令牌(使用TOKEN_QUERY | TOKEN_DUPLICATE) if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle, NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_DUPLICATE, out hToken)) { throw new Win32Exception(); } // 检测是否此系统是Windows Vista或后续版本(主版本号 >= 6)。这是由于自 // Windows Vista开始支持链接令牌(LINKED TOKEN),而之前的版本不支持。 // (主版本 < 6) if (Environment.OSVersion.Version.Major >= 6) { // 运行于Windows Vista 或后续版本(主版本 >= 6). // 检测令牌类型:受限(limited),(已提升)elevated, // 或者默认(default) // 为提升类别信息对象分配内存 cbSize = sizeof(TOKEN_ELEVATION_TYPE); pElevationType = Marshal.AllocHGlobal(cbSize); if (pElevationType == IntPtr.Zero) { throw new Win32Exception(); } // 获取令牌提升类别信息 if (!NativeMethod.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType, cbSize, out cbSize)) { throw new Win32Exception(); } // 转换TOKEN_ELEVATION_TYPE枚举类型(从原生到.Net) TOKEN_ELEVATION_TYPE elevType = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(pElevationType); // 如果为受限的,获取相关联的已提升令牌以便今后使用。 if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) { // 为连接令牌分配内存 cbSize = IntPtr.Size; pLinkedToken = Marshal.AllocHGlobal(cbSize); if (pLinkedToken == IntPtr.Zero) { throw new Win32Exception(); } // 获取连接令牌 if (!NativeMethod.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken, cbSize, out cbSize)) { throw new Win32Exception(); } // 转换连接令牌的值(从原生到.Net) IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken); hTokenToCheck = new SafeTokenHandle(hLinkedToken); } } // CheckTokenMembership要求一个伪装令牌。如果我们仅得到一个链接令牌,那 // 它就是一个伪装令牌。如果我们没有得到一个关联式令牌,我们需要复制当前 // 令牌以便得到一个伪装令牌。 if (hTokenToCheck == null) { if (!NativeMethod.DuplicateToken(hToken, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out hTokenToCheck)) { throw new Win32Exception(); } } // 检测是否被检测的令牌包含管理员组SID WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle()); WindowsPrincipal principal = new WindowsPrincipal(id); fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator); } finally { // 集中清理所有已分配的内存资源 if (hToken != null) { hToken.Close(); hToken = null; } if (hTokenToCheck != null) { hTokenToCheck.Close(); hTokenToCheck = null; } if (pElevationType != IntPtr.Zero) { Marshal.FreeHGlobal(pElevationType); pElevationType = IntPtr.Zero; } if (pLinkedToken != IntPtr.Zero) { Marshal.FreeHGlobal(pLinkedToken); pLinkedToken = IntPtr.Zero; } } return fInAdminGroup; }
public static extern bool LogonUser( string principal, string authority, string password, LogonTypes logonType, LogonProviders logonProvider, ref SafeTokenHandle token);
public static extern bool OpenProcessToken( IntPtr hProcess, TokenAccessLevels DesiredAccess, ref SafeTokenHandle TokenHandle);
public static extern bool DuplicateToken( SafeTokenHandle ExistingTokenHandle, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, out SafeTokenHandle DuplicateTokenHandle);
public static extern bool OpenThreadToken( IntPtr ThreadToken, TokenAccessLevels DesiredAccess, bool OpenAsSelf, ref SafeTokenHandle TokenHandle);
public static extern bool OpenProcessToken(IntPtr hProcess, UInt32 desiredAccess, out SafeTokenHandle hToken);
internal static extern bool WTSQueryUserToken( /* _In_ ULONG */ [In] uint sessionId, /* _Out_ PHANDLE */ [Out] out SafeTokenHandle token );