2019 year-end link clearance: The different kinds of DLL planting

Raymond Chen

This time, the link clearance is just one link:

That link summarizes various causes of alleged DLL planting vulnerabilities and how the Microsoft Security Response Center assesses them.

I’ve discussed many of these scenarios in the past.

In my experience, people tend to mistake application directory planting for current directory planting because they run the proof-of-concept in a scenario where the current directory is the same as the application directory. They plant a file in the current directory, and it gets loaded: Aha, a current directory vulnerabilily!

Nope. The DLL is being loaded from the directory because it is the application directory, not because it is the current directory. To be sure that it’s a current directory attack, you need to make the current directory different from the application directory.

Consider this scenario:

C:\appdir> copy \\badplace\files\attack.dll
        1 file(s) copied.

C:\appdir> C:\appdir\app.exe

In this case, the application directory is C:\appdir. Copying a file into the application directory means that you have already crossed the airtight hatchway and entered the app’s “safe zone”. If you weren’t supposed to be able to get into the app’s safe zone, then whoever set up the application directory messed up.

To make this a current directory attack, you need to do this:

C:\appdir> mkdir C:\attack

C:\attack> copy \\badplace\files\attack.dll
        1 file(s) copied.

C:\attack> C:\appdir\app.exe

If this loads the attack.dll, then you’ve found something.

As for path planting, there tend to be three categories of false reports.

The first is the blatant “other side of the airtight hatchway”, where the proof of concept requires planting a DLL into administrator-only directories.

The second is a case where an application running with full user permissions alters the path for the current user, and then uses it to attack that same user. Note that no elevation occurred: The user is attacking himself. It is not a security vulnerability that users can make their own lives miserable.

Besides, if you have a bad actor running with full user permissions, there’s no point going through all this path attack nonsense. The bad actor already has full user permissions, so it can just do the bad thing directly. Doesn’t need to be sneaky about it.

The third case is where some application’s installer put an insecure directory onto the global system path. This is a security vulnerability in the application’s installer, where they create an insecure system and then are shocked that the resulting system is insecure

This third case is frustrating to diagnose because the finder typically doesn’t realize that they have installed some program that made changes to the system that introduced the vulnerability. The bug goes through a few rounds of “Not repro”, “Is too”, “Is not” until we realize that the finder is probably testing on their own machine rather than in a freshly-installed system with all settings at their factory defaults.

Bonus planting: Exploits that require planting C:\Program.exe are also invalid, because the default permissions for C:\ require administrator privileges to create a file. (You do not need administrator privileges to create a new directory in the root, but you do need administrator privileges to create a new file in the root.)

¹ Occasionally, somebody will just come right out and create the insecure system directly in their proof of concept.

  1. Create the C:\Sucker directory and put a bad thing in it.
  2. Add C:\Sucker to the PATH for the user (or for the system).
  3. User (or system) component does bad thing.

Yup, that’s a problem. A problem that you created right there in step 2.

Sometimes the finder doesn’t quite understand that the problem was of their own doing, and it takes a few more rounds of back-and-forth to get it through to them that all they did was show that users have permission to make their own lives miserable, and that administrators have permission to make everybody’s lives miserable.


Discussion is closed. Login to edit/delete existing comments.

  • Alex Martin 0

    “This house is badly designed. If the owner doesn’t lock their door, I can just walk in.”

    “Isn’t it the owner’s responsibility to lock their door?”

    “No, this is bad design.”


    *incoherent rage*

    • cheong00 0

      Or you can do heavy re-engineering and replace the door with something that will automatically locked, and be unlocked with Bluetooth key held by house owner.

      “This house is badly designed. If the owner leaves the key near the door (under the carpet), I can just walk in.”

      And here it goes…

  • skSdnW 0

    While technically a app dir plant, I feel like installers need their own category.

    Installers often end up in the Downloads folder with who knows what. Before the “force loading from system32” API was added it was extremely hard to prevent Windows itself from calling LoadLibrary without a path behind your back, even CreateWindow and simple functions in shell32 will do it.

    I wish Microsoft could add a manifest entry that forces system32 to be first on the dll search path. Another mitigating factor would be for the system dlls that use delay loading to use the full path when loading their dlls.

      • skSdnW 0

        No, I said manifest so that it is applied before any code runs. SetDefaultDllDirectories is the API I was referring to.

      • Stefan Kanthak 0

        /DEPENDENTLOADFLAG is not sufficient: it applies only to runtime linking performed with LoadLibrary(). It does neither apply to runtime linking performed with LoadLibraryEx() nor load-time linking.
        The same goes for SetDefaultDllDirectories().
        All 3 can but mitigated per manifest: <file name=… loadFrom=”fully-qualified path”>
        And besides of this limitation, it fails to work as advertised/documented!

  • Henke37 0

    I get the feeling that someone have had to deal with one questionable report too many.

  • Lambda Goblin 0

    Just curious, what do you think about these electron apps that install to the user’s home folder with no other protection? Some people feel the OS protection of the user’s home folder is enough, while others think not requiring an elevation prompt to replace parts (or the entirety) of an installed application is risky.

    • Georg Rottensteiner 0

      Oh yeah, that would be of interest to me too. Not only electron programs, but also other programs, that run under the user’s home folder to avoid elevation. Don’t they simply undermine a safety measure just by trying to avoid the elevation prompt?

    • Raymond ChenMicrosoft employee 0

      You have to determine who the attacker is, who the victim is, and what the attacker has gained. The victim is presumably the user running the application. Who is attacking a user’s home directory? What do they gain?

      • Alex Martin 0

        Perhaps an attacker with a temporary compromise of the user account using it to get persistence? There are easier ways, but maybe they’re shooting for stealth?

      • aidtopia 0

        You also have to determine who the victim is.

        If I can compromise user accounts, there are easier ways to attack those users than planting a DLL. But if my goal is to attack the reputation of some other app, FOO, then by planting a DLL that FOO is going to load could be simple and effective.

        Sure, security researchers will figure out that FOO was the victim rather than the cause, but by then the reputational damage is done. The initial round of media will point out that FOO could have prevented this attack by installing itself to C:\Program Files\FOO rather than C:\User\Me\AppData\Local\FOO. No matter how many articles get published later marking me as the evil doer, people will remember that using FOO is what made them vulnerable.

        • Raymond ChenMicrosoft employee 0

          You don’t need to plant DLLs to attack FOO’s reputation. You can use a cheat engine-like program to patch arbitrary bytes in the FOO program, or just inject a DLL at runtime.

          • Stefan Kanthak 0

            In order to inject a DLL at runtime, an attacker needs a (permanently) running program which performs the injection. Such (background) programs can be spotted during a casual inspection.
            In order to patch arbitrary bytes in an existing program/file, an attacker must also be able to run some program. The modification can be detected (for example due to a now invalid authenticode signature), repaired/rolled back (if the application is installed via MSI or APPX package), or FOO can be replaced by an update.
            An additional DLL is a little bit harder to detect and thus stealthier, and will more likely survive any updates of FOO.

    • Alex Martin 0

      Note: Microsoft is currently distributing two of these programs, namely Visual Studio Code and Microsoft Teams. (Teams just mysteriously uninstalled itself from my machine so I can’t verify for sure that it still does this, but I remember that it did at one point.)

      • Stefan Kanthak 0

        You forgot OneDrive, for example.

        JFTR: Teams is a security nightmare, you should be glad that this crap is gone!

        • Alex Martin 0

          Everything here is on Teams. I use it through my Web browser.

Feedback usabilla icon