Tuesday, September 22, 2009

Aquisition drive too small? Loop and offset to the rescue!

On any given day, I might need to take an image of a physical drive to analyze offline. In the past, our imaging target drives of 1TB were plenty to handle a raw dump of the drive as well as partition dumps or carves later on. However, with the spate of large capacity drives being installed, even in laptops, I'm lucky to just get the raw dump of the drive with some working space for an evidence locker. But what if I need to parse through the partitions individually or want to mount them remotely? Loop device mounting and offset (commands operands supported within the mount command) to the rescue. After imaging the entire drive and of course verifying the hash, I have everything I need. Now for the fun.

Typically, you can mount a raw image with the loop device operand:

#mount -o loop,ro -t auto /some/image.raw /your/mountpoint

I use this often when I only have an image of a partition. However, this option will not work when trying to mount an image of an entire physical device with one or more logical drives defined within it. So now what?

Given that an image is really just a block level copy of data, we are only dealing with data. Using the the loop device with further options - offset specifically - offers you the ability to tell it where you want it to consider the starting point within the string of data. In essence, the offset operand tells mount and the loop device to offset from the actual beginning of the string of data n bytes. But where do my partitions start and end?

To get an idea of what is contained inside the image, as far as file system information, logical drives etc, you will need to use a utility like fdisk. fdisk is a partition table manipulator for Linux. While it can be used to manipulate the partitions, we'll just use it to find out what's inside the image. The following command will give you all the details we need about an image:

# fdisk -ul image.001

You must set cylinders.
You can do this from the extra functions menu.

Disk image.001: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0xd42ad42a

Device Boot Start End Blocks Id System
image.001p1 * 63 42154559 21077248+ 7 HPFS/NTFS
Partition 1 has different physical/logical endings:
phys=(1023, 254, 63) logical=(2623, 254, 63)
image.001p2 42154560 156296384 57070912+ 5 Extended
Partition 2 has different physical/logical beginnings (non-Linux?):
phys=(1023, 0, 1) logical=(2624, 0, 1)
Partition 2 has different physical/logical endings:
phys=(1023, 254, 63) logical=(9728, 254, 63)
image.001p5 42154623 156296384 57070881 7 HPFS/NTFS

In the example above, I pointed "fdisk -ul" at an image of a Windows drive that had two partitions. I used option "u" to list the sizes in sectors instead of cylinders and "l" to list the partitions within the device and then exit. So, from here, how do we calculate where the starting point is for each partition and then tell mount where we want the beginning to be? First we start by determining the sector size. This will be in bytes, and the number we use as a multiplier to determine how many bytes into the image we want to offset. We can see in the output that the sector size is 512 bytes:

Units = sectors of 1 * 512 = 512 bytes

Next we need to know at what sector each partition starts. In the example above, we see several partitions listed; image.001p1, image.001p2, image.001p5. Each partition entry in the output has a start point denoted in sectors:

Device Boot Start End Blocks Id System
image.001p1 * 63 42154559 21077248+ 7 HPFS/NTFS
image.001p2 42154560 156296384 57070912+ 5 Extended
image.001p5 42154623 156296384 57070881 7 HPFS/NTFS

But wait - in this example I have a drive image that only contained two partitions - why are there three listed? This is because the drive I imaged was partitioned with one primary boot partition and an extended partition which contains another partition. There are many religious debates on how to partition drives, but suffice it to say, this is by far more common than not. Today, we are only concerned about mounting the two NTFS partitions listed. In the fdisk output we can see that partition 1 starts at sector 63 and partition 5 starts at sector 42154623. We'll multiply these starting sectors by our sector size to determine what our offset (in bytes) is for each mount operation:

sector size * starting sector = offset
512 * 63 = 32256
512 * 42154623 = 21583166976

Now that we have the offset, in bytes, we can formulate our mount commands:

#mount -o ro,loop,offset=32256 -t ntfs-3g image.001 /some/mountpoint
and
#mount -o ro,loop,offset=21583166976 -t ntfs-3g image.001 /another/mountpoint

And there we have it - both partitions within a raw drive image mounted and ready to explore without having to take more images of just the logical drives - or carve them out of what we have. Of course, file systems will vary along with disk geometry and associated mounting options. However these basic steps can be used to identify and mount every partition contained within a raw disk image.

No comments: