Windows Memory Analysis (Windows Forensic Analysis) Part 3

Alternative Approaches for Dumping Physical Memory

The software we’ve discussed so far aren’t the only means by which the contents of physical memory can be dumped from a live system; several alternative methods have been put forth in the past. Some of those methods use native functionality inherent to the operating system (i.e., crash dumps) or to virtualization platforms (i.e., VMware). As we’ll see, other alternative methods for dumping physical memory from a system take a more physical approach.

Hardware Devices

In February 2004, the Digital Investigation Journal published a paper by Brian Carrier and Joe Grand titled "A Hardware-Based Memory Acquisition Procedure for Digital Investigations." In the paper, Brian and Joe presented the concept for a hardware expansion card dubbed Tribble (possibly a reference to that memorable Star Trek episode) that could be used to retrieve the contents of physical memory to an external storage device. This would allow an investigator to retrieve the volatile memory from the system without introducing any new code or relying on potentially untrusted code to perform the extraction. In the paper, the authors stated that they had built a proof-of-concept Tribble device, designed as a Payment Card Industry (PCI) expansion card that could be plugged into a PC bus. Other hardware devices are available that allow you to capture the contents of physical memory and are largely intended for debugging hardware systems. These devices may also be used for forensics.


As illustrated in the DFRWS 2005 Memory Challenge (referred to earlier in this topic), one of the limitations of a software-based approach to retrieving volatile memory is that the program the investigator is using has to be loaded into memory. Subsequently, particularly on Windows systems, the program may (depending on its design) rely on untrusted code or libraries (DLLs) that the attacker has subverted. Let’s examine the pros and cons of such a device:

Hardware devices such as Tribble are unobtrusive and easily accessible. Dumping the contents of physical memory in this manner introduces no new or additional software to the system, minimizing the chances of data being obscured in some manner. However, the primary limitation of using the hardware-based approach is that the hardware needs to be installed prior to the incident. At this point, the Tribble devices are not widely available. Other hardware devices are available and intended for hardware debugging, but they must still be installed prior to an incident to be of use.

FireWire

Due to technical specifics of FireWire devices and protocols, there is a possibility that with the right software, an investigator can collect the contents of physical memory from a system. FireWire devices use direct memory access (DMA), meaning they can access system memory without having to go through the CPU. These devices can read from and/or write to memory at much faster rates than systems that do not use DMA. The investigator would need a controller device that contains the appropriate software and is capable of writing a command into a specific area of the FireWire device’s memory space. Memory mapping is performed in hardware without going through the host operating system, allowing for high-speed low-latency data transfers.

Adam Boileau (see www.storm.net.nz/projects/16) came up with a way to extract physical memory from a system using Linux and Python. The software used for this collection method runs on Linux and relies on support for the /dev/raw1394 device as well as Adam’s pythonraw1394 library, the libraw1394 library, and Swig (software that makes C/C++ header files accessible to other languages by generating wrapper code). In his demonstrations, Adam even included the use of a tool that will collect the contents of RAM from a Windows system with the screen locked, then parse out the password, after which Adam logs in to the system.

Jon Evans, an officer with the Gwent police department in the United Kingdom, has installed Adam’s tools and successfully collected the contents of physical memory from Windows systems as well as from various versions of Linux. As part of his master’s thesis, Jon wrote an overview on how to install, set up, and use Adam’s tools on several different Linux platforms, including Knoppix v.5.01, Gentoo Linux 2.6.17, and BackTrack, from Remote-exploit.org. Once all the necessary packages (including Adam’s tools) have been downloaded and installed, Jon walks through the process of identifying FireWire ports and tricking the target Windows system into "thinking" the Linux system is an iPod by using the Linux romtool command to load a data file containing the Control Status Register (CSR) for an iPod (the CSR file is provided with Adam’s tools). Here are the pros and cons of this approach:

Many systems available today have FireWire/IEEE 1394 interfaces built right into the motherboards, increasing the potential accessibility of physical memory using this method. However, Arne Vidstrom has pointed out some technical issues (see http://ntsecurity.nu/ onmymind/2006/2006-09-02.html) regarding the way dumping the contents of physical memory over FireWire can result in a hang or in parts of memory being missed. George M. Garner, Jr., noted in an e-mail exchange on a mailing list in October 2006 that in limited testing, there were notable differences in important offsets between a RAM dump collected using the FireWire technique and one collected using George’s own software. This difference could only be explained as an error in the collection method. Furthermore, this method has caused Blue Screens of Death (BSoDs, discussed further in a moment) on some target Windows systems, possibly due to the nature of the FireWire hardware on the system.

Crash Dumps

We’ve all seen crash dumps at one point or another; in most cases they manifest themselves as an infamous Blue Screen of Death (a.k.a. BSoD, with more descriptive information available at http://en.wikipedia.org/wiki/Blue_Screen_of_Death). In most cases they’re an annoyance, if not indicative of a much larger issue. However, if you want to obtain a pristine, untainted copy of the content of RAM from a Windows system, perhaps the only way to do that is to generate a full crash dump. This is because when a crash dump occurs, the system state is frozen and the contents of RAM (along with about 4 Kb of header information) are written to the disk. This preserves the state of the system and ensures that no alterations are made to the system, beginning at the time the crash dump was initiated.

This information can be extremely valuable to an investigator. First, the contents of the crash dump are a snapshot of the system, frozen in time. I have been involved in several investigations during which crash dumps have been found and used to determine root causes, such as avenues of infection or compromise. Second, Microsoft provides tools for analyzing crash dumps—not only in the Microsoft Debugging Tools (www.microsoft.com/ whdc/devtools/debugging/default.mspx) but also in the Kernel Memory Space Analyzer (a tool with a ridiculously long URL, so it’s best to do a search for it), which is based on the Debugging Tools.

Sounds like a good deal, doesn’t it? After all, other than having a 1GB file written to the hard drive, possibly overwriting evidence (and not really minimizing the impact of your investigation on the system), there are no limitations to this approach, right? Under some circumstances, this is true … or you might be willing to accept that condition, depending on the circumstances. However, there are still a couple of stumbling blocks. First, not all systems generate full crash dumps by default. Second, by default, Windows systems do not generate crash dumps on command.

The first issue is relatively simple to deal with, according to Microsoft Knowledge Base article Q254649 (http://support.microsoft.com/kb/254649). This article lists the three types of crash dumps: small (64 KB), kernel, and complete crash dumps. We’re looking for the complete crash dump because it contains the complete contents of RAM. The article also states that Windows 2000 Pro and Windows XP (both Pro and Home) will generate small crash dumps, and Windows 2003 (all versions) will generate full crash dumps. My experience with Windows Vista RC1 is that it will generate small crash dumps, by default.

Note

Microsoft Knowledge Base article 235496 (http://support.microsoft.com/ kb/235496) specifies the Registry entries that contain configuration information for Windows systems with respect to the memory.dmp file that is the result of a crash dump. The default location for the memory.dmp file is %SystemRoot%\memory.dmp, but the administrator can specify another location via the DumpFile Registry value.

Along the same lines, Microsoft Knowledge Base article Q274598 (http://support. microsoft.com/kb/274598) states that complete crash dumps are not available on systems with more than 2 GB of RAM. According to the article, this is largely due to the space requirements (i.e., for systems with complete crash dumps enabled, the page file must be as large as the contents of RAM + 1 MB) as well as the time it will take to complete the crash dump process.

Microsoft Knowledge Base article Q307973 (http://support.microsoft.com/kb/307973) describes how to set the full range of system failure and recovery options. These settings are more for system administrators and information technology (IT) managers who are setting up and configuring systems before an incident occurs, but the Registry key settings can provide some significant clues for an investigator. For example, if the system was configured (by default or otherwise) to generate a complete crash dump and the administrator reported seeing the BSoD, the investigator should expect to see a complete crash dump file on the system.

Note

Investigators must be extremely careful when working with crash dump files, particularly from systems that process but do not necessarily store sensitive data. In some cases, crash dumps have occurred on systems that processed information such as credit card numbers, Social Security numbers, or the like, and these crash dumps have been found to contain that sensitive information. Even though the programmers specifically wrote the application so that no sensitive personal information was saved locally on the system, a crash dump wrote the contents of memory to the hard drive.

So, let’s say the system failure and recovery configuration options on a system are set ahead of time (as part of the configuration policies for the systems) to perform a full crash dump. How does the investigator "encourage" a system to perform a crash dump on command, when it’s needed? It turns out that there’s a Registry key (see Knowledge Base article Q244139, available at http://support.microsoft.com/kb/244139) that can be set to cause a crash dump when the right Ctrl key is held down and the Scroll Lock key is pressed twice. However, once this key is set, the system must be rebooted for the setting to take effect. Let’s look at the pros and cons of this technique:

Dumping memory via a crash dump is perhaps the only technically accurate (albeit not "forensically sound") method for creating an image of the contents of RAM. This is because when the KeBugCheck API function is called, the entire system is halted and the contents of RAM are written to the page file, after which they are written to a file on the system hard drive (overwriting data). Further, Microsoft provides debugging tools as well as the Kernel Memory Space Analyzer (which consists of an engine, plug-ins, and user interface) for analyzing crash dump files. Some Windows systems do not generate full crash dumps by default (e.g., Vista RC1; I had an issue with a driver when I first installed Vista RC1 and I would get BSoDs whenever I attempted to shut down the machine, which resulted in mini dump files).

In addition, modifying a system to accept the keystroke sequence to create a crash dump requires a reboot and must be done ahead of time to be used effectively for incident response. Even if this configuration change has been made, the crash dump process will still create a file equal in size to physical memory on the hard drive. To do so, as stated in Knowledge Base article Q274598, the page file must be configured to be equal to at least the size of physical memory plus 1 MB. This is an additional step that must be corrected to use this method of capturing the contents of physical memory; it’s one that is not often followed.

Tip::

A support article available at the Citrix Web site (http://support.citrix.com/ article/CTX107717&parentCategoryID=617) provides a methodology for using livekd.exe (http://technet.microsoft.com/en-us/sysinternals/bb897415.aspx) and the Microsoft Debugging Tools to generate a full kernel dump of physical memory. Once livekd.exe is launched, the command .dump /f <filepath> is used to generate the dump file. The support article does include the caveat that RAM dumps generated in this manner can be inconsistent because the dump can take a considerable amount of time and the system is live and continues to run during the memory dump.

Virtualization

VMware is a popular virtualization product (VMware Workstation 5.5.2 was used extensively in this topic) that, for one thing, allows the creation of pseudo-networks utilizing the hardware of a single system. This capability has many benefits. For example, you can set up a guest operating system and create a snapshot of that system once you have it configured to your needs. From there, you can perform all manner of testing, including installing and monitoring malware, and you will always be able to revert to the snapshot, beginning anew. I have even seen active production systems run from VMware sessions.

When you’re running a VMware session, you can suspend that session, freezing it temporarily. Figure 3.10 illustrates the menu items for suspending a VMware session.

Figure 3.10 Menu Items for Suspending a Session in VMware Workstation 6.5

Menu Items for Suspending a Session in VMware Workstation 6.5

When a VMware session is suspended, the contents of physical memory are contained in a file with the .vmem extension. The format of this file is very similar to that of raw, dd-style memory, and in fact, it can be parsed and analyzed with the same tools discussed previously in the topic.

VMware isn’t the only virtualization product available. Others include VirtualPC from Microsoft, as well as the freeware Bochs (http://bochs.sourceforge.net/). None of these virtualization products have been tested to determine whether they can generate dumps of physical memory; however, if this is an option available to you, suspending a VMware session to obtain a dump of physical memory is quick and easy and minimizes your interaction with and impact on the system.

Tip::

In May 2006, Brett Shavers wrote an excellent article for the ForensicFocus Web site, titled "VMware as a forensic tool" (available at www.forensicfocus.com/vmware-forensic-tool). Brett followed that article in 2008 with the paper "Virtual Forensics: A Discussion of Virtual Machines Related to Forensics Analysis" (www.forensicfocus.com/downloads/virtual-machines-forensics-analysis.pdf), which is by far the best treatment of the topic that I’ve been able to find anywhere.

Hibernation File

When a Windows (Windows 2000 or later) system "hibernates," the Power Manager saves the compressed contents of physical memory to a file called hiberfil.sys in the root directory of the system volume. This file is large enough to hold the uncompressed contents of physical memory, but compression is used to minimize disk I/O and to improve resume-from-hibernation performance. During the boot process, if a valid hiberfil.sys file is located, the NT Loader (NTLDR) will load the file’s contents into physical memory and transfer control to code within the kernel that handles resuming system operation after a hibernation (loading drivers, etc.). This functionality is most often found on laptop systems. Here are the pros and cons:

Analyzing the contents of a hibernation file could give you a clue as to what was happening on the system at some point in the past. Matthieu Suiche decoded the hibernation file format and presented his findings at the BlackHat USA 2008 conference (www.blackhat.com/presentations/bh-usa-08/Suiche/BH_US_08_Suiche_Windows_ hibernation.pdf ). This presentation followed his earlier write-up on the subject from February 2008 titled "Sandman Project" ( http://sandman.msuiche.net/docs/SandMan_ Project.pdf ), and his previous work from 2007 with Nicolas Ruff. The Sandman tool is available from www.msuiche.net/category/sandman/, and the functionality is incorporated into the Volatility Framework (discussed later in this topic).

Something else to consider about hibernation files is that this functionality may be the only option available for capturing the full contents of physical memory. Some of the available tools for collecting the contents of physical memory may have "issues" (more specifically, they may have caused systems with more than 4 GB of physical memory— including 64-bit systems—to crash) or may not be available or feasible for use in some environments.

The hibernation file is compressed and in most cases will not contain the current contents of memory. Thanks to the work performed by Matthieu and Nicolas, the hibernation file can be accessed in the same manner as a live memory dump, so I can’t really think of any "cons" to using it. In addition to dumping memory from a live system, having a hibernation file available will give you memory contents from a previous point in time against which to compare your memory dump.

Analyzing a Physical Memory Dump

Now that you have seen ways to acquire the contents of RAM from a system (both local and remote methods), what can you do with the memory dump? For the most part, prior to summer 2005, the standard operating procedure for most folks who had bothered to collect a memory dump (usually via the version of dd.exe available with George M. Garner, Jr.’s Forensic Acquisition Utilities) was to run strings.exe against it, or run grep searches (for e-mail addresses, IP addresses, etc.), or both. Although this would result in investigative leads (finding what appeared to be a password geographically "close" to a username might give an investigator a clue or something to examine further) that would often lead to something definitive, it does not provide overall context to the information that is discovered. For example, is that string that was located part of a word processing or text document, or was it copied to the system Clipboard? What process was using the memory where that string or IP address was located?

With the DFRWS 2005 Memory Challenge as a catalyst, steps have been taken in an attempt to add context to the information found in RAM. By locating specific processes (or other objects maintained in memory) and the memory pages used by those processes, investigators can gain greater insight into the information they discover as well as perform significant data reduction by filtering out "known good" processes and data and focusing on the data that appears "unusual." Several individuals have written tools that can be used to parse through RAM dumps and retrieve detailed information about processes and other structures.

In 2007, Aaron Walters released the Volatility Framework (https://www.volatilesystems.com/), an open source, Python-based framework for parsing memory dumps from (at the time of this writing) Windows XP systems. During summer 2008, Aaron held the first Open Memory Forensics Workshop (https://www.volatilesystems.com/default/omfw) just prior to the DFRWS 2008 conference, during which researchers, analysts, and practitioners could rub elbows and discuss issues surrounding memory acquisition and analysis. Version 1.3 of the Volatility Framework was available at the conference, and was even used during the DFRWS Forensic Rodeo exercise.

Throughout the rest of this topic, we will look at these tools for performing analysis of memory dumps. We will initially use the memory dumps from the DFRWS 2005 Memory Challenge as exemplars, for examples and demonstrations of tools and techniques for parsing Windows 2000 memory dumps. You’re probably asking yourself, why even bother with that? Windows 2000 is the new MS-DOS, right? Well, that’s probably not far from the truth, but the dumps do provide an excellent basis for examples because they have already been examined in great detail. Also, they’re freely available for download and examination.

Determining the Operating System of a Dump File

Have you ever been handed an image of a system, and when you asked what the operating system is/was, you simply got "Windows" in response? Shakespeare doesn’t cut it here, my friends, because a rose by any other name might not smell as sweet. When you’re working with an image of a system, the version of Windows that you’re confronted with matters, and depending on the issue you’re dealing with, it could matter a lot. The same is true when you’re dealing with a RAM dump file; in fact, it could be even more so. As I’ve already stated, the structures that are used to define threads and processes in memory vary not only between major versions of the operating system but also within the same version with different service packs installed.

So, when someone hands you a RAM dump and says "Windows," you’d probably want to know how to figure that out, wouldn’t you? After all, you don’t want to waste a lot of time running the dump file through every known tool until one of them starts producing valid hits on processes, right? Through personal correspondence (that’s a fancy term for "e-mail") awhile ago, Andreas Schuster suggested to me that the Windows kernel might possibly be loaded into the same location in memory every time Windows boots. Now, that location is likely to, and does, change for every version of Windows, but so far it seems to be consistent for each version. The easiest way to find this location is to run LiveKD as we did earlier in this topic, but note in particular the information that’s displayed as it starts up (shown here on a Windows XP SP2 system):

tmp160-87

We’re most interested in the information that I’ve boldfaced—the address of the kernel base. We subtract 0×80000000 from that address and then go to the resultant physical location within the dump file. If the first two bytes located at that address are MZ, we could have a full-blown Windows portable executable (PE) file at that location, and we might have the kernel. From this point, we can use code similar to what’s in lspi.pl to parse apart the PE header and locate the various sections within the PE file. Because the Windows kernel is a legitimate Microsoft application file, we can be sure that there is a resource section within the file that contains a VS_VERSION_INFO section. Following information provided by Microsoft regarding the various structures that make up this section, we can then parse through it looking for the file description string.

On the accompanying DVD, you’ll find a file called osid.pl that does just that. Osid.pl began life as kern.pl and found its way into Rick McQuown’s PTFinderFE utility. Rick asked me via e-mail one day whether there was a way to shorten and clarify the output, so I made some modifications to the file (changed the output, added some switches, etc.) and renamed it.

Tip::

Most analysis tools, discussed later in this topic, are capable of performing the same function as was just discussed. For example, you can use the Volatility ident command to identify the operating system of a memory dump.

Process Basics

Throughout this topic, we will focus primarily on parsing information regarding processes from a memory dump. This is due, in part, to the fact that the majority of the publicly available research and tools focus on processes as a source of forensic information. That is not to say that other objects within memory should be excluded, but rather that most researchers seem to be focusing on processes. We will discuss another means of retrieving information from a RAM dump later in the topic, but for now, we will focus our efforts on processes. To that end, we need to have a pretty good idea of what a process "looks like" in memory. The following section focuses on processes in Windows 2000 memory, but most of the concepts remain the same for all versions of Windows. The biggest difference is in the actual structure of the process itself, and going into the details of the process structures on all versions of Windows is beyond the scope of this topic.

EProcess Structure

Each process on a Windows system is represented as an executive process, or EProcess, block. This EProcess block is a data structure in which various attributes of the process, as well as pointers to a number of other attributes and data structures (threads, the process environment block) relating to the process, are maintained. Because the data structure is a sequence of bytes, with each sequence having a specific meaning and purpose, these structures can be read and analyzed by an investigator. However, the one thing to keep in mind is that the only thing consistent between versions of the Windows operating system regarding these structures is that they aren’t consistent. You heard right: The size and even the values of the structures change not only between operating system versions (e.g., Windows 2000 to XP) but also between service packs of the same version of the operating system (Windows XP to XP SP2).

Andreas Schuster has done a great job of documenting the EProcess block structures in his blog (http://computer.forensikblog.de/en/topics/windows/memory_analysis). However, it is relatively easy to view the contents of the EProcess structure (or any other structure available on Windows). First, download and install the Microsoft Debugging Tools and the correct symbols for your operating system and Service Pack. Then download livekd.exe from Sysinternals.com (when you type sysinternals.com into the address bar of your browser, you will be automatically redirected to the Microsoft site, because by now, Mark Russinovich has long since been in the employ of Microsoft), and for convenience copy it into the same directory as the Debugging Tools.

This command will open WinDbg, the GUI interface to the debugger tools. To see what the entire contents of an EProcess block "looks like" (with all the substructures that make up the EProcess structure broken out), type dt -a —b —v _EPROCESS into the command window and press Enter. The —a flag shows each array element on a new line, with its index, and the —b switch displays blocks recursively. The —v flag creates more verbose output, telling you the overall size of each structure, for example. In some cases, it can be helpful to include the —r flag for recursive output.

Note

The Windows kernel keeps track of active processes by way of a doubly linked list; this means that each process "points to" both the process after it and the process before it, in a circular list. The operating system enumerates a list of active processes by walking PsActiveProcessList and developing a list of known active processes. Within the EProcess structure is a LIST_ENTRY item named ActiveProcessLinks. This entry has two values, flink and blink, which are pointers to the next and previous processes, respectively. Many memory analysis tools will do the same thing (i.e., walk the list of active processes) in a memory dump file, whereas others will perform a brute force enumeration of process objects (e.g., lsproc.pl and Volatility), enumerating even exited processes. This is very important, as some rootkits hide processes by unlinking their processes from this doubly linked list.

An important element of a process that the EProcess structure points to is the process environment block, or PEB. This structure contains a great deal of information, but the elements that are important to us, as forensic investigators, are:

■ A pointer to the loader data (referred to as PPEB_LDR_DATA) structure that includes pointers or references to modules (DLLs) used by the process

■ A pointer to the image base address, where we can expect to find the beginning of the executable image file

■ A pointer to the process parameters structure, which itself maintains the DLL path, the path to the executable image, and the command line used to launch the process

Extracting this information from a dump file can prove to be extremely useful to an investigator, as you will see throughout the rest of this topic.

Next post:

Previous post: