We’ve covered ASLR, stack and heap randomization, heap defenses, NX, /GS, and SafeSEH. Unless there are compelling reasons, you need to be using all of these in your application. Here’s what you should be doing:
ASLR Link with the /dynamicbase option
Heap defenses Enable HeapTerminateOnCorrupt
NX Link with /NXCOMPAT
/GS Don’t do anything! Just take the defaults!
SafeSEH Link with /SAFESEH
Use the latest compiler At the very least, Visual Studio 2005 with Service Pack 1–and ensure all of the DLLs the process links with are also compiled with the same compiler and C runtime library.
So, what’s still exploitable with all these overlapping countermeasures in place? Note that there are ways to overcome every one of these mitigations. Overcoming them all at once is a lot harder, but it is still possible. Data-driven attacks should also be considered. As a quick example, say an application would call LoadLibrary on a DLL, and an attacker was able to overwrite the DLL path or name–you’d load the wrong DLL, and call the attacker’s DllMain function. Some of the most prevalent attacks against Web servers don’t involve arbitrary code but attack the logic of the underlying application, and these attacks won’t be thwarted by compiler or linker options. At the end of the day, the only way to get secure code is to write solid code.