12

One of the challenges with deploying ASLR for everything is that, at least on Windows, some DLLs (libraries) are not compiled in a way that's compatible with ASLR. (They're not compiled as position-independent code, and so the place where they are loaded in memory cannot be randomized.)

This is problematic, because if an application loads even just one non-randomized DLL, then it is effectively not randomized. To stop standard attacks (e.g., ROP attacks), all the code has to be randomized: even a single non-randomized DLL is enough of a foothold that ROP attacks can become possible. So, to a first-order approximation, ASLR is only useful in protecting a particular application if all of its DLLs are randomized. Applications often load many DLLs, and since all it takes is one non-randomized DLL, this makes it especially important to ensure that all DLLs are randomized.

Generally, the industry is moving towards increased use of randomization, but slowly: I guess it takes time to bring this to every DLL any program will ever use. For instance, it was recently revealed that the Dropbox DLL does not use randomization, so any program that uses the Dropbox DLL is not protected against ROP attacks (any program that uses the Dropbox DLL loses the benefit of ASLR).

My question: What are the typical reasons why some DLLs are not randomized? Is it typically some sort of technical barrier or technical issue that makes it difficult or impossible to compile the DLL as position-independent code? Is it lack of awareness/attention to security, on the part of the developers building the DLL? Is it legacy DLLs that are very old and haven't been recompiled to take advantage of randomization? Does Microsoft Visual C++ fail to do the right thing by default (does it fail to compile DLLs as position-independent code by default)? Is it something else entirely?

Are there any technical advances or tools that would help facilitate greater deployment of ASLR/randomization for DLLs that currently don't support randomization?

Related resources: SlopFinder is a tool to scan your system for DLLs that don't support ASLR.

D.W.
  • 98,420
  • 30
  • 267
  • 572
  • To combat problems like this you can try using EMET 4.0 from microsoft which forces things like DEP among other things on programs you select. I only came across it recently but i added my usual favourite programs and havent observed any issues. – NULLZ Sep 11 '13 at 22:10
  • 1
    Windows doesn't need normal PIC to load dlls at other addresses. It's enough if it has a table which describes which pieces to modify when the dll gets loaded at a different address (called relocation info). Traditionally that ability was used to move one dll when the default base-address collided with an already loaded dll. A bit annoying that ASRL requires additional opt-in, even when relocation info is available. – CodesInChaos Sep 12 '13 at 07:12
  • Fascinating! Thank you, @CodesInChaos. Does anyone know why Windows requires additional opt-in? (Would anything go wrong if we just pretended as though all DLLs had opted in? Is there a compatibility risk? Would things break? If so, why? i.e., from a technical perspective, what constructs could cause it to break?) – D.W. Sep 12 '13 at 16:44

1 Answers1

9

There is some good information here. Apparently, a DLL can be subject to ASLR only if it is tagged as such, because of "backward compatibility issues". Although a DLL is, by nature, meant to be relocated, I can imagine that some (poorly) written software may do some tricks which rely on the DLL ending up in a relatively small range of the address space (a possible candidate would be some Garbage Collector that needs to distinguish between "pointers to data" and "pointers to code" -- I know that such issues occurred with some versions of Chrome's Javascript interpretor when launched on OpenBSD with Linux emulation).

If Microsoft went to the trouble of implementing an additional flag, then it is plausible, if not probable, that they encountered at least one case of such software that they could not ignore (backward compatibility is very important in the Windows world).

So DLL will allow ASLR to happen if the static linker said so, when the DLL was last built. This is a matter of using the /DYNAMICBASE flag. The documentation states that:

By default, /DYNAMICBASE is on.

The documentations for Visual Studio 2010 and 2012 contain this sentence, but NOT the documentation for Visual Studio 2008. So one has to assume that most people who use Visual Studio 2010+ produce ASLR-compatible DLL, but most people who use Visual Studio 2008 or a previous version produce DLL which are not subject to ASLR.

In the page I first link above, one of the comments says:

You can still use the Microsoft linker to do that, after your PE image is built. Use link /edit /dynamicbase (or editbin /dynamicbase ).

So you can "fix" a DLL, but that's assuming that the DLL will not break with ASLR, i.e. the lack of flag was just due to the default configuration of Visual Studio, as used by the DLL vendor.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • Apparently, with Windows 8 and [HiASLR](http://security.stackexchange.com/q/23638/971), you might also want to specify `/HIGHENTROPYVA` in addition to `/DYNAMICBASE` to ensure you get the full benefits of HiASLR (high-entropy ASLR). I can't tell if/when this flag is actually needed, though. Mentioning this as a public service to others who may stumble across this. – D.W. Jun 04 '14 at 18:33