Per-service SID

(This is part 3 of our series of posts on service hardening.)  

Under Windows Vista/Longhorn Server, your service can now have its own SID (Security Identifier), which you can then use in ACLs to protect your service resources. You configure your service to be assigned a per-service SID during its installation with the ChangeServiceConfig2 API (dwInfoLevel= SERVICE_CONFIG_SERVICE_SID_INFO) or the sc.exe command with the sidtype verb. In either case, three values are possible:

None – 0x0
Unrestricted – 0x1
Restricted – 0x3

If you want your service to have a per-service SID (as covered in this blog post), you should use "Unrestricted" for the type of SID. This means setting the SERVICE_SID_INFO.dwServiceSidType to SERVICE_SID_TYPE_UNRESTRICTED (0x1) if you are using the API, or using the following syntax with sc.exe:

sc sidtype [service name] unrestricted

You can also query the current configuration of your service with:

sc qsidtype[service name]

We find the semantics "type of SID" is a little funny, but once you get used to it, it's okay. A type of SID "None" means your service will not have a per-service SID nor a write-restricted token. Currently this is the default configuration for a service: no per-service SID. A type of SID "Unrestricted" means your service will have a per-service SID. A type of SID "Restricted" means your service will have a per-service SID and also a "write-restricted" token (this is our next post).

When configured to have a per-service SID (i.e. type of SID either "Unrestricted" or "Restricted"), the service SID is computed as S-1-5-80-{SHA-1(service name in uppercase)} and added to the host process token. If you need to know what the SID is or would be for a given service name, you can use the

sc showsid[service name]

command. This can be done through the use of APIs as well.

Once you have configured your service to have a per-service SID, you can grant access to resources your service needs. Prior to Windows Vista, when running your service with a built-in account (Local Service or Network Service), granting access to a resource for your service meant granting access to the other services running with that account as well. To avoid that side effect, you had to run your service with a dedicated account. Now with the per-service SID mechanism of Windows Vista, you can use the built-in service accounts while benefiting from the higher granularity of the per-service SID and thus ACL resources for your service only. When using the ACL editor (either on the file system, or registry) or icacls command line tool, you can use the "NT SERVICE \<service_name> " syntax to add your service SID to a resource.

In a recent Security Briefs article, Keith Brown shows how to factor out the higher privileged protocol transition operation in a COM+ component so a network facing gateway can be ran with lower privileges. In one of our projects, the gateway is a service configured with a service SID. We tried to add the service SID in COM+ roles with the "Component Services" mmc , to allow only our service to access the protocol transition component. But we found we couldn’t. However using a local group as an indirection, and adding the service SID to the local group worked just fine.

Configuring your service for a type of SID "Unrestricted" and thus having a service SID is a great way to either protect the resources your service needs, or in an environment that has been hardened, make sure that you only open access to your service. It is cheap to implement with a good return in terms of security gain.