Win32_Process.Create fails if user profile is not loaded

Hi all, welcome back,

The other day I worked on an issue which happened when using WMI method Win32_Process.Create to spawn a process from an ASP.NET application. This method was returning an UNKNOWN FAILURE (8) and the new process wasn't created. The application was running as Network Service and WMI was impersonating a special user when launching the new process.

We could also reproduce the issue with a VBScript that we launched as the special user with runas command and its /noprofile option. When we used /profile option instead, the script worked fine, and so did the ASP.NET app! So it seems that this WMI method is dependant of the user profile being loaded.

After some tests and some debugging, I confirmed this:

Win32_Process.Create always tries to access the registry of the user which will launch the process (the one we are impersonating). This behavior is by design and can't be modified.

If the user profile is loaded, there is no problem as Create can access the registry keys it needs. But if the profile is not loaded, it will try to load the registry hive of the user (NTUSER.DAT file) into the registry. For doing that it uses RegLoadKey API, which in our case is failing with ERROR_PRIVILEGE_NOT_HELD error. This internal error will cause the misleading ERROR_NOT_ENOUGH_MEMORY that we get from Create method.
I verified the privileges this API requires in its documentation: "The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges on the computer in which the registry resides."

Summing up, Win32_Process.Create will work if the user we are impersonating has SE_RESTORE_NAME (a.k.a. SeRestorePrivilege a.k.a. "Restore files and directories") and SE_BACKUP_NAME (a.k.a. SeBackupPrivilege a.k.a."Backup files and directories") privileges in the local machine where the WMI code is running. This way it can load the registry hive if the profile for that user is not loaded.

An alternate solution may be to load the profile before calling Create. IIS won’t load it automatically, and WMI neither. We may load it by calling LoadUserProfile API, for instance. But the user calling this API needs high privileges. So if we know the user we are impersonating, we may have an easier way to load the profile: Service Control Manager (SCM) automatically loads the user profile of the user running a Windows service. We may create a dummy service which does nothing but always stay alive and which runs as our special user, so its profile gets loaded. Once the profile of the user gets loaded by SCM, every other app which requires it will have access to it, like a web app or a web service.

I hope this helps.

Cheers,

 

Alex (Alejandro Campos Magencio)