Date: | July 2, 2004 / year-entry #265 |
Tags: | history |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20040702-00/?p=38583 |
Comments: | 32 |
Summary: | Reaching back into the history bucket... Some people have discovered that strange things happen if you name your DLL "security.dll". The reason is that there is already a system DLL called "security.dll"; it's the Security Support Provider Interface DLL, and it used to go by the name "security.dll", though nowadays the name "secur32.dll" is preferred.... |
Reaching back into the history bucket... Some people have discovered that strange things happen if you name your DLL "security.dll". The reason is that there is already a system DLL called "security.dll"; it's the Security Support Provider Interface DLL, and it used to go by the name "security.dll", though nowadays the name "secur32.dll" is preferred. If you look into your system32 directory, you'll see both "security.dll" and "secur32.dll" in there. And if you're handy with an export dumper, you'll see that "security.dll" is just a bunch of forwarders to "secur32.dll". If you browse through the MSDN documentation, you'll see that everybody talks about "secur32.dll" and hardly any mention is made of its doppelgänger "security.dll". Okay, here's where the history comes in. Wind back to Windows 95. Back in those days, the Security Support Provider Interface was implemented in two different DLLs. The one you wanted depended on whether you are running Windows NT or Windows 95. On Windows 95, it was called "secur32.dll", but on Windows NT, it was called "security.dll". This was obviously a messed-up state of affairs, so the Windows NT folks decided to "go with the flow" and rename their security DLL to "secur32.dll". This was probably for application compatibility reasons: Applications that were written to run on Windows 95 and were never tested on Windows NT just went straight for "secur32.dll" instead of loading the correct DLL based on the operating system. Okay, so now pop back to the present day. When you put a DLL called "Security.dll" in your application directory, what happens? Recall that the rules for the order in which DLLs are searched for checks the application directory before it checks the system directory. As a result, anybody in your application who wants "Security.dll" will get your version instead of the system version. Even if the system version is the one they really wanted. That's why overriding the system's Security.dll with your own results in a bunch of SSPI errors. Components you are using in your program are trying to talk to SPPI by loading "security.dll" and instead of getting the system one, they get yours. But yours was never meant to be a replacement for "security.dll"; it's just some random DLL that happens to have the same name. You would have had the same problem if you happened to name your DLL something like "DDRAW.DLL" and some component in your program tried to create a DirectDraw surface. "Security.dll" has the disadvantage that it has a simple name (which people are likely to want to name their own DLL), and its importance to proper system functionality is not well-known. (Whereas it would be more obvious that creating a DLL called "kernel32.dll" and putting it in your application directory is going to cause nothing but trouble.) |
Comments (32)
Comments are closed. |
If you put kernel32.dll in application’s directory, nothing happens – Windows check "KnownDLLs" registry key and will load it from correct location. I just wonder why not put all "mission critical" DLLs in that list.
I’d wager that in some cases you’d want security.dll to be overridable. If you’re creating a replacement login system, or… heck, I don’t know.
On the bright side we ran into this problem two years ago on one of our first forays into .NET. I thought it was humorous and obvious at the time.
Ah the joys of using filenames. I hope that WinFS come through with some sort of GUID system or something so you know which file is which.
wow, this is potentially a major vulnerability, right?
On a side note, this is how Total Annihilation Demo Recorder implements hooking into Total Annihilation’s network layer to support game recording and other enhanced team play features. Also does the same with DirectDraw to provide a few GUI enhancments.
Implementing a DirectPlay3 proxy in pascal, scary scary stuff.
The KnownDlls Registry entries can be a source of huge headaches. The fact that these entries override the ‘normal’ search order is not very well documented (e.g., the link that Raymond quotes does not mention it). Couple this with programs that mess with these entries and suddenly a program that worked for ages does not work any more or (even worse) behaves different in subtle ways. I remember when the installation of IE 4.01 under Win95 suddenly screwed up an otherwise well-behaved program and it took us days to track down the reason.
(And no, my memory is not that great, this took place about a year ago.)
Not only will it mess things up, but it’s a pretty clear indication that it’s a good place to start dissassembling/decompiling/debugging if you want to bypass security checks.
Shouldn’t it look in the system directories first?
Also, why does it look in the current directory? Can’t it cause surprising behavior (the application behaves differently depending on where your current directory is)? Not to mention the potential security trouble (some joker putting a dll in a shared directory and waiting for you to run a program while in that directory).
Starting in Windows XP SP1, the current directory is searched *after* system directories. This change was made with much trepidation because some very popular programs relied on the old behavior, but security trumps compatibility.
Fudging with SSPI on a client box won’t help you break into a remote SQL Server… basic rule of security is that servers should not trust their clients (and vice-versa).
I helped a guy troubleshoot this problem through the CodeProject forums back in March: http://www.codeproject.com/script/comments/forums.asp?msg=805487&forumid=1650#xx805298xx.
Basically, whether his website worked depended on whether another site on the same server, with a stray security.dll, loaded first. Ouch.
It would be nice if there was a way of controlling where DLLs load from when using a DllImport directive. The .NET Framework shouldn’t break because the current directory contains a DLL with the same name as the DLL being imported!
But that’s the whole point of putting a DLL in your EXE’s directory: To override the system DLL. The "modern" way of accomplishing this is with a manifest.
Oops, a security hole. Even if you can’t modify the files in the, say, Program files directory, you can put a DLL named after some system library into, for example, the Microsoft Office directory, then just wait until the administrator runs Word, and your code is run with admin privileges!
And how do you get write permission into the Microsoft Office directory?
If you look at the documentation for LoadLibrary, you will see that the application directory does take precedence over all other directories, as you suggested.
The programs in question did
SetCurrentDirectory("somewhere");
LoadLibrary("somelibrary.dll");
and expected somelibrary.dll to be loaded from the "somewhere" directory, overriding the matching library in the system32 directory. Perhaps you find it hard to believe, but it’s true nonetheless. I remember one meeting where this was the primary topic on the agenda.
7/2/2004 2:47 PM Raymond Chen
> Starting in Windows XP SP1, the current
> directory is searched *after* system
> directories. This change was made with much
> trepidation because some very popular
> programs relied on the old behavior, but
> security trumps compatibility.
This is rather hard to believe. Surely popular programs rely on loading DLLs that are located in the same directory where the EXE is located. The old behavior only happened to work for them usually, because the current directory is the same directory where the EXE is located usually.
If the rule were changed to give priority to the directory where the EXE is located (or more precisely, the directory where the invoker is located, since the invoker might also be a DLL and might have been loaded by its own full path), then surely this would obtain security plus 99% backward compatibility?
As for whether the current directory is included at all, maybe there should be an option to enable it last (after the invoker’s directory and system directories) because maybe some abnormal people such as developers might need it for some reason. Otherwise, maybe security should trump the other 1% of backwards compatibility and the current directory shouldn’t even be searched.
"And how do you get write permission into the Microsoft Office directory? "
‘cos you’re a Power User?
If you’re a Power User there are even easier ways to attack the administrator account than this roundabout DLL thingie. For example, just change the default handler for DOC files to be your hackorama.exe.
7/4/2004 11:13 PM Raymond Chen
> The programs in question did
> SetCurrentDirectory("somewhere");
> LoadLibrary("somelibrary.dll");
[…]
> Perhaps you find it hard to believe
No, that example does make it believable. I can half-imagine a program doing this in order to invoke some other program, maybe another program included in some suite, or maybe invoking a plug-in.
Since backward compatibility is being broken in a documented manner, it might still be better to drop the current directory entirely from the search path. Old programs don’t only get broken immediately by this change, some will break in the future when other random DLLs in the system32 directory get added or renamed. And changes to the contents of the system32 directory might happen not only from future Windows changes, but from installing or changing other random applications. It would be better for programmers to find out now that their use of the current directory is no longer reliable.
It’s a balancing act. It seems, Norman, that your approach is to say that "All the thousands of programs that do this (some of them EXTREMELY popular) are hereby declared broken. If your company was relying on one of these programs, then you’re screwed." That’s great for security but doesn’t make you many friends among your 100 million customers.
Raymond, they wouldn’t be declared broken, they would be declared incompatible with the newer version of the operating system. The customers can still keep using the older version.
So customers who were using these programs would stay with the original version of XP instead of upgrading to SP1? They would miss out on all the security fixes then.
Funny things also happen when you place an executable file name winlogon.exe into a directory and set the directory in the PATH env. variable to be searched first.
You will get a mysterious bootup blue screen without any apparent reason. Happened to me once I set up a new computer. :)
7/6/2004 11:30 AM Cesar Eduardo Barros
> Raymond, they wouldn’t be declared broken,
> they would be declared incompatible with the
> newer version of the operating system.
Bingo, thank you for explaining it.
7/5/2004 9:49 PM Raymond Chen
> but doesn’t make you many friends among your
> 100 million customers.
That has never been a concern of Microsoft. Each version of Windows is already broken in so many ways by itself, things like this are trivial by comparison. Document the change, conform to the document, and you’ll be a lot farther towards friendship than your company’s past and present practices.
7/6/2004 11:55 AM Raymond Chen
> So customers who were using these programs
> would stay with the original version of XP
> instead of upgrading to SP1? They would miss
> out on all the security fixes then.
More or less the same as customers who miss out on security fixes for six months, being the interval between discoveries of flaws and patches being available on Windows Update. Fortunately the patches on Windows Update tend to add fewer new bugs than SPs do, while usually finally providing the security improvements that they’re intended for.
It must be admitted that Windows XP SP1a didn’t add many new bugs, it just left most of Windows XP’s existing bugs unchanged. But how did Windows XP Explorer get to be so much buggier than Windows 2000 Explorer? How did Windows XP’s USB floppy disk driver get to cause blue screens when Windows 2000’s didn’t? How did Windows 2000’s video drivers get to cause blue screens when Windows NT4’s and 98’s didn’t? How did Windows 98 Second Edition fdisk get to be broken after Windows 98 First Edition fdisk could reliably create partitions (though even that one wasn’t safe for use in deleting partitions)? For some of these items, Microsoft posted knowledge base articles saying that fixes were developed but not available for download, and Microsoft won’t even listen to requests for these fixes unless victims pay for submitting requests. To repeat, friendship with 100 million Microsoft victims has never been a concern of Microsoft.
Meanwhile, you have an opportunity to make a security improvement.
? Now I’m confused. Then why were you recommending that we break those programs?
Norman, I understand your frustration with the USB floppy disk driver and fdisk, but complaining to me gets you nowhere. I have no influence over those things.
I guess I didn’t emphasize enough how critical some of the affected programs are. We’re talking about progams on the scale of Photoshop and Microsoft Office. (Note: Those are *NOT* the affected programs. I’m just trying to give a sense of scope.) If any update broke Photoshop people would be screaming bloody murder.
7/6/2004 5:36 PM Raymond Chen
> We’re talking about progams on the scale of
> Photoshop and Microsoft Office. (Note: Those
> are *NOT* the affected programs.
Sometimes they are. That’s exactly what Windows NT4 SP4 did, it was only half-fixed in SP5, and it remains broken in Windows 2000 (except for the US version) and Windows 2003 (including the US version). I guess Microsoft really is unaware that sometimes newly added bugs have such critical effects.
> If any update broke Photoshop people would
> be screaming bloody murder.
Yup, some of us have very good reasons for screaming bloody murder. Thank you for your understanding.
7/6/2004 10:16 PM Raymond Chen
> ? Now I’m confused. Then why were you
> recommending that we break those programs?
Microsoft already broke Office 97 for no reason at all (in days when it was supposedly supported i.e. NT4SP4-5-6, along with later days i.e. W2000 except US and W2003 including US). Microsoft did not care about making friends or avoiding screams of bloody murder. Microsoft did not and does not care enough to fix these things, and usually no one else has the power to do so.
But when there is a reason, i.e. security, for doing something that might cause comparable breakage, then Microsoft suddenly pretends to care about making friends and avoiding screams of bloody murder. Some additional breakage is avoided, while the original breakage remains and security is not obtained. This backwards attitude does not really buy friends and does not reduce the reasons for crying bloody murder.
When a change is documented (and documented correctly) developers usually do have the power to cope with it. Maybe even the support web site for Photoshop would announce a workaround for old versions, i.e. copy such and such DLL from so and so directory to the system32 or system directory.
By the way, everyone knows that Mr. Chen has no control over drivers and fdisk and many apps. Most screams of bloody murder concern Microsoft not Mr. Chen personally. But Mr. Chen personally says that people should not blame Microsoft for problems like broken drivers and broken applications. Therefore I point out the seriousness of broken Microsoft drivers and broken Microsoft apps and the refusal of fixes for them, and we are correct to blame Microsoft.
Go ahead and blame Microsoft for its own broken drivers and broken applications. Bear in mind however that complaining to me won’t accomplish much, though perhaps it may make you feel better.
Norman, you say "That has never been a concern of Microsoft". I remember you having read this weblog for a while now just as I have. And somehow I got quite the opposite impression from Raymond’s postings.