Dubious security vulnerability: Luring somebody into your lair


A security report was received that went something like this:

The XYZ application does not load its DLLs securely. Create a directory, say, C:\Vulnerable, and copy XYZ.EXE and a rogue copy of ABC.DLL in that directory. When C:\Vulnerable\XYZ.EXE is run, the XYZ program will load the rogue DLL instead of the official copy in the System32 directory. This is a security flaw in the XYZ program.

Recall that the directory is the application bundle, The fact that the XYZ.EXE program loads ABC.DLL from the application directory rather than the System32 directory is not surprising because the ABC.DLL has been placed inside the XYZ.EXE program's trusted circle.

But what is the security flaw, exactly?

Let's identify the attacker, the victim, and the attack scenario.

The attacker is the person who created the directory with the copy of XYZ.EXE and the rogue ABC.DLL.

The victim is whatever poor sap runs the XYZ.EXE program from the custom directory instead of from its normal location.

The attack scenario is

  • Attacker creates a directory, say, C:\Vulnerable.
  • copy C:\Windows\System32\XYZ.EXE C:\Vulnerable\XYZ.EXE
  • copy rogue.dll C:\Vulnerable\ABC.DLL
  • Convince a victim to run C:\Vulnerable\XYZ.EXE.

When the victim runs C:\Vulnerable\XYZ.EXE, the rogue DLL gets loaded, and the victim is pwned.

But the victim was already pwned even before getting to that point! Because the victim ran C:\Vulnerable\XYZ.EXE.

A much simpler attack is to do this:

  • Attacker creates a directory, say, C:\Vulnerable.
  • copy pwned.exe C:\Vulnerable\XYZ.EXE
  • Convince a victim to run C:\Vulnerable\XYZ.EXE.

The rogue ABC.DLL is immaterial. All it does is crank up the degree of difficulty without changing the fundamental issue: If you can trick a user into running a program you control, then the user is pwned.

This is another case of if I can run an arbitrary program, then I can do arbitrary things, also known as MS07-052: Code execution results in code execution.

Note that the real copy of XYZ.EXE in the System32 directory is unaffected. The attack doesn't affect users which run the real copy. And since C:\Vulnerable isn't on the default PATH, the only way to get somebody to run the rogue copy is to trick them into running the wrong copy.

It's like saying that there's a security flaw in Anna Kournikova because people can create things that look like Anna Kournikova and trick victims into running it.

Comments (31)
  1. pc says:

    Surely there's a bit of a concern here (though perhaps not a flaw in the security model as designed), in that the "real" XYZ.EXE may be digitally signed by a party that the user trusts and is willing to run code from, but the attacker's pwned.exe masquerading as XYZ.EXE won't be. It almost makes me want to have the Digital Signatures tab of the Properties for a file to give a warning if there are DLLs in the same directory that aren't signed or are signed by a different party. Almost.

  2. Joshua says:

    Well there was this antivirus bypass back in the day that involved static linking against .lib files derived from system DLLs. This did, of course, have to be prepared against the patch level of the target machine.

  3. Kevin says:

    TRWTF is installing things into e.g. C:Games without applying proper security to it (i.e. it's world-writable, or at least writable-by-non-admins).  This is fairly common in the PC gaming space.  I think some installers may even do it out of the box.

  4. alegr1 says:

    That's a fundamental flaw of Windows security model: whatever the user runs is considered as trusted as the user. This assumption is wrong for about fifteen years already. Microsoft missed a chance to sandbox applications. Windows 8 apps model is too late and still doesn't protect from legacy apps. UAC is just a kludge.

  5. Nick says:

    @alegr1: Have you looked at the Windows 10 support for Win32 in Store Apps? It looks like it's all about sandboxing legacy apps.

  6. Kevin says:

    @alegr1: Unix traditionally does precisely the same thing.  You can fake it with lots of little user accounts, but that's… ugly.

  7. dtm says:

    @Nick: there is no sandboxing going on in Centennial, at least not in my understanding. The App-V-like sequencer is used to find out what the installer does to the target system, and access to certain storage locations (%APPDATA%, HKCU) is subsequently redirected. Of course the app needs to go through the Store submission process (except in case of sideloading). But once the application is deployed, no further security mechanisms apply.

    @alegr1: you can accomplish what you want with Software Restriction Policies.

  8. Anon says:

    @alegr1

    So nothing the user runs should be considered trusted by the user? Why should I have to jump through numerous additional security hoops just because some idiots run quite literally any executable anyone provides them?

  9. Darran Rowe says:

    @alegr1:

    Besides wanting to have a random rant at UAC, why did you mention it? UAC has nothing to do with this situation at all. In fact, the real fallacy here is thinking that UAC is anything more than a way to force developers into writing programs that are limited user account aware.

    Now the thing which was introduced with Vista that I think really is underused on the desktop, especially with regards to downloaded files is the integrity levels. An example of this is suppose you downloaded an executable from the internet, and the web browser marked the file as came from another computer. Well, Windows could have changed it so that these files got executed with low integrity by default. Of course that would probably have had a huge backlash because of breakage and stuff, but that is most likely the best thing for this situation.

    Other than that, to get an executable file on the system then the attacker must have had physical/remote access to the machine. This means that any kind of sandboxed environment could have been bypassed because in a sense, the machine has already been pwned.

  10. @James Picone: I have a hard time buying this argument.  Under what circumstance is it ever a good idea to place executable binaries in a world-writable location?  If you're planning on supporting updates, your program should have an update wrapper executable that gets admin privileges as needed.  Plenty of applications do this, games aren't special in any way with this requirement.  I've seen several games use UAC for their updaters, so this isn't impossible to do.  Cumbersome?  Sure, but being a good programmer means you take the security of your software and users into account.

    The same argument can be applied to where data gets stored.  User-specific data goes to AppData, system-specific data goes to ProgramData, and user-owned files goes in one of the user libraries (usually either Documents or Games).  The Linux world has had these different layers of separation for ages, and from a security standpoint this makes good sense.  If, as a user, you want that data stored on a different drive, you can always use symlinks to the SSD (very few games would even notice, since this is handled on the NTFS layer).

  11. Emjayen says:

    @Joshua Would've been easier (and likely more stealth-ier) just to invoke native services directly via syscall. The dispatch table barley changes between releases anyway.

  12. alegr1 says:

    Applications need to run in a sandbox with privileges assigned to them by a signed manifest. They should only be able to communicate with applications within their sandbox. Only MS-signed executables should be able to function outside a sandbox, even if ran from administrator desktop. Access to resources should be controlled by a manifest. Those controllable resources are file system (limited directories, limited file extensions and operations), network stack (ability to listen, ability to communicate with a fixed server or with an arbitrary server), etc.

  13. Anon says:

    @Kevin

    Writing to, say, c:games is fine. What idiots have traditionally done (See: Valve, Steam) is place things into %ProgramFiles% and then set them globally-writeable.

    Or, alternately, they place things into %ProgramFiles% and then tell users to disable all of the security on the machine rather than, say, spending five minutes to place the thing where it *actually belongs*.

  14. James Picone says:

    @alegr1 I don't know about you, but I quite like having a general-purpose computing device. I'm not sure that's compatible with that security model.

    Obvious objections:

    – What about scriptability? How do you write, say, AutoHotKey under that model?

    – It can sometimes be really, really useful to intercept an application's DLL calls and/or directly modify the application's code. The most obvious contemporary example is x360ce, which is a general-purpose application that proxies a dinput controller to an xinput controller so you can use it for modern games. It's amazingly great, and it works by proxying the xinput dll. Other things worth mentioning are the Skyrim Script Extender and dsfix, which add modding capabilities to Skyrim and make Dark Souls and Dark Souls 2 playable, respectively. How do you do something like that in your brave new security world?

    – This application requires the following privileges: [list of every privilege possible]

    – The fundamental problem in the loop is almost always the user – how much does signing and sandboxing limit the damage someone can do by downloading some signed malware and then saying 'yeah, sure, it can do everything it wants'? That can still grab any files on the HDD, send spam, etc. About the best I can see is that you've successfully prevented that malware hooking the web browser and sniffing bank account passwords. Well, unless it's a plugin for their web browser.

    – When developing, how do you run code to test it? Do you need to ensure you can sign something before you can run any code? How do you write a debugger?

    – Does limiting a computer's external attack surface to MS-signed executables actually help? Surely most wide-spread malware is already targeting bits of Windows that will, under this scheme, be MS-signed (possible exception – internet explorer).

    It almost makes you think that the Slashdot paranoia about iPhone walled-gardens is justified.

  15. James Picone says:

    @Cheong00

    You misunderstand – Minecraft just stores its executable in %AppData% and runs it from there, for whatever reason. It performs updates by downloading the most recent version of the executable and then running that one. It's Java, so someone using that as an attack would have to break the JRE at least.

    I'm not complaining about installers. I'm complaining about all the other times something might want to write into Program Files. I'm also complaining about the various locations data gets stored now that the obvious and convenient location isn't available. I guess having the game elevate every time you run it would also solve the problem, but that's throwing the baby out with the bathwater.

  16. alegr1 says:

    @James Picone:

    It's cool to have a computer to screw around, if you know what you're doing. 99.9% of users don't know what they're doing, and I grew tired of having to know what I'm doing in order to keep my computers alive and healthy and safe and cozy and warm.

  17. James Picone says:

    @Anon: The actual outcome of your policy if it were enforced would be that everybody would install to some nonstandard location – say, C:programs – and nobody installs into %ProgramFiles%, and we're in the exact same situation of users having write access to a directory with programs in it (the horror!) but minus any of the benefits of %ProgramFiles%.

    Games are *particularly* bad for the %ProgramFiles% model, what with very often wanting to write into their own directory (for example, because they've patched), and there are significant downsides to %AppData% being used as general storage location for everything (rather hard to actually find where any given program stores its data – there are roughly three locations I have to check for any given game to find savefiles, I have to be very careful to make sure %AppData% is on a disc that I want huge clumps of hard-to-move data dropped onto, it means some games don't get the full benefits of running on an SSD because anything they want to easily write to must be in %AppData% and you probably don't want %AppData% on an SSD, no locality of storage, etc.)

    tl;dr: Program Files not being world-writable is utterly awful in some significant use-cases. If you're installing Steam on a machine, making %ProgramFiles% world-writable is probably sensible.

  18. James Picone says:

    @MNGoldenEagle

    Personal desktop computer, where it's highly unlikely that another user of the computer is malicious, and if they are they have physical access and a number of other non-computer mechanisms for causing trouble. In the extreme case, it's the personal desktop computer of one person.

    Wrapper executables and UAC and so on is cumbersome, as you've admitted, and provides approximately zero actual security in this case. Games where this kind of thing is relevant are almost always used in this kind of context. What's an actual example threat that this stops? The best I can come up with is that I share a computer with an idiot and they download and execute malware from the internet, and for some reason they don't have administrator access (and thus can't UAC elevate for the malware, which they will if prompted, almost certainly). Most common case for that setup I can come up with is parents with a kid, and there are better approaches to stopping problems there (like, for example, not letting your kid download executables from the 'net unsupervised if they're young, or teaching your kid about not being an idiot if they're old).

    So now if I want to find some file a game has stored somewhere on the system, I need to check Appdata/Local, Appdata/Roaming, AppData/LocalLow for a subdirectory that looks like it might be promising (and which won't be named something immediately obvious, it's probably named after the company that made the game, or maybe their publisher), and yes it could be in any or all of those three. Also I need to check the documents folder in case there's something in there. Of course, many games will write in several of those locations, often different data, so I need to dig through the directory trees to find what I'm looking for. God help you if they keep stuff you want to modify in the registry.

    Compare to the previous model, now deprecated, where the folder with the game's data in it contains subdirectories that contain any relevant game-related data, and maybe they write something into the registry. Settings-in-the-registry having mostly died is very much a good thing, but the loss of any kind of locality of file is not. There's a reason people disable this and *** about it and so on, and it's not a general hostility to microsoft or security features. It's because it's incredibly annoying, takes up a significant amount of time, and has just given game devs new and interesting ways to be terrible (Did you know Minecraft updates by downloading the new versions into %AppData% and executing them from there?)

  19. Darran Rowe says:

    @James Picone:

    You should be complaining about installers though. An installer should set up the environment in such a way that it makes it capable of running the application.

    Having to make Program Files world writable shows that an installer has failed, because not only does it make all other applications inside Program Files a target, but it shows that the installer hasn't completed its job.

    Now the real thing an installer should do in this case, is if it wants to install to Program Files but also write to its own directory, then it should modify the ACL on the directory, or a sub directory and put all the files it wants to write to there. Another option is to make the files exist from the start and modify the ACL on those files to allow limited users to write to it. In fact, I am always surprised that actually changing the ACL of the directory/file very rarely gets mentioned, and instead people complain about other things, like having to elevate.

    Program Files as a convenient location hasn't gone, it is just that people still haven't moved along with it and started doing things correctly. They still like to take the quickest/easiest over the best.

    Steam or other games is the same here. While the default is to install to Program Files, is it really that much of an issue to add a new library in the root directory, i.e. C:SteamLibrary? The same with other games, installing them outside of Program Files also helps.

    One of these options allows for the game directory to be writable but at the same time it keeps the security of the system as high as it can be. One of the biggest issues with security on any system is actually users, and reducing security anywhere is always a sign that something is wrong.

  20. ender says:

    @alegr: you're free to use an iPad or some Android or Windows RT-based tablet then – they'll give you exactly what you want.

  21. cheong00 says:

    (Did you know Minecraft updates by downloading the new versions into %AppData% and executing them from there?)

    Actually downloading the new versions of installer into %AppData% and executing them from there is enough. The properly manifested installer should invoke UAC consent prompt, and from there things goes as what you think it should be if otherwise.

    Do you think creating proper manifest file *one time only* is difficult task? IMO it's significantly easier than getting the performance right.

  22. Anon says:

    @Darran Rowe

    Perfect description of the problem there. Valve now recommends, despite still installing to a bad location, exactly that — they want you to set up a Steam Library in a non-protected location.

    @James Picone

    If developers didn't behave in stupid ways, you wouldn't have to check three locations. They would ALWAYS put user-modified files where they belong — in the appropriate subdirectory of %UserProfile% on Windows, or ~ on Linux/OSX. Developers should adhere to the standard of the OS, the OS shouldn't break itself to suit the developers.

  23. Random User 90934752 says:

    Arguably:

    Games should start following the normal install rules(/guidelines/suggestions/hallucinations). If it was installed per-machine by an admin into FOLDERID_ProgramFiles, it should only be able to be patched by an admin. Otherwise, per-user installs should go into FOLDERID_UserProgramFiles, can be patched by the owning user, and has no impact on any other user. If the dev wants to be fancy, they can offer a third, hybrid approach where an admin can install a base into FOLDERID_ProgramFiles and let users selectively override with patch files in FOLDERID_UserProgramFiles (auto-cleanup, etc., let as an exercise).

    In any case, user data should go under the user's data folder. Shared data (local high-scores, etc.) is fuzzier; off-hand I would say it should only be an option in one of the scenarios where an admin did the install, and put it under the common data folder with the installer setting the appropriate permissions.

  24. AndyCadley says:

    @Darran Rowe: Fiddling the permissions under Program Files can lead to security vulnerabilities, it's a trusted location for things like UIPI, not to mention actually making the kind of vulnerabilities that Raymond's post describes a reality.

    It's much better and easier to use the right locations for creating files in the first place. You don't have to write awkward ACL code, you don't have to worry about multiple users, it just works.

  25. Darran Rowe says:

    @AndyCadley:

    I think you managed to misunderstand the context of the post somewhat. In no way did I say that making an application directory writable is a good thing. I never said that an application should prefer to write to its own directory over the per user directories. The theme of my post was more to do with how to limit the stupidity that you had to deal with when you are installing other applications.

    My post was in direct response to someone saying that if you use a games platform like Steam, making the Program Files directory is probably the most sensible. As you may or may not know, games, especially older games, do stupid things. My post was completely about keeping Program Files completely locked up, but at the same time being flexible enough to allow games or applications that decide to write to its own directory happy and working.

    Of course, as a caveat, there are times when an application may want to make its settings writable, but storing them per user may not be the best idea. This can occur if the settings involved are global, placing them inside the per user settings isn't right. In these cases, making a sub directory of the application writable is the way to go.

  26. Random User 90934752 says:

    Agreed, Anon. But much of what I said applies there as well.

    The LoB I routinely work with was originally created for maybe Win95, probably Win 3.x, and has evolved completely ad-hoc and everywhere except the installer. It takes the approach of creating it's own folders in the root of the specified drive. It doesn't change any permissions on it's own, but heaven help you if you don't go back and grant at least Modify access to Authenticated Users.

    Both the installer and it's auto-update stub (actually, the same EXE that changes behavior based on its name) have other permissions and per-user issues (COM, etc.), so we try to do all out installs and updates with a custom MSI. But that doesn't resolve the actual program expecting users to be able the write in the core folder. They only just in the past year or two moved part of the user-modifiable data to a folder under the user's profile; and I mean the profile (%USERPROFILE%), not either of the user's AppDatas.

  27. Max says:

    @James Picone:

    Ideally, games wouldn't create files that the user needs to manually find and modify outside of the game. Unless you've run into some massive bug, a user shouldn't even really need to know the default location of a game's config files or save files, let alone go digging around in the filesystem for them. Of course, the reality is somewhat different, but bad coding isn't an excuse to engage in bad practices as a workaround for the problems caused by program issues.

  28. Medinoc says:

    @James Picone: Whoa, WHOA! Making %ProgramFiles% world-writable is NEVER reasonable. However, making your own subdirectory thereof is, in some circumstances.

    The ideal for applications would be giving them a "portable" mode, which keeps everything in the application's directory *without elevating* (which forces it to be put in a user-writable (and preferably user-specific) directory, which is good for a "portable" application).

    The "portable mode" setting should be determined by a configuration file in the application's directory, since that's the only place a "portable" application is supposed to store anything.

    And another good thing is the application outright telling you where it puts its config, preferably with a button/menu item to directly open the directory in an Explorer window.

  29. Anon says:

    Somehow we've gotten into a discussion of games.

    Steam was an *example*, because it is one of the most wide-spread applications.

    Games were an *example*, because they very frequently don't write user-owned-files to the correct location(s).

    Games are *NOT*, however, the largest offender.

    LOB-applications are the largest offender (most of them written in garbage languages with frameworks which make it more difficult to produce well-formed applications), and there are millions upon millions of them.

  30. Xtreem Gam3r says:

     "Ideally, games wouldn't create files that the user needs to manually find … outside of the game … Unless you've run into some massive bug … "

    Most games do not provide a facility to move saved games to another machine (or user account), so it becomes necessary to find them outside of the game.  

    It used to be simple, they were in the directory of the game itself!  But, it is way better to have multiple user accounts, with protections, so changes in the OS to improve that feature, if it means multiple places to search for the files, that is not a problem.  

  31. anonymouscommenter says:

    blog.trendmicro.com/…/new-wave-of-plugx-targets-legitimate-apps Is the concern discussed in this "vulnerability" An adversary is using clean programs as their persistence mechanism, since if a user looks at the program, they will see a legit signed application in the ASEP. It is not a vulnerability, other than the program itself has a DLL Load Order Vulnerability. msdn.microsoft.com/…/ff919712(v=vs.85).aspx

Comments are closed.

Skip to main content