Saturday, January 20, 2007

Windows Memory Forensics, Part 1

Despite my earlier bold claims that I'd be doing more analysis of "Big Yellow," I'm going to have to renege for now. At work, we recently came across a user who was trying to connect to an external IP upwards of a thousand times per day; some investigation showed that his machine had been compromised by a trojan, and so we started in on incident response. This has left me with very little time to look at Big Yellow, but it did give me something new to write about--Windows memory forensics.

Our first response was to get the user to run a cool little bundle that my friend Andy and I have been working on that collects as much forensically important information from the user's system as possible and uploads it to a server using Webjob. The package includes a bunch of Sysinternals tools, ftimes to get file hashes and search for specific strings, and a version of dd from the Forensic Acquisition Utilities that can dump physical memory. This last bit is what we'll focus on in this article--extracting useful information from a dump of Windows memory. In this first part, I'll deal with what information can be gotten with traditional utilities, and introduce ftimes and XMagic, which, together, can be used to do some really powerful stuff.

The most obvious thing to do is just grep through the raw dump for anything you might be looking for (in our case, we had the domain name of the site that the user was continually attempting to contact), or run strings on it and browse through to see what piques your interest. The nice thing about memory is that things nearby each other in the dump are often (though not always) owned by the same process, and hence related. So if you see, a few bytes away from "evil-hacker.net", a file in the Windows directory that isn't supposed to be there, you might want to investigate it more thoroughly.

Even more powerful things can be done using ftimes (part of the Integrity project). In its "dig" mode, it will go over a file or set of files and search for strings according to criteria you specify. It can search for plain strings (DigStringNormal), regular expressions (DigStringRegexp), or XMagic patterns (DigStringXMagic). Included in the ftimes tarball is a script called hipdig.pl that has several useful predefined regular expressions, including hostnames, IP addresses, password hashes, and a lot more. These can help cut down on the amount of data you have to sift through to get to the stuff that you really need, and time is often critical during incident response.

The coolest part of ftimes in dig mode, by my reckoning, is the ability to dig for XMagic patterns. XMagic is an updated and extended version of the patterns used by the venerable UNIX file(1) command, which are known as "magic". XMagic adds some powerful features to traditional magic, including tests for various cryptographic hashes, entropy, and, of course, perl-compatible regular expressions. In this case, it allows us to find files in memory based on characteristic signatures; for example, here's a signature to find all Windows executables:

# XMagic

0 string = MZ DOS Header
<&0x3c lelong x - \b, PE Offset = %lu <<(0x3c.l) regexp:4 =~ ^PE\x00\x00 \b, Windows PE

You could also just grab the most recent XMagic file and see what it turns up on physical memory; this can be a lot of fun even outside a forensic investigation, just to see what's actually being kept in memory, and for how long.

That's all I have time for right now, but tune in next time, when we really tear into the memory dump, go hunting for kernel memory structures, reconstruct executables from memory, and generally party like it's 1999. As a teaser, here's some XMagic that will find all process structures in a memory dump from an XP SP2 system:

# XMagic

0 string = \x03\x00\x1b\x00 Windows Process
# PDB is not null
<0x18> 0
# flink in kernel space
<<0x50> 0x80000000
# blink in kernel space
<<<0x54> 0x80000000
# SYNCH struct at 0xD8
<<<<0xD8 regexp =~ \x01.\x04.
# SYNCH struct at 0xFC
<<<<<0xFC regexp =~ \x01.\x04.
# Print out some pertinent info
>>>>>>0x84 lelong x - \b, PID %u
>>>>>>0x14C lelong x - \b, PPID %u
# Image Name
>>>>>>0x174 string x - \b, %s