Didier Stevens

Tuesday 18 October 2011

HeapLocker: Preventing Heapsprays

Filed under: My Software,Vulnerabilities — Didier Stevens @ 8:34

I’ve been using my HeapLocker tool for almost a year now, and I’ve encountered no issues, except for the NOP sled detection. When used with Adobe Reader, HeapLocker will generate too many false positives when looking for NOP sleds. So I’ve disabled NOP sled detection for Adobe Reader.

The last feature I want to talk about is heap spray mitigation.

Like EMET, HeapLocker can pre-allocate memory pages so that they can’t be used by the heap. And this renders a heap spray useless, as it will not be able to inject shellcode at the addresses HeapLocker protects. But unlike EMET, HeapLocker has 2 modes of pre-allocating memory pages. The first mode is just like EMET, while the second mode will write special shellcode to the pre-allocated pages. When this shellcode is hit due to an exploit, it will callback to HeapLocker which will suspend all threads and display a warning dialog. This is what you see in the video. There are 2 advantages to this mode: the user is warned that she opened a malicious document, and you can also use this in a malware lab to find out which address the exploit is hitting.

To prevent the HeapLocker shellcode from being used for ROP exploits, I randomized the injected NOP sled and shellcode. But if you still find this too risky, just use the standard mode for pre-allocating pages.

For more details about the exact way to configure this, read the documentation found in the HeapLocker download.

FYI: I’m also working on a 64-bit version of HeapLocker.

Thursday 29 September 2011

Add Bottom Up Randomization To (Your Own) Source Code

Filed under: Vulnerabilities,Windows 7,Windows Vista — Didier Stevens @ 19:14

EMET’s new Bottom Up Randomization spectacularly increased the entropy of DLL’s base addresses loaded into my test program. Instead of 15 different addresses, I had more than 200.

Matt Miller told me how he implemented Bottom Up Randomization:

“It works by reserving a random number (between [0,256]) of 64K regions via VirtualAlloc. This has the effect of consuming a small portion of the bottom part of the address space. Since the Windows kernel assigns base addresses for collided DLLs by searching for a free region starting at the bottom of the address space, bottom up randomization ensures that a random base address will be assigned. Without bottom up randomization the bottom part of the address space remains fairly static (with some exceptions, such as due to heap, stack, and EXE randomization).”

So I decided to add this algorithm at the start of my test program:

int iIter;
int iRand;

srand(time(NULL));
iRand = rand() % 256 + 1;
for (iIter = 0; iIter < iRand; iIter++)
 VirtualAlloc(NULL, 64*1024, MEM_COMMIT | MEM_RESERVE, PAGE_NOACCESS);

Again, the result is spectacular. In stead of 15 base addresses, with the most frequent address being using 30% of the time, my Bottom Up Randomization implementation gives me more than 300 addresses after 150.000 runs. And there’s no single address being used more than 0,5% of the time.

From now on, I’m going to include this in my programs, and I advise you to do the same with your programs. Or to open source programs you use.

Thursday 1 September 2011

Bottom Up Randomization Saves Mandatory ASLR

Filed under: Vulnerabilities,Windows 7,Windows Vista — Didier Stevens @ 17:32

I recently found out that pseudo-ASLR (or mandatory ASLR in EMET) has a lower entropy than real ASLR. While real ASLR has a 8-bit entropy for base addresses, mandatory ASLR turned out only to have about 4 bits of entropy, and the distribution was far from uniform. What I forgot to tell you in that post, is that I just enabled Mandatory ASLR as mitigation in EMET, and nothing else:

Matt Miller told me that a new feature of EMET version 2.1, Bottom Up Randomization, would greatly improve the entropy of mandatory ASLR.

The results are spectacular. When I let my test program run around 500,000 times, I get almost 200 different base addresses. And the distribution is more uniform too, no address appears more frequently than 3% of the time.

To get decent protection from mandatory ASLR, be sure to use the latest version of EMET (2.1) and enable Bottom Up Randomization. This gives you the same entropy than real ASLR, with the added bonus that the base address will change each time the application is started, compared to real ASLR which requires a reboot.

Tuesday 16 August 2011

So How Good is Pseudo-ASLR?

Filed under: Vulnerabilities,Windows 7,Windows Vista — Didier Stevens @ 0:29

Let me first define what I mean with pseudo-ASLR. Address Space Layout Randomization (introduced in Windows Vista) loads executable files at different memory addresses. Studies have shown that ASLR uses 256 different base addresses and that the distribution is pretty uniform.

Pseudo-ASLR is what EMET and my tool SE_ASLR enforce. When a DLL does not support ASLR, memory at the base address of this DLL is allocated right before the DLL is loaded into the process. Since the address is not free, the image loader will load the DLL at a different address, thereby « randomizing » the base address. But how good is this randomization?

As I pointed out in my article on EMET, this base address is different each time a new process is started (unlike ASLR which needs a reboot for the base address to change). So maybe this is better ?

I developed a test program that loads a DLL but pre-allocates memory at the address of the DLL before loading. Then I ran that program thousands of times on a Windows 7 32-bit machine.

Running this program about 50.000 times gives me 68 different addresses. That’s by far not as good as 256 with ASLR. But what’s more important, is that the distribution of these addresses is not uniform at all:

There’s one address (0x000E0000 in my test) that is used 30% of the time. 2 other addresses are used 10% of the time. Rebooting the machine does not change this distribution.

When I do the same test, but enforce ASLR with EMET, I get a similar result:

Again there’s an address that is selected 30% of the time, but it’s different from my previous test. Rebooting the Windows 7 machine doesn’t change the address.

In this test, EMET uses only 15 different addresses, compared to the 68 addresses in the first test. I’ll have to research this difference, I’ve no explanation for it.

Conclusion from this simple test: pseudo-ASLR is rather weak, because I can predict the base address and I will be right one time out of three, which is not bad at all when I can launch my attack several times.

Wednesday 10 August 2011

Force “ASLR” on Shell Extensions

Filed under: My Software,Vulnerabilities — Didier Stevens @ 0:49

I’ve written about Shell Extension without ASLR support before.

Not only do they open up explorer.exe to ROP attacks, but other applications too, like Adobe Reader and Microsoft Office.

You could use EMET to force ASLR on these DLLs, assuming you know which applications load shell extensions. Because shell extensions are not only loaded into explorer.exe, but other programs too, I wrote a tool to force Shell Extension DLLs to load at another address than their base address, effectively simulating ASLR.

When my tool, SE_ASLR.dll, is loaded into a process, it will check for the presence of comdlg32.dll inside the list of loaded modules. When comdlg32.dll is used by an application, the likelihood of shell extensions being loaded into the process by user interaction with the file dialogs is significant.

Hence SE_ASLR will patch the IAT to intercept calls to LdrLoadDll. Each time the application loads a DLL (all DLLs, not only shell extension), SE_ASLR will check if the DLL supports ASLR. If it doesn’t, SE_ASLR will pre-allocate a memory page at the base address of the DLL, thereby forcing the loader to load the DLL at another address.

Although SE_ASLR’s primary goal is to relocate shell extensions, it will effectively relocate all DLLs without ASLR support once SE_ASLR is loaded into the process.

You need to load my tool into all applications that could use shell extension, for example via the AppInit_DLLs registry key. But before you do, be sure to test this out on a test machine. Not all shell extensions support relocation.

SE_ASLR_V0_0_0_1.zip (https)
MD5: 9D6AE1A96D554AEE527EB802FE59FB20
SHA256: 8A6C1406A757CD9788A2630D76A497E2C058333EE4D44CA0B85B2A05A39F257E

Wednesday 22 June 2011

Quickpost: Need a PoC to Test Your Security Setup? Not Necessarily…

Filed under: Quickpost,Vulnerabilities — Didier Stevens @ 13:30

People regularly ask me for a PoC (PDF or other type) to test their security setup. For example, they sandboxed Adobe Reader and now they want to test that Adobe Reader can’t write to sensitive Windows directories like system32.

Well, you don’t need a PoC to test your setup in this way. Just develop and compile a DLL that writes to system32, and inject it in the target process.

The problem however, is that not everybody has the skills to develop and compile such a DLL. But almost everybody can write a VBScript that accomplishes the same. Here’s a one-liner that creates test.txt in system32:

CreateObject("Scripting.FileSystemObject").CreateTextFile("c:\windows\system32\test.txt")

But how do you get the target process to execute this script? That is something I worked out 2 years ago: bpmtk: Injecting VBScript. In a nutshell: I developed a DLL that once injected into a process, instantiates a VBScript engine and executes the provided script.

Monday 13 June 2011

EMET Article

Filed under: Vulnerabilities — Didier Stevens @ 0:00

(IN)SECURE Magazine published my article on Microsoft’s Enhanced Mitigation Experience Toolkit.

It contains many details I’ve yet to discuss on this blog.

 

Monday 14 March 2011

HeapLocker: Null Page Allocation

Filed under: My Software,Vulnerabilities — Didier Stevens @ 5:03

Just like EMET, HeapLocker can allocate a page at address 0 (null or 0x00000000) to mitigate null pointer dereferencing.

I actually implemented this code in HeapLocker because I wanted to find out how one can allocate a page at address 0. You see, when you call VirtualAlloc with address 0, VirtualAlloc will allocate a page at an address chosen by VirtualAlloc, and not at address 0. So I would think that the trick is to call VirtualAlloc with address 1, and that VirtualAlloc will allocate a page that contains address 1, and that this page must start at boundary 0.

But the problem is that you get an error when you try to allocate a page at address 1 with VirtualAlloc. Ivanlef0u explains this in his blogpost (French). VirtualAlloc rejects addresses inferior to 0x1000, one must use NtAllocateVirtualMemory to successfully allocate address 1.

Friday 18 February 2011

HeapLocker: String Detection

Filed under: My Software,Vulnerabilities — Didier Stevens @ 12:43

A third protection technique I implemented in HeapLocker is string detection.

When you enable string monitoring, HeapLocker will create a new thread to periodically check (every second) newly committed virtual pages that are readable and writable. When a specific string (configured in the registry) is detected inside these pages, HeapLocker will suspend all threads (except this monitoring thread used by HeapLocker) and warn the user that the string was detected.

I’ve had very good result with this technique searching for string “unescape” in Adobe Reader (the string “unescape” must be preceded by an equal sign or followed by a left parentheses). Almost all malicious PDF documents in my collection were detected by this. But like NOP-sled detection, it’s not 100% reliable. Sometimes HeapLocker will scan a page before the string “unescape” has been written to that page.

Tuesday 25 January 2011

Circumventing SRP and AppLocker to Create a New Process, By Design

Filed under: Vulnerabilities — Didier Stevens @ 0:00

There’s an interesting comment on my Circumventing SRP and AppLocker, By Design post.

In my previous post, I showed a feature to circumvent SRP and AppLocker validation when a DLL is loaded.

The anonymous commenter points out a feature to create a new process, while circumventing SRP and AppLocker. Flag SANDBOX_INERT in function CreateRestrictedToken allows you to do this.

Per MSDN:

If this value is used, the system does not check AppLocker rules or apply Software Restriction Policies. For AppLocker, this flag disables checks for all four rule collections: Executable, Windows Installer, Script, and DLL.

When creating a setup program that must run extracted DLLs during installation, use the flag SAFER_TOKEN_MAKE_INERT in the SaferComputeTokenFromLevel function.

I wrote a small program to test this:

HANDLE hToken;
HANDLE hNewToken;
PROCESS_INFORMATION sPI;
STARTUPINFO sSI;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
	if (CreateRestrictedToken(hToken, SANDBOX_INERT, 0, NULL, 0, NULL, 0, NULL, &hNewToken))
	{
		memset(&sSI, 0, sizeof(sSI));
		sSI.cb = sizeof(sSI);
		if (CreateProcessAsUser(hNewToken, L"c:\\test\\Dialog42.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sSI, &sPI))
		{
			puts("process created");
		}
}

This program starts another program, Dialog42.exe. I’ve configured SRP with a whitelist, Dialog42.exe is not whitelisted:

But when I use my program with the SANDBOX_INERT flag to start Dialog42.exe, it is allowed to run:

« Previous PageNext Page »

Blog at WordPress.com.