There are several different types of accounts one should be aware of: Virtual Accounts, Managed Service Accounts & Group Managed Service Accounts. Today, in part 1 of this blog series, we will discuss Virtual Accounts.
Virtual Accounts
Virtual Accounts were introduced in Windows 7 and have been progressively extended in subsequent releases. A Virtual Account has a well-known SID (or more accurately a well-known SID prefix), just like the predefined local accounts that pre-dated them (e.g LocalSystem, whose well-known SID is S-1-5-18).
Incidentally, I say ‘well known’, but in some cases, this corresponds to ‘undocumented but well known to the authors of the Windows codebase’.
Virtual Accounts, unlike predefined accounts, are rather peculiar beasts. Like many Windows enhancements over the years (the 8.3 filename hack in particular) they are a cunning hack on top of an existing infrastructure.
A Virtual Account consists of two parts, just like any other built-in account, i.e., for a pre-existing predefined local account we have, for example, the two-part name:
NT AUTHORITY\Network Service
And for Virtual Accounts, we have the same naming convention i.e.:
Account Class\Account Name
Virtual Accounts are defined for a fixed set of class names – which are (I believe) hard-wired into the OS and can’t be extended by the user – but – and this is the critical difference – the account NAME isn’t defined. Instead, an infinite number of accounts within a class is available. You don’t create or delete Virtual Accounts, they just ‘are’.
How this works has to do with the cunning hackery I referred to earlier. Everything in Windows revolves around the concept of a security principal and in general, this is associated with a SID. So Virtual Accounts start with a distinct SID prefix (allocated to the account class) and then add a unique suffix for each account. Unlike ‘real’ accounts, the Virtual Accounts don’t exist as such. They aren’t created or deleted and can’t be managed through the GUI. Instead, a SID is calculated dynamically, so that for an account:
Account Class\xxyyzzz
We can get a unique SID. This is done by computing the SHA-1 hash of the name (in this case xxyyzzz).
Now you can allocate permissions to this SID, just like any other SID. Hence, Virtual Accounts give you an infinite number of local accounts, each of which can be given permissions separately because it maps to a distinct SID. Thus, the problem of services sharing a built-in account and thus having cross-service permissions they shouldn’t have is solved.
Also, another advantage of this approach is that the SID is fixed across machines – unlike a true local account created on the machine, where, apart from the built-in accounts, the SID associated with that account would be specific to that machine. This has advantages when you need to migrate secured resources since the SIDs associated with the ACLs for the resources will now remain constant. However, as discussed at the end of this document, a Virtual Account uses the computer account to access external resources, so although the SID is invariant, this doesn’t mean that a secured resource can be migrated seamlessly if external resources are involved. (this is one reason why MSAs and then gMSAs were invented. They are domain-level accounts, however, and beyond the scope of this discussion).
Virtual Account classes and the Virtual Service Account class
As stated previously, the set of Virtual Account classes is hard-wired into the OS. The best-documented of these classes is the Virtual Service Account. This uses the class name:
NT SERVICE
Consequently, all Virtual Service Accounts will be in the form.
NT SERVICE\xxyyzzz
Microsoft has embraced these enthusiastically so you’ll find SQL Server using them, for instance. For example, on my lab machine, I have an instance of SQL Server running under the Virtual Account NT Service\MSSQL$SQL2014STD
Now the xxyyzzz name is just the name of the service. Critically it DOES NOT NEED TO EXIST. You can see this by using the ‘sc’ utility to show you the calculated SID for a service ‘xxyyzzz’ which does not exist. You can see here that the NT SERVICE well-known SID prefix (S-1-5-80) is suffixed with the dynamically-calculated part, which as mentioned is derived from the SHA1 hash of the service name.