Browsing the Web and Reading E-mail Safely as an Administrator, Part 2
Michael Howard
Microsoft Security Engineering
January 13, 2005
Summary: Michael Howard builds upon his previous article by showing you how to use SAFER with local or enterprise policy to reduce potential threats when running as an admin. (7 printed pages)
Download the SetSAFER.msi file.
In my last article, Browsing the Web and Reading E-mail Safely as an Administrator, I outlined how you can programmatically spawn a process that runs with reduced privilege, even if you are logged on as an administrator. The aim was to run processes performing Internet functions (applications most subject to attack), such as Web browsers and e-mail clients, in reduced privilege to decrease the damage potential of any malware using these agents as attack vectors.
Windows XP and later support this capability using a technology called Software Restriction Policies, also known as SAFER. There are two ways to use SAFER. One is through APIs like SaferCreateLevel and SaferComputeTokenFromLevel, which is outlined in my last article. The other, and the subject of this paper, is through local or enterprise policy.
Note You must be a local administrator to set SAFER policy on your computer.
So, let's take a look. Open the Local Machine Policy object by running MMC and adding the Group Policy Object snap-in, and navigate to the Software Restriction Policies. You should see something like Figure 1.
Figure 1. The Policy Snap-in, expanded to show Software Restriction Policy.
You'll see there are two security levels—Disallowed and Unrestricted. Disallowed will prevent an application from executing, and Unrestricted means the application executes with the same trust as the user. So, if the user is an admin, the application runs with full admin rights.
Try it out! Here's how to do it:
- Right-click on Additional Rules.
- Click New Path Rule.
- Browse to Notepad.exe in the \Windows\System32 directory.
- Set the Security Level to Disallowed.
- Go to the command-line and type gpupdate (you may need to wait a few seconds for the policy to take effect).
- Run notepad.exe.
- Well, try to run notepad.exe.
You should see a dialog box like Figure 2.
Figure 2. Software Restriction Policy preventing Notepad from running
Now go back and delete the policy, and rerun gpupdate. You should now be able to run Notepad. Again, you may need to wait a few seconds.
The Disallow setting is a very useful option if you know there is some malware "in the wild" and you want to proactively stop it from running. Let's say there's a virus that drops a file named nuke.exe to the c:\windows\system32 directory and the c:\ root directory. You can add two Disallow rules, one for c:\windows\system32\nuke.exe and another for c:\nuke.exe to your Group Policy and roll the policy out to the entire organization. Now you are protected from the malware because it simply won't run. You could also just add nuke.exe with no directory name, but this would block a legitimate nuke.exe. Of course, a file named nuke.exe is a little suspect, anyway! And remember, you can use Windows environment variables, such as %PROGRAMFILEs% in place of hard-coded path names.
Okay, now to the new stuff and the purpose of this paper. There are in fact three other SAFER security levels beyond Disallow and Unrestricted. The three other settings are:
- Normal User (also named Basic User)
- Constrained (also named Restricted)
- Untrusted
You probably already knew this if you read the code in my last article, as these options were referenced in the main switch statement:
switch(argv[2][0]) {
case 'C' :
case 'c' : hSaferLevel = SAFER_LEVELID_CONSTRAINED; break;
case 'U' :
case 'u' : hSaferLevel = SAFER_LEVELID_UNTRUSTED; break;
default : hSaferLevel = SAFER_LEVELID_NORMALUSER; break;
}
I want to focus on the Basic User security level, as this offers the best results in terms of application compatibility and security. And based on comments from readers of my last article, constrained and untrusted caused too many applications to break in weird and wonderful ways that are hard to debug. Let's face it, security doesn't get in the way until it doesn't inform the user of what exactly failed and why. So, let's stick with Basic User.
To make this perfectly clear, you can run applications at much lower privileges than Basic User, but you're on your own because things may break. For example, I often run Internet Explorer in Constrained mode when browsing sites laden with exploit code. That said, it probably can't hurt to call out some of the end-effects of Constrained and Untrusted:
- HKCU is read-only.
- %USERPROFILE% is inaccessible.
- Some crypto operations including SSL negotiation do not work.
The first step is to enable the Basic User setting. You can do this with a registry tweak. Add a DWORD value named Levels set to 0x20000 to:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers
Now reload the MMC snap-in and add the Group Policy Object editor. You will see the Basic User under Software Restriction Policy as shown in Figure 3.
Figure 3. The Basic User Security Level
Now here comes the cool part—you can set the policy on an application such as a Web browser or e-mail program such that it runs as a normal, low-privilege user rather than as the admin account. For example, to make Internet Explorer run as a normal user, perform the following steps once you have loaded the Group Policy Object snap-in:
- Right-click on Additional Rules.
- Click New Path Rule.
- Browse to c:\Program Files\Internet Explorer\iexplore.exe.
- Set the Security Level to Basic User.
The beauty of this solution over the solution using the SAFER APIs is that the SAFER policy mechanism is enforced by the operating system when a process starts. So you can invoke Internet Explorer from a shortcut on the desktop or a saved URL on the desktop, and Internet Explorer will run as a user. Of course, you could copy iexplore.exe to your desktop and the SAFER policy would not apply because the browser is not being executed from the c:\program files\internet explorer directory.
Setting SAFER Policy Without Using the Policy Snap-in
I've written a small program named SetSAFER to set SAFER policy. All it does is read from an XML file and set the appropriate registry keys to enable or disable SAFER policy on applications defined in the XML file. You can, of course, add your own applications to the XML file. Below is the example included with the tool:
<?xml version="1.0" encoding="UTF-8"?>
<safer>
<app comment="Internet Explorer"
path="C:\Program Files\Internet Explorer"
user="true" />
<app comment="Microsoft Office 2003"
path="C:\Program Files\Microsoft Office\OFFICE11"
user="true" />
<app comment="MSN Messenger"
path="C:\Program Files\MSN Messenger\msnmsgr.exe"
user="true" />
</safer>
You'll notice you can use an application name or a directory. Setting SAFER policy on a directory affects all executables in that directory.
There's a very important point you should know about this tool. It will blow away any existing Basic User SAFER settings you have in the registry and set them to whatever is held in the tool. To be clear, this is an experimental tool only. You've been warned!
Also note, the tool was written and compiled with the May 2004 release of Visual Studio .NET 2005 beta, so you'll need a beta of the .NET Runtime 2.0 available at https://lab.msdn.microsoft.com/vs2005/downloads/default.aspx to run the tool. I also tested the code with the latest community release, December 2004, and it works fine.
If you don't want to use this tool, you could always set the registry keys yourself, or simply use the Software Restriction Policy snap-in I mentioned earlier. The registry keys reside under HKLM\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers\131072. For each file or directory, add a new key named {GUID} where GUID is a random GUID in classic GUID format, such as {cc845d85-f38e-426a-8644-9d2f90c830d8}, and then add the following values:
Description (REG_SZ) A comment about the rule.
ItemData (REG_SZ) Directory or filename
SaferFlags (REG_DWORD) 0x0
Now here's an important caveat. This technology will change in Longhorn, so don't be too surprised if this tool and the Software Restriction Policy technology doesn't work as they do on Windows XP and Windows Server 2003.
A Quick Start
If you want to get started right away, and set your Internet Explorer browser to run as a user, copy the following text and save it to a file named LowRightsIE.reg.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer
\CodeIdentifiers\131072\Paths\{effd8629-e248-4c3c-a06b-c178921c6745}]
"Description"="Internet Explorer"
"ItemData"="C:\\Program Files\\Internet Explorer"
"SaferFlags"=dword:00000000
You can set the browser to run as your normal administrative account by simply removing this registry key. Another trick is to copy iexplore.exe to your desktop. By default, Internet Explorer will run as a user, but for administrative tasks, you could double-click iexpore.exe on the desktop.
Determining Success
How do you know the process is running with reduced privilege? It's pretty easy to determine—just look at the token associated with the process. The best tool, in my opinion, is Process Explorer from Sysinternals (sysinternals.com.) When using this tool, simply double-click the process you're interested in, and then select the Security tab. A dialog box like that in Figure 4 will appear. Note the Admin SID is set to Deny, and there are no potentially hazardous privileges in the token. This application is running as a user, not an admin.
Figure 4. Example token of an admin running a non-admin process
What If I Need to Run the Application as Admin?
If you need to run an application as admin, perhaps Internet Explorer so you can load an ActiveX control, or run Windows Update, all you have do is run the SetSAFER tool and uncheck the Internet Explorer setting and load a fresh browser instance. Or, you could remove the registry keys manually.
Now for the final caveat, don't apply SAFER policy to system directories! The SetSAFER tool will simply not display the system directory to help protect you from making this mistake.
Now the real final caveat. This is no replacement for running as a non-admin, and only elevating (using RunAs) as needed. Think about it. If you run some malware as non-admin, that malware could send keystrokes to another, possibly high-privilege process if that process handles keystrokes or messages.
What We Tested
I want to point out that a number of us at Microsoft have tested the following applications solely as User using SAFER. The list of applications is:
- Internet Explorer 5.x and 6.x
- Microsoft Office 2003 (including Outlook)
- Outlook Express (Windows XP SP1, Windows XP SP2, and Windows Server 2003)
- MSN Messenger 6 and 7 beta
- Windows Messenger (Windows XP SP2 and Windows Server 2003)
- Windows Media Player 9 and 10
Of course, you can run any application using SAFER, but note the list above is all we tested because they are all Internet-facing client applications, and subject to attack. If you have issues running an application with these software restriction policies, try logging on as a normal user and rerun the application. If it still does not work, then the application does not run as a normal user anyway. For some known issues, review Aaron Margosis' blog at https://weblogs.asp.net/aaron_margosis. For any new issues, please post a comment to my blog at https://blogs.msdn.com/michael_howard because we want to know what doesn't work.
Michael Howard is a Senior Security Program Manager in the Secure Engineering group at Microsoft and is the coauthor of Writing Secure Code, now in its second edition, and the main author of Designing Secure Web-based Applications for Windows 2000. He is also a co-editor of Basic Training in IEEE Security & Privacy Magazine. His main focus in life is making sure people design, build, test, and document nothing short of a secure system. His favorite line is "One person's feature is another's exploit."