Friday, December 21, 2012

Earlier this month, FireEye researchers Abhishek Singh and Yasir Khalid introduced Trojan Upclicker - malware that detects automated sandboxes by hooking mouse movements. If these user interactions never occur, the malware stays dormant, but as soon as someone clicks the left mouse button, it wakes up, injects code into explorer, and proceeds with infection. I recently developed a Volatility plugin for Detecting Hooks in the Windows GUI Subsystem that are installed the same way as Upclicker (SetWindowsHookEx), so I was interested to take it for a test drive. This quickly led to the realization that the malware behind Upclicker's packing is the popular Poison Ivy RAT. Additionally, Cuckoo Sandbox 0.5 was just released, with an option to acquire full memory dumps that are compatible with Volatility's VirtualBoxCoreDump Address Space. In this blog, we'll report our experiences with that new functionality and how the open-source Cuckoo can be modified in a way that forces Upclicker to execute.

Detecting User Interactions

As described by Singh and Khalid, Upclicker used SetWindowsHookEx to install a hook into the windows messaging subsystem. The hook ID was WH_MOUSE_LL (low level mouse operation) and it filtered for wParam WM_LBUTTONUP (left button up). The malware could also have checked for other input event such as the right mouse button, key strokes; or used the GetLastInputInfo API to determine the number of ticks since the last user interaction of either type. This has been known to work with detecting some sandboxes, but not all. The trick is estimating how many ticks indicate a normal user's "idle" time compared to a sandbox environment. If the delta in tick count exceeds several hours, it may very well be a sandbox system, but then again, if the sandbox developer clicked buttons or pressed keys immediately before taking a snapshot, each time the VM is reverted, it resets the last input tick count to the original value (making it seem like a user was just there).

Anyway, a while back I created a simple test program that checked idle time and I uploaded it to various public sandboxes. It needed a way to convey the value back to me though, which it accomplished by just creating a file named according to the number of idle ticks. The sandbox analysis results would identify the name of the newly created file and that's what I looked at for gathering the info. Unfortunately, this was years ago and I've since lost the data, but the code is below if you want to re-test it and I do remember that several sandboxes reported idle times over a week.

To enable memory dumps, edit the conf/cuckoo.conf file and set the memory_dumps field to "on" as shown below:

# Enable creation of memory dump of the analysis machine before shutting# down. Even if turned off, this functionality can also be enabled at# submission. Currently available for: VirtualBox and libvirt modules (KVM).memory_dump = on

As mentioned in the comment, you can leave memory dumps disabled by default and just enable them for a specific submission...but IMO the more memory dumps, the better ;-)

In the case of VirtualBox, the memory dumps are acquired with the dumpguestcore command and are output in the ELF64 core dump format. Volatility parses these files natively starting with 2.3 alpha. Here's the meta-data of the core dump, using the new vboxinfo plugin:

The first time we ran Upclicker in Cuckoo, the results were as expected - no one was there to click the mouse's left button during analysis. Thus there were no dropped files, no mutexes, no modified or created registry values, and it only recorded two API calls from the single Upclicker process:

SetWindowsHookExA is the last API called, because that's when it enters the "waiting" state. As you can see, the HookIdentifier is 14 (0xE) for WH_MOUSE_LL. The ModuleAddress (PE containing the hook procedure) is located at 0x400000. This is a typical ImageBase for the process' executable. The ProcedureAddress (hook function) is at RVA 0x10b0 from the containing PE and the ThreadId was 0 indicating the hook should be applied to all threads in the desktop.

Should you need to validate the API monitor logs, or just analyze the artifacts from a forensic perspective, all of the information should be available in the full memory dump that Cuckoo acquired. To do this, we'll use the messagehooks Volatility plugin:

There you see the proof of Upclicker's hooks as extracted from physical memory. They are HF_GLOBAL hooks (the result of ThreadId = 0) and they filter WH_MOUSE_LL. The hook procedure is at RVA 0x10b0 of the module which is located on disk at C:\DOCUME~1\cooks\LOCALS~1\Temp\ce69dee5307d58db4e2a6fdbcbf87e9d. This is the binary submitted to Cuckoo - which the sandbox extracts to a temporary directory before executing.

Patching Cuckoo Sandbox

Cuckoo 0.5 is the first version of the framework that I've downloaded and installed. And its been out less than 12 hours, so admittedly I haven't explored much of the code. I did manage to find the analyzer/windows/modules/packages/exe.py file which contains the package for handling executable PEs submitted to the sandbox. I modified the Exe class's start() method such that it sleeps a few seconds after executing the Upclicker process (to allow the SetWindowsHookExA API to finish), then it uses mouse_event to send a MOUSEEVENTF_LEFTUP signal (the left mouse button is up). This should trigger the malware's trap for user interactions and force it to follow through and infect the system.

As mentioned in the comment, the Exe package's start() method is undoubtedly the wrong place to put code like this, unless you want it to send a mouse event for all your submissions. But, until I've spent more time getting familiar with the source layout, it'll have to do ;-)

The second time we ran Upclicker in Cuckoo, the results were much different. First, you can see the signatures detected a new Windows executable was created (dropped) by the malware:

The behavior analysis shows the created file(s). First the submitted sample itself (in the temp directory), then the dropped file named MCPUPlayer.exe which is attached to the system32 directory as an alternate data stream. You also can see the names of the new mutex and registry keys.

The API monitor logs were also expanded to include explorer.exe this time, since Upclicker was allowed to inject code into explorer.

Here's a look at Upclicker actually performing the injection:

Now looking at explorer.exe's API calls, you can see it creates an Internet Explorer instance and then injects more code into the IE process.

Hopping from one process to another with code injection isn't anything new. Zeus did it way back in 2006 (and probably was not the first). Next, we'll explore how that appears in memory.

Unpclicker Drops Poison Ivy

Curiosity killed the cat, or curiosity connected the dots - I can't remember what the real saying is. Using Volatility on the memory dump of the infected VM, you can see IEXPLORE.EXE is pid 1740.

If there's injected code, we should be able to find it pretty easily. In fact, the malfind plugin located 20+ suspicious segments of memory - each which contain what looks like the beginning of a function.

Based on the VirusTotal results supplied with Cuckoo's analysis, only Trend Micro identified the Upclicker sample as Poison Ivy (BKDR_POISON.BNE). The other 44 engines either failed to detect anything (22/45 ratio) or identified it as a generic backdoor.

Conclusion

Now that you've reached the end, you know that Trojan Upclicker is a wrapper/packer that in this case transmitted Poison Ivy as its payload. Cuckoo Sandbox can be easily modified to fit your analysis needs, even if you're a first time user. Starting with 0.5, it can be configured to acquire full memory dumps - thus it gets along quite nicely with Volatility's new VirtualBoxAddressSpace for those who wish to go deep diving in memory after an infection. You've also seen some recent malware leveraging the GUI subsystem to further its malicious intentions, which is always exciting.

Wednesday, December 12, 2012

I'm a big fan of Dexter. As I recently mentioned during an impromptu discussion with our first group of memory analysis training attendees, if there are only a few minutes left in an episode and he hasn't killed anyone yet, I start getting nervous. So when I heard there's malware named dexter that has also been "parsing memory dumps" of specific processes on POS (Point of Sale) systems, I was excited to take a look. How exactly does this memory dump parsing occur? Is it scanning for .vmem files on an infected VM host? Maybe walking directories of network shares to find collections of past memory dumps taken by forensic teams? Perhaps acquiring a crash dump or mini-dump of the POS system itself? Turns out its none of the above, and the memory dump parsing is just a ReadProcessMemory loop, but figuring that out was nonetheless a textbook example of how to use Volatility in a reverse-engineering malware scenario.

Getting started in the typical way, you can see dexter is packed. There are PE sections named .conas, .ts10, .ts20, .ts30, .ts40, and .ts50; suspiciously named exports like RenameHerbal, RenameFortation, and LoadMemberData; only two imported APIs - GetKeyboardState and GetSystemWindowsDirectoryW; and roughly 10% of the file is recognized by IDA as executable code (the rest is compressed/packed data).

If you needed further proof, you could check the strings:

$ strings -a ~/Desktop/dexter.exe

!This program cannot be run in DOS mode.

IRich,

.text

`.conas

.const

@.data

.ts050

@.ts040

@.ts030

@.ts020

@.ts010

iopiio

worG

uNqkObyOqdrSDunixUVSmOFucsNpJUJKkmpmqlUW

FvlLutksfHVJWIzigOJfTfFRxxUmwtdRKhmgjhdiXlSq

TZJ_QaVg_vGB

OWMu_wWH_EHz

SOU_GTUQ

PSOsqo_Jk

GetKeyboardState

USER32.dll

GetSystemWindowsDirectoryW

KERNEL32.dll

C:\Debugger.fgh

,vr1

rnyCsipvZnUURpjurWxiRqgauylOKfl3J

owz{

tjpudajfQwdBCBGAtjpcrTlenAyHMz

nuymGmpBownDvVIErgffsrBxQskLJu

zn|c

p}mOPSJqtFxbQlmrSPiThjdwfHxndtrP

ModuleReplace.exe

LoadMemberData

Nothing too interesting there. If we're going to understand how this malware parses memory dumps, we'll need to unpack it first. There's the manual option of finding OEP, dumping a sample with OllyDbg or LordPE, and fixing imports with ImpREC (or something similar), but I try to save that more time consuming and technical approach for when its really needed. In the case of dexter, and a majority of malware these days, all you need to do is run it and let it unpack itself. Being lazy never felt so good!

After copying the malware to a VM, it was executed and resulted in the creation of two new Internet Explorer processes. The code has to persist on the system in some way, so if the process (dexter.exe) doesn't stay running itself, you can bet it dissolves (i.e. injects) into another process. A reasonable first guess of the targets would be the two new IE instances: pids 1480 and 820.

Now back in Volatility, working with the suspended VMs memory file, let's list processes just to orient ourselves with this new perspective:

The next thing I did since code injection was suspected is run malfind on the two IE pids. It located two memory segments - one in each IE process, same base address in both (0x150000), same protection (PAGE_EXECUTE_READWRITE), and according to the hexdump there's an MZ header at the base of the region.

Now that we've quite effortlessly identified where the unpacked code is hiding, let's dump it out of memory. We'll use the dlldump plugin for this. Although the PE at 0x15000 isn't necessarily a DLL, the dlldump plugin allows the extracting/rebuilding of any PE in process memory if you supply the --base address (which we know).

For a quick understanding of how effective this approach can be in unpacking malware, take a look at the strings now:

$ strings -a dexter/module.1480.1b27558.150000.dll

!This program cannot be run in DOS mode.

.text

.data

.rsrc

wuauclt.exe

alg.exe

spoolsv.exe

lsass.exe

winlogon.exe

csrss.exe

smss.exe

System

explorer.exe

iexplore.exe

svchost.exe

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

SeDebugPrivilege

NTDLL.DLL

NtQueryInformationProcess

/portal1/gateway.php

11e2540739d7fbea1ab8f9aa7a107648.com

7186343a80c6fa32811804d23765cda4.com

e7dce8e4671f8f03a040d08bb08ec07a.com

e7bc2d0fceee1bdfd691a80c783173b4.com

815ad1c058df1b7ba9c0998e2aa8a7b4.com

67b3dba8bc6778101892eb77249db32e.com

fabcaa97871555b68aa095335975e613.com

Windows 7

Windows Server R2

Windows Server 2008

Windows Vista

Windows Server 2003 R2

Windows Home Server

Windows Server 2003

Windows XP Professional x64

Windows XP

Windows 2000

32 Bit

64 Bit

http://%s%s

Content-Type:application/x-www-form-urlencoded

POST

Mozilla/4.0(compatible; MSIE 7.0b; Windows NT 6.0)

LowRiskFileTypes

Software\Microsoft\Windows\CurrentVersion\Policies\Associations

rpcrt4.dll

gdi32.dll

wininet.dll

urlmon.dll

shell32.dll

advapi32.dll

user32.dll

IsWow64Process

WindowsResilienceServiceMutex

Software\Resilience Software

Software\Microsoft\Windows\CurrentVersion\Run

.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

UpdateMutex:

response=

page=

&ump=

&opt=

&unm=

&cnm=

&view=

&spec=

&query=

&val=

&var=

DetectShutdownClass

download-

update-

checkin:

scanin:

uninstall

The strings output shows a list of process names, which makes sense - the Seculert Blog mentioned that it enumerates processes. You also see it references SeDebugPrivilege, likely for the ability to call OpenProcess and read/write the memory of other processes. The ABCDEF[....] is a base64 alphabet, so you can expect it to encode some or all of the data it POSTs to gateway.php on one of the randomly named .com domains. It would create the WindowsResilienceServiceMutex and make a run key in the Software\Resilience Software registry key.

To solve our real question - how does this malware parse memory dumps - we need to open the unpacked file in IDA. Its import table is already fixed up, so aside from switching the ImageBase value in the PE header so RVAs are interpreted correctly by IDA, we're done unpacking before we even really started. A quick look through the unpacked file's IAT shows it calls ReadProcessMemory, and cross-referencing that leads to one function, shown below:

What you see here is the "memory dump parsing" function. It iterates once for each active process on the system, calling OpenProcess() to obtain a handle, then using VirtualQueryEx() to determine which memory ranges are accessible to the process, and reading them into a local buffer with ReadProcessMemory(). The data is then passed off to two scanning sub-functions which do the real work of deciding which data to steal from the buffer.

In summary, though I'm slightly disappointed that the memory dump parsing function is just a ReadProcessMemory() loop, at least I didn't waste much time getting there. Unpacking the malware by leveraging Volatility was as easy as 1-2-3. Lastly, since some of our students in the Windows Memory Forensics training requested videos of common ways we use Volatility, here's an initial example in quicktime format showing the steps described in this blog: http://www.mnin.org/dexter.mov.zip.