UAC Virtualization – Allowing standard users to update a system protected area
You should know the score by now – I install application FOO into “C:\Program Files\Foo Inc\Foo” and it has a built-in manifest stating that asInvoker is used for its requested privilege level, allowing standard users to run it.
Attempts by standard users to write to “C:\Program Files\Foo Inc\Foo” do not fail with “access denied” (as they would have on version of Windows prior to Vista), but instead the disk write is redirected to the user’s own profiles (under “%userprofile%\AppData\Local\VirtualStore\Program Files”).
So far, so good – the application is happy as it believes it is able to write to a system protected area of the volume even when running without admin rights.
But imagine that FOO has an “automatic updater” or a “launcher” stub process whose job it is to check the current version of the application and download an update package & apply it…
The write operation is virtualized into the user’s profile, so the new patch will download okay – but when it comes to apply it this is also virtualized and the file it is updating or replacing is not in VirtualStore… so it fails.
Re-run the launcher and it will either start over with the download of the update, or try again to apply it and fail once more.
There are now plenty of apps (and games) that will run okay without admin privileges, but they have problems patching because of UAC virtualization unless the launcher was started elevated (or by the Administrator, who is the only user exempt from UAC as per my previous blog entry).
So how to leave UAC enabled and be able to use and update this program as a standard user?
First, we need to verify that the application is not being virtualized – when it is running you can check in Task Manager and right-click the process name – in the context menu if there is a check against “UAC Virtualization” then we need to create a manifest so the OS thinks it is “UAC aware”.
If the executable is named FOO.EXE, the manifest in the same folder needs to be FOO.EXE.MANIFEST, and it is just a human-readable XML file.
(Bear in mind if there is a stub launcher it may be necessary to create a similar manifest for the main executable too.)
Based on the example on MSDN, the contents of the manifest file would be something like this:
|<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="22.214.171.124" processorArchitecture="X86" name="FOO" type="win32"/> <description>The Amazing Foo (Launcher)</description> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly>|
If using Notepad to create the file, make sure to save the file in quotation marks to avoid .txt being appended to the name.
Now, launching FOO.EXE should not trigger an OTS prompt and UAC virtualization should be disabled – note that if the application is trying to write to its folder then it will now have errors as it is behaving as Windows XP would.
(We could disable just the OTS prompt but leave the application UAC virtualized by using the Application Compatibility Toolkit to create a shim to set requestedPrivileges=asInvoker and import it with sdbinst.exe, but this blog is about working around an application’s design flaw to disable UAC virtualization.)
So the next thing we need to do is to grant the required permissions on the folder we’re trying to write to.
In this case the easiest thing is probably to take “C:\Program Files\Foo Inc\Foo” and set:
- the owner to the group “Users”
- permissions for group “Users” to Full Access
This will let anyone authenticated as a member of the Users group able to create and delete files in this folder – but you should also check the permissions on the files & folders that are already there to ensure that Users have Full Access on those too, or editing/deleting existing files may fail.
A quick way to check the owner of a folder or file is to use the /Q switch for DIR at a command prompt:
C:\Program Files\Foo Inc\Foo>dir /q Volume in drive C is CDRIVE Volume Serial Number is 1234-4321
Directory of C:\Program Files\Foo Inc\Foo>
2010-08-11 15:27 <DIR> BUILTIN\Users . 2010-08-11 15:27 <DIR> NT SERVICE\TrustedInsta.. 2010-08-11 15:27 18 BUILTIN\Administrators foo.dll 2010-08-11 15:27 22 BUILTIN\Administrators foo.exe 2010-08-11 15:27 12 BUILTIN\Administrators foo.exe.manifest 3 File(s) 52 bytes
Here you can see I’ve set ownership of the folder itself (“.” is the current folder) to “Users”, but it has not changed the owner of the items in the folder.
(You can also add the “Owner” column when browsing the folder in Explorer, but you won’t see “.” or “..” in this case.)
ICACLS can be used for viewing and editing permissions at an elevated command prompt:
C:\Program Files\Foo Inc\Foo>icacls * foo.dll NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Administrators:(I)(F) BUILTIN\Users:(I)(RX)
foo.exe NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Administrators:(I)(F) BUILTIN\Users:(I)(RX)
foo.exe.manifest NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Administrators:(I)(F) BUILTIN\Users:(I)(RX)
Successfully processed 3 files; Failed processing 0 files
We can then change the owner of the files, if we work with just foo.exe as a simple example:
C:\Program Files\Foo Inc\Foo>icacls foo.exe /setowner BUILTIN\Users processed file: foo.exe Successfully processed 1 files; Failed processing 0 files
As CREATOR OWNER (a member of Users) we now have permission to change the permissions even without the process being elevated:
C:\Program Files\Foo Inc\Foo>icacls foo.exe /grant BUILTIN\Users:F processed file: foo.exe Successfully processed 1 files; Failed processing 0 files
Finally, we can verify that our discretionary ACE is there (note the lack of “(I)” indicating inheritance):
C:\Program Files\Foo Inc\Foo>icacls foo.exe foo.exe BUILTIN\Users:(F) BUILTIN\Users:(I)(F) NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Administrators:(I)(F)
Successfully processed 1 files; Failed processing 0 files
This sounds like a lot of work, but remember we are fixing a compatibility issues for an application that somebody else designed, and if it’s done correctly (and there are no other quirks of the application) it shouldn’t need doing again.
An alternative that at least one vendor did to get round this for non-technical users was to move the installation folder for the app (actually a game) into the %PUBLIC% folder (the “public” or “all users” profile) which is not UAC virtualized, and grant permissions for anyone to write there.
1. If an application wants to write to the %SYSTEMROOT% folder, I would never recommend taking ownership or trying this method – the vendor should fix their application in this case.
2. Similarly, I would never advocate taking ownership of the %PROGRAMFILES% folder itself as this reduces security.