Inside Windows Vista User Account Control
At a Glance:
- Running as a standard user
- File and registry virtualization
- Elevating account status
User Account Control (UAC) is an often misunderstood feature in Windows Vista. In my three-part TechNet Magazine series on Windows Vista kernel changes, available online at technetmagazine.com, I didn’t cover UAC because I felt that it merited its own article.
In this article I discuss the problems UAC solves and describe the architecture and implementation of its component technologies. These technologies include the refactoring of operations that previously required administrative rights, lightweight virtualization to help programs run correctly without administrative rights, the ability for programs to explicitly request administrative rights, and isolation of administrative processes from non-administrative processes running on the same user desktop.
UAC is meant to enable users to run with standard user rights, as opposed to administrative rights. Administrative rights give users the ability to read and modify any part of the operating system, including the code and data of other users—and even Windows® itself. Without administrative rights users cannot accidentally (or deliberately) modify system settings, malware can’t alter system security settings or disable antivirus software, and users can’t compromise the sensitive information of other users on shared computers. Running with standard user rights can therefore reduce urgent help desk calls in corporate environments, mitigate the impact of malware, keep home computers running more smoothly, and protect sensitive data on shared computers.
UAC had to address several problems to make it practical to run with a standard user account. First, prior to Windows Vista™, the Windows usage model has been one of assumed administrative rights. Software developers assumed their programs could access and modify any file, registry key, or operating system setting. Even when Windows NT® introduced security and differentiated between accesses granted to administrative and standard user accounts, users were guided through a setup process that encouraged them to use the built-in Administrator account or one that was a member of the Administrators group.
The second problem UAC had to address was that users sometimes need administrative rights to perform such operations as installing software, changing the system time, and opening ports in the firewall.
The UAC solution to these problems is to run most applications with standard user rights, obviate the need for administrator rights all the time, and encourage software developers to create applications that run with standard user rights. UAC accomplishes these by requiring administrative rights less frequently, enabling legacy applications to run with standard user rights, making it convenient for standard users to access administrative rights when they need them, and enabling even administrative users to run as if they were standard users.
Running as Standard User
A full audit of all administrative operations during the development of Windows Vista identified many that could be enabled for standard users without compromising the security of the system. For example, even corporations that adopted standard user accounts for their Windows XP desktop systems were unable to remove their travelling users from the Administrators group for the sole reason that Windows XP does not differentiate changing the time zone from changing the system time. A laptop user who wants to configure the local time zone so that their appointments show correctly in their calendar when they travel must have the have the "Change the system time" privilege (internally called SeSystemTimePrivilege), which by default is only granted to administrators.
Time is commonly used in security protocols like Kerberos, but the time zone only affects the way that time is displayed, so Windows Vista adds a new privilege, "Change the time zone" (SeTimeZonePrivilege), and assigns it to the Users group, as seen in Figure 1. This makes it possible for many corporations to have their laptop users run under standard user accounts.
Figure 1 The “Change the time zone” privilege (Click the image for a larger view)
Windows Vista also lets standard users configure WEP settings when they connect to wireless networks, create VPN connections, change power management settings, and install critical Windows updates. In addition, it introduces Group Policy settings that enable standard users to install printer and other device drivers approved by IT administrators and to install ActiveX® controls from administrator-approved sites.
What about consumer and line of business (LOB) applications that do not run correctly in standard user accounts? While some software legitimately requires administrative rights, many programs needlessly store user data in system-global locations. Microsoft recommends that global application installers that expect to run with administrative rights create a directory under the %ProgramFiles% directory to store their application’s executable files and auxiliary data and create a key under HKEY_LOCAL_MACHINE\Software for their application settings. When an application executes, it can be running in different user accounts and it should therefore store user-specific data in the per-user %AppData% directory and save per-user settings in the user’s registry profile under HKEY_CURRENT_USER\ Software. Standard user accounts don’t have write-access to the %ProgramFiles% directory or HKEY_LOCAL_MACHINE\Software, but because most Windows systems are single-user and most users have been administrators up until Windows Vista, apps that incorrectly save user data and settings to these locations work anyway.
Windows Vista enables these legacy applications to run in standard user accounts through the help of file system and registry namespace virtualization. When an application modifies a system-global location in the file system or registry and that operation fails because access is denied, Windows redirects the operation to a per-user area; when the application reads from a system-global location, Windows first checks for data in the per-user area and, if none is present, permits the read attempt from the global location.
For the purposes of this virtualization, Windows Vista treats a process as legacy if it’s 32-bit (versus 64-bit), is not running with administrative rights, and does not have a manifest file indicating that it was written for Windows Vista. Any operations not originating from a process classified as legacy according to this definition, including network file sharing accesses, are not virtualized. A process’s virtualization status is stored as a flag in its token, which is the kernel data structure that tracks the security context of a process, including its user account, group memberships, and privileges.
You can see the virtualization status of a process by adding the Virtualization column to Task Manager’s Processes page. Figure 2 shows that most Windows Vista components, including Desktop Window Manager (Dwm .exe), Client Server Runtime Subsystem (Csrss.exe), and Explorer, either have virtualization disabled because they have a Windows Vista manifest or are running with administrative rights and hence do not allow virtualization. Internet Explorer® (iexplore.exe) has virtualization enabled because it can host multiple ActiveX controls and scripts and must assume that they were not written to operate correctly with standard user rights.
Figure 2 Task Manager shows virtualization status (Click the image for a larger view)
The file system locations that are virtualized for legacy processes are %ProgramFiles%, %ProgramData%, and %SystemRoot%, excluding some specific subdirectories. However, any file with an executable extension, including .exe, .bat, .scr, .vbs, and others, is excluded from virtualization. This means that programs that update themselves from a standard user account fail instead of creating private versions of their executables that aren’t visible to an administrator running a global updater. To add additional extensions to the exception list, enter them in the following registry key and reboot:
Use a multi-string type to delimit multiple extensions and do not include a leading dot in the extension name.
Modifications to virtualized directories by legacy processes redirect to the user’s virtual root directory, %LocalAppData%\VirtualStore. For example, if a virtualized process that is running on my system creates C:\Windows\Application.ini, the file that it actually creates is C:\Users\Markruss\AppData\Local\VirtualStore\Windows\Application.ini. The Local component of the path highlights the fact that virtualized files don’t roam with the rest of the profile when the account has a roaming profile.
If you navigate in Explorer to a directory containing virtualized files, Explorer displays a button labeled Compatibility Files in its toolbar, as shown in Figure 3. Clicking the button navigates you to the corresponding VirtualStore subdirectory to show you the virtualized files.
Figure 3 Compatibility Files button indicates virtualized files nearby (Click the image for a larger view)
Figure 4 shows how the UAC File Virtualization Filter Driver (%SystemRoot%\System32\Drivers\Luafv.sys) implements file system virtualization. Because it’s a file system filter driver, it sees all file system operations, but it only implements functionality for operations from legacy processes. You can see that it changes the target file path for a legacy process that creates a file in a system-global location, but does not for a process running a Windows Vista application with standard user rights. The legacy process believes that the operation succeeds when it really created the file in a location fully accessible by the user, but default permissions on the \Windows directory deny access to the application written for Windows Vista.
Figure 4 File system virtualization
Registry virtualization is implemented slightly differently than file system virtualization. Virtualized registry keys include most of the HKEY_LOCAL_MACHINE\Software branch, but there are numerous exceptions, such as the following:
HKLM\Software\Microsoft\Windows HKLM\Software\Microsoft\Windows NT HKLM\Software\Classes
Only keys that are commonly modified by legacy applications, but that don’t introduce compatibility or interoperability problems, are virtualized. Windows redirects modifications of virtualized keys by a legacy application to a user’s registry virtual root at HKEY_ CURRENT_USER\Software\Classes\VirtualStore. The key is located in the user’s Classes hive, %LocalAppData%\Microsoft\Windows\UsrClass.dat, which, like any other virtualized file data, does not roam with a roaming user profile.
Instead of maintaining a fixed list of virtualized locations as Windows does for the file system, the virtualization status of a key is stored as a flag, REG_ KEY_DONT_VIRTUALIZE, in the key itself. The Reg.exe utility can show the flag as well as the two other virtualization-related flags, REG_KEY_ DONT_SILENT_FAIL and REG_KEY_ RECURSE_FLAG, as seen in Figure 5. When REG_KEY_DONT_SILENT_FAIL is clear and the key is not virtualized (REG_KEY_DONT_VIRTUALIZE is set), a legacy application that would be denied access performing an operation on the key is instead granted any access the user has to the key rather than the ones the application requested. REG_KEY_RECURSE_FLAG indicates if new subkeys inherit the virtualization flags of the parent instead of just the default flags.
Figure 5 Reg utility shows virtualization flags (Click the image for a larger view)
Figure 6 shows how registry virtualization is implemented by the Configuration Manager, which manages the registry in the operating system kernel, Ntoskrnl.exe. As with file system virtualization, a legacy process creating a subkey of a virtualized key is redirected to the user’s registry virtual root, but a Windows Vista process is denied access by default permissions.
Figure 6 Registry virtualization
In addition to file system and registry virtualization, some applications require additional help to run correctly with standard user rights. For example, an application that tests the account in which it’s running for membership in the Administrators group might otherwise work, but won’t run if it’s not in that group. Windows Vista therefore defines a number of application-compatibility shims so that such applications work anyway. The shims most commonly applied to legacy applications for operation with standard rights are shown in Figure 7. Corporate IT professionals can use tools like the Application Compatibility Toolkit (ACT, available from technet.microsoft .com/windowsvista/aa905066.aspx) and its Standard User Analyzer (SUA) utility, or Aaron Margosis’s LUA Buglight to identify the shim requirements for their LOB applications. They assign shims to an application using the Compatibility Administrator, also part of ACT, and then deploy the resulting compatibility database (.sdb file) to their desktops via Group Policy. Note that, if required, virtualization can be completely disabled for a system using a local security policy setting.
Figure 7 Common user shims
|ElevateCreateProcess||Changes CreateProcess to handle ERROR_ELEVATION_REQUIRED errors by calling the Application Information Service to prompt for elevation.|
|ForceAdminAccess||Spoofs queries of administrator group membership.|
|VirtualizeDeleteFile||Spoofs successful deletion of global files and directories.|
|LocalMappedObject||Forces global section objects into the user’s namespace.|
|VirtualizeHKCRLite, VirtualizeRegisterTypeLib||Redirects global registration of COM objects to a per-user location.|
The Effects of Virtualization
You can change the virtualization status of a process by selecting Virtualization from the context menu that appears when you right-click it in Task Manager. Figure A shows the behavior of a command prompt when its virtualization status changes. It starts out with virtualization disabled because it has a Windows Vista manifest. Because it’s running with standard user rights, it is unable to create a file in the \Windows directory, but after it becomes virtualized with Task Manager it appears to create the file successfully. When its virtualization returns to its disabled state it can’t find the file, which is actually in the user’s virtual store.
Figure A A virtualization status change (Click the image for a larger view)
Administrator Approval Mode
Even if users run only programs that are compatible with standard user rights, some operations still require administrative rights. The vast majority of software installations require admin rights to create directories and registry keys in system-global locations or to install services or device drivers. Modifying system-global Windows and application settings also requires administrative rights, as does the Windows Vista parental controls feature. It would be possible to perform most of these operations by switching to a dedicated admin account, but the inconvenience of doing so would likely result in most users remaining in the administrative account to perform their daily tasks.
Windows Vista therefore includes enhanced "run as" functionality so that standard users can conveniently launch processes with administrative rights. This functionality required giving applications a way to identify operations for which the system can get administrative rights on behalf of the application as necessary, which I’ll describe shortly.
Further, so that users acting as system administrators can run with standard user rights, but not have to enter user names and passwords every time they want to access administrative rights, Windows Vista introduces Admin Approval Mode (AAM). This feature creates two identities for the user at logon: one with standard user rights and another with administrative rights. Since every user on a Windows Vista system is either a standard user or running for the most part as a standard user in AAM, developers must assume that all Windows users are standard users, which will result in more programs working with standard user rights without virtualization or shims.
Granting a process administrative rights is called elevation. When it’s performed by a standard user account, it’s referred to as an Over the Shoulder (OTS) elevation because it requires the entry of credentials for an account that’s a member of the administrator’s group, something that’s usually completed by another user typing over the shoulder of the standard user. An elevation performed by an AAM user is called a Consent elevation because the user simply has to approve the assignment of his administrative rights.
Windows Vista considers a user an administrator if the user is a member of any of the administrator-type groups listed in Figure 8. Many of the groups listed are used only on domain-joined systems and don’t directly give users local administrative rights, but allow them to modify domain-wide settings. If a user is a member of any of those groups, but not the actual administrators group, then the user accesses his administrative rights via OTS elevations instead of Consent elevations.
Figure 8 Administrative groups
|Enterprise Read-Only Domain Controllers|
|Read-Only Domain Controllers|
|Network Configuration Operators|
|Pre-Windows 2000 Compatible Access|
When a user belonging to one of the listed groups logs on, Windows Vista creates a token representing the standard-user version of the user’s administrative identity. The new token is stripped of all the privileges assigned to the user except those listed in Figure 9, which are the default standard user privileges. In addition, any of the administrator-type groups are marked with the USE_FOR_DENY_ONLY flag in the new token. Figure 10 shows the Sysinternals Process Explorer (a process management tool you can download from microsoft .com/technet/sysinternals) displaying the group memberships and privileges of a process running with administrative rights on the left and without administrator rights on the right. (To prevent inadvertent use, the Windows security model requires that a privilege with the disabled flag be enabled before it can be used.)
Figure 9 Standard user privileges
|Friendly Name||Internal Name|
|Bypass traverse checking||SeChangeNotifyPrivilege|
|Shut down the system||SeShutdownPrivilege|
|Remove computer from docking station||SeUndockPrivilege|
|Increase a process working set||SeIncreaseWorkingSetPrivilege|
|Change the time zone||SeTimeZonePrivilege|
Figure 10 AAM administrator and standard user tokens (Click the image for a larger view)
A group with the deny-only flag can only be used to deny the user access to a resource, never to allow it, closing a security hole that could be created if the group was instead removed altogether. For example, if a file had an access control list (ACL) that denied the Administrators group all access, but granted some access to another group the user belongs to, the user would be granted access if the administrators group was absent from the token, giving the standard user version of the user’s identity more access than their administrator identity.
Standalone systems, which are typically home computers, and domain-joined systems treat AAM access by remote users differently because domain-connected computers can use domain administrative groups in their resource permissions. When a user accesses a standalone computer’s file share, Windows requests the remote user’s standard user identity, but on domain-joined systems Windows honors all the user’s domain group memberships by requesting the user’s administrative identity.
Conveniently Accessing Administrative Rights
There are a number of ways the system and applications identify a need for administrative rights. One that shows up in the Explorer UI is the "Run as administrator" context menu entry and shortcut option. These items include a colored shield icon that should be placed on any button or menu item that will result in an elevation of rights when it is selected. Choosing the "Run as administrator" entry causes Explorer to call the ShellExecute API with the "runas" verb.
The vast majority of installation programs require administrative rights, so the image loader, which initiates the launch of an executable, includes installer detection code to identify likely legacy installers. Some of the heuristics it uses are as simple as detecting if the image has the words setup, install, or update in its file name or internal version information; more sophisticated ones involve scanning for byte sequences in the executable that are common to third-party installation wrapper utilities.
The image loader also calls the application compatibility (appcompat) library to see if the target executable requires administrator rights. The library looks in the application compatibility database to see if the executable has the RequireAdministrator or RunAsInvoker compatibility flags associated with it.
The most common way for an executable to request administrative rights is for it to include a requestedElevationLevel tag in its application manifest file. Manifests are XML files that contain supplementary information about an image. They were introduced in Windows XP as a way to identify dependencies on side-by-side DLL and Microsoft .NET Framework assemblies. The presence of the trustInfo element in a manifest (which you can see in the excerpted string dump of Firewallsettings.exe below), denotes an executable that was written for Windows Vista and the requestedElevationLevel element nests within it. The element’s level attribute can have one of three values: asInvoker, highestAvailable, and requireAdministrator.
<trustInfo xmlns=”urn:schema-microsoft-com:asm.v3”> <security> <requestedPrivileges> <requestedExecutionLevel Level=”requireAdministrator” uiAccess=”false”/> </requestedPrivileges> </security> </trustInfo>
Executables with no need for administrative rights, like Notepad.exe, specify the asInvoker value. Some executables expect administrators to always want maximum access, so they use the highestAvailable value. A user who runs an executable with that value will be asked to elevate only if he is running in AAM or considered an administrator according to the rules defined earlier and must elevate in order to access his administrative rights. Regedit.exe, Mmc.exe, and Eventvwr.exe are examples of applications that use highestAvailable. Finally, requireAdministrator always causes an elevation request and is used by any executable that will fail to operate without administrative rights.
Accessibility applications specify "true" for the uiAccess attribute in order to drive the window input of elevated processes, and they must also be signed and in one of several secure locations, including %SystemRoot% and %ProgramFiles%, to get that power.
An easy way to determine the values specified by an executable is to view its manifest with the Sysinternals Sigcheck utility like this:
sigcheck –m <executable>
Executing an image that requests administrative rights causes the Application Information Service (also known as AIS, contained in %SystemRoot%\System32\Appinfo.dll), which runs inside a Service Host process (%SystemRoot%\System32\Svchost .exe), to launch Consent.exe (%SystemRoot%\System32\Consent.exe). Consent captures a bitmap of the screen, applies a fade effect to it, switches to a desktop that’s only accessible to the Local System account, paints the bitmap as the background, and displays an elevation dialog box that contains information about the executable. Displaying on a separate desktop prevents any malware present in the user’s account from modifying the appearance of the dialog box.
Figure 11 OTS elevation dialogs (Click the image for a larger view)
If an image is a Windows component digitally signed by Microsoft and the image is in the Windows system directory, then the dialog displays a blue stripe across the top as shown at the top of Figure 11. The gray stripe (middle dialog) is for images that are digitally signed by someone other than Microsoft, and the orange stripe (bottom dialog) is for unsigned images. The elevation dialog shows the image’s icon, description, and publisher for digitally signed images, but only a generic icon, the file name, and "Unidentified Publisher" for unsigned images. This makes it harder for malware to mimic the appearance of legitimate software. The Details button at the bottom of the dialog expands to show the command line that will be passed to the executable if it launches. The AAM Consent dialog, shown in Figure 12, is similar, but instead of prompting for administrator credentials the dialog has Continue and Cancel buttons.
Figure 12 AAM elevation dialog (Click the image for a larger view)
If a user declines an elevation, Windows returns an access-denied error to the process that initiated the launch. When a user agrees to an elevation by either entering administrator credentials or clicking Continue, AIS calls CreateProcessAsUser to launch the process with the appropriate administrative identity. Although AIS is technically the parent of the elevated process, AIS uses new support in the CreateProcessAsUser API that sets the process’s parent process ID to that of the process that originally launched it (see Figure 13). That’s why elevated processes don’t appear as children of the AIS Service Hosting process in tools like Process Explorer that show process trees.
Figure 13 Elevation Flow
Even though elevation dialogs appear on a separate secure desktop, users have no way by default of verifying that they are viewing a legitimate dialog and not one presented by malware. That isn’t an issue for AAM because malware can’t gain administrative rights with a faked Consent dialog, but malware could wait for a standard user’s OTS elevation, intercept it, and use a Trojan horse dialog to capture administrator credentials. With those credentials they can gain access to the administrator’s account and infect it.
For this reason, OTS elevations are strongly discouraged in corporate environments. To disable OTS elevations (and reduce help desk calls), run the Local Security Policy Editor (Secpol.msc) and configure "User Account Control: Behavior of the elevation prompt for standard users" to "Automatically deny elevation requests."
Home users who are security-conscious should configure the OTS elevations to require a Secure Attention Sequence (SAS) that malware cannot intercept or simulate. Configure SAS by running the Group Policy Editor (Gpedit.msc), navigating to Computer Configuration | Administrative Templates | Windows Components | Credential User Interface, and enabling "Require trusted path for credential entry." After doing so you will be required to enter Ctrl+Alt+Delete to access the elevation dialog.
Isolating Elevated Processes
Windows Vista places a barrier around elevated processes to protect them from malware running on the same desktop with standard user rights. Without a barrier, malware could drive an administrative application by sending it synthesized mouse and window input via window messages. And although the standard Windows security model prevents malware running in a process with standard user rights from tampering with an elevated process running as a different user, it does not stop malware running as the standard-rights version of an administrative user from opening the user’s elevated processes, injecting code into them, and starting threads in them to execute the injected code.
The Windows Vista shield for window messages is called User Interface Privilege Isolation (UIPI). It’s based on the new Windows Integrity Mechanism that Windows Vista also uses as the barrier around elevated processes. In this new security model, all processes and objects have integrity levels, and an object’s integrity policy can restrict the accesses that would otherwise be granted to a process by the Windows Discretionary Access Control (DAC) security model.
Integrity levels (IL) are represented by Security Identifiers (SIDs), which also represent users and groups, where the level is encoded in the SID’s Relative Identifier (RID). Figure 14 shows the display name, SID, and hexadecimal version of the SID’s RID for the four primary ILs. The hex numbers reveal gaps of 0x1000 between each level that allows for intermediate levels for use by UI accessibility applications as well as future growth.
Figure 14 Primary integrity levels
|Low Mandatory Level||S-1-16-4096||0x1000|
|Medium Mandatory Level||S-1-16-8192||0x2000|
|High Mandatory Level||S-1-16-12288||0x3000|
|System Mandatory Level||S-1-16-16384||0x4000|
Figure 15 lists the object IL policies and the access types they restrict, which correspond to the generic accesses defined for an object. For example, No-Write-Up prevents a lower IL process from gaining any of the accesses represented by the GENERIC_WRITE accesses. The default policy for most objects, including files and registry keys, is No-Write-Up, which prevents a process from obtaining write access to objects that have a higher IL than itself, even if the object’s discretionary access control list (DACL) grants the user such access. The only objects with a different policy are the process and thread objects. Their policy, No-Write-Up plus No-Read-Up, stops a process running at a lower IL from injecting code into and reading data—like passwords—out of a process that has a higher IL.
Figure 15 Integrity level policies
|No-Write-Up||A Lower IL process cannot modify a higher IL object|
|No-Read-Up||A lower IL process cannot read from a higher IL object|
|No-Execute-Up||A lower IL process cannot execute a higher IL object|
Windows assigns every process an IL that it places in the process’s token alongside the SIDs of the groups to which the user running the process belongs. Figure 16 lists examples of processes assigned to different ILs. Processes usually inherit the IL of their parent, but a process can also launch a process at a different IL, as AIS does when it launches an elevated process. You can view process integrity levels with the built-in Whoami utility by specifying the /all option, or with Sysinternals Process Explorer or AccessChk. Process Explorer can display process ILs with the addition of the Integrity Level column.
Figure 16 Sample process integrity level assignment
|Integrity Level||Example Processes|
|Low Mandatory Level||Protected Mode Internet Explorer and processes launched by Protected Mode Internet Explorer|
|Medium Mandatory Level||Standard user and non-elevated AAM processes|
|High Mandatory Level||Processes running with administrative rights|
|System Mandatory Level||Local System, Local Service, and Network Service processes|
Every securable object has an IL that’s either explicit or implicit. Process, thread, and token objects always have an explicitly assigned IL that’s usually the same as the IL stored in the corresponding process token. Most objects have no explicit IL and so default to an IL of Medium. The only objects created with an IL other than Medium are the objects created by a process running at Low IL, which therefore have a Low IL. You can use the built-in iCacls tool (%SystemRoot%\System32\iCacls.exe) to view the ILs of files and the Sysinternals AccessChk utility to view the ILs of files, registry keys, services and processes. Figure 17 reveals that the IL of a directory that needs to be accessible by Protected Mode Internet Explorer is Low.
Figure 17 AccessChk showing the IL of a user’s favorites directory (Click the image for a larger view)
If an object has an explicit IL, it is stored in an access control entry (ACE) of a type new to Windows Vista, the Label ACE, in the System Access Control List (SACL) of the object’s security descriptor (see Figure 18). The SID in the ACE corresponds to the object’s IL, and the ACE’s flags encode the object’s integrity policy. Prior to Windows Vista, SACLs stored only auditing ACEs, which require the "Manage auditing and security log" privilege (SeSecurityPrivilege), but reading a Label ACE requires only Read Permissions (READ_CONTROL) access. For a process to modify an object’s IL it must have Change Owner (WRITE_OWNER) access to the object and an IL that’s equal to or higher than the object, and the process can only set the IL to its own IL or lower. The new "Modify an object label" (SeRelabelPrivilege) privilege gives a process the ability to change the IL of any object the process has access to and even raise the IL above the process’s own IL, but by default that privilege is not assigned to any account.
Figure 18 An object's Label ACE
When a process tries to open an object, the integrity check happens before the standard Windows DACL check in the kernel’s SeAccessCheck function. Given the default integrity policies, a process can only open an object for write access if its IL is equal to or higher than the object’s IL and the DACL also grants the process the accesses it desires. For example, a Low IL process cannot open a Medium IL process for write access, even if the DACL grants the process write access.
With the default integrity policy, processes can open any object—with the exception of process and thread objects—for read access so long as the object’s DACL grants them read access. That means a process running at Low IL can open any files accessible to the user account in which it’s running. Protected Mode Internet Explorer uses ILs to help prevent malware that infects it from modifying user account settings, but it does not stop malware from reading the user’s documents.
Process and thread objects are exceptions because their integrity policy also includes No-Read-Up. That means a process’s IL must be equal to or higher than the IL of the process or thread it wants to open and the DACL must grant it the accesses it wants for an open to succeed. Assuming the DACLs allow the desired access, Figure 19 shows the accesses that the processes running at Medium and Low have to other processes and objects.
Figure 19 Object and Process Accesses
The Windows messaging subsystem also honors integrity levels to implement UIPI by preventing a process from sending all but a few informational windows messages to the windows owned by a process having a higher IL. That disallows standard user processes from driving input into the windows of elevated processes or from shattering an elevated process by sending it malformed messages that trigger internal buffer overflows. Processes can choose to allow additional messages past the guard by calling the ChangeWindowMessageFilter API. UIPI also blocks window hooks from affecting the windows of higher IL processes so that a standard user process can’t log the key strokes the user types into an administrative app, for example.
Elevations and Security Boundaries
It’s important to be aware that UAC elevations are conveniences and not security boundaries. A security boundary requires that security policy dictates what can pass through the boundary. User accounts are an example of a security boundary in Windows because one user can’t access the data belonging to another user without having that user’s permission.
Because elevations aren’t security boundaries, there’s no guarantee that malware running on a system with standard user rights can’t compromise an elevated process to gain administrative rights. For example, elevation dialogs only identify the executable that will be elevated; they say nothing about what it will do when it executes. The executable will process command-line arguments, load DLLs, open data files, and communicate with other processes. Any of those operations could conceivably allow malware to compromise the elevated process and thus gain administrative rights.
Playing in a Low-IL Sandbox
Protected Mode Internet Explorer runs at Low IL to create a fence around malware that might infect its process. This prevents the malware from changing the user’s account settings and installing itself in an autostart location. You can use the Sysinternals PsExec utility, along with the -l switch, to launch arbitrary processes at Low IL in order to explore the sandbox. Figure B shows how a command prompt running at Low IL can’t create a file in the user’s temporary directory, which has a Medium IL, but can do so in the Internet Explorer temporary directory, which has a Low IL.
Figure B Command prompt can only create files in similar IL (Click the image for a larger view)
Elevated AAM processes are especially susceptible to compromise because they run in the same user account as the AAM user’s standard-rights processes and share the user’s profile. Many applications read settings and load extensions registered in a user’s profile, offering opportunities for malware to elevate. For example, the common control dialogs load Shell extensions configured in a user’s registry key (under HKEY_CURRENT_USER), so malware can add itself as an extension to load into any elevated process that uses those dialogs.
Even processes elevated from standard user accounts can conceivably be compromised because of shared state. All the processes running in a logon session share the internal namespace where Windows stores objects such as events, mutexes, semaphores, and shared memory. If malware knows that an elevated process will try to open and read a specific shared memory object when the process starts, it could create the object with contents that trigger a buffer overflow to inject code into the elevated process. That type of attack is relatively sophisticated, but its possibility prevents OTS elevations from being a security boundary.
The bottom line is that elevations were introduced as a convenience that encourages users who want to access administrative rights to run with standard user rights by default. Users wanting the guarantees of a security boundary can trade off convenience by using a standard user account for daily tasks and Fast User Switching (FUS) to a dedicated administrator account to perform administrative operations. On the other hand, users who want to forgo security in favor of convenience can disable UAC on a system in the User Accounts dialog in the Control Panel, but should be aware that this also disables Protected Mode for Internet Explorer.
Running as standard user has numerous benefits, including helping to protect systems from accidental or deliberate damage and protecting the data and integrity of users sharing a system from unauthorized access. UAC’s various changes and technologies will result in a major shift in the Windows usage model. With Windows Vista, Windows users can for the first time perform most daily tasks and run most software using standard user rights, and many corporations can now deploy standard user accounts.
Mark Russinovich is a Technical Fellow at Microsoft in the Platform and Services Division. He is a coauthor of Microsoft Windows Internals (Microsoft Press, 2004) and a frequent speaker at IT and developer conferences. He joined Microsoft with the recent acquisition of the company he cofounded, Winternals Software. He also created Sysinternals, where he published the Process Explorer, Filemon, and Regmon utilities.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.