When a sector on a disk gets damaged, it becomes unusable. Modern disks have spare sectors that are used to replace these bad sectors, so they’re handled and fixed automatically. If you’re young enough, you might never have witnessed these bad sectors, because modern hardware handles them transparently, but there’ still there. I’ll show you how to store data in “fake” bad blocks.
This is part 3 in a series on how to hide your data.
Warning: Don’t rely on this tutorial actually hiding your data. This is for academic and experimental purposes only. Always complement using encryption and plausible deniability methods like TrueCrypt.
When the disk runs out of spare sectors, or never had any in the first place (like 3.5” disks, or very old hard disks), the filesystem is the second line of defense. Inside the filesystem is a list of known bad blocks – blocks on bad sectors. The filesystem takes care not to use these blocks and just skips them.
We can’t force the disk to remap certain blocks to spare sectors, but we can tell the filesystem which blocks have (supposedly) gone bad. If the blocks aren’t really damaged, any data we put there will never be touched, because the filesystem thinks it’s garbage anyway. That, is exactly what we’re going to do.
To keep it simple and fast, we’ll hide a whole partition inside a burst of bad blocks. The partition we’ll create has to be small and reside somewhere in the middle of the disk. We can’t put the partition at the beginning or the end of the disk, because most likely the filesystem requires an intact header at the start and end of the partition.
The partition has to be small enough to be able to fit inside the non-secret partition while not arousing suspicion. Some operating systems mark bad blocks as used blocks, which means if we put a 100MB partition inside bad blocks, the “parent” filesystem will always have at least 100MB in use. This could arouse suspicion when there aren’t any files on it.
I’ll be using my trusty 256MB Compactflash card for this, which is excellent for illustratory purposes.
Here’s what sfdisk has to say about it:
$ sudo sfdisk -l /dev/sde Disk /dev/sde: 1009 cylinders, 9 heads, 56 sectors/track Units = cylinders of 258048 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System /dev/sde1 0 - 0 0 0 Empty /dev/sde2 0 - 0 0 0 Empty /dev/sde3 0 - 0 0 0 Empty /dev/sde4 0 - 0 0 0 Empty
We can see the card is comprised of 1009 cylinders. I want to create a partition of about 20MB, which is about 82 cylinders on this disk (see the second line of sfdisk -l). Because we can’t create the partition at the start of the disk, let’s put it 214 cylinders in:
$ sudo sfdisk /dev/sde << EOF 214,82,6 EOF
Just like before, put FAT16 on it and transfer your secret data.
$ sudo mkfs.vfat -F16 /dev/sde1 mkfs.vfat 2.11 (12 Mar 2005)
If you want, you can copy the current partition table to the back of the disk for easy restoring, just like in the previous article.
Unmount it, and remove the partition:
$ sudo sfdisk /dev/sde << EOF 0,0,0 EOF
Now create the parent partition. This should at least encompass the whole secret partition. If you’ve copied the partition table to the back of the disk, make sure to leave at least the last cylinder free.
$ sudo sfdisk /dev/sde << EOF ,,6 EOF
Creating Bad Blocks
We need to calculate what blocks our secret partition resides on so we can mark them as bad. We know it starts at cylinder 214 and is 82 cylinders in size. Since on this disk, a cylinder is 258048 bytes big, the secret partition starts at byte 55222272. Divide this by the size of one block, which is 1024 bytes, and we get block 53928. Do the same for the size of the partition, and we find that 82 cylinders equal 20664 blocks. Now we know our partition starts at block 53928 and ends at block 74592. We’ll use a margin of 10 blocks on each side just in case our calculations aren’t precise.
Since we’re putting a FAT16 filesystem on it, we need to tell mkfs.vfat what blocks have supposedly gone bad. This is done by using a bad blocks file, which is a text-file with the address of each bad block on a new line. Let’s create our bad blocks file:
$ seq 53918 74602 > /tmp/badblocks
If you open /tmp/badblocks, you should see something like this:
53918 53919 53920 53921 ...
To create the filesystem, we pass the bad blocks file using the -l parameter:
$ sudo mkfs.vfat -n "Camera" -l /tmp/badblocks /dev/sde1 mkdosfs 2.11 (12 Mar 2005) 20685 bad blocks
That’s it! You can now use your disk to your heart’s delight, nothing will touch your secret partition. One awesome way is to put the card in your camera and take some pictures with it. Your data will remain safe, and there’ll be nothing suspicious about a 4GB card “missing” some megabytes.
If you’ve smuggled your secret data across state borders, you’re ready to recover the secret partition. Just recreate the partition table to contain the secret partition:
$ sudo sfdisk /dev/sde << EOF 214,82,6 EOF
That’s it! You can even reuse the setup: by switching partition tables you’re effectively changing which partition is “active” on your card, and changing data in either partition won’t affect the other.
- Pretty much undetectable
- Infinitely reusable
- Bad blocks are less suspicious than unallocated space
- Quite complex to set up
- Possibly suspicious size discrepancy in empty filesystems