2

I'm experiencing a weird phenomena regarding Windows SYSTEM Account. Looking at these three different ways to start a process as SYSTEM:

  • Sysinternals PSExec
  • Task Scheduler
  • GPO Startup Script.

Processes started with these methods result in different access token group memberships!

Processes started by Task Scheduler have the full set of groups in their access token.

started by Task Scheduler (Image)

Processes started by PSExec/Startup Script on the other hand have a massively reduced set of groups in their access token - only those four

started by PSExec/Startup Script (Image)

BUILTIN\Administrators (S-1-5-32-544)
Everyone (S-1-1-0)
NT AUTHORITY\Authenticated Users (S-1-5-11)
Mandatory Label\System Mandatory Level (S-1-16-16384)

Anyone an idea why that is?

For context:

BITS Service throws a "user has not logged on to the network" 0x800704DD error when trying to add a file to a transfer in processes started with Startup Script or PSExec - works fine with ones started with Task Scheduler.

All tests on Windows 10 1703; Group memberships taken from whoami /all and Sysinternals Process Explorer

alexander.polomodov
  • 1,060
  • 3
  • 10
  • 14

2 Answers2

0

I FOUND the frickin root cause of the problem - at least for Startup Script.

I looked at the call stack and turns out a Startup Script is called through:

svchost.exe (hosts gpsvc) > gpscript.exe > cmd.exe

All three processes have a reduced set of group memberships in their access token. Turns out since Windows 10 1703 svchost services are not grouped anymore, if you have above 3.5 GB of memory. https://docs.microsoft.com/en-us/windows/application-management/svchost-service-refactoring

Each service of svchost gets its own process - with different group memberships in access token (background to this still unclear, input to this still very much appreciated!). Luckily there's an opt-out:

Solution:

Adding the registry value

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\gpsvc\SvcHostSplitDisable=1 [DWORD]

keeps the service gpsvc in the main svchost process with the full set of group memberships - even if above 3.5 GB of memory. And therefore gpscript.exe and Startup Script is called with the full set of memberships.

For me it's still very unclear to why a process with the same user can have a different set of group memberships in their access token - when no actual membership has changed. I'd appreciate any input on this.

Sadly after all this: BITS service still doesn't accept file transfers and throws "user has not logged on to the network" 0x800704DD. I have opened a new question for this https://stackoverflow.com/questions/51009804/how-to-start-a-bits-download-as-system-account-current-error-user-has-not-log

0

This depends on how the service is configured, more specifically on the Service SID Type.

If the Service SID Type is "none" then the service just gets a plain SYSTEM token, the same as is used by other system processes such as services.exe and winlogon.exe and so on. This is the legacy situation; back in Windows XP all services had this sort of token, unless they were configured to run as a particular user account.

If the Service SID Type is "restricted" or "unrestricted" then a more specific token is generated for the service, including a special security identifier specific to that service, e.g., NT SERVICE\Schedule for the Task Scheduler. This helps to provide some granularity between different services. In Windows 7 and later most of the built-in services are "unrestricted". The Group Policy Service is an exception; this was probably an oversight on Microsoft's part. (I would have thought it was a deliberate choice for backwards compatibility, but this is undermined by the fact that in Windows 7 it always runs in a shared service process.)

As you have already observed, as well getting the NT SERVICE identifier, the token is given a number of other identifiers. This isn't documented as far as I can see but also isn't especially surprising; it makes the service token more like an interactive token would be, which can be useful. (It is particularly important that this be the case for restricted tokens, which would otherwise have very little access at all.)

As described in the self-answer, when multiple services are shared by a single process the process token has to contain every SID that any of the services needs. So if the Group Policy Service (or any other service with a SID type of "none") is sharing a process with an "unrestricted" service, it gets the exact same token as if it were itself "unrestricted".

Because earlier versions of Windows effectively ran the Group Policy Service as "unrestricted" and because even Windows 10 does so on machines with very limited memory, it would probably not be too dangerous to reconfigure the SID Type for the Group Policy service if it is absolutely necessary to do so. I don't recommend this other than perhaps as a very short-term solution, partly because there is still some risk (particularly regarding forwards compatibility) but mainly because every time you upgrade to a new version of Windows 10 the setting is likely to be reverted.

A better workaround would be for a startup script to run a scheduled task or to install and run a service to do whatever work is needed on the startup script's behalf.

Harry Johnston
  • 5,875
  • 4
  • 35
  • 52
  • thank you so much for your extensive input. I didn't know about Service SID Types - gonna research this a bit and see what I can come up with. In retrospect this all comes together as PSExec starts the System process via installing a service – CounterClockWise Jun 25 '18 at 12:04