|Informative Information for the Uninformed
Although the problem outlined in this article is indeed a privilege escalation hole, there are some limitations to it. First of all, if the caller is running as a plain user instead of a non-elevated administrator, appinfo creates the uiaccess process with integrity level 0x1010 (low integrity + 16). This is still less than medium integrity (0x2000), and thus in the true limited user case, the new process, while protected from other low integrity processes, is still unable to interfere with medium integrity processes directly.
In the case where a user is running as an administrator but is not elevated (which happens to be the default case for most Windows Vista users), it is true that appinfo.exe returns a handle to a process running at high integrity level. However, only the integrity level is changed; the process is most certainly not an administrator (and in fact has BUILTIN Administrators as a deny only SID). This does mean that the new process is quite capable of injecting code into any processes the user has started though (with zero user interaction). If the user happens to already have a high integrity process running on the desktop as a full administrator, the new process could be used to attack it as the process would be running at the same integrity level and it would additionally be running as the same user. This means that in the default configuration, this issue can be used to escape from Protected Mode, but one is still not given full-blown administrative access to the system. However, any location in the user profile directory could be written to. This effectively eliminates the security benefit of Protected Mode for a non-elevated administrator (with respect to treating the user as a plain user).
Source code to a simple program to demonstrate the appinfo service issue is included with the article. The problem is at this point expected to be fixed by Windows Vista Service Pack 1 and Windows Server 2008 RTM. The sample code launches osk.exe with ShellExecute, patches out the CloseHandle calls in ShellExecute to retain the process and thread handles, and then injects a thread into osk.exe that launches cmd.exe. The sample program also includes a facility to create a low integrity process to verify correct function; the intended use is to launch a low integrity command shell, verify that directories such as the user profile directory cannot be written to, and then use the sample program from the low integrity process to launch a medium integrity cmd.exe instance without user interaction, which does indeed have free reign of the user profile directory. The same code will operate in the context of Internet Explorer in Protected Mode, although in the interest of keeping the example clear and concise, the author has not included code to inject the sample program in some form into Internet Explorer (which would simulate an attack on the browser).
Note that while the uiaccess process is launched as a high integrity process, it is configured such that unless a token is explicitly provided that requests high integrity, new child processes of the uiaccess process will launch as medium integrity processes. It is possible to work around this issue and retain high integrity with the use of CreateProcessAsUser by code injected into the uiaccess process if desired. However, as described above, simply retaining high integrity does not provide administrative access on its own. If there are no other high integrity processes running as the current user on the current desktop, running as high integrity and running as medium integrity with the non-elevated token are functionally equivalent, for all intents and purposes.