processus de lancement de l’isolement de la session 0

Sur Windows 8.1, j’ai un service qui lance les scripts PowerShell. Le service s’exécute en tant que «nt autorité \ système» dans la session 0 Isolation. Tous les processus générés par PowerShell s’exécutent sous le nom “ntutorité \ système” dans l’isolement de la session 0.

J’ai besoin d’exécuter un script qui se trouve sous un compte d’utilisateur hors de la session 0 et non du compte système. J’ai essayé ça

Start-Process "$PsHome\PowerShell.exe" -Credential $pp -ArgumentList $script -wait 

et PsExec spécifiant la session que je veux avec l’argument “-I 1”.

 & PsExec.exe "Install.bat" -i 1 -accepteula -u "domain\user" -p "awesomePassword" -w "startdir" -h 

J’ai essayé de configurer “Autoriser le service à interagir avec le bureau”.

Des erreurs sont toujours refusées lorsque j’essaie de démarrer le processus à partir de PowerShell ou du service c #.

Voici un exemple d’exception lorsque j’essaie de m’évader en utilisant c # sur le service.

 System.ComponentModel.Win32Exception (0x80004005): Access is denied at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo) 

Comment puis-je m’échapper de la session 0?

Je peux ré-écrire le code c # pour démarrer un processus sous un autre utilisateur. ou je peux réécrire le script appelé PowerShell pour démarrer un autre processus en tant qu’utilisateur. Quoi que j’essaye, je n’arrive pas à sortir de la session 0.

En utilisant l’exemple que j’ai trouvé dans le projet de code, j’ai eu une solution partielle. L’exemple dans le lien ci-dessus lancera un processus en tant qu’utilisateur qui exécute le processus “winlogon”. Afin de lancer un processus en tant qu’utilisateur connecté, j’ai simplement modifié le processus pour qu’il recherche plutôt “explorateur”.

Voici un extrait du code original

 // obtain the process id of the winlogon process that is // running within the currently active session Process[] processes = Process.GetProcessesByName("winlogon"); 

Je viens de changer le processus pour rechercher l’explorateur.

 Process[] processes = Process.GetProcessesByName("explorer"); 

Maintenant, le processus démarre en tant que domaine / moi dans la session 3 en tant qu’utilisateur non administrateur.

Il doit y avoir des problèmes avec cette approche, telle que le Bureau à distance, mais ce que je veux, c’est finalement ce que je veux.

Voici le code final pour la complétude au cas où le lien d’origine s’évaporerait.

Voici comment le lancer

 // the name of the application to launch Ssortingng applicationName = "cmd.exe"; // launch the application ApplicationLoader.PROCESS_INFORMATION procInfo; ApplicationLoader.StartProcessAndBypassUAC(applicationName, out procInfo); 

Voici le code

 using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; namespace SuperAwesomeNameSpaceOfJustice { ///  /// Class that allows running applications with full admin rights. In /// addition the application launched will bypass the Vista UAC prompt. ///  public class ApplicationLoader { #region Structures [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int Length; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; } [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public int cb; public Ssortingng lpReserved; public Ssortingng lpDesktop; public Ssortingng lpTitle; public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; public uint dwYCountChars; public uint dwFillAtsortingbute; public uint dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; } #endregion #region Enumerations enum TOKEN_TYPE : int { TokenPrimary = 1, TokenImpersonation = 2 } enum SECURITY_IMPERSONATION_LEVEL : int { SecurityAnonymous = 0, SecurityIdentification = 1, SecurityImpersonation = 2, SecurityDelegation = 3, } #endregion #region Constants public const int TOKEN_DUPLICATE = 0x0002; public const uint MAXIMUM_ALLOWED = 0x2000000; public const int CREATE_NEW_CONSOLE = 0x00000010; public const int IDLE_PRIORITY_CLASS = 0x40; public const int NORMAL_PRIORITY_CLASS = 0x20; public const int HIGH_PRIORITY_CLASS = 0x80; public const int REALTIME_PRIORITY_CLASS = 0x100; #endregion #region Win32 API Imports [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CloseHandle(IntPtr hSnapshot); [DllImport("kernel32.dll")] static extern uint WTSGetActiveConsoleSessionId(); [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public extern static bool CreateProcessAsUser(IntPtr hToken, Ssortingng lpApplicationName, Ssortingng lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAtsortingbutes, ref SECURITY_ATTRIBUTES lpThreadAtsortingbutes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, Ssortingng lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("kernel32.dll")] static extern bool ProcessIdToSessionId(uint dwProcessId, ref uint pSessionId); [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAtsortingbutes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); [DllImport("kernel32.dll")] static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId); [DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurity] static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle); #endregion ///  /// Launches the given application with full admin rights, and in addition bypasses the Vista UAC prompt ///  /// The name of the application to launch /// Process information regarding the launched application that gets returned to the caller ///  public static bool StartProcessAndBypassUAC(Ssortingng applicationName, ssortingng startingDir, out PROCESS_INFORMATION procInfo) { uint winlogonPid = 0; IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero; procInfo = new PROCESS_INFORMATION(); // obtain the currently active session id; every logged on user in the system has a unique session id uint dwSessionId = WTSGetActiveConsoleSessionId(); // obtain the process id of the winlogon process that is running within the currently active session // -- chaged by ty // Process[] processes = Process.GetProcessesByName("winlogon"); Process[] processes = Process.GetProcessesByName("explorer"); foreach (Process p in processes) { if ((uint)p.SessionId == dwSessionId) { winlogonPid = (uint)p.Id; } } // obtain a handle to the winlogon process hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid); // obtain a handle to the access token of the winlogon process if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken)) { CloseHandle(hProcess); return false; } // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser // I would prefer to not have to use a security atsortingbute variable and to just // simply pass null and inherit (by default) the security atsortingbutes // of the existing token. However, in C# structures are value types and therefore // cannot be assigned the null value. SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.Length = Marshal.SizeOf(sa); // copy the access token of the winlogon process; the newly created token will be a primary token if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup)) { CloseHandle(hProcess); CloseHandle(hPToken); return false; } // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning // the window station has a desktop that is invisible and the process is incapable of receiving // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user // interaction with the new process. STARTUPINFO si = new STARTUPINFO(); si.cb = (int)Marshal.SizeOf(si); si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop // flags that specify the priority and creation method of the process int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; // create a new process in the current user's logon session bool result = CreateProcessAsUser(hUserTokenDup, // client's access token null, // file to execute applicationName, // command line ref sa, // pointer to process SECURITY_ATTRIBUTES ref sa, // pointer to thread SECURITY_ATTRIBUTES false, // handles are not inheritable dwCreationFlags, // creation flags IntPtr.Zero, // pointer to new environment block startingDir, // name of current directory ref si, // pointer to STARTUPINFO structure out procInfo // receives information about new process ); // invalidate the handles CloseHandle(hProcess); CloseHandle(hPToken); CloseHandle(hUserTokenDup); return result; // return the result } } }