It rather involved being on the other side of this airtight hatchway: Planting DLLs into directories on the PATH for applications whose current directory is always System32


A bunch of security vulnerability reports came in from the same person, all of the form, "Program X is vulnerable to DLL planting if you create a DLL with the name Y in a directory on the PATH," with varying values of X and Y. In all the cases, Program X runs as SYSTEM with the System32 directory as its current directory, so a current directory attack does not apply here. The only remaining directory to attack is the PATH.

But if you can attack the PATH for the SYSTEM user, then you are already on the other side of the airtight hatchway.

The default PATH directories are all directories which are read-only to non-administrative users. In order to plant a DLL there, you must already be an administrator, at which point you are on the other side of the airtight hatchway. If you gain administrative access, then why bother planting DLLs in sneaky places? You already pwn the machine. Just do whatever you want! In other words, planting a DLL into secured directories can be carried out only by administrators, at which point it's just the administrator attacking his own computer. Not interesting.

The next angle of investigation is whether somebody can sneak an insecure directory onto the global PATH. But modifying the global PATH requires administrative privileges, so if you have the privilege to add an insecure directory to the path, you are already an administrator, so this is another case of an administrator attacking his own computer. Still not interesting.

Finally, the third option is that some application, as part of its installation, added an insecure directory to the global PATH. But in that case, you don't need to do any DLL planting at all. Just put a rogue executable on the PATH. For example, you might call it tpye.exe, so that somebody who typos the type command runs your rogue executable instead. In other words, in order for DLL planting into an insecure directory on the global PATH to work, you must already have a system whose integrity has already been violated, albeit inadvertently in this case. If you have an attack along these lines, then the security vulnerability is in the application whose installer added an insecure directory to the global PATH. This is another case of If you set up an insecure system, don't be surprised that there's a security vulnerability.

Now, there is still a flaw in the application that gets tricked into loading the rogue DLL. It should be more specific about how it loads DLLs so it doesn't load the wrong one by accident. But there is no elevation of privilege, since only administrators can trick the application into loading the wrong DLL.

Comments (29)
  1. Joshua says:

    If this ts true, then Windows 7's UAC is no defense in default configuration. DLLs may be planted in the PATH by silent COM elevation (inject explorer).

  2. Tim says:

    You can inject COM into Explorer without elevating?

  3. Peter says:

    Here's the real security vulnerability: I am unable to install applications on Windows without giving them permission to do _anything they like_ to my machine, when all I really want is for them to copy their files into C:Program Files.

    [Um, if you have write permission in C:Program Files, you can pwn the machine. That's why we have per-user install. -Raymond]
  4. Mason Wheeler says:

    Gotta agree with Peter on this one.  That's always bugged me a little.  When the folks at Microsoft were designing UAC, how did they not see that that is a security hole big enough to drive a truck through?

  5. Joshua says:

    And here we go down the dark corridor of per-application security settings.

  6. alegr1 says:

    @Peter:

    Totally agree. If you have to give any installer that you've downloaded from some site all privileges, it's rather scary. I'd rather prefer to not allow a non-MS signed (or unsigned) installer to install any privileged services or write to privileged directories, or install drivers.

  7. Peter says:

    "Um, if you have write permission in C:Program Files, you can pwn the machine. That's why we have per-user install. -Raymond"

    Right.  That's really my point.  I always get a chill when I install a new program and Windows asks me "Do you want to allow program X to make changes to your computer?  Yes/No"  I do, but I'd really like a say in what changes it's allowed to make.  Copy files to a new directory in under C:Program Files?  Sure.  Install services and device drivers?  Not so much.  That being said, I do like UAC.  I think it's a huge improvement over what we had previously, but it's not enough.

    @Joshua: I'm not sure why this is a "dark corridor."  It sounds like a great idea to me.

    [Vote with your wallet. Tell the vendor "I won't buy your software until it supports per-user install, or explain to me why it requires system privileges." -Raymond]
  8. Fleet Command says:

    @Peter: Well, here is the problem: Even if there was more granular security that issued different prompts for different administrative task (say, one prompt for writing in Program Files folder and one prompt in Windows Registry), the user would zealously answered both prompts the same and thought "who the hell designed this granular UAC?"

    If you like such a system, there are third-party security suites that add such a feature. But I personally find testing unknown apps in virtualized testbed more promising.

  9. Joshua says:

    [Vote with your wallet. Tell the vendor "I won't buy your software until it supports per-user install, or explain to me why it requires system privileges." -Raymond]

    Now if I could install .NET Framework or a virtual printer as per-user I might support that …

  10. alegr1 says:

    >And here we go down the dark corridor of per-application security settings.

    >[Vote with your wallet. Tell the vendor "I won't buy your software until it supports per-user install, or explain to me why it requires system privileges." -Raymond]

    Two most popular smartphone operating systems run applications in sandboxes with per-application permissions. The vendor A takes more profits than the rest of the industry combined.

  11. Nick says:

    > I do, but I'd really like a say in what changes it's allowed to make.

    But then we end up with the mess like we have for mobile app permissions.  Eventually 90% of the apps will just request all permissions because it makes things easier (for them to use and abuse, not at all for you).

    The only reasonable answer is what Raymond said. Look for a "portable" archive or per-user installer. If you can't find one, ask them for one. If you can't or they won't offer one, there are still a few options.

    – Extract the installer's contents using something like 7-Zip (which can open almost any archive format)

    – Use the installer software's built-in switches (can require some detective work to determine the kind of installer and/or guessing of switches).

    – Install in a virtual machine and install the software there. Then copy and paste the extracted program onto your computer.

    An awful lot of "installers" are completely spurious and do little more than add a shortcut to the desktop and an entry to the Add/Remove control panel.

    [The standard Windows installer even has a MSIINSTALLPERUSER flag. Set it and dust off your hands. (Of course, you still have to deal with people who use a custom installer.) -Raymond]
  12. @alegr1 says:

    Except you're forgetting those operating systems were designed with the so called application sand-boxing in mind. Win32 (and all of its predecessors), however, was not.

  13. AndyCadley says:

    UAC is not a security boundary, it's merely a convenience feature that allows compliant applications to elect to run with lower privileges. An Administrator running with UAC enabled is *still* an Administrator and thus the various mechanisms to supposedly bypass it aren't classed as vulnerabilities – they will all fail if a non-Administrator is logged on, because the process can't elevate without an Administrator providing credentials.

  14. Chris says:

    A lot of these seem to work out like saying "If I leave my front door unlocked, a robber can come in and unlock a window, and use the window to steal my stuff!"

    ["And this is a flaw in the window!" -Raymond]
  15. @alger1 says:

    The three most popular smartphone OSs do this… Android, iPhone, and Windows Phone.

  16. Joker_vD says:

    Well, sorry, security and covenience rarely go along. Some people remove password protection from the SSL's private key on their servers because "I can't enter the password for every bloody packet now can I?"

    However, I agree about the option "Try to run the program even without permissions it asked for", but what, say, GetContactList should do without a permission? Return ERROR_ACCESS_DENIED or pretend that the contact list is empty?

  17. Gabe says:

    Joker_vD: Funny you should ask.

    If you make GetContactList return ERROR_ACCESS_DENIED, iTunes may refuse to run (even though you're not actually using its "social" features). Maybe it's intentionally being malicious, preventing you from using the app without its viral features, or (more likely) it goes to initialize the feature on startup and nobody thought to catch the exception.

    On the other hand, what happens if you just pretend the contact list is empty? You end up with a randomly broken app. Whenever the app goes to use the feature you disabled, it won't work and the app won't be able to tell you why. All you'll know is that you can't email your playlist to your friend. You won't know that it's because you denied access to your contact list.

    What app author wants the support hassles of trying to debug random breakage. If I ask to use 10 privileges, that means 1k different configurations!

  18. Cheong says:

    [Now if I could install .NET Framework or a virtual printer as per-user I might support that …]

    IMO, it fits the "or explain to me why it requires system privileges" clause.

  19. Paradice says:

    > The three most popular smartphone OSs do this… Android, iPhone, and Windows Phone.

    Yeah, and it's a complete joke. Twitter can prevent your phone from sleeping. Angry Birds wants your location. iTunes demands access to your contact list.

    There's no "hey, actually can you run Angry Birds but maybe *without* giving it access to my call history?". Nope. To take security seriously, effectively you no longer have a smartphone, because you can't run any apps.

  20. Rick C says:

    .Net Framework is a system update, not an application.  Why would you want to make it per-user?  That seems crazy.

  21. Joshua says:

    @Rick C: Because somebody wants to install w/o admin rights, duh.

  22. Cheong says:

    @Joshua: Actually, inspired by your comment, I created this suggestion in visualstudio.uservoice.com/…/4771782-create-a-subset-of-net-runtime-for-installation-b

    Such trimmed-down version of runtime is useful to lightweight application builders.

  23. @Joshua says:

    Why would you want to install a System level component without administrative rights? What other framework allows you to do such a thing? Java? Python? Ruby?

  24. John Doe says:

    @Nick, comparing snapshots after installing in a virtual machine, you can theoretically create manifests for registry-free com.

    .NET could almost be used this way, if it weren't for WXP+ treating .NET PE's specially on process creation.

    It could at least probably allow having a small custom application launching .NET through COM and loading the atual assembly with the Main() method. (Remember how 32-bit .NET EXE's still have a stub that is run in W2K?) For isolated applications, this could be just enough.

  25. Anon says:

    @cheong00

    Except .NET isn't just a set of libraries. .NET is hooked into the system, and .NET code is compiled at runtime. .NET depends on other system updates, which depend on other system updates, etc etc.

    Having individual versions of .NET libraries floating around would cause other problems, too:

    "I'm getting errors running .NET 6.2 applications, they throw exceptions on a random set of obscure.function calls."

    *40 hours later*

    "Oh, I installed Poorly_Designed_Widget, and it put Obscure.Function.Assembly.DLL v5.1.6827-Tiny.NET in my path, got rid of that and everything else works, but how do I get Poorly_Designed_Widget to run alongside .NET 6.2?! It is critical, we can't get updates since the author died in a freak accident involving a shark, two unicyclists, and some spray cheese. Stupid Microsoft, always breaking things with their updates!"

  26. lsl says:

    > What other framework allows you to do such a thing? Java? Python? Ruby?

    All of them. Those are implemented as normal programs. Just copy the interpreter binary (and maybe the shared libraries it needs) to some directory and execute it with a Perl/Python/Ruby/Java program as an argument. Done. I can imagine this would be perfectly possible with NET, too. I don't know that much about it, though.

    Giving up on nice automatic updating as a system component would be a major downside IMHO. All recent Windows variants ship with NET by default anyway, right?

  27. Cheong says:

    @lsl: It's included as Windows feature, but not a default installed one. Someone has to enable (install) it to use it.

    If the company doesn't use .NET internally, and doesn't use ATI display cards (their control center uses .NET framework), you cannot expect their technical support to enable it be default.

  28. Cheong says:

    @Anon: That's why I said "trimmed down version".

    You know the Windows Server Core versions doesn't ship with GDI+ libraries so the original .NET runtime won't install on that? However that also means these servers cannot serve ASP.NET pages, therefore Microsoft release a trimmed down copy of .NET runtime that doesn't require GDI+ to enable .NET runtime be installed there.

Comments are closed.