none
Restricted Token Created from Elevated Process Behaves Differently than when Its Created From Standard-User Process

    Question

  • On Windows 7, I'm attempting to create an application with a restricted token from an elevated process.  This restricted app will also later create a child process.  The problem is that this child process fails to initialize, citing error 0xc0000142 (dll failed to initialize).

    I should note the restricted token I'm using is designed to mirror a standard app's token with UAC enabled; that is the Admin group is disabled, it has medium IL and there are only a handful of privileges available.  

    If I do not disable the Admin group in the restricted token then the child process works correctly.  If I leave the Admin group disabled and create the parent application from a non-elevated process then the child process works correctly.  

    I guess my question is, why is my restricted application behaving differently when its created from an elevated process versus a standard process?

    Friday, September 03, 2010 6:19 PM

Answers

  • I've discovered the root of my problem.  My restricted process was inheriting the DACL from the Admin process.  Because of this my restricted process did not have access to the appropriate secure objects to create a new console.  By modifying the DACL of the restricted process I have solved this problem and thus I can now create a standard-user process from an Admin process.

    I used the following as a basis for my solution:

    http://support.microsoft.com/kb/193073

    • Marked as answer by amcorn3 Tuesday, September 14, 2010 4:39 PM
    Tuesday, September 14, 2010 4:38 PM

All replies

  • You get this error (0xc0000142) because the child application is not able to access on the default desktop. Try running your application on a different desktop. Or initialize lpDesktop of startupinfo to "" (empty string) before passing it into CraeteProcessAsUser. See this support article: CreateProcessAsUser() windowstations and desktops 

    You may have this problem if you are lauching the child application on the same desktop as of the parent. You can't have the elevated application launching a non-elevated application on the same desktop. See the folowing section in CreateRestrictedToken  

    Warning  Applications that use restricted tokens should run the restricted application on desktops other than the default desktop. This is necessary to prevent an attack by a restricted application, using SendMessage or PostMessage, to unrestricted applications on the default desktop. If necessary, switch between desktops for your application purposes.

     


    My next phone is Windows Phone 7
    Saturday, September 04, 2010 5:37 PM
  • Why then can I successfully run the child process with the restricted token without invoking it from the restricted parent process?  And why can the parent process create other child processes without the aforementioned error being thrown?

    Also, the parent and child processes must be launched on the interactive desktop.  Because of this requirement and assuming what you said is correct, is there any workaround you can suggest?

    Monday, September 06, 2010 12:57 AM
  • Why then can I successfully run the child process with the restricted token without invoking it from the restricted parent process?  And why can the parent process create other child processes without the aforementioned error being thrown?

    >> Because both parent and child have same token, either elevated or non elevated.

    assuming what you said is correct, is there any workaround you can suggest?

    You may try to use the linked token in case you are dealing only with interactive processes. See a code example here http://blogs.msdn.com/b/winsdk/archive/2010/05/31/dealing-with-administrator-and-standard-user-s-context.aspx 

    Let us know how does it goes.


    My next phone is Windows Phone 7
    Monday, September 06, 2010 9:49 AM
  • Why then can I successfully run the child process with the restricted token without invoking it from the restricted parent process?  And why can the parent process create other child processes without the aforementioned error being thrown?

    >> Because both parent and child have same token, either elevated or non elevated


    I will look into linked tokens, but your above answer confuses me.  I'll describe the scenario once more.  

    I have written an application, which runs elevated, that will create a restricted, non-elevated process which I will refer to as the "parent process."  The only differences between the main app's token and the parent's token is that the Admin group is disabled and the integrity level is set to medium.  The parent process can spawn several different child processes, only one of which receives the 0xc0000142 error.

    So I can create a non-elevated application on the same desktop as the launching elevated process, and the non-elevated app can create child processes.  Its the one instance where a child process does not launch that I'm curious about.

    Tuesday, September 07, 2010 2:46 PM
  • I see. I undersatnd the problem now

    If I am right this time here is the sequence

    Elvated Process ---------->Parent Process (with resricted token) -------------->Child Processes and creattion of one of the child process fails with 0xc0000142. Or on one of the machines the child process fail to launch with 0xc0000142.

    You get this error if you dont have access to desktop or desktop heap is full. You may want to use Desktop heap monitor to see if the heap is being exploited. On Windows Server 2003 and other server OS you can find a event entry as well for the heap exploitation.

    If there is a problem in accessing the desktop. You need to verify the identity of your applications. Can you share the simplified code of process creation on each level (Elevared-Parent-Child) ?   Also, share if you are using any application manifest.                                            

     


    My next phone is Windows Phone 7
    Tuesday, September 07, 2010 5:45 PM
  • I will only be able to supply code for the process that spawns the restricted parent.  But before I do I should also note that I experience none of the above problems if I leave the Admin group enabled in the restricted token -  unfortunately it is a requirement I disable the Admin group to deny access to sensitive areas, e.g. the registry. 

    So Admin group disabled and I get 0xc0000142.  Admin group enabled and I receive no errors and everything works correctly.  I hope this makes things even clearer.

     

    Tuesday, September 07, 2010 9:47 PM
  • I am running short of ideas. I will create a demo test today and see if I can reproduce and debug the problem. If you happen to have a demo, that will be great, (it will be more accurate and more people will be able to look at it) may be you can attach it to this thread (I am not sure if there is any attachment option, may be you can keep it on on skydrive and share)

     


    My next phone is Windows Phone 7
    Wednesday, September 08, 2010 4:17 PM
  • To reproduce the problem I've described, run "start cmd" in the command prompt that is created by the code below.
    EDIT: Be sure you run this elevated.

      BOOL bRet;
    	HANDLE hToken;
    	HANDLE hNewToken;
    
    	WCHAR wszProcessName[MAX_PATH] =
    		L"cmd.exe";
    
    	// Medium integrity SID
    	WCHAR wszIntegritySid[20] = L"S-1-16-8192";
    	PSID pIntegritySid = NULL;
    
    	TOKEN_MANDATORY_LABEL TIL = {0};
    	PROCESS_INFORMATION ProcInfo = {0};
    	STARTUPINFO StartupInfo = {0};
    
    	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
    	StartupInfo.cb = sizeof(STARTUPINFO);
    
    	if (OpenProcessToken(GetCurrentProcess(),MAXIMUM_ALLOWED, &hToken))
    	{
    		SID_AND_ATTRIBUTES *sid_and_attributes;
    		sid_and_attributes = static_cast<SID_AND_ATTRIBUTES *>(LocalAlloc(LPTR, sizeof(SID_AND_ATTRIBUTES)));
    		sid_and_attributes->Attributes = 0;
      // Disable Builtin Admin group
    		ConvertStringSidToSid(L"S-1-5-32-544", &sid_and_attributes->Sid);
    
    		if (CreateRestrictedToken(hToken, DISABLE_MAX_PRIVILEGE, 1, sid_and_attributes, 0, NULL, 0, NULL, &hNewToken))
    		{
    		 if (ConvertStringSidToSid(wszIntegritySid, &pIntegritySid))
    		 {
    			 TIL.Label.Attributes = SE_GROUP_INTEGRITY;
    			 TIL.Label.Sid = pIntegritySid;
    
    			 // Set the process integrity level
    			 if (SetTokenInformation(hNewToken, TokenIntegrityLevel, &TIL,
    				sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)))
    			 {
    				 // Create the new process at Low integrity
    				 bRet = CreateProcessAsUser(hNewToken, NULL,
    					 wszProcessName, NULL, NULL, FALSE,
    					 0, NULL, NULL, &StartupInfo, &ProcInfo);
    
    			 }
    			 LocalFree(pIntegritySid);
    		 }
    		 CloseHandle(hNewToken);
    	 }
    	 CloseHandle(hToken);
    	}
    	LocalFree(&StartupInfo);
    

     

    Wednesday, September 08, 2010 8:13 PM
  • Any ideas?
    Saturday, September 11, 2010 5:37 AM
  • I've discovered the root of my problem.  My restricted process was inheriting the DACL from the Admin process.  Because of this my restricted process did not have access to the appropriate secure objects to create a new console.  By modifying the DACL of the restricted process I have solved this problem and thus I can now create a standard-user process from an Admin process.

    I used the following as a basis for my solution:

    http://support.microsoft.com/kb/193073

    • Marked as answer by amcorn3 Tuesday, September 14, 2010 4:39 PM
    Tuesday, September 14, 2010 4:38 PM