Make a bit-for-bit copy of your system’s disk for forensic analysis.
Before you format and reinstall the operating system on a recently compromised machine, you should take the time to make duplicates of all the data stored on the system. Having an exact copy of the contents of the system is not only invaluable for investigating a break-in, but may be necessary for pursuing any future legal actions. Before you begin, you should make sure that your md5sum, dd, and fdisk binaries are not compromised (you are running Tripwire [Hack #97] or otherwise have installed your packages using RPM [Hack #98], right?).
But hang on a second. Once you start wondering about the integrity of your system, where do you stop? Hidden processes could be running, waiting for the root user to log in on the console and ready to remove all evidence of the break-in. Likewise, there could be scripts installed to run at shutdown to clean up log entries and delete any incriminating files. Once you’ve determined that it is likely that a machine has been compromised, you may want to simply power down the machine (yes, just switch it off!) and boot from an alternate media. Use a boot CD or another hard drive that has a known good copy of the operating system. That way you can know without a doubt that you are starting the system from a known state, eliminating the possibility of hidden processes that could taint your data before you can copy it. The downside to this procedure is that it will obviously destroy any evidence of running programs or data stored on a RAM disk. However, chances are very good that the intruder has installed other backdoors that will survive a reboot, and these changes will most certainly be saved to the disk.
To make a bit-for-bit copy of our disks, we’ll use the dd command. But before we do this we’ll generate a checksum for the disk so that we can check our copy against the disk contents, to ensure that it is indeed an exact copy.
To generate a checksum for the partition we wish to image, run this command:
# md5sum /dev/hda2 > /tmp/hda2.md5
In this case we’re using the second partition of the first IDE disk on a Linux system. Now that that’s out of the way, it’s time to make an image of the disk:
# dd if=/dev/hda of=/tmp/hda.img
Note that you will need enough space in /tmp to hold a copy of the entire /dev/hda hard drive. This means that /tmp shouldn’t be a RAM disk and should not be stored on /dev/hda. Write it to another hard disk altogether.
Why do you want to image the whole disk? If you image just a partition, it is not an exact copy of what is on the disk. An attacker could store information outside of the partition, and this wouldn’t be copied if you just imaged the partition itself. In any case, we can always reconstruct a partition image as long as we have an image of the entire disk.
In order to create separate partition images, we will need some more information. Run fdisk to get the offsets and sizes for each partition in sectors. To get the sectors offsets for the partition, run this:
# fdisk -l -u /dev/hda
Disk /dev/hda: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders, total 8388608 sectors
Units = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 63 208844 104391 83 Linux
/dev/hda2 208845 7341704 3566430 83 Linux
/dev/hda3 7341705 8385929 522112+ 82 Linux swap
Be sure to save this information for future reference, just in case you want to create the separate image files at a later date.
Now create an image file for the second partition:
# dd if=hda.img of=hda2.img bs=512 skip=208845 count=$[7341704-208845]
7132859+0 records in
7132859+0 records out
Note that the count parameter does some shell math for us: the size of the partition is the location of the last block (7341704) minus the location of the first block (208845). Be sure that the bs parameter matches the block size reported by fdisk (usually 512, but it’s best to check it when you run fdisk). Finally, we’ll generate a checksum of the image file and then compare it against the original one we created:
# md5sum hda2.img > /tmp/hda2.img.md5 && diff /tmp/hda2.md5 /tmp/hda2.img.md5
The checksum for the image matches that of the actual partition exactly, so we know we have a good copy. Now you can rebuild the original machine and look through the contents of the copy at your leisure.