Running as Limited User - the Easy Way

Malware has grown to epidemic proportions in the last few years. Despite applying layered security principles, including running antivirus, antispyware, and a firewall, even a careful user can fall victim to malware. Malware-infected downloads, drive-by exploits of Internet Explorer (IE) vulnerabilities, and a careless click on an Outlook attachment sent by a friend can render a system unusable and lead to several hours with the Windows setup CD and application installers.

As this eWeek study shows, one of the most effective ways to keep a system free from malware and to avoid reinstalls even if malware happens to sneak by, is to run as a limited user (a member of the Windows Users group). The vast majority of Windows users run as members of the Administrators group simply because so many operations, such as installing software and printers, changing power settings, and changing the time zone require administrator rights. Further, many applications fail when run in a limited-user account because they’re poorly written and expect to have write access to directories such as \Program Files and \Windows or registry keys under HKLM\Software.

An alternative to running as limited user is to instead run only specific Internet-facing applications as a limited user that are at greater risk of compromise, such as IE and Outlook. Microsoft promises this capability in Windows Vista with Protected-Mode IE and User Account Control (UAC), but you can achieve a form of this today on Windows 2000 and higher with the new limited user execution features of Process Explorer and PsExec.

Process Explorer’s Run as Limited User menu item in the File menu opens a dialog that looks like and acts like the standard Windows Run dialog, but that runs the target process without administrative privileges:

PsExec with the –l switch accomplishes the same thing from the command line:

An advantage to using PsExec to launch limited-user processes is that you can create PsExec desktop shortcuts for ones you commonly launch. To make a shortcut for Outlook, for example, right-click on the desktop, choose New->Shortcut, enter the path to PsExec in the location field and click Next. Enter Outlook as the name of the shortcut and press Finish. Then right click on the shortcut to open its properties, add “-l –d“ and the path to Outlook (e.g. C:\Program Files\Microsoft Office\Office11\Outlook.exe) to the text in the Target field. Finally, select Change Icon, navigate to the Outlook executable and choose the first icon. Activating the shortcut will result in a Command Prompt window briefly appearing as PsExec launches the target with limited rights.

Both Process Explorer and PsExec use the CreateRestrictedToken API to create a security context, called a token, that’s a stripped-down version of its own, removing administrative privileges and group membership. After generating a token that looks like one that Windows assigns to standard users Process Explorer calls CreateProcessAsUser to launch the target process with the new token.

You can use Process Explorer itself to compare the token of a process running with full administrative rights and one that’s limited by viewing the Security tab in the Process Properties dialog. The properties on the left are for an instance of IE running in an account with administrative group membership and the one on the right for IE launched using Run as Limited User:

The privilege lists immediately stand out as different because the limited-user token has so few privileges. Process Explorer queries the privileges assigned to the Users group and strips out all other privileges, including powerful ones like SeDebugPrivilege, SeLoadDriverPrivilege and SeRestorePrivilege.

The difference between the group lists is more subtle: both tokens contain the Builtin\Administrators group, but the group has a Deny flag in the limited-user version. Fully understanding the effect of that flag requires a quick background on the Windows security model.

Windows stores an object’s permissions in a Discretionary Access Control Lists (DACL) that consists of zero or more Access Control Entries (ACEs). Each ACE specifies the user or group to which it applies, a type of Allow or Deny and the accesses (e.g. read, delete) it allows or denies. When a process tries to open an object Windows normally considers each ACE in the object’s DACL that matches the user or any of the groups in the process’ token. However, when the Deny flag is present on a group that group is only used by during a security access check to deny access to objects, never to grant access.

CreateRestrictedToken marks groups you don’t want present in the resulting token with the Deny flag rather than removing them altogether to prevent the security hole doing so would create: a process using the new token could potentially access objects for which the removed groups have been explicitly denied access. Users would therefore be able to essentially bypass permissions by using the API. Consider a directory that has permissions denying the Builtin\Administrators account access, but allows Mark access. That directory wouldn’t be accessible by the original instance of IE above, but would be accessible by the limited user version.

The result of running applications as limited user is that malware invoked by those applications won’t be able to modify system settings, disable antivirus or antispyware, install device drivers, or configure themselves in system-wide autostart locations.

There are some limitations, however: because the limited-user processes are running in the same account and on the same desktop as other processes running with administrative privileges, sophisticated malware could potentially inject themselves into more privileged processes or remotely control them using Windows messages. When it comes to security, there’s no single cure all and every layer of protection you add could be the one that eventually saves you or your computer.

Next post I’ll take a look inside Vista’s UAC to see how it uses the same approach as Process Explorer and PsExec, but leverages changes to the Windowing system and process object security model to better isolate limited-user processes from those running with higher privilege.

Originally by Mark Russinovich on 3/2/2006 10:29:00 AM
Migrated from original Sysinternals.com/Blog