Поделиться через


RunAs Verb (Process.Start) doesn't work from a LocalSystem .NET Service

 The Process.Start method in System.Diagnostics is equivalent to CreateProcess() in Win32. If you want to 
 launch a process as a different user, in Win32 you either need to call CreateProcessAsUser, 
 CreateProcessWithLogonW or CreateProcessWithTokenW. In .NET using Process.Start, you can use the 
 “runas” verb to the same thing.
 
If you have a .NET Service configured with the LocalSystem account, the “runas” verb doesn’t work and 
 you’ll encounter an exception and a failure of “access denied”. 
 
Unhandled Exception: System.ComponentModel.Win32Exception: Access is denied
 at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo) 
 at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) 

Internally what is happening is that .NET is using CreateProcessWithLogonW() to implement the 
 “runas” verb. If you take a look at the remarks for CreateProcessWithLogonW(), you’ll find the following, 
 https://msdn.microsoft.com/en-us/library/windows/desktop/ms682431(v=vs.85).aspx :
  “You cannot call CreateProcessWithLogonW from a process that is running under the "LocalSystem"  
 account, because the function uses the logon SID in the caller token, and the token for the "LocalSystem"  
 account does not contain this SID.  As an alternative, use the CreateProcessAsUser and LogonUser functions.” 
 The reason this is happening is that CreateProcessWithLogonW() is assuming that the desktop of the 
 launched process is  “Winsta0\Default” . This is known as the INTERACTIVE desktop. The security on this 
 desktop is based on the Logon SID associated with the INTERACTIVELY logged on user. (This is the 
 user who logged onto the system via CTRL-ALT-DELETE). The desktop associated with a LocalSystem 
 service is a hidden desktop. When CreateProcessWithLogonW() attempts to add the Logon SID from 
 the current user (LocalSystem), it won't find a LOGON SID (since LocalSystem doesn't have one). 
 This will cause CreateProcessWithLogonW() to fail with error code 5 or "access denied". Not only is 
 this an issue, CreateProcessWithLogonW() is assuming it is modifying  "Winsta0\Default"  which it isn't.