Running Vista Every Day!
UAC – The Good and The Bad
User Account Control (UAC) is a new security mechanism introduced in Vista, whose primary goal is to force users to work using restricted accounts, instead working as administrators. This is, in my opinion the most important security mechanism introduced in Vista. That doesn’t mean it can not be bypassed in many ways (due to implementation flaws), but just the fact that such a design change has been made into Windows is, without doubt, a great step towards securing consumer OSes.When UAC is active (which is a default setting) even when user logs in as an administrator, most of her programs run as restricted processes, i.e. they have only some very limited subset of privileges in their process token. Also, they run at, so called, Medium integrity level, which, among other things, should prevent those applications from interacting with higher integrity level processes via Window messages. This mechanism also got a nice marketing acronym, UIPI, which stands for User Interface Privilege Isolation. Once the system determines that a given program (or a given action) requires administrative privileges, because e.g. the user wants to change system time, it displays a consent window to the user, asking her whether she really wants to proceed. In case the user logged in as a normal user (i.e. the account does not belong to the Administrators group), then the user is also asked to enter password for the one of the administrator's accounts. You can find more background information about UAC, e.g. at this page.
Many people complain about UAC, saying that it’s very annoying for them to see UAC consent dialog box to appear every few minutes or so, and claim that this will discourage users from using this mechanism at all (and yes, there’s an option to disable UAC). I strongly disagree with such opinion - I’ve been running Vista more then a month now and, besides the first few days when I was installing various applications, I now do not see UAC prompt more then 1-2 times per day. So, I really wonder what those people are doing that they see UAC constantly appearing every other minute…
One thing that I found particularly annoying though, is that Vista automatically assumes that all setup programs (application installers) should be run with administrator privileges. So, when you try to run such a program, you get a UAC prompt and you have only two choices: either to agree to run this application as administrator or to disallow running it at all. That means that if you downloaded some freeware Tetris game, you will have to run its installer as administrator, giving it not only full access to all your file system and registry, but also allowing e.g. to load kernel drivers! Why Tetris installer should be allowed to load kernel drivers?
How Vista recognizes installer executables? It has a compatibility database as well as uses several heuristics to do that, e.g. if the file name contains the string “setup” (Really, I’m not kidding!). Finally it looks at the executable’s manifest and most of the modern installers are expected to have such manifest embedded, which may indicate that the executable should be run as administrator.
To get around this problem, e.g. on XP, I would normally just add appropriate permissions to my normal (restricted) user account, in such a way that this account would be ale to add new directories under C:\Program Files and to add new keys under HKLM\Software (in most cases this is just enough), but still would not be able to modify any global files nor registry keys nor, heaven forbid, to load drivers. More paranoid people could chose to create a separate account, called e.g. installer and use it to install most of the applications. Of course, the real life is not that beautiful and you sometimes need to play a bit with regmon to tweak the permissions, but, in general it works for majority of applications and I have been successfully using this approach for years now on my XP box.
That approach would not work on Vista, because every time Vista detects that an executable is a setup program (and believe me Vista is really good at doing this), it will only allow running it as administrator… Even though it’s possible to disable heuristics-based installer detection via local policy settings – see picture below:
that doesn’t seem to work for those installer executables which have embedded manifest saying that they should be run as administrator.
I see the above limitation as a very severe hole in the design of UAC. After all, I would like to be offered a choice whether to fully trust given installer executable (and run it as full administrator) or just allow it to add a folder in C:\Program Files and some keys under HKLM\Software and do nothing more. I could do that under XP, but apparently I can’t under Vista, which is a bit disturbing (unless I’m missing some secret option to change that behavior).
Integrity Levels – Protect the OS but not your data!
Integrity Levels (IL) mechanism has been introduced to help implementing UAC. This mechanism is very simple – every process can be assigned one of the four possible integrity levels:• Low
• Medium
• High
• System
Similarly, every securable object in the system, like e.g. a directory, file or registry key, can also be assigned an integrity level. Integrity level is nothing else then just an ACE of a special type assigned to the SACL list. If there’s no such ACE at all, then the integrity level of the object is assumed to be Medium. You can use icacls command to see integrity levels on file system objects:
C:\>icacls \Users\joanna\AppData\LocalLow
\Users\joanna\AppData\LocalLow silverose\joanna:(F)
silverose\joanna:(OI)(CI)(IO)(F)
NT AUTHORITY\SYSTEM:(F)
NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(F)
BUILTIN\Administrators:(F)
BUILTIN\Administrators:(OI)(CI)(IO)(F)
Mandatory Label\Low Mandatory Level:(OI)(CI)(NW)
BTW, I don’t know any tool/command to see and modify integrity levels assigned to registry keys (I think I know how to do this in C though). Anybody?Now, the whole concept behind IL is that a process can only get write-access to those objects which have the same or lower integrity level then the process itself.
Update (March 5th, 2007): This is the default behavior of IL and is indicated by the “(NW)” symbol on the picture above, which stands for NoWriteUp policy. I have just learned that one can use the chml tool by Mark Minasi to set also a different policy, i.e. NoReadUp (NR) or NoExecuteUp (NX), which would result that IL mechanism will not allow a lower integrity process to read or execute the objects marked with higher IL. See also my recent post about this tool.
UAC is implemented using IL – even if you log in as administrator, all your processes (like e.g. explorer.exe) run with Medium IL. Once you elevated to the “real admin” your process runs at High IL. System processes, like e.g. services, runs at System IL. From the security point of view High IL seems to be equivalent to System IL, because once you are allowed to execute code at High IL you can compromise the whole system.
Internet Explorer’s protected mode is implemented using the IL mechanism. The iexplore.exe process runs at Low IL and, in a system with default configuration, can only write to %USERPROFILE%\AppData\LocalLow and HKCU\Software\AppDataLow because all other objects have higher ILs (usually Medium).
If you don’t like surfing using IE, you can very easily setup your Firefox (or other browser of your choice) to run as Low integrity process (here we assume that Firefox user’s profile is in j:\config\firefox-profile):
C:\Program Files\Mozilla Firefox>icacls firefox.exe /setintegritylevel low
J:\config>icacls firefox-profile /setintegritylevel (OI)(CI)low
Because firefox.exe is now marked as a Low integrity file, Vista will also create a Low integrity process from this file, unless you are going to start this executable from a High integrity process (e.g. elevated command prompt). Also, if you, for some reason (see below), wanted to use runas or psexec to start a Low integrity process, it won’t work and will start the process as Medium, regardless that the executable is marked as Low integrity.It should be stressed that IL, by default, protects only against modifications of higher integrity objects. It’s perfectly ok for the Low IL process to read e.g. files, even if they are marked as Medium or High IL. In other words, if somebody exploits IE running in Protected Mode (at Low IL), she will be able to read (i.e. steal) all user’s data.
This is not an implementation bug, this is a design decision and it’s cleverly called the “read-up policy”. If we think about it for a while, it should become clear why Microsoft decided to do it that way. First, we should observe, that what Microsoft is most concerned about, is malware which permanently installs itself in the system and that could later be detected by some anti-malware programs. Microsoft doesn’t like it, because it’s the source of all the complains about how insecure Windows is and also the A/V companies can publish their statistics about how many percent of computers is compromised, etc… All in all, a very uncomfortable situation, not only for Microsoft but also for all those poor users, who now need to try all the various methods (read buy A/V programs) to remove the malware, instead just focus on their work…
On the other hand, imagine a reliable exploit (i.e. not crashing a target too often) which, after exploiting e.g. IE Protected Mode process, steals all the user’s DOC and XLS files, sends them back somewhere and afterwards disappears in an elegant fashion. Our user, busy with his every day work, does not even notice anything, so he can continue working undisturbed and focus on his real job. The A/V programs do not detect the exploit (why should they? – after all there’s no signature for it nor the shellcode uses any suspicious API) so they do not report the machine as infected – because, after all it’s not infected. So, the statistics look better and everybody is generally happier. Including the competition, who now has access to stolen data ;)
User Interface Privilege Isolation and some little Fun
UAC and Integrity Levels mechanism makes it possible for processes running with different ILs to share the same desktop. This raises potential security problem, because Windows implements a mechanism to allow one process to send a “window message”, like e.g. WM_SETTEXT, to another process. Moreover, some messages, like e.g. the infamous WM_TIMER, could be used the redirect execution flow of the target thread. This has been popular a few years ago in so called “Shatter Attacks”.UIPI, introduced in Vista, is for the rescue. UIPI basically enforces the obvious policy that lower integrity processes can not send messages to higher integrity processes.
Interestingly, UIPI implementation is a bit “unfinished” I would say… For example, in contrast to design assumption, on my system at least, it is possible for the Low integrity process to send e.g. WM_KEYDOWN to e.g. open Administrative shell (cmd.exe) running at High IL and gets arbitrary commands executed.
One simple scenario of the attack is that a malicious program, running at Low IL, can wait for the user to open elevated command prompt – it can e.g. poll the open window handles e.g. every second or so (Window enumeration is allowed even at Low IL). Once it finds the window, it can send commands to execute… Probably not that cool as the recent “Vista Speech Exploit”, but still something to play with ;)
It’s my feeling that there are more holes in UAC, but I will leave finding them all as an exercise for the readers...
Do-It-Yourself: Implementing Privilege Separation
Because of the limitations of the UAC and IL mentioned above (i.e. the read-up policy), I decided to implement a little privilege-separation policy in my system. The first thing we need, is to create a few more accounts, each for a specific type of applications or tasks. E.g. I decided that I want a separate account to run my web browser, a different one for running my email client as well as IM client (which I occasionally run) and a whole other account to deal with my super-secret projects. And, of course, I need a main account, that is, the one which I will use to log in to the system. All in all, here is the list of all the accounts on my Vista laptop:• admin
• joanna
• joanna.web
• joanna.email
• joanna.sensitive
So, joanna is used to log into system (this is, BTW, a truly limited account, i.e. it doesn’t belong to the Administrators group) and Explorer and all applications like e.g. Picassa are started using this account. Firefox and Thunderbird run as joanna.web and joanna.email respectively. However, a little trick is needed here, if we want to start those applications as Low IL processes (and we want to do this, because we want UIPI to protect, at least in theory, other applications from web and mail clients if they got compromised somehow). As it was mentioned above, if one uses runas or psexec the created process will run as Medium IL, regardless the integrity level assigned to the executable. We can get around this, buy using this simple trick (note the nested quotations):
runas /user:joanna.web "cmd /c start \"c:\Program Files\Mozilla Firefox\firefox.exe\""
c:\tools\psexec -d -e -u joanna.web -p l33tp4ssw0rd "cmd" "/c start "c:\Program Files\Mozilla Firefox\firefox.exe""
Obviously, we also need to set appropriate ACLs on the directories containing Firefox and Thunderbird user’s profiles, so that each of those two users get full access to the respective directories as well as to a \tmp folder, used to store email attachments and downloaded files. No other personal files should be accessible to joanna.web and joanna.email.Finally, being a paranoid person as I am, I have also a special user joanna.sensitive, which is the only one granted access to my \projects directory. It may come as a surprise, but I decided to make joanna.sensitve a member of the Administrators group. The reason for that is that I need to make all the applications which run as joanna.sensitve (e.g. gvim, cmd, Visual Studio, KeePass, etc) to have their UI isolated from all other normal applications, which run as joanna at Medium IL. It seems like the only way to start a processes at High IL is to make it part of the Administrators group and then use ‘Run As Administrator’ or runas command to start it.
That way we have the highly dangerous applications, like web browser or email client, run at Low IL and as very limited users (joanna.web and joanna.email), who have access only to the necessary profile directories (the restriction, this time, applies both to read- and write- accesses, because it’s enforced by normal ACLs on file system objects and not by IL mechanism). Then we have all other applications, like Explorer, various Office applications, etc. running as joanna at Medium IL and finally the most critical programs, those running as joanna.sensitve, like KeePass and those which get access to my \projects directory, they all run at High IL.
Thunderbird, GPG and Smart Cards
Even though the above configuration might look good, there’s still a problem with it I haven’t solved yet. The problem is related to mail encryption and how to isolate email client from my PGP private keys. I use Thunderbird together with Enigmail’s OpenPGP extension. The extension is just a wrapper around gpg.exe, a GnuPG implementation of PGP. When I open encrypted email, my Thunderbird processes spawns a new gpg.exe process and passes the passphrase to it as an argument. There are two alarming things here – first Thunderbird process needs to know my passphrase (in fact I enter it into a dialog box displayed by the Enigmail’s extension) and second, the gpg.exe process runs as the same user and at the same IL level as the thunderbird.exe process. So, if thunderbird.exe gets compromised, the malicious code executing inside thunderbird.exe will not only be able to get to know my passphrase, but will also be free to read my private key from disk (because it has the same rights as gpg.exe).Theoretically it should be possible to solve the problem with passphrase stealing by using GPG Agent, which could run in the background as a service and gpg.exe would ask the agent for the passphrase instead asking thunderbird.exe process, which will never be in possession of the passphrase. Ignoring the fact that there doesn’t seem to be a working GPG Agent implementation for Win32 environment, this still is not a good solution, because thunderbird.exe still gets access to gpg.exe process, which is its own child after all – so it’s possible for thunderbird.exe to read the contents of gpg.exe memory and to find a decrypted PGP private key there.
It would help if GPG was implemented as a service running in the background and thunderbird.exe would only communicate with it using some sort of LPC to send request to encrypt, decrypt, sign and verify buffers. Unfortunately I’m not aware of such implementation, especially for Win32.
The only practical solution seems to be to use a Smart Card, which would perform all the
necessary crypto operations using its own processor. Unfortunately, GnuPG supports only, a so called, OpenPGP smart cards, but it seems that the only two cards which implements this standard (i.e. Fellowship card and the g10 card) implement only 1024 bits RSA keys, which is definitely not enough for even a moderately paranoid person ;)
In the last hope, I turned to commercial PGP, downloaded the trial of PGP Desktop and… it turned out that it doesn’t support Vista yet (what a shame, BTW).
So, for the time being I’m defenseless like a baby against all those mean people who would try to exploit my thunderbird.exe and steal my private PGP key :(
The forgotten part: Detection
One might think that it’s a pretty secure system configuration… Well, more precisely, it could be considered as pretty secure, if UIPI was not buggy and UAC didn’t force me to run random setup programs with full administrator rights and if GPG supported Smart Cards with RSA keys > 1024 (or alternatively PGP Desktop supported Vista). But let’s not be that scrupulous and forgot about those minor problems…Still, even though that might look like a secure configuration, this is all just an illusion of security! The whole security of the system can be compromised if attacker finds and exploits e.g. a bug in kernel driver.
It should be noted that Microsoft has also implemented several anti-exploitation techniques in Vista, the two most advertised are Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP). However, ASLR does not protect against local kernel exploitation, because it’s possible, even for the Low IL process, to query system about the list of loaded kernel modules together with their base addresses (using ZwQuerySystemInformation function). Also, hardware DEP,
UPDATE (see above): David Solomon, pointed out, that Hardware DEP is also available on many modern 32-bit processors (as the NX bit is implemented in PAE mode).
It’s very good that Microsoft implemented those anti-exploitation technologies (besides ASLR and NX, there are also some others). However the point is, they could be bypassed by a clever attacker under some circumstances. Now think about how many 3rd party kernel drivers are typically present in an average Windows systems – all those graphics card drivers, audio drivers, SATA drivers, A/V drivers, etc... and try answering the question how many possible bugs could be there? (BTW, it should be mentioned that Microsoft did a clever step by moving some classes of kernel drivers into user mode, like e.g. USB drivers – this is called UMDF).
When attacker successfully exploits kernel bug, then all the security scheme implemented by the OS is just worth nothing. So, what can we do? Well, we need to complement all those cool prevention technologies with effective detection technology. But has Microsoft done anything to make systematic detection possible? This is a rhetoric question of course and the negative answer applies unfortunately not only to Microsoft products but also to all other general purpose operating systems I’m aware of :(
My favorite quote of all those people who negate the value of detection is this: “once the system is compromised we can’t do anything!”. BS! Even though it might be true today – because the Operating System are not designed to be verifiable, but that doesn’t mean we can’t change this!