Saturday, January 5, 2008

The integrity drop - or - How to disable UIPI take 2

On vista if you create a process with a low integrity level token, the User Interface Privilege Isolation (UIPI) will prevent it from talking to windows owned my medium/high integrity level processes.

What if you don't want that? Maybe you already have another plan for UI protection? Running in a job for example.

There is the easy way: [From MSDN]

By specifying UIAccess=”true” in the requestedPrivileges attribute [of the application manifest], the application is stating a requirement to bypass UIPI restrictions on sending window messages across privilege levels. Windows Vista implements the following policy checks before starting an application with UIAccess privilege.
The application must have a digital signature that can be verified using a digital certificate that chains up to a trusted root in the local machine Trusted Root
Certification Authorities certificate store.
The application must be installed in a local folder application directory that is writeable only by administrators, such as the Program Files directory.

Unfortunately this is not going to work if you application can be installed by non-admin users.

Fortunately, there is another (not documented) way to "disable" UIPI.

Windows initializes UIPI during the process startup. If you create the process with a low integrity level, then UIPI will prevent it from accessing windows owned by medium/high integrity level processes.

But no one said that it was not possible to change the integrity level of a process AFTER it is started. If you own the process, and you trust that it's not going to run any potentially malicious piece of code before main(), you can add code at the beginning of your main() to drop the integrity level. From now on, the process is going to run with the new integrity level and UIPI won't be updated.

Dropping the integrity level is easy:

Get a handle to the process token using OpenProcessToken and call SetTokenInformation on it with the TokenIntegrityLevel information class to set the new integrity level.

But this is not all. If you only do this, your process won't be able to play sound. This is because when you play sound, audiodg.exe creates some objects on your behalf. At some point it will impersonate your token and open your process. Since your process was created with a medium integrity level token, the integrity/mandatory label on the process is Medium. When audiodg tries to open your process with your token, it does not have access and it fails.

What you must do is change the security label on the process to be low integrity level. The easy way to do this is to create a SDDL string for the integrity label and to follow the code in this example. You should use this SDDL string: "S:(ML;;NWNR;;;LW)" It means that it's a SDDL for a SACL (S:), with a Mandatory Label ace type (ML), the ace access is No-Write-Up and No-Read-Up (NWNR) and the integrity level is low (LW). The example is using NW instead of NWNR but for a process it's better to prevent lower privileges processes from being able to read it's process memory.


lauren said...

I recently started using Windows vista on my laptop and I am not aware of all the security mechanism followed by it.I faced same problem and your blog helped me to sort out easily by using (not documented) way to "disable" UIPI.
digital signature autocad

zorro59 said...

Can you please give some sourcecode for part 2?

wei chen said...

Hi Sylvain, I get into trouble about UIPI event I UIAccess=”true” and signed my application and put it into a security directory as you mentioned in this blog. I still can not bypass the UIPI. I asked a question on stackoverflow, I hope you can help me answser it. Especially this sentence "Unfortunately this is not going to work if you application can be installed by non-admin users" in your blog article. Thanks.