Jump to content



Welcome to AstaHost - Dear Guest , Please Register here to get Your own website. - Ask a Question / Express Opinion / Reply w/o Sign-Up!

Toggle shoutbox Shoutbox Open the Shoutbox in a popup

@  agyat : (24 May 2013 - 05:15 PM) O Dear, Where Are You? Without Your Words This Sb Is ..
@  agyat : (23 May 2013 - 01:23 AM) Wow! Mr. Sb Back Home.
@  OpaQue : (23 May 2013 - 12:44 AM) Ting
@  OpaQue : (24 April 2013 - 02:44 PM) I guess, Time to run Mycent script.
@  OpaQue : (24 April 2013 - 02:43 PM) wow.. not much spam. except habatt posting lot of links.. :P
@  yordan : (23 April 2013 - 01:04 PM) You're welcome, agyat. Nice to have been helpful. Second lesson: try full words, "you" instead of "EW".
@  agyat : (23 April 2013 - 05:03 AM) @YORDAN: tHANK EW FOR YOUR FIRST LESSON.   :D
@  yordan : (22 April 2013 - 09:43 PM) @agyat : "why don't you help me", or "please help me", or "please teach us"
@  yordan : (22 April 2013 - 09:42 PM) welcome back, velma
@  velma : (22 April 2013 - 07:51 AM) **yawns** Good to be back, wonder what is going on here :)
@  agyat : (22 April 2013 - 03:50 AM) Oh! so, why don't help me learn english..
@  yordan : (21 April 2013 - 08:38 PM) The goal mentioned by shiu : "learning english, learning computer"
@  agyat : (21 April 2013 - 06:31 PM) WHAT GOAL?
@  yordan : (20 April 2013 - 10:39 AM) yes, that's our goal. simultaneouly learning English and teaching/learning computer using.
@  shiyu : (20 April 2013 - 07:30 AM) learning english,learning computer
@  yordan : (19 April 2013 - 01:11 PM) Oh, I see, it's just a trick in order to force people looking at your texte. Somehow smart, maybe.
@  agyat : (19 April 2013 - 02:54 AM) And of course I know it is not SEO friendly.
@  agyat : (19 April 2013 - 02:52 AM) There may be two possible answers for that ....


1) Shout was posted using mobile keypad.

2) To force people read content carefully and/or with more concentration.
@  agyat : (19 April 2013 - 02:49 AM) There may be two possible answers for that ....
@  yordan : (18 April 2013 - 09:35 PM) however, why this mixing of capital letters in the middle of your text?

Photo
- - - - -

Creating New Process Under Alternate Credentials (createprocessasuser)


20 replies to this topic

#1 tansqrx

tansqrx

    Super Member

  • [HOSTED]
  • 759 posts

Posted 10 July 2006 - 10:09 PM

I am having quite the time spawning a process under a different user context. My preferred method involves using the Windows API functions LogonUser() and CreateProcessAsUser() but I have not figured out a way to overcome several error messages. I also have the particular problem of running my program from the system account which I have found affects the behavior of CreateProcessAsUserW. Added to this toxic mix are several bugs scattered throughout the Windows API and .NET framework. After numerous attempts and about two weeks of frustrations I am open to suggestions.

Background

I am working on a side software project for my company that involves managing and administrating several computers in a lab. The project currently uses VB.NET 2005. One aspect of my project involves providing command line access from a lab computer to a central data collection computer. This functionality has already been accomplished by use of creating a service running under the SYSTEM account and netcat (http://netcat.sourceforge.net/). Basically what happens is when the lab computer is booted; a Windows service starts and creates a netcat session with the central computer. The central machine already has a netcat listener running so when the request comes in, an instant command prompt of the lab computer is given on the central machine. This solution has been thoroughly tested, signed off on, and works great so there can not be any changes to this part of the project. Here comes the problem. The netcat session is running under the context of SYSTEM, localsystem, or NT Authority. As some of you may know, the SYSTEM account is noninteractive and does not have access to the default desktop. Let’s take for example you wanted to start Notepad from this session. Enter the command and nothing happens. This is because SYSTEM can not access WINSTA0 and no commands with graphics or forms can be run.

The next phase of our project involves running interactive programs on the desktop of any user that happens to be logged in (and perhaps those who are not). From experiments I have found that a netcat session running under the currently logged in user is able to run all GUI programs. My dilemma is creating a program that can be run under the SYSTEM service and launch a program or another netcat session with alternate credentials.

As a side note, Microsoft does provide a well know utility called runas. This is of course what I would use but I have found that it will not work under a netcat session. After entering the command, the password is never asked for and it dumps me right back to the prompt. I have also tried several other third-party runas utilities such as sanur and CPAU but none of them works either.

Requirements

1. Parent process running under SYSTEM context from Windows service.
2. Child process must run under alternate credentials and be able to launch a GUI application or another netcat instance.
3. Child process window must have the ability to start without a window.
4. Run under Windows XP SP2.
5. Child process should have access to the default desktop.
6. Program written in VB.NET, .NET framework 2.0. Desired but I will take anything in .NET (C#), C++, or C

Methods

Over the course of several weeks I have tried many different things. Here is what I have gone through.

Method 1 - .NET Process Class
This is the simplest way to create another process. This is not meant to create a process under another user but more of a reality check. Some interesting points are found by running the program under both a normal account (running straight from Visual Studio IDE) and the SYSTEM account. Under a normal account a DOS window briefly flashes and the program runs as expected. This is still a bug as the CreateNoWindow property is set to True and a window is still created. Under the SYSTEM account the same program starts a netcat session but never connects to the listener.

Problem: No alternate credentials

Method 2 - .NET Process Class Using Username, Domain, and Password
.NET 2.0 added a new feature to the framework that allows programmers to spawn a process all within .NET. Just one problem, there is a bigger bug. Even if the CreateNoWindow property is set to True, a window is still created and this time it stays maximized. Under the SYSTEM account an exception is thrown “System.ComponentModel.Win32Exception: Access is denied.” According to MSDN (http://msdn2.microso....startinfo.aspx), System.Diagnostics.Process is just a wrapper for the CreateProcessWithLogonW API. As I will explain later this presents its own problems. Microsoft also mentions that even though WindowStyle=hidden and CreateNoWindow=True, a window will still be created. I have seen in other articles that this is not intentional but a bug.

Problem: Exception thrown, Window in normal account.

Method 3 - Windows API LogonUser and CreateProcessAsUser
From everything I have read this should be the one that works no matter what but alas it does not. My primary guide to this method is by K. Scott Allen (http://odetocode.com.../10/28/602.aspx). This method uses two API functions, LogonUser and CreateProcessAsUser. LogonUser acquires a security token from the kernel. That token is then passed to CreateProcessAsUser along with what program and arguments to run. Under a normal account I get a 1314 - ERROR_PRIVILEGE_NOT_HELD (http://msdn.microsof..._1300-1699_.asp) when CreateProcessAsUser is called. When running under SYSTEM I get 1307 - ERROR_INVALID_OWNER when CreateProcessAsUser is called.

Problem: 1307 under SYSTEM, 1314 under normal account.

Method 4 - Windows API LogonUser, DuplicateTokenEx, and CreateProcessAsUser
This is a slight change from method 3 as DuplicateTokenEx is added and is still the front runner for a finial solution. DuplicateTokenEx transforms the token retrieved from LogonUser into a primary token. Once again a 1314 is thrown under a normal account. Under the SYSTEM account a 1004 - ERROR_INVALID_FLAGS error is thrown on DuplicateTokenEx and 1307 is thrown on CreateProcessAsUser.

A few interesting problems pop up when using this solution. For one, the command to launch can be passed two different ways, through lpApplicationName or lpCommandLine. MSDN says that lpApplicationName can be used to pass the command name and lpCommandLine for the arguments. You can also set lpApplicationName to nothing and pass both the command and arguments through lpCommandLine. I have tried both methods and I have not found any combination that works. Under certain variations I also get a 2 - ERROR_FILE_NOT_FOUND / 5 - ERROR_ACCESS_DENIED on LogonUser and 2 - ERROR_FILE_NOT_FOUND for CreateProcessAsUser. I have also used a known good application (notepad) and location to add to the mix and confirm the results.

Once again according to MSDN documentation (http://support.micro....com/?id=285879) certain permissions must be set for both the calling account and alternate account. When running under SYSTEM, the calling account should have all permissions as it is the OS. Also the alternate account should have all the desired permissions because MAXIMUM_ALLOWED is set in DuplicateTokenEx. Perhaps there is another API that I must call to set these but I have not found one yet. Also there might be an API that could check the permissions?

Problem: 1004, 1307, 2 under SYSTEM, 1314, 2, 5 under normal account.

Method 5 - Windows API LogonUser, DuplicateTokenEx, and CreateProcessAsUserW
This is the same as method 4 but uses the Unicode version of CreateProcessAsUser. I have read in several forums that this will solve the problem under Windows XP. A normal account produces a 2 - ERROR_FILE_NOT_FOUND under CreateProcessAsUserW. Under SYSTEM 1004 is thrown for DuplicateTokenEx and 2 for CreateProcessAsUser. Additionally 123 - ERROR_INVALID_NAME is thrown in some variations.

Problem: 1004, 2 under SYSTEM, 2, 5 under normal account.

Method 6 - Windows API CreateProcessWithLogonW
This API function is new 2000, XP, and 2003 Server and combines the functions of LogonUser and CreateProcessAsUserW. From many forums, many users accomplished their goals by using CreateProcessWithLogonW. A caveat of CreateProcessWithLogonW is that it can’t be called from the SYSTEM account according to the MSDN documentation (http://msdn.microsof...swithlogonw.asp) which defeats the purpose of my program.
Under a normal account, the program almost makes due. A window is created (which I think I can fix by tweaking one of the lpStartupInfo properties) and a nonfatal 203 - ERROR_ENVVAR_NOT_FOUND error thrown, but it does run. Under SYSTEM a 203 is thrown but nothing happens.

Problem: CreateProcessWithLogonW will not run under SYSTEM account

Method 7 – The Kitchen Sink
I have seen many different variations on method 4 floating around out on the Internet. This is my attempt to throw everything at the wall and see what sticks. GetProcessWindowStation, OpenWindowStation, SetProcessWindowStation, and OpenDesktop have been added to the mix. The bottom line is CreateProcessAsUser is throws a 1314 error and GetProcessWindowStation throws a 5 - ERROR_ACCESS_DENIED. Under the normal account. Under SYSTEM GetProcessWindowStation throws a 2 - ERROR_FILE_NOT_FOUND and a 1307 for CreateProcessAsUser.

Problem: 2, 1307 under SYSTEM, 5, 1314 under normal account.

Method 7 – .NET Impersionation
I quickly saw that this was not going to work. You can set a section of code to run under differed credentials but you can not start a new process under different credentials. I figured I would just throw this one in for completeness.

Problem: No alternate credentials

Possible Fixes?
• Perhaps the command to be processed is not formatted correctly. I have also tried a known good application (notepad) and usually get the same results.
• Additional permissions must be added to the account but I don’t know what the API would be to do this.
• Additional API’s needed?

Conclusion

It appears that everything was OK in Microsoft land until SP2 and Windows 2003 hit the market. Apparently Microsoft purposely sabotaged some of their API’s so that you can not easily spawn a process with alternate credentials from the SYSTEM account. There has to be a way of doing this, surely Microsoft didn’t paint themselves into a corner on this one. What happens if the OS wants to create a process under a different user (such as when a service is started under an account)? Sorry for such a long article but I wanted to show how completely I have researched this problem. Any constructive suggestions are welcomed with open arms and if you have a working example then I will be your new best friend.

Code is provided below. I did not run each method concurrently, I simply commented out methods and tested one at a time. You may get 6 - ERROR_INVALID_HANDLE if LogonUser is called more than once. You will have to replace user/pass where needed.

Full Project: http://www.ycodersco.../Files/raex.rar

Code

Option Strict On
Option Explicit On

Imports System
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports System.Threading

<Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True), _
Assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name:="FullTrust")> 
Module raex

	Dim strUser As String = Nothing
	Dim strPassword As String = Nothing
	Dim strServer As String = "192.168.1.109"
	Dim strPort As String = "2000"
	Dim strApplication As String = Nothing

#Region "Const"

	Const LOGON32_LOGON_INTERACTIVE As Integer = 2
	Const LOGON32_PROVIDER_DEFAULT As Integer = 0
	Const WINSTA_ALL_ACCESS As Integer = &H37F
	Const READ_CONTROL As Integer = &H20000
	Const WRITE_DAC As Integer = &H40000
	Const DESKTOP_WRITEOBJECTS As Integer = &H80
	Const DESKTOP_READOBJECTS As Integer = &H1
	Const GENERIC_ALL As Integer = &H10000000
	Const MAXIMUM_ALLOWED As Integer = &H2000000
	Const SECURITY_IMPERSONATION As Integer = 2
	Const TOKEN_PRIMARY As Integer = 1
	Const LOGON_NETCREDENTIALS_ONLY As Integer = &H1&
	Const CREATE_DEFAULT_ERROR_MODE As Integer = &H4000000

#End Region

#Region "Structures"

	Public Structure PROCESS_INFO
		Public hProcess As IntPtr
		Public hThread As IntPtr
		Public dwProcessId As Integer
		Public dwThreadId As Integer
	End Structure

	Public Structure STARTUP_INFO
		Public cb As Integer
		Public lpReserved As Integer
		<MarshalAs(UnmanagedType.LPTStr)> Public lpDesktop As String
		<MarshalAs(UnmanagedType.LPTStr)> Public lpTitle As String
		Public dwX As Long
		Public dwY As Integer
		Public dwXSize As Integer
		Public dwYSize As Integer
		Public dwXCountChars As Integer
		Public dwYCountChars As Integer
		Public dwFillAttribute As Integer
		Public dwFlags As Integer
		Public wShowWindow As Short
		Public cbReserved2 As Short
		Public lpReserved2 As Integer
		Public hStdInput As Integer
		Public hStdOutput As Integer
		Public hStdError As Integer
	End Structure

	Public Structure SECURITY_ATTRIBUTES
		Public nLength As Integer
		Public lpSecurityDescriptor As IntPtr
		Public bInheritHandle As Boolean
	End Structure

#End Region

#Region "API Imports"

	<DllImport("C:\\Windows\\System32\\advapi32.dll")> _
	Public Function CreateProcessWithLogonW(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpUsername As String, _
											<MarshalAs(UnmanagedType.LPWStr)> ByVal lpDomain As String, _
											<MarshalAs(UnmanagedType.LPWStr)> ByVal lpPassword As String, _
											ByVal dwLogonFlags As Integer, _
											<MarshalAs(UnmanagedType.LPWStr)> ByVal lpApplicationName As String, _
											<MarshalAs(UnmanagedType.LPWStr)> ByVal lpCommandLine As String, _
											ByVal lpCreationFlags As Integer, _
											ByVal lpVoid As Integer, _
											<MarshalAs(UnmanagedType.LPWStr)> ByVal lpCurrentDirectory As String, _
											ByRef lpStartupInfo As STARTUP_INFO, _
											ByRef lpProcessInfo As PROCESS_INFO) As Integer
	End Function

	<DllImport("C:\\Windows\\System32\\advapi32.dll")> _
Public Function LogonUser(ByVal lpUsername As String, _
							ByVal lpDomain As String, _
							ByVal lpPassword As String, _
							ByVal dwLogonType As Integer, _
							ByVal dwLogonProvider As Integer, _
							ByRef pToken As IntPtr) As Boolean
	End Function
	<DllImport("C:\\Windows\\System32\\user32.dll", SetLastError:=True)> _
Public Function GetProcessWindowStation() As IntPtr
	End Function


	<DllImport("C:\\Windows\\System32\\user32.dll", SetLastError:=True)> _
Public Function OpenWindowStation(ByVal lpszWinSta As String, _
									ByVal fInherit As Boolean, _
									ByVal dwDesiredAccess As UInteger) As IntPtr
	End Function

	<DllImport("C:\\Windows\\System32\\user32.dll", SetLastError:=True)> _
Public Function SetProcessWindowStation(ByVal hWinSta As IntPtr) As Boolean
	End Function

	<DllImport("C:\\Windows\\System32\\user32.dll", SetLastError:=True)> _
Public Function OpenDesktop(ByVal lpszDesktop As String, _
							ByVal dwFlags As Integer, _
							ByVal fInherit As Boolean, _
							ByVal dwDesiredAccess As UInteger) As IntPtr
	End Function

	<DllImport("C:\\Windows\\System32\\advapi32.dll", SetLastError:=True)> _
Public Function ImpersonateLoggedOnUser(ByVal hToken As IntPtr) As Boolean
	End Function

	<DllImport("C:\\Windows\\System32\\advapi32.dll", SetLastError:=True)> _
Public Function CreateProcessAsUser(ByVal pToken As IntPtr, _
									ByVal lpApplicationName As String, _
									ByRef lpCommandLine As String, _
									ByRef lpProcessAttributes As SECURITY_ATTRIBUTES, _
									ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, _
									ByVal bInheritHandles As Boolean, _
									ByVal dwCreationFlags As Integer, _
									ByRef lpEnvironment As IntPtr, _
									ByVal lpCurrentDirectory As String, _
									ByRef lpStartupInfo As STARTUP_INFO, _
									ByRef lpProcessInfo As PROCESS_INFO) As Boolean
	End Function

	<DllImport("C:\\Windows\\System32\\advapi32.dll", SetLastError:=True)> _
Public Function CreateProcessAsUserW(ByVal pToken As IntPtr, _
								ByVal lpApplicationName As String, _
								ByRef lpCommandLine As String, _
								ByRef lpProcessAttributes As SECURITY_ATTRIBUTES, _
								ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, _
								ByVal bInheritHandles As Boolean, _
								ByVal dwCreationFlags As Integer, _
								ByRef lpEnvironment As IntPtr, _
								ByVal lpCurrentDirectory As String, _
								ByRef lpStartupInfo As STARTUP_INFO, _
								ByRef lpProcessInfo As PROCESS_INFO) As Boolean
	End Function

	<DllImport("C:\\Windows\\System32\\advapi32.dll", SetLastError:=True)> _
Public Function DuplicateTokenEx(ByVal hExistingToken As IntPtr, _
									ByVal dwDesiredAccess As UInteger, _
									ByRef lpTokenAttributes As SECURITY_ATTRIBUTES, _
									ByVal ImpersonationLevel As Integer, _
									ByVal TokenType As Integer, _
									ByRef phNewToken As IntPtr) As Boolean
	End Function

#End Region

	<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
	Sub Main()
		Try
			Dim bReturn As Boolean
			Dim strNC As String = System.Environment.CurrentDirectory + "\nc.exe "
			Dim strNCArgs As String = strServer + " " + strPort + " -e cmd.exe"
			Dim strNotepad As String = "c:\windows\notepad.exe"

			'token returned from LogonUser and CreateProcessAsUser
			Dim pUserToken As IntPtr = IntPtr.Zero

			'Security attributes struct
			Dim pSecurityAttributes As SECURITY_ATTRIBUTES
			pSecurityAttributes.bInheritHandle = True
			pSecurityAttributes.nLength = Marshal.SizeOf(pSecurityAttributes)
			pSecurityAttributes.lpSecurityDescriptor = IntPtr.Zero
			'Start information struct
			Dim pStartInfo As STARTUP_INFO = Nothing
			pStartInfo.cb = Len(pStartInfo)
			pStartInfo.lpTitle = ""
			pStartInfo.dwFlags = 0&
			pStartInfo.lpDesktop = "winsta0\default"
			'Process information struct
			Dim pProcessInfo As PROCESS_INFO
			'Enviroment variable
			Dim pEnviroment As IntPtr = IntPtr.Zero

			'Method 1 - Use the built in .NET process class no user
			startProcessNoUser()

			'method 2 - .NET with new 2.0 user and password
			startProcess()

			'method 3 - Windows API LogonUser and CreateProcessAsUser

			bReturn = LogonUser("U3er", ".", "Pa33Word", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pUserToken)
			System.Console.WriteLine("Method 3 LogonUser - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = CreateProcessAsUser(pUserToken, System.Environment.CurrentDirectory + "\nc.exe", strServer + " " + strPort + " -e cmd.exe", Nothing, Nothing, False, 0, Nothing, System.Environment.CurrentDirectory, pStartInfo, pProcessInfo)
			System.Console.WriteLine("Method 3 CreateProcessAsUser - " + CStr(Marshal.GetLastWin32Error()))
			System.Console.WriteLine()

			'Method 4 - Same as 3 but add DuplicateTokenEx after LogonUser

			'Primary token
			Dim DupedToken As IntPtr = IntPtr.Zero

			bReturn = LogonUser("U3er", ".", "Pa33Word", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pUserToken)
			System.Console.WriteLine("Method 4 LogonUser - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = DuplicateTokenEx(pUserToken, MAXIMUM_ALLOWED, pSecurityAttributes, SECURITY_IMPERSONATION, TOKEN_PRIMARY, DupedToken)
			System.Console.WriteLine("Method 4 DuplicateTokenEx - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = CreateProcessAsUser(pUserToken, strNC, strNCArgs, pSecurityAttributes, pSecurityAttributes, False, 0, Nothing, System.Environment.CurrentDirectory, pStartInfo, pProcessInfo)
			System.Console.WriteLine("Method 4 CreateProcessAsUser - " + CStr(Marshal.GetLastWin32Error()))
			System.Console.WriteLine()

			'Method 5 - Same as 4 but use the unicode version of CreateProcessAsUser (CreateProcessAsUserW)
			bReturn = LogonUser("U3er", ".", "Pa33Word", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pUserToken)
			System.Console.WriteLine("Method 5 LogonUser - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = DuplicateTokenEx(pUserToken, MAXIMUM_ALLOWED, pSecurityAttributes, SECURITY_IMPERSONATION, TOKEN_PRIMARY, DupedToken)
			System.Console.WriteLine("Method 5 DuplicateTokenEx - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = CreateProcessAsUserW(pUserToken, strNC, strNCArgs, pSecurityAttributes, pSecurityAttributes, False, 0, Nothing, System.Environment.CurrentDirectory, pStartInfo, pProcessInfo)
			System.Console.WriteLine("Method 5 CreateProcessAsUserW - " + CStr(Marshal.GetLastWin32Error()))
			System.Console.WriteLine()

			'Method 6 - Use the API CreateProcessWithLogonW
			Dim iReturn As Integer
			iReturn = CreateProcessWithLogonW("U3er", System.Environment.MachineName, "Pa33Word", LOGON_NETCREDENTIALS_ONLY, Nothing, System.Environment.CurrentDirectory + strNC + " " + strNCArgs, CREATE_DEFAULT_ERROR_MODE, Nothing, System.Environment.CurrentDirectory, pStartInfo, pProcessInfo)
			System.Console.WriteLine("Method 6 CreateProcessWithLogonW - " + CStr(Marshal.GetLastWin32Error()))
			System.Console.WriteLine()

			'Method 7 - APIs with everything but the kitchen thrown in
			Dim hwinstaSave As IntPtr
			Dim hwinsta As IntPtr
			Dim hdesk As IntPtr

			hwinstaSave = GetProcessWindowStation()
			System.Console.WriteLine("Method 7 GetProcessWindowStation - " + CStr(Marshal.GetLastWin32Error()))
			hwinsta = OpenWindowStation("winsta0", False, WINSTA_ALL_ACCESS)
			System.Console.WriteLine("Method 7 OpenWindowStation - " + CStr(Marshal.GetLastWin32Error()))
			SetProcessWindowStation(hwinsta)
			System.Console.WriteLine("Method 7 SetProcessWindowStation - " + CStr(Marshal.GetLastWin32Error()))
			hdesk = OpenDesktop("default", 0, False, READ_CONTROL And WRITE_DAC And DESKTOP_WRITEOBJECTS And DESKTOP_READOBJECTS)
			System.Console.WriteLine("Method 7 OpenDesktop - " + CStr(Marshal.GetLastWin32Error()))
			SetProcessWindowStation(hwinstaSave)
			System.Console.WriteLine("Method 7 SetProcessWindowStation - " + CStr(Marshal.GetLastWin32Error()))

			'use method 4
			bReturn = LogonUser("U3er", ".", "Pa33Word", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pUserToken)
			System.Console.WriteLine("Method 7 LogonUser - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = DuplicateTokenEx(pUserToken, MAXIMUM_ALLOWED, pSecurityAttributes, SECURITY_IMPERSONATION, TOKEN_PRIMARY, DupedToken)
			System.Console.WriteLine("Method 7 DuplicateTokenEx - " + CStr(Marshal.GetLastWin32Error()))
			bReturn = CreateProcessAsUser(pUserToken, strNC, strNCArgs, Nothing, Nothing, False, 0, Nothing, System.Environment.CurrentDirectory, pStartInfo, pProcessInfo)
			System.Console.WriteLine("Method 7 CreateProcessAsUser - " + CStr(Marshal.GetLastWin32Error()))
			System.Console.WriteLine()

			'Method 8 - Use some crazy ideas from .NET to set impersonation

			'get token from LogonUser API
			bReturn = LogonUser("U3er", ".", "Pa33Word", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pUserToken)
			System.Console.WriteLine("Method 8 LogonUser - " + CStr(Marshal.GetLastWin32Error()))
			Dim newId As New WindowsIdentity(pUserToken)
			Dim impersonatedUser As WindowsImpersonationContext = newId.Impersonate()
			'Use method 1
			startProcessNoUser()

			Console.ReadKey()

		Catch ex As Exception
			Console.WriteLine(" Exception thrown " + ex.ToString)
		End Try
	End Sub


	Public Sub startProcessNoUser()
		Try
			Dim p As New Process
			p.StartInfo.Arguments = strServer + " " + strPort + " -e cmd.exe"
			p.StartInfo.CreateNoWindow = True
			p.StartInfo.ErrorDialog = False
			p.StartInfo.FileName = System.Environment.CurrentDirectory + "\nc.exe"
			p.StartInfo.UseShellExecute = False
			p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
			p.StartInfo.RedirectStandardOutput = True
			Console.WriteLine("Method 1 .NET No User - Command: " + p.StartInfo.FileName + " " + p.StartInfo.Arguments)
			p.Start()
		Catch ex As Exception
			Console.WriteLine(ex.ToString)
		End Try
	End Sub

	Public Sub startProcess()
		Try
			Dim p As New Process
			p.StartInfo.UserName = "U3er"
			Dim ssPass As New System.Security.SecureString
			Dim c As Char
			For Each c In "Pa33Word"
				ssPass.AppendChar(c)
			Next
			p.StartInfo.Password = ssPass
			p.StartInfo.Domain = System.Environment.MachineName
			p.StartInfo.Arguments = strServer + " " + strPort + " -e cmd.exe"
			p.StartInfo.CreateNoWindow = True
			p.StartInfo.ErrorDialog = False
			p.StartInfo.FileName = System.Environment.CurrentDirectory + "\nc.exe"
			p.StartInfo.UseShellExecute = False
			p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
			p.StartInfo.RedirectStandardOutput = True
			Console.WriteLine("Method 1 .NET No User - User: " + p.StartInfo.Domain + "\" + p.StartInfo.UserName + " Command: " + p.StartInfo.FileName + " " + p.StartInfo.Arguments)
			p.Start()
		Catch ex As Exception
			Console.WriteLine(ex.ToString)
		End Try
	End Sub

End Module


#2 bnewsom

bnewsom

    Newbie [ Level 1 ]

  • Members
  • 1 posts

Posted 21 August 2006 - 05:45 PM

I am running into the exact same issue... I also need to spawn a process from NT Authority\system with alternate credentials.

Did you ever figure out how to do this?

#3 tansqrx

tansqrx

    Super Member

  • [HOSTED]
  • 759 posts

Posted 23 August 2006 - 07:12 AM

Well I never did find a good answer to my .NET question. Apparently there are a whole lot of programmers with the exact same question. Personally I think Microsoft painted themselves into a bug corner.

But I did get an answer and one that worked almost perfectly for me. I posted the same question to microsoft.public.dotnet.security and got one response (http://groups.google...af51c2444d5d8bf). A very nice lady posted a link to an old project that she completed. The project is in C++ but at that point in time I would try anything. The only modification I had to do was to add code to hide the window when opened (STARTUP_INFO struct).

I really liked the solution because of the –i option. It automatically finds out who the interactive user is and does all the dirty work for you. In the end I modified the hidden window problem and just used the program as is. I know you would like to hear of a definite answer but I saw the opportunity and simply used someone else’s hard work. I don’t think you will ever get this to work under the current .NET framework. If you really need this then I would write it as a dll in C++.

#4 tansqrx

tansqrx

    Super Member

  • [HOSTED]
  • 759 posts

Posted 29 March 2008 - 05:50 AM

I recently got an email from someone looking for the source code referred to in my previous post. Apparently the original link died so I have uploaded it to my website and can be found at http://www.ycodersco...ocessAsUser.rar

#5 Guest_FeedBacker_*

Guest_FeedBacker_*
  • Guests

Posted 09 June 2008 - 06:39 AM

Still a issue...
Creating New Process Under Alternate Credentials (createprocessasuser)

Hey tansqrx, I tried using the above code as is(with trivial changes to make it compile) to run an executable as a diffrent user, but it won't work.

I am still guessing how you got it working. Any clues?

-reply by Stilltrying

#6 Guest_FeedBacker_*

Guest_FeedBacker_*
  • Guests

Posted 01 July 2008 - 09:07 AM

I had a go as well
Creating New Process Under Alternate Credentials (createprocessasuser)

Great bit of code...
I compiled it up after 1 minor mod...
It runs fine and seems to start processes up, but they can only be seen in the task manager...
Am I missing something...?


-question by jbryers

#7 tansqrx

tansqrx

    Super Member

  • [HOSTED]
  • 759 posts

Posted 08 July 2008 - 09:09 PM

It runs fine and seems to start processes up, but they can only be seen in the task manager...


Being able to see the process only in the task manager is the entire point of this application. You can change the way the application shows itself by modifying the STARTUP_INFO structure (http://msdn.microsof.../ms686331(VS.85).aspx). The two fields that you should look at is dwFlags and wShowWindow.

My original problem was getting a process to start under the current user context from a Windows service that was running under the SYSTEM account. The SYSTEM account is the all powerful account that Windows runs in and is even more powerful than administrator but has its limitations. Each user on a system gets a screen session when they login. If I login as Joe then I get my own screen (desktop) and any application that I open will be rendered on that screen. I can only see the windows on my screen and no one else can see my screen. SYSTEM on the other hand is not assigned a screen and if an application is opened by SYSTEM then the current user can not see the window. An example of this is creating a Windows service running under SYSTEM that opens Notepad. Once the service is started you will see the Notepad process in Task Manager but the current user will not see the Notepad window because it was not opened on their screen. The purpose of CreateProcessAsUser.exe is to open a process under the current user so they are able to see the Notepad window. To alter the above example to make Notepad visible, call CreateProcessAsUser.exe with process.start and add the appropriate command line arguments.

I needed CreateProcessAsUser.exe to create a process without a visible window yet still be in the current user’s context. As demonstrated in the original thread, it is not possible to do this in the .NET Framework because of a deliberate(?) omission to the .NET API.

#8 Guest_(G)Philip Patrick_*

Guest_(G)Philip Patrick_*
  • Guests

Posted 01 April 2009 - 03:54 PM

Not working nowadays :(Creating New Process Under Alternate Credentials (createprocessasuser)

So I got myself into this trouble as well. Now I know this is possible, because, for example, Task Scheduler service, that runs under SYSTEM account can start and show Notepad no problem, but I cannot do this.

I took the code and changed the SW_HIDE back to SW_SHOWNORMAL (is that all you have changed? or something else?). I wasn't able to show notepad to user, but the behavior was different in 3 cases:

1. Running on Vista - I see message box with a message that a program tries to interact with desktop. Allowing this - you can see the notepad in a separate "clean" desktop".

2. Running on Windows 2003 SP2 with physical access - notepad is visible, but is not operable - I see only title bar with icon, no menus, nothing else

3. Running on Windows 2003 SP2 but logged in via Remote desktop - Nothing shown at all although I see the notepad in tasks manager :(

-reply by Philip Patrick

 



#9 tansqrx

tansqrx

    Super Member

  • [HOSTED]
  • 759 posts

Posted 08 April 2009 - 04:20 PM

Once again I have found that my original question cannot be performed in .NET due to a bug in the framework. The bug has been known about for years (first found it on a .NET 1.1 forum) so I can only assume Microsoft wants it this way. My work around is code in c++ which you can call from .NET. Not my code but here is a link to a copy. http://ycoderscookbo...ocessAsUser.rar

#10 Guest_(G)Shawn B_*

Guest_(G)Shawn B_*
  • Guests

Posted 18 April 2009 - 01:03 AM

Executable WrapperCreating New Process Under Alternate Credentials (createprocessasuser)

I have a problem relating to the same type of issue but in my case I have created a Visual Basic .NET 2008 executable that when I run it I can successfully allow a normal domain user who is logged in to his/her desktop interactively to run a program with elevated domain privileges.  I know this is working because if I just run the executable as a user I get an access denied error but running the executable wrapper it works fine.

Now the problem I am having is when I push this new program from our Network Access Control (NAC) device so the logged on user can self-remeidate the problem without involving an Administrator and maintain network access it fails with an Access Denied error.  I have determined that the NAC is using the Task Scheduler service to start a new task which is running under the NT AuthoritySystem account.  I know this because I added debugging code to the wrapper application to determine the currently logged on user right before it hits the lines of code that start the remediation executable under the elevated privileges.  This code is returning NT AuthoritySystem and that seems correct since the Task Scheduler service runs under this account.  It appears to be failing when it tries to access the executable file to run that was copied into a directory that is created on the fly during program execution.  I also have the file permissions set to Everyone Full Control on the executable file and still get an Access Denied.  I thought NT AuthoritySystem should have Full access to every file by default but am now at wits end trying to figure out the Access Denied error.

Also in my situation I am running the application interactive because the logged in user needs to provide some simple input while the elevated program is running.

-reply by Shawn B

 



#11 Guest_(G)_*

Guest_(G)_*
  • Guests

Posted 23 June 2009 - 06:09 AM

PhilipTake a look at the Session ID and access token type. In your Vista case, your service is starting in Session 0 and trying to spawn an apllication. Unfortunately, in Vista onwards, Session 0 does not have an associated desktop - hence the strange error you got.If you use the CreateProcessAsUser, you also need to make sure you use the Primary access token and not the Impersonation access token.Http://blogs.Msdn.Com/sripod/archive/2006/11/21/session-0-isolation-in-vista-and-application-compatibility.aspx

 



#12 Guest_(G)Monika_*

Guest_(G)Monika_*
  • Guests

Posted 13 August 2009 - 12:34 PM

problem hiding the window created by createprocessasuserCreating New Process Under Alternate Credentials (createprocessasuser)

Hi,

I am not able to hide the window of the process which I have started using CreateProcessAsUser(). I am using c# and have tried setting values for dwFlags and wShowWindow .

Please help.

-reply by Monika

#13 Guest_(G)Dave_*

Guest_(G)Dave_*
  • Guests

Posted 01 November 2009 - 06:02 PM

C# Process.StartInfo with UserName and Password flashes!Creating New Process Under Alternate Credentials (createprocessasuser)

Anyone ever figure out how to eliminate the flash using the .NET Process object. Works fine without credentials. This BUG has plagued me for years back when I used to use CreateProcess as well. I'm all native code now though so would love to fix this for.NET native. Thanks for any suggestions. Dave

-reply by Dave

 



#14 Guest_(G)scott_*

Guest_(G)scott_*
  • Guests

Posted 31 December 2009 - 09:29 PM

start interactive process from scheduled taskCreating New Process Under Alternate Credentials (createprocessasuser)

My problem is that I need to start an interactive session from a scheduled task and then send commands to the application windows on server 2003. The credentials for the task and the application process need to be the same. I tried doing an interactive login, but I guess I also need to start a process associated with that login? Doesn't just logging in start an interactive desktop session?

-reply by scott

 



#15 Guest_(G)_*

Guest_(G)_*
  • Guests

Posted 31 December 2009 - 09:16 PM

Replying to tansqrxMy problem is that I need to start an interactive session from a scheduled task and then send commands to the application windows. The credentials for the task and the application process need to be the same. I tried doing an interactive login, but I guess I also need to start a process associated with that login? Doesn't just logging in start an interactive desktop session?

#16 Guest_(G)Fernando Nomellini_*

Guest_(G)Fernando Nomellini_*
  • Guests

Posted 27 January 2010 - 12:32 PM

Solution for 1314 problemCreating New Process Under Alternate Credentials (createprocessasuser)

Hi ! I hope you already find the solution for 1314 issue that arises when calling CreateProcessAsUser. If not, I found it,  and it workey fine to me.

I will try to put in english, but my sistem is Brasilian Portiguese, ok ?

go to control panel / administrative tools / local security / local / user rights /

then in "replace token in user level" (or so)  ADD local ASPNET account.

then reboot.

that´s it.

-reply by Fernando Nomellini

 



#17 AndrehPoffo

AndrehPoffo

    Newbie [ Level 1 ]

  • Members
  • 1 posts

Posted 21 July 2010 - 08:31 PM

Solution for 1314 problem
Creating New Process Under Alternate Credentials (createprocessasuser)

Hi ! I hope you already find the solution for 1314 issue that arises when calling CreateProcessAsUser. If not, I found it, and it workey fine to me.

I will try to put in english, but my sistem is Brasilian Portiguese, ok ?

go to control panel / administrative tools / local security / local / user rights /

then in "replace token in user level" (or so) ADD local ASPNET account.

then reboot.

that´s it.

-reply by Fernando Nomellini



How that SQL Express can modify these user policies?

#18 Guest_(G)Wes_*

Guest_(G)Wes_*
  • Guests

Posted 09 March 2011 - 10:56 PM

Can you provide a compiled version that doesnCreating New Process Under Alternate Credentials (createprocessasuser)

 Hi [font=" Verdana, Arial, Tahoma, Trebuchet, sans-serif, MS, Georgia, Courier, 'Times New Roman', serif; font-size: 13px; font-weight: bold; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px"]tansqrx[/font][font=" Verdana, Arial, Tahoma, Trebuchet, sans-serif, MS, Georgia, Courier, 'Times New Roman', serif; font-size: 13px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px"],[/font]

Thank you very much for sharing the C++ solution (as I am attempting to do the same thing as you on Windows 7). However, I have no knowledge of C/C++ and no compiler - could you please change the properties for hiding the process window so that it will show/display the process in its normal application state, compile it and share it too?

I would VERY MUCH appreciate your assistance!

Thanks,

Wes



#19 Guest_(G)Nagendra_*

Guest_(G)Nagendra_*
  • Guests

Posted 11 October 2011 - 02:32 PM

Creating New Process Under Alternate Credentials Creating New Process Under Alternate Credentials (createprocessasuser)

Replying to tansqrx,Can you provide me the same code, which is there in that link, I am not able to access the link.. And I need it very badly.

-reply by Nagendra



#20 Guest_(G)Nagendra Simhadri_*

Guest_(G)Nagendra Simhadri_*
  • Guests

Posted 11 October 2011 - 05:20 PM

Creating New Process Under Alternate Credentials (createprocessasuser)Creating New Process Under Alternate Credentials (createprocessasuser)

Replying to tansqrxReplying to (G)Philip PatrickI need the same code. Creating process under alternate credentials, I checked the link provided by tansqrx, but it is not working... Seems it is a little old site. Can somebody please help me. I need a C++ code only.Issue,I am trying to run a service with alternate credentials, but it is not granting the permisions, so I am trying to create a process (here is the confusion which WINDOWS API need to be used? CreateProcessAsUser or CreateProcessWithLogonW ). Somebody help me with proper info. How I need to create a process, so it will have priviliages and it will run with alternate credentials.

-reply by Nagendra Simhadri





Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users