Why running a service as Local System is bad on windows? - windows

I am trying to find out the difference between difference service account types. I tumbled upon this question.
The answer was because it has powerful access to local resources, and Network Service should be used if possible.
But still I am not able to understand that if it has powerful access to local resources, how attacker can access the account? What are the ways to compromise the account? I understood it is all about security, but I don't know how. It could be dark hacker's world, however anybody could explain, in simple terms, why network service account is better than local account ?
Thanks in advance.

Every program you run increases the attack surface of your server.
You have to assume that a determined, malicious actor can exploit bugs or loopholes in your program to make it do anything. You mitigate that by executing your programs with the least privileges required to do their jobs.
Some of these exploits include:
Luring attacks, in which an attacker tricks your program into executing their code under the program's elevated privileges.
Buffer Overrun Attacks, in which extra data sent to a method is written into adjacent memory, which may be the target of control flow logic.
Man in the Middle attacks, where an attacker falsifies messages to your program.
Often, a given service isn't obviously vulnerable to any of these. Running under network service (or another account with reduced permissions) is a 'better safe than sorry' strategy that acknowledges two important facts of software development: programmers are fallible and attackers are inventive.

The LocalSystem account is the Windows equivilant of the *nix root account. It's even more privileged than an administrator account. When you run as LocalSystem, you have full access to every resource on the machine.
As others have written, you should write your code to run with the least possible privileges.
The primary difference between LocalService and NetworkService is that services running as NetworkService have the ability to authenticate to other machines in the domain (as the machine account I believe).
Please note that the LocalService and NetworkService accounts both have the "Impersonate" privilege which is a potentially dangerous privilege - it allows the service to impersonate the user who is calling into the service. If that user is an administrator, then even though your code is running in a low privileged service, it can do anything that the administrator does. If an attacker can exploit a buffer overflow in your least privilege service, they can hook out the APIs you use to impersonate your caller and wait until a high privileged caller calls into your service. This technique is known as "Token Kidnapping" and the MSRC has a great blog post describing the issue (and contains links that describe how to mitigate many of the other risks associated with using LocalService and NetworkService accounts).

The Local account has effectively full administrative priviledges on the local machine. Hence any code that might escape from say a buffer overrun and get itself executing has significant scope to do damage.
On the other hand, the Network Service account has by default only Guest level access to the local system. Hence even if an attacker managed to find way to send and execute code within the service that code would have limited access.

If your service has a bug, which can allow attacker to execute arbitrary code (like buffer overflow), he can do everything with your computer if service is running under Local System account, which is equivalent to Administrator account. So the lesser priveleged account your service is running, the lesser privilege the attacker can get.

The simplest scenario is when the service allows the user of the service to execute some code on command line. For example MS SQL Server has a stored procedure that allows you to run a 'command line' command (i.e. run a program).

Related

Services Creating Services - Assigning SC_MANAGER_CREATE_SERVICE to a User

I'm trying to create a Windows service that has the right to create additional services. But I'd prefer not to make this service run with an Administrative login.
The users rights are otherwise quite limited - I just need it to be able to spin-up a service on request.
I've seen mention online that SC_MANAGER_CREATE_SERVICE is a permission you can now assign and/or change, but I haven't seen much on how that is done. There is mention of being able to change permissions for individual services via subinacl, via OpenSCManager and the - gulp - sc command. But these examples show how to change the permissions on a single service, not how to give a user SC_MANAGER_CREATE_SERVICE permissions.
However, I've noticed that the documentation on CreateService specifically says that it requires administrator privilages - so perhaps it's simply not possible.
Am I going to have to start the service with an admin account? Or does anyone know another trick?
See Service Security and Access Rights:
To get or set the security descriptor for the SCM, use the QueryServiceObjectSecurity and SetServiceObjectSecurity functions with a handle to the SCManager object.
Be aware that having the right to create services gives you effective administrator access, since you can create a service to run as local system. So you do need to be careful not to grant that right to accounts that untrusted users have access to, to make sure that all accounts with that right have strong passwords, and so on.
This also means that if your system service is compromised by a remote code execution vulnerability you haven't gained anything, the attacker will still be able to get control of your system. If the service is at a high risk of direct attack, it may be wise to instead have a second service that is responsible only for the tasks that require special privilege. However, for a service that is unlikely to be directly attacked, or is considered reasonably secure, running without administrator privileges (other than the ability to create services) may prevent a less severe vulnerability from being exploitable, or limit the damage caused by a non-security-related bug.
See also Granting service control manager access permission to user outside of administrator group on Server Fault, the answer shows how to change the SCM permissions from the command line.
Try opening an handle to the service control manager with the WRITE_DAC access right, and change the security of it by calling SetServiceObjectSecurity to change the dacl of the service control manager. Don't forget to do the same thing for the service registry key (HKLM\SYSTEM\CurrentControlSet\Services) using RegOpenKeyEx and RegSetKeySecurity function.
WARNING
Be aware that this is a potential security risk since it would allow a standard user account to elevate its privileges to SYSTEM.

How do I write a Windows 8 software to run with SYSTEM privileges?

I apologize for the bad phrasing in the title, but here's a little more context.
I recently bought a Windows 8 laptop and noticed that Norton was pre-installed and running with SYSTEM level privileges. Thus, it occurred to me that there must be some way for third-party applications to run with SYSTEM privileges.
However, after much googling, I could not figure out whether it was an API call or a registry setting or something else entirely that enabled Norton to do this, so I decided to ask the SO community. How can I write an application that runs with SYSTEM privileges?
Services can be configured to run as several different accounts, including LOCAL SERVICE, NETWORK SERVICE, SYSTEM, or any user's account.
Using SYSTEM isn't recommended, because any security problem can lead to complete compromise of the machine, but it is available.
This is configured by the lpServiceStartName parameter of CreateService and/or ChangeServiceConfig. Pass a NULL pointer as this parameter of CreateService, or ".\\LocalSystem" to ChangeServiceConfig, to use the local system account.
It's a bad idea to run a GUI application as local system. The best approach is to have both a GUI application (running as the logged-on user) and a service (running as SYSTEM) and have them communicate as needed using any suitable IPC method. This is probably what Norton is actually doing.
However, it is possible to get a system service to launch an application as SYSTEM in the user's session. To do this, duplicate the processes security token with DuplicateTokenEx and then use SetTokenInformation with the TokenSessionId option. This will give you a token in SYSTEM context but in the user's session which you can use to launch an executable. (There may be additional issues; for example, you might also need to change the permissions on the workstation and desktop.)

Which service account is suitable?

I have developed a .NET Windows Service (in VS2010) that needs to:
Access shared folders (read/write) on machines on the local network
Write to HKLM/SOFTWARE part of the registry
Write files and create folders in all parts of the local file system (ex. in root of C:)
Download files from the web (using http)
My service must do well with all Windows (PC) operating systems, starting from Windows XP SP3 and onwards.
Problem: Which service account should I choose for my service?
Normally, I would use either “LocalService” or “NetworkService”, but none of those grants all needed privileges by themselves.
Should I use the “LocalSystem” account then? Or, should I create a complete separate account for my service's use only (this should then be done automatically during installation)?
For now I use the “NetworkService” account and just adds it to the adimistrators group during installation, which works fine. But I think this approach ruins the whole idea about limited service accounts and thus poses a security risk - don’t you agree?
You should not use LOCALSYSTEM. This has far too much power and all best practice tells you not to use it.
In my view you should be creating a local user with appropriate rights as part of your installation. This is a fairly common practice for server/database products.
Sounds like you need to separate out your requirements.
You mention needing access to shares on other computers, but then you also mention that the machines this service will be installed on won't necessarily be part of the domain.
Have the service execute under a user account that grants you the appropriate LOCAL permissions. Then have some type of alternative user account with access to the appropriate shares that your service knows about and impersonates when needed.
Now, with regard to writing and creating files in the ROOT, that's going to be interesting. Your service will need full administrative permissions in order to do this on a Windows 7 box if UAC is turned on. Which, it would probably be safe to assume is on machines you don't directly control. Either eliminate this requirement or you'll have to live with the idea that your service is a security risk.

When is SeTcbPrivilege used? ("Act as part of the operating system.)

For what purpose(s) is the SeTcbPrivilege privilege in Windows used? Can it be used, for example, to run a program under the SYSTEM account?
Acting as a part of the operating system allows you to do things like create login tokens. It's unlikely that you would ever need to write a service that uses this privilege unless you're writing an authentication provider.
Since you can create access tokens, you can act as any user. Of course, this means that you can run programs under the SYSTEM account, but there are much easier ways to run something as SYSTEM.
To add to Gabe's answer, here is what MS says,
Allows a process to assume the identity of any user and thus gain
access to the resources that the user is authorized to access.
Typically, only low-level authentication services require this
privilege.
Default setting: Not assigned.
Note that potential access is not limited to what is associated with
the user by default; the calling process might request that arbitrary
additional privileges be added to the access token. The calling
process might also build an access token that does not provide a
primary identity for tracking events in the audit log.
When a service requires this privilege, configure the service to log
on using the Local System account, which has the privilege inherently.
Do not create a separate account and assign the privilege to it.
Source: Microsoft TechNet
SeTcbPrivilege is very useful for debugging purpose. For example, if you are developing Windows service that has to be run under system account and perform impersonate things it is conveniently to run this service as standalone exe. SeTcbPrivilege will allow to do this.

On Windows XP: How to create a user with read access to only one certain directory?

Let me state first: I know that any user that wants to run a program (or even log in), has to have access to (probably at least) the Windows system directories and the shared libraries in %ProgramFiles%, but I'd like to be able to access Skype, for example, by running it with an unprivileged user and make sure that it can't access any unnecessary files.
I fear that the only way to do this would be to identify all of the gazillion directories where I store files that I don't want this user to access and then create a new user group that can access these directories, or run Skype and Azureus in a VM.
Is there a better way?
Normally, accounts are members of the Users group at least, which does have access to many things. You could make the account a member of no groups, or the Guests group which is very restrictive.
The real issue is that the program's token (an internal security object that keeps track of what security identities a running process has) will contain the Everyone and Authenticated Users groups, which also have read access to lots of stuff. There is no way to create an account without those groups. You could remove the access that Everyone and Authenticated Users groups have to most everything, but it would be a lot of work to track all those down.
I would say that creating a standard user or guest access account for untrusted programs would be plenty secure enough. To support self-updates and to keep related files in the same place, I suggest you install those programs directly in the profile of the user account they will be running as, e.g. C:\Documents and Settings\skype\Program Files\Skype
If you want to get really fancy, you can use a restricted token to either make the Everyone, Authenticated Users, etc. groups deny only (so they can't grant any access) or create a Restricted SID list. This will be difficult to implement because there are global objects that programs will expect to access that the Everyone group has access to, which is normally a safe choice.
See CreateRestrictedToken Function.
There is also an open-source command line program I created a program for creating restricted tokens and job objects on the fly for that purpose: UlimitNT
Maybe sudown is a solution. It's a sudo-similar (as known from Linux) approach to running as unprivileged user, but having the possibility to promote to an administrative account (with password) when needed.
I suppose you could lock down the machine so the user can solely log on, not even start skype with his rights, but start skype by "run as" with sudown.
Besides using a VM you could look into using a Sandbox. Look at Sandboxie fox an example.
simply use acl apis (samples in msdn)

Resources