Virtual Service Account without Network Access, like NT AUTHORITY\LocalService - windows

Background: I'm writing a service and want to give it as few privileges as necessary.
Virtual Accounts (sometimes "Virtual Service Accounts") are sparsely documented feature new to Windows 7/2008R2 that are automatically managed accounts for services that need minimal privileges but access the network with a computer identity in a domain environment.
My service doesn't need network access, so I'm using LocalService, but I don't like the fact that if I grant access to a file/etc I granting access to all services running as that account.
Is there a least privileged account I can use?

You don't need to change the account the service runs under; LocalService is fine.
Instead, configure the service to have a non-zero SID type, i.e., specify either SERVICE_SID_TYPE_UNRESTRICTED or SERVICE_SID_TYPE_RESTRICTED. You can do this using the ChangeServiceConfig2() function and the SERVICE_CONFIG_SERVICE_SID_INFO option.
You can then grant access to files and other protected resources using the service SID, whose name is NT SERVICE\myservice, rather than LocalService. This will grant access to only your service. (Well, and any other services sharing the same process, but most third-party services run in their own process.)
For least privilege, use SERVICE_SID_TYPE_RESTRICTED. This means that the service can only access protected objects that explicitly grant access to either Everyone, the service SID, the logon session SID, or WRITE_RESTRICTED. You should also use the SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO option to reduce the privileges granted to the service; many services do not need any privileges at all. (In that case, you may find that you need to specify SE_CHANGE_NOTIFY_NAME rather than an empty list, though I might be misremembering.)

Related

LookupAccountName / LsaLookupNames fails for cached domain credential when DC unavailable

I'm investigating a failure in my Windows 10 Credential Provider. It calls out to LookupAccountName in order to get the SID of the user that is attempting to log in. Its per-user configuration uses the account SID as the key.
The failure scenario is as follows:
There is a mixture of local and domain accounts on a domain joined computer.
The computer is in an offline or otherwise disconnected state and cannot contact the domain controller.
The domain user has logged in to this computer in the past and its credential is cached.
The call to LookupAccountName fails with ERROR_TRUSTED_RELATIONSHIP_FAILURE (0x6FD)
Here's where things are interesting:
I can log in with a local account and then "Run As" the domain user. Then subsequent calls to LookupAccountName (even when run in the context of the local user) succeeds in looking up the SID of the domain user. It will continue to work until the computer is rebooted.
I've tried calling LookupAccountName as well as LsaLookupNames2. Both exhibit the same behavior. (I assume LookupAccountName is built off of LsaLookupNames2).
It doesn't look like the NetUser* APIs will help me, as I believe they are intended for local accounts.
Is there a way to lookup the account SID for an offline domain credential? Without requiring them to log in first?
Why does using "Run As" cause these APIs to suddenly work?

Installing services as different users

I was installing the filebeat application and I noticed that I needed to run powershell as administrator in order to install them. When I checked the service using wmic service get name,startname,status it showed Local System. I'm wondering what this account is as this is neither the user account or the administrator account. Will this always be the case when I install services as administrator? What is the difference if I install it as a normal user and as administrator?
In any case, I've set this service to start automatically when windows start. Would this service start only when the user I used to install it logs in or will it start regardless of which user logs in?
OK, let's unpack that one by one, in no particular order:
Only a user with administrator rights can install a service.
Services that are configured to start automatically are started as soon as Windows is up and running; Windows does not wait until somebody logs in. It makes no difference to the service who the logged-on user is, or whether anybody is logged in at all, unless the service application itself has been explicitly programmed to check.
The program that installs the service decides what account the service uses to run. Windows doesn't care what user account was used to install the service, it doesn't even keep track.
If the program that installs the service wants it to use an ordinary user account, it must know the password for that account. There are various special accounts that a service can run in, these accounts do not require a password. One of these special accounts is Local System.
Local System is the highest-privilege service account in Windows; it has all the same rights as an administrator, and can do things an administrator can't. Local System is also the account that the user-mode part of Windows itself runs in, roughly equivalent to the UNIX root account except that it doesn't have a password.
Additional notes, for completeness:
One alternative to Local System is for the service to run as Local Service or as Network Service, which are non-administrative service accounts. The only difference between the two is that if the computer is joined to an Active Directory domain, the Network Service account has network access to other machines in the domain and the Local Service account does not.
It is also possible to configure a service to run in a special service account that is unique to that particular service. This is mostly useful if you want the service to have access to a particular file or folder, but do not want to give it administrator rights.
Nitpickers corner:
It is I believe technically possible to reconfigure Windows to allow non-administrators to install services, but this is not supported and would be a Very Bad Idea. If you did, though, it would still make no difference who installed the service. Windows doesn't record this information.

Giving a registry key read permissions to one single Service application

I'm writing a Windows Service that occasionally queries data in HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles, to detect if the system has changed network (e.g. it's a laptop and they connect to a new Wifi Hotspot).
The Service must run as a LocalService account, so has no administration privileges, however the read permissions on this particular key and its subkeys are for Administrators ony, so the LocalService account is not able to read them.
I'd like to manually add read permissions for my Service to the key, but ONLY for that one Service. I could grant the "Local Service" account read privileges, but this would allow all LocalService Services to read the key, which I do not want. Is there any way of doing this, maybe creating a user account for a single application?
Vista added Service Isolation and it can assign a service SID to the process. You can then add this SID to the ACL of the registry key.

How can I tell if the server side of a named pipe is an admin?

I am trying to use named pipes on Windows XP SP2+. The pipe server will be a service, running as some kind of administrator / system level account. The pipe client could be any user, possibly a guest, possibly an admin. In my case, I am fine with having a guest account successfully communicate with my service running as administrator.
Before I start using the pipe in my client code, I want to validate that the other side of the pipe is really owned by an administrator / the system.
I have discovered the GetSecurityInfo function, and I think I should be able to use that as part of the solution. However, I don't know how to get from a SID to an "is admin" check.
The default owner for all objects created by an administrative account (including the system account) is the well-known Administrators group, and you can't assign ownership of an object you create to someone else without administrative privilege.
So you can check as follows:
Use GetSecurityInfo to fetch the SID of the owner of the pipe object.
Use CreateWellKnownSid with the WinBuiltinAdministratorsSid option to create a SID for the Administrators group.
Use EqualSid to compare the two SIDs.
Make sure that when you open the pipe (using CreateFile) you pass the SECURITY_IDENTIFICATION flag to ensure that the potentially malicious server cannot impersonate you.

Confused over LocalSystem and LocalService Accounts

I am new to windows services programming. I have confusion about what to set the Account type while writing a windows services.
How to choose or how to determine to which account type we need to set while writing a service?
We generally create special windows (local for local only access or domain account for things that need to authenticate accross the network) accounts to run custom services. This way we can restrict and lock down the permissions to make sure it only has access to what we need. You can also see which specific users are culprits or resource hogging with monitoring on a shared server.
As for the built in accounts...
Local System:
The built-in LocalSystem user account has a high level of access privileges; it is part of the Administrators group.
Network Service:
The built-in Network Service user account has fewer access privileges on the system than the LocalSystem user account, but the Network Service user account is still able to interact throughout the network with the credentials of the computer account.
Local Service:
The built-in Local Service user account has fewer access privileges on the computer than the Network Service user account, and those user privileges are limited to the local computer. Use the Local Service user account if the worker process does not require access outside the server on which it is running.
Source(s):
Microsoft Technet
LocalSystem
The LocalSystem account is a predefined local account used by the service control manager. This account is not recognized by the security subsystem, so you cannot specify its name in a call to the LookupAccountName function.
It has extensive privileges on the local computer, and acts as the computer on the network. Its token includes the NT AUTHORITY\SYSTEM and BUILTIN\Administrators SIDs; these accounts have access to most system objects. The name of the account in all locales is .\LocalSystem. The name, LocalSystem or ComputerName\LocalSystem can also be used. This account does not have a password. If you specify the LocalSystem account in a call to the CreateService or ChangeServiceConfig function, any password information you provide is ignored.
NetworkService
The NetworkService account is a predefined local account used by the service control manager. This account is not recognized by the security subsystem, so you cannot specify its name in a call to the LookupAccountName function. It has minimum privileges on the local computer and acts as the computer on the network.
This account can be specified in a call to the CreateService and ChangeServiceConfig functions. Note that this account does not have a password, so any password information that you provide in this call is ignored. While the security subsystem localizes this account name, the SCM does not support localized names. Therefore, you will receive a localized name for this account from the LookupAccountSid function, but the name of the account must be NT AUTHORITY\NetworkService when you call CreateService or ChangeServiceConfig, regardless of the locale, or unexpected results can occur.
A service that runs in the context of the NetworkService account presents the computer's credentials to remote servers. By default, the remote token contains SIDs for the Everyone and Authenticated Users groups. The user SID is created from the SECURITY_NETWORK_SERVICE_RID value.
The NetworkService account has its own subkey under the HKEY_USERS registry key. Therefore, the HKEY_CURRENT_USER registry key is associated with the NetworkService account.

Resources