Didier Stevens

Wednesday 19 October 2011

LoadDLLViaAppInit 64-bit

Filed under: My Software — Didier Stevens @ 16:47

Many of my security tools are DLLs. If you want to use these tools inside a 64-bit process, you’re stuck, because you can’t use 32-bit DLLs inside a 64-bit process (and vice versa).

LoadDLLViaAppInit is a tool I released to load DLLs inside selected processes. If you want to use this 32-bit version of LoadDLLViaAppInit on a 64-bit Windows machine, you need to configure AppInit_DLLs in this registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows

You also need to copy LoadDLLViaAppInit.dll in this directory: C:\Windows\SysWOW64

Today I’m releasing a 64-bit version of LoadDLLViaAppInit: LoadDLLViaAppInit64.dll. This will help you to load DLLs inside 64-bit processes.

This 64-bit version has to be installed and configured just like its 32-bit version on a 32-bit OS: you copy the DLL in directory C:\Windows\System32 and you configure the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows

The configuration file is LoadDLLViaAppInit64.bl.txt.

This 64-bit version has only been tested on 64-bit Windows, not on 64-bit XP neither on 64-bit Windows Server. I expect it to work on these systems too, but you need to test first. I’ve also compiled this 64-bit version with Visual Studio 2010 and an option to include the runtime Visual C++ libraries inside the DLL, so you don’t need to install the Microsoft Visual C++ 2010 Redistributable Package. But this option has a drawback: when Microsoft releases a patch for the libraries, I (or you) will have the recompile the DLL with the new version of the libraries.

LoadDLLViaAppInit64_V0_0_0_1.zip (https)
MD5: 94C38717690CE849976883FFE4B22CA1
SHA256: 447C8F61A6398CBE6BD5E681FCE28C55D426D4E4EA49BBE367AE5B334B073A55

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.

Monday 17 October 2011

Quickpost: Some Windows 8 Observations

Filed under: Quickpost,Windows 8 — Didier Stevens @ 20:36

I assume you know Microsoft released Windows 8 Developer Preview.

1) The UserAssist registry keys still exist, and still use ROT13 encoding:

Notice that there are also entries for the launching of Metro apps (e.g. alarms).

But there are also a couple of extra keys, I’ll analyze them when more definitive versions of Windows 8 are released:

2) My USBVirusScan tool still works.

3) The AppInit_DLLs registry key still exists:

4) And the SafeBoot keys also still exists, but Safe Mode (F8) has a Metro-style GUI.

Saturday 15 October 2011

TaskManager Runs on 64-bit Excel

Filed under: My Software — Didier Stevens @ 11:21

I’m releasing a new version of TaskManager.xls that runs on Excel 2010 64-bit too. The previous version ran on 64-bit Windows, provided you used Excel 32-bit. But this new version runs on both implementations of Excel.

TaskManager_V0_1_0.zip (https)
MD5: 5ED2AB6036CA94FAC7DEE5352718D07C
SHA256: EBCF4832C4DBAB0AFE778E19423EBB56CA4644DA1FDB5B2EB1BB4C27A26DB18C

Saturday 8 October 2011

Update: USBVirusScan 1.7.4

Filed under: My Software,Update — Didier Stevens @ 0:00

This new version 1.7.4 adds some extra debug info to the debug option (-d) and adds a new option (-w) to disable WOW64 filesystem redirection.

When USBVirusScan launches the program that was specified as argument upon insertion of a removable drive, it will provide debug information regarding the launching of this program.

In case of failure to launch the program, the debug info will include the error message from the Windows API:

If successfully launched, the debug info will include the process ID of the launched program:

USBVirusScan is a 32-bit application, but it works fine on 64-bit Windows. It can launch 64-bit programs without problems, except Windows’ own applications that come in 32-bit and 64-bit versions. For example, if you configure USBVirusScan to launch calc.exe on 64-bit Windows 7, it will launch the 32-bit version of calc.exe and not the 64-bit version. This is due to the WOW64 filesystem redirection mechanism. USBVirusScan has an option (-w) to disable this WOW64 filesystem redirection (only for USBVirusScan, not for your other programs). Disabling WOW64 filesystem redirection allows USBVirusScan to launch the 64-bit version of calc.exe.

Wednesday 5 October 2011

The Matryoshka Router

Filed under: Networking — Didier Stevens @ 0:00

I had an unpleasant surprise when I connected a new Cisco 887W router I had just configured to the Internet via its ADSL interface.

As it was the first time I worked with a 887, I did an nmap scan of its ADSL interface to check that I had closed all ports. Surprise: ports 2002, 4002, 6002 and 9002 were open. Even bigger surprise: I could logon via telnet to these ports with the default password, although I had changed it…

I’m omitting the details of how I figured out what went wrong, so here is the explanation.

The 887W has a wireless interface. But in this particular router, the wireless interface is not integrated in IOS (that’s Cisco’s IOS, not Apple’s iOS) like in other wireless routers like the 877W. In the 887W, the wireless interface is a service module with its own IOS and configuration. Both devices communicate with each other via a Gigabit interface.

The router IOS can be accesses via the serial console. The wireless IOS not (at least not directly).

To list the installed service modules, you issue the service-module ? command on the router CLI:

  wlan-ap  Service module interface to embedded AP

To access the wireless CLI, you issue the command service-module wlan-ap0 session command on the router CLI, and you get a telnet session on the wireless CLI. After I configured and hardened the wireless IOS, the ports were still open. The service-module wlan-ap0 status command displays the following information:

Service Module is Cisco wlan-ap0
Service Module supports session via TTY line 2
Service Module is in Steady state
Service Module reset on error is disabled
Service Module heartbeat-reset is enabled
Getting status from the Service Module, please wait..

  Image path       = flash:/ap801-k9w7-mx.124-21a.JA1/ap801-k9w7-mx.124-21a.JA1
  System uptime    = 1 day, 6 hours, 0 minutes, 51 seconds

Notice that the session is accessible via the router’s TTY line 2. After I put an ACL on this tty (with the router CLI) to deny all traffic not originating from the internal network, all 4 ports were closed on the ADSL interface.

Another detail good to now: when you are connected to tty2, all ports are closed (because you can have only one session on tty2).

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.

Friday 23 September 2011

simple-shellcode-generator.py

Filed under: My Software — Didier Stevens @ 9:04

To help the attendees of my Brucon White Hat Shellcode workshop, I wrote a new program to generate simple shellcode. I’m releasing it now.

People regularly ask me for malware so they can test their security setup. First, that’s a bad idea, and second, you can do without.

Why is using malware a bad idea? It’s dangerous and not reliable. Say you use a trojan to test your sandbox. You notice that your machine is not compromised. But is it because your sandbox contained the trojan, or because the trojan failed to execute properly? It might surprise you, but there’s a lot of unreliable malware out in the wild.

So how can you reliably test your sandbox without risking infection, or even worse, have malware escape into your corporate network? Just use simple shellcode that creates a file in a location your sandbox should prevent, like system32.

To generate this shellcode with simple-shellcode-generator.py, create a text file (call it createfile.def) with these 2 lines:

kernel32.dll CreateFileA str 0x0 0x0 0x0 0x2 0x80 0x0
kernel32.dll CloseHandle eax

Each line in this definition file instructs the generator to generate assembler code to lookup the address of the WIN32 API function, and to call it with the arguments you provide. The first column defines the dll that contains the function to call, the second column is the actual API function, and the rest are arguments to this function. The arguments you provide are copied literally into the generated assembler code, except for 3 keywords.
Keyword int is used to represent any DWORD, it will result in the generation of a push 0x0.
Keyword str is used to reserve space for a string, and the address of the string is used as argument.
Keyword pint is user to reserve space for a DWORD, and the address of the DWORD is used as argument.

To generate our shellcode, issue this command:

simple-shellcode-generator.py -o createfile.asm createfile.def

This generates the following assembler code:

; Shellcode generated by simple-shellcode-generator.py
; Generated for NASM assembler (http://www.nasm.us)
; https://DidierStevens.com
; Use at your own risk
;
; History:
;   2011/09/23: generated

BITS 32

KERNEL32_HASH equ 0x000D4E88
KERNEL32_NUMBER_OF_FUNCTIONS equ 2
KERNEL32_CREATEFILEA_HASH equ 0x00067746
KERNEL32_CLOSEHANDLE_HASH equ 0x00067E1A

segment .text
	call geteip
geteip:
	pop ebx

	; Setup environment for kernel32.dll
	lea esi, [KERNEL32_FUNCTIONS_TABLE-geteip+ebx]
	push esi
	lea esi, [KERNEL32_HASHES_TABLE-geteip+ebx]
	push esi
	push KERNEL32_NUMBER_OF_FUNCTIONS
	push KERNEL32_HASH
	call LookupFunctions

	; call to CreateFileA
	push 0x0
	push 0x80
	push 0x2
	push 0x0
	push 0x0
	push 0x0
	lea eax, [STRING1-geteip+ebx]
	push eax
	call [KERNEL32_CREATEFILEA-geteip+ebx]

	; call to CloseHandle
	push eax
	call [KERNEL32_CLOSEHANDLE-geteip+ebx]

	ret

%include "sc-api-functions.asm"

KERNEL32_HASHES_TABLE:
	dd KERNEL32_CREATEFILEA_HASH
	dd KERNEL32_CLOSEHANDLE_HASH

KERNEL32_FUNCTIONS_TABLE:
KERNEL32_CREATEFILEA dd 0x00000000
KERNEL32_CLOSEHANDLE dd 0x00000000

STRING1: db "String 1", 0

You can replace “String 1” on line 57 with the file you want to create: “C:\Windows\System32\testfile.txt”.

This shellcode uses the library sc-api-functions.asm you can find in my shellcode repository.

Download:

simple-shellcode-generator_V0_0_1.zip (https)
MD5: 3A6D00C6EBC1F20589C952817174653E
SHA256: FEFD4059810DA7855CC3CBC6A198FD75607C4F7B7B2F71817689E1520B454C58

Friday 16 September 2011

Quickpost: create-remote-thread.py

Filed under: My Software,Quickpost — Didier Stevens @ 15:17

create-remote-thread.py is a new tool I’ll publish after my White Hat Shellcode workshop at Brucon.

It’s a Python program to create a thread in another process (using CreateRemoteThread), and you can specify the API function to execute.

In the example above, I call SetProcessDEPPolicy with an argument of 1 to force permanent DEP on calc.exe

But there are many more uses for my tool.

 

Friday 9 September 2011

DEP Enforcing Shellcode

Filed under: My Software — Didier Stevens @ 7:25

I developed shellcode that enforces permanent DEP when it is injected inside a process:

This is for my Brucon workshop. More details to be posted later.

BITS 32

KERNEL32_HASH equ 0x000d4e88
KERNEL32_NUMBER_OF_FUNCTIONS equ 1
KERNEL32_SETPROCESSDEPPOLICY_HASH equ 0x06f26f66

PROCESS_DEP_ENABLE equ 1

segment .text
	call geteip
geteip:
	pop ebx

  ; Setup environment
	lea esi, [KERNEL32_FUNCTIONS_TABLE-geteip+ebx]
	push esi
	lea esi, [KERNEL32_HASHES_TABLE-geteip+ebx]
	push esi
	push KERNEL32_NUMBER_OF_FUNCTIONS
	push KERNEL32_HASH
	call LookupFunctions

	; Enable permanent DEP in current process
	push PROCESS_DEP_ENABLE
	call [KERNEL32_SETPROCESSDEPPOLICY-geteip+ebx]

	ret

%include "sc-api-functions.asm"

KERNEL32_HASHES_TABLE:
	dd KERNEL32_SETPROCESSDEPPOLICY_HASH

KERNEL32_FUNCTIONS_TABLE:
KERNEL32_SETPROCESSDEPPOLICY dd 0x00000000

« Previous PageNext Page »

Blog at WordPress.com.