Solving the problem rather than answering the question: How can a non-administrator modify a registry key that requires administrator permission?


A customer opened with a question, which the customer liaison forwarded to the product group with High Priority. (Because, apparently, their customer is more important than any other customer.)

Our program needs to modify a registry key in HKEY_LOCAL_MACHINE even when not running as an administrator. We tried setting an entry in the registry key HKLM\Software\Microsoft\Windows NT\Current­Version\App­Compat­Flags\Layers to run our application elevated, but it didn't help. We also tried setting the entry in our application manifest to say that it requires elevation, but that didn't work either. Please provide us with a way to override UAC.

The fact that they went in and tried to enable an application compatibility setting on their own application means that instead of fixing their program, they are just going to keep throwing garbage on the sidewalk and hope the street sweeper will still come and clean up behind them.

Upon closer questioning, they explained that setting the manifest entry didn't work in the sense that when the user ran the program, the operating system prompted for elevation. But they wanted their program to elevate without prompting.

Okay, first of all, if any program could could elevate without prompting, then there would be no point to elevation. Every program would simply ask for secret unprompted elevation, and there would be no point to elevation in the first place. So that angle is a non-starter.

We asked them for details on the problem they are having, the problem where they think writing to HKLM is the solution. That way, we can solve the problem instead of answering the question.

When our program is installed, it prompts the person doing the installation for the name of the server to connect to. The installer writes this information to HKLM. When a non-administrator runs the program, we want them to be able to switch to a different server. That's why we need to be able to write to HKLM.

Okay, now that we understand the scenario, we can provide a solution.

First of all, the reason why you can't write to HKLM is that it would allow a non-administrative user to change the server settings of another user. Suppose that I run the program and change the server to http://evil-hackers.example.com. Then I log off and wait. The next person to use the computer and run the program will connect to the hacker site instead of the real site, and now I can harvest credentials or launch a man-in-the-middle attack or otherwise do bad things.

The solution, then, is to reduce the scope of any changes a non-administrative user makes to just that user. That way, if they choose to point the program at a rogue server, they are merely attacking themselves.

  • At install time, write the default server information to HKLM.
  • When a user changes the server, write the new server to HKCU.
  • When the program needs to decide which server to connect to:
    • Check if there is a local setting in HKCU. If so, then use it.
    • If there is no setting in HKCU, then use the setting in HKLM.
  • Optional: Add an administrative option to change the default server in HKLM.
Comments (32)
  1. Joshua says:

    I don't see any bad security implications of an application shimming itself.

    Since HKCU can store applied shims, I'd have shown them that.

    Had to do it once. Discovered by research the shim I wanted could be added by environment variable, so I did that in the launcher.

    Shim: don't prompt for elevation and don't elevate.

    Reason: don't require admin rights at build time anymore.

  2. Anon says:

    @Joshua

    Suddenly: Detection causes elevation to be required.

    Event: Build breaks.

    Days: Time spent trying to track down the problem.

    Problem: Application requires a shim.

    Solution: Fix the broken code in the application.

  3. Random User 729764 says:

    Depending on the environment, a potential addition to the proposed plan: a Last Updated date/time. If the architecture typically dictates only one server within the environment, that would allow for a design in which the program silently falls back to the value in HKLM if the date is greater (and maybe only if attempting HKCU failed), or a design that resets the user's setting if the date is greater, or some other method of letting the admins help the users without contacting every user or loading every hive.

    [That's an interesting idea. It lets the adminstrators do a "mass reset" while still letting users have local overrides. -Raymond]
  4. Joshua says:

    @Anon: Which is worse? Application has wrong manifest at build time or application has wrong manifest at release time? (Same application, different invocation demands different shim.)

  5. Boris says:

    I tried going to the Evil Hackers website, but the link doesn't work.

  6. Andre says:

    I'm stunned that anyone who actually knows what HKLM and HKCU are needs this pointed out. Isn't this completely obvious and the reason why these two keys are distinct in the first place?

    Users change user settings, not machine settings.

    How did they get so far programming whatever they did, Infinite Monkeys?

    [The customer never mentioned HKCU. I bet they grew up in a world where every user was an administrator and therefore programs were perfectly free to write to HKLM any time they wanted, so their program put everything in HKLM. And then somebody tells them that their program doesn't work for standard users, and they're all like "But… but… how can we write to HKLM now?" -Raymond]
  7. Ben Voigt says:

    Other option (use only if the setting value is not security critical): Store this value inside a nested subkey, and give the "Authenticated Users" identity write access to that subkey.  Voila, no settings leftover in user hives when the application is uninstalled, or changes that fail to take effect because the value also exists in the user hive, or any of that.

  8. lazarus says:

    related question – is there an official way of bypassing UAC for a specific, trusted application?

  9. Cesar says:

    Overkill solution: create a "settings service". Install the service when installing the program. To read or modify the setting, the program calls the service. Since each machine will have a single copy of the service, there will be a single copy of their settings.

  10. Jim Lyon says:

    @lazarus: "Is there an official way of bypassing UAC for a specific, trusted application?"

    No. That's the entire point of UAC.

  11. Cesar says:

    @Jim Lyon: actually, it's easy, AFAIK services already run elevated, just use a service. That way you also gain privilege separation for free (no need to have the user interface run elevated, just the few operations which need it).

  12. Engywuck says:

    at least they are using registry. The other "classic" option in the world where everyone was Administrator was to write a .INI next to the .EXE – of course located in C:Program Files. And then act surprised when Vista (finally!) took things like %appdata% seriously.

  13. Anon says:

    @Joshua

    If the manifest is wrong at build time, it is, by definition, wrong at release, unless you've found a way to bypass building your releases.

    If you FORCE the process to be un-elevated, at least with an external manifest, it will fail to execute if the OS determines that it needs to be elevated, for any reason, because the elevation will fail.

  14. Anon says:

    @Raymond

    The Apple ecosystem is built such that while it is actively hostile to developers, it at least breeds an environment where devs actually have to read the docs.

    So many Windows developers don't know that you need to use HKCU, and they don't care because in most cases, it 'just works' (read: Is shimmed so that they never see the problems until there's a catastrophic failure, and a User loses vital business or personal data.)

  15. Anon says:

    @IanBoyd

    If you ask "What would you have done under Windows XP?", most Windows developers will say "Oh, I'll just require elevation. Thanks!"

    Financial and LOB software does that, because the devs are too lazy to produce properly working software. Why worry about security? That's a different department!

  16. Joshua says:

    @Anon: The difference is at build time the "application" directory is the build output directory so elevation is irrelevant (it's a maintenance tool so it really does need to write to the application directory).

  17. Paperino says:

    "Is there an official way of bypassing UAC for a specific, trusted application?"

    Potentially yes, Windows 7 has a whitelist of applications that can bypass UAC prompts. IIRC (unless fixed) even calculator is on that list. More info here, http://www.pretentiousname.com/…/win7_uac_whitelist2.html

    But even if technically is possible, it's not an easy solution for people that ignore even HKCU exists! :)

    [Also, I believe that list is ignored if you set your UAC settings to "Always prompt." -Raymond]
  18. alegr1 says:

    >Potentially yes, Windows 7 has a whitelist of applications that can bypass UAC prompts.

    It only elevates from Restricted Administrator to unrestricted administrator. It will not make an User to Administrator.

  19. IanBoyd says:

    Whenever this question comes up on SO, i ask the person, "What would have done under Windows XP?"

    When your standard users were running your application under Windows XP: how did you handle it then?

    If you *really* do desire a single, machine wide, option that is editable by all users, then grant all users permission to edit the registry key. You could also store the setting in an .ini file in CSIDL_COMMON_APPDATA (which is ACL'd already to allow all users to modify).

    When presented with the suddenly reality of having to "grant" all users permission to a machine-wide key, people instantly become security conscious. They are suddenly afraid of doing exactly what they were doing (allowing all users to run amok).

    Which, is some way, was the entire point of UAC – to push developers into adopting a different mindset and way of doing things.

    And if you still want to grant Everyone full control to your registry key, then that option is still available to you.

  20. AndyCadley says:

    @Anon:

    If you FORCE your application to run unelevated, the OS won't ever "detect" it needs elevation because all elevation detection is disabled the moment an application is manifested with a required execution level.

  21. sxtvt says:

    >Okay, first of all, if any program could could elevate without prompting, then there would be no point to elevation.

    But there already ways to elevate without prompting using batch jobs in task scheduler, for cases when user is split-token admin. This works for at least in nt62 and nt63 (and doesn't work for win7).

    For demo just paste that into unelevated cmd: schtasks /create /st 00:00 /sc daily /np /tn x /tr "cmd /c echo hi!>%windir%z" && schtasks /run /tn x

    File "z" in the protected windows directory would be created.

    This issue with task scheduler was discovered and reported to MS by James Forshaw, but was discarded 'wontfix' because apparently it's just UAC bypass (despite it works no matter how high that UAC slider is, that is – it's not attack on autoelevation feature).

    The sad thing is, there are elevation methods for non split-token admins (i.e. normal users) were also discovered (e.g. AppInfo AiCheckSecureApplicationDirectory Bypass), but they were too discarded by MS as 'uac bypass'. It's Windows XP era all over again!

  22. Mark says:

    sxtvt: UAC isn't really a security boundary. It's more to reduce the number of programs that do terrible things than to protect users from malicious code.

  23. 640k says:

    @Mark: Read Paperino's link.

    http://www.pretentiousname.com/…/win7_uac_whitelist2.html

    "To those saying, 'but UAC isn't a security boundary'

    That is a cop-out, IMO. Yes, there were ways things could piggy-back on or spoof elevations on Vista. Just because you can break some glass to enter a house doesn't mean you leave the doors unlocked, though…"

    And it goes on explains why your reasoning is illogical.

  24. sxtvt says:

    Mark: yeah, but when the flaw is that easy to abuse I'm pretty sure applications will start to utilize that (did someone just say 'bonus'?)

    Besides, it doesn't answer the issue with token Integrity Level bypass (by normal users!). It's like someone decided to discard the issue without thinking, only because there was that 'UAC' word in one of the sentences of the report.

  25. Mark says:

    640k: I'm not saying it shouldn't be a security boundary, I'm just saying it isn't currently. Just like kernel escalation wasn't a security issue on Windows 9x, only a reliability issue. Personally, I'd love for Microsoft to make it a security boundary, but until then I run Windows as a standard user, instead of relying on UAC.

  26. Mark says:

    640k: Also, the argument you cite doesn't prove my "reasoning" (which I'm taking to be your interpretation of my description of facts) wrong. Any bypass of UAC is trivial once the knowledge is out there because it's easy to follow steps. The aim of UAC is to pragmatically prevent developers from feeling they can rely on those steps. It's not to force customers to avoid rootkits, because someone writing a rootkit can use security bugs to escalate privileges. It's not to push customers towards LUA, it's to allow users who continue to be admins to work reasonably safely. And the reason it uses a secure desktop for the prompt is to prevent clickjacking.

  27. DebugErr says:

    About editing compatibility settings programmatically… what if Aero (Glass) throws garbage on the street, my program falls over it and wants someone to clean it up? stackoverflow.com/…/disabling-gdi-hardware-acceleration-in-winforms-mdi-with-aero-for-speed-up

  28. ANon says:

    @AndyCadley

    Only if your application is signed, AND uses an embedded manifest, AND doesn't trip Installer Detection.

  29. AndyCadley says:

    @ANon: If your application has a valid manifest then no appcompat functionality kicks in, including installer detection.

  30. Anon says:

    @AndyCadley

    My last statement on the back-and-forth here: This is provably false. I have an application on my desktop *right now* which, if I manifest it to run asInvoker, will fail to execute because Installer Detection attempts to run it as Admin, while the manifest prohibits it.

  31. Joshua says:

    @Anon: Manifest overrides installer detection. I depend on it to run patch.exe (which got its first update in 10 years that did nothing but add the manifest).

  32. IanBoyd says:

    UAC is convenience feature. It is the moral equivalent of: "Right-click, Run as different user".

    Is it also the moral equivalent of Windows 2000's: "Logout, Login as administrator", and Windows XP's: "Fast user switch, and login as administrator"

    You were told not to run all the time as an administrator. You were told to switch to an administrator account when you need to do something that requires administrative privileges. Windows Vista helps you do that with a convenience feature.

    You can choose to disable UAC, then then you have to do what we did in Windows XP: Fast user switch to an administrator.

Comments are closed.

Skip to main content