Way back in the days of Windows for Workgroups, we knew it was a dumb idea.
Moving from being a Unix developer to being a Windows developer, I could tell it was a dumb idea.
People inside of Microsoft knew it was a dumb idea.
[It doesn’t load DLLs from the current working directory as a first resort, it will usually search first in the application’s install directory, then in a couple of Windows directories, but if those fail, it will load from the current directory – see this MSDN article for details]
If you’re a developer, and you were aware that this is a bad idea, then you could take defensive measures – for example, setting the “current working directory” (CWD, for short) to be a safe location – such as the application’s own directory.
If you weren’t aware that this is a bad idea, however, you’d blithely ignore the issue and carry on calling LoadLibrary to open custom DLLs.
There’s two parts to that question:
Well, as a hypothetical scenario, imagine a media playing application.
Media players know how to handle several “packages” (media files, which often can contain different formats of media), and may also know how to handle several “codecs” (the format of the media inside the package). To support maximum flexibility, they may allow the use of codecs that are not supplied with the application.
These third-party codecs are provided in the form of DLLs with specific documented entry points. They aren’t all installed with the operating system, and they aren’t all installed with the media player.
So, a media player may know about a few dozen codec DLLs, but may not know whether or not those codecs are installed. So how would it find out?
Simple – it would try to load each DLL, and flag as successful those codecs whose DLLs load.
DLLs supplied with an application should be found in the application’s install directory – and that’s the first place LoadLibrary looks.
System DLLs should be found in the Windows or Windows\SYSTEM32 directory. Second and third places.
The fourth place LoadLibrary looks in is the CWD. If you load your media player by double-clicking a media file (or any number of similar methods), the CWD will be the same folder as the media file is in, so a poorly-written media player (such as iTunes) would thus load a codec DLL from the same folder as the media file.
Codec DLLs should be registered in the registry using MFTRegister. So you should know exactly where to search for them.
By no means is this restricted to one type of application. The risk here is from having all of these present:
I think this is where Microsoft suffers from being an interesting platform for developers who are somewhat hard of thinking.
Don’t get me wrong, there are many expert and experienced developers on the Windows platform – but there are apparently at least several hundred developers who are not very well versed in the operating system on which they develop, and as such, fall to this issue and its like.
Unix, and by extension, Linux, doesn’t have the same problem, because it doesn’t put “.” (the current working directory) into the executable path environment variable, or the dynamic library search order. Well, actually, that’s not really correct – Unix and Linux do have this problem, because application authors are just as dumb on those platforms, and have insisted that ‘to make this application work, “.” needs to be in the path and/or load order’.
Not completely – there will always be stupid developers, and there will, as I have pointed out before, always be developers who don’t like the platform they’re developing for, and who will therefore screw things up, deliberately or accidentally. When you view the OS platform as the enemy, you can’t write trustworthy code. This should be seen as a problem particularly by companies such as Apple and Google, who have expressed direct hostility towards Windows, and therefore may not be the best examples of good coding practices in writing applications for that system.
Even if Microsoft do change this behaviour, the story isn’t over, because removing support for loading DLLs from the current directory may kill the operation of a significant number of applications. Perhaps even one that your company relies on. That’s not a decision I want them making lightly.
I’d rather see an extension to SAFER / Software Restriction Policies / AppLocker (or whatever it’s called this week) that allows me to specify that DLLs can only be loaded from specific named paths. That, and/or the ability to specify which apps can load DLLs from CWD, and that all others should not. Then I can reduce my threat to only those applications I deem necessary.
Update: As if by magic, Microsoft released just such an extension – OK, maybe it’s not implemented in the place I suggested, but it should have the same effect. I would strongly advise enterprises to start testing this with your standard line-of-business apps, to see whether they break.
H D Moore’s post on Application DLL Load Hijacking. Note the quote from ACROS Security which suggests that they are in this job only to make money, rather than to enhance your security. Perhaps this is poorly worded, but it is indicative of a worrying trend.
Apple’s security bulletin on the poor programming in iTunes (right down at the bottom).
Microsoft releases an update to allow you to change LoadLibrary’s behaviour on a system-wide and application-specific level: MSRC blog entry, SRD blog entry, Knowledge Base Article (and update download).
Microsoft releases documentation on the right ways to call LoadLibrary to prevent this problem.
Don’t forget, if you’re using LoadLibrary to get at strings, images, sounds, or other resources stored in a DLL, you should be using LoadLibraryEx instead, and calling it with the flags appropriate to loading the DLL for resource / data access only, so that you don’t execute the code inside the DLL.
(*) The reference to “more” is because of the previous LoadLibrary issues, with a .LNK code execution flaw recently patched.
As a big fan of The IT Crowd, I’m a happy reader of the author, Graham Linehan,’s blog, “Why That’s Delightful!”. It certainly helps to explain to American viewers tonight’s episode. And yes, I did try and persuade Microsoft to give Moss an MVP award. Maybe I should have suggested Roy instead, since he mostly does windows.
However, the other day, looking for the blog on a machine on which my bookmarks don’t reside, I was rather shocked to see “Why, that’s delightful!”, when I typed in what I thought was Mr Linehan’s blog address. Totally not the site I was looking for. I was completely unprepared. I hope Graham Linehan knows he has a competitor for the same search meme.
Graham Linehan is the author (along with Arthur Mathews) of that other staple of British (or Irish?) humour, “Father Ted” (memorable, also, for being produced by the late Geoffrey Perkins, of Radio Active and Hitch-Hiker’s fame). If you’ve not seen them yet, go watch them – rent them on Netflix, watch The IT Crowd on IFC, and Father Ted on wherever you can find it in this country, whatever you have to do to make this a part of your comedy intake.
But beware of imitations, when it comes to your favourite blogs.
[And don’t try and use Windows Media Center to sync The IT Crowd from IFC to your Zune, because IFC marks all their programming for DRM, with the aim that it can’t be copied. Boo, hiss, IFC.]