How to hide data between drive partitions


thumbnail

Pros

Cons

Setup

Here’s an example drive using the following partition configuration:

Disk /dev/sdb: 15728640 sectors, 7.5 GiB
...
Sector size (logical/physical): 512/512 bytes
...
Number  Start (sector)    End (sector)  Size       Code  Name
   1            4096         4198399   2.0 GiB     8300  Linux filesystem
   2         4202496        15724543   5.5 GiB     8300  Linux filesystem

Notice that there is a gap between the end sector of the first partition and the start sector of the second partition, this is the gap we’re going to use to write our hidden data to.

The reason the sector alignment value is 4096, is because it targets a specific group of people who might assume that the partitioning program accidentally (or purposefully) left a gap between the partitions equal to the sector alignment value. In the real world this should never happen. Anyone experienced enough won’t be fooled by this.

Partitioning the drive

For partitioning we’re going to use gdisk, but any other disk manipulating utility should work just as well.

Create a new GPT

$ sudo gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.9.1

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Set the sector alignment value (optional)

Command (? for help): x

Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 4096

Expert command (? for help): m

Command (? for help):

Create the first partition

Command (? for help): n
Partition number (1-128, default 1):
First sector (34-15728606, default = 4096) or {+-}size{KMGTP}:
Last sector (4096-15728606, default = 15724543) or {+-}size{KMGTP}: +2G
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'

Command (? for help):

Create the second partition with a starting sector offset of 4096

Command (? for help): n
Partition number (2-128, default 2):
First sector (34-15728606, default = 4198400) or {+-}size{KMGTP}: +4096
Last sector (4202496-15728606, default = 15724543) or {+-}size{KMGTP}:
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Command (? for help): p
Disk /dev/sda: 15728640 sectors, 7.5 GiB
Model: UDisk
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): AA1E2E4C-26BC-477D-BD76-0391D5958730
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 15728606
Partitions will be aligned on 4096-sector boundaries
Total free space is 12221 sectors (6.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            4096         4198399   2.0 GiB     8300  Linux filesystem
   2         4202496        15724543   5.5 GiB     8300  Linux filesystem

Things to write down and remember:

Creating a loop device

We are going to create a loop device in which we’re going to store the data, this has the following benefits:

The loop device will have an --offset of A and a --sizelimit of B:

sudo losetup /dev/loop0 /dev/sda --offset 4198399 --sizelimit 4096

The --sizelimit option makes it so that losetup only reads 4096 bytes from the end sector of the first partition (value A). This is the space where we can store anything as raw data.

Writing data

To write data we are going to use dd, also known as the “disk destroyer”. It is a convenient tool used to copy data, but if used incorrectly, can give you quite a bad time.

Check the data prior to writing

$ sudo dd if=/dev/loop0 of=tmp.bin
8+0 records in
8+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.000284813 s, 14.4 MB/s
$ hexyl tmp.bin
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │00000000┊00000000│
│*
│00001000│
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

dd options:

Write the data

In this example we are going to use /dev/urandom as input, but you can theoretically use anything that’ll fit.

$ sudo dd if=/dev/urandom of=/dev/loop0
dd: writing to '/dev/loop0': No space left on device
9+0 records in
8+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.000393695 s, 10.4 MB/s

Check the data after writing

$ sudo dd if=/dev/loop0 of=tmp.bin
8+0 records in
8+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.000288863 s, 14.2 MB/s
$ hexyl tmp.bin
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 00 61 ac a7 31 22 aa ea 90 62 cf c4 cc fb dd d1 │0a××1"××┊×b××××××│
│00000010│ 3b ae 9f 37 f2 cd 19 01 ┊ cb d2 01 d5 c5 26 37 52 │;××7×ו•┊×ו××&7R│
│00000020│ 53 85 d1 10 96 86 dc b4 ┊ 81 90 79 8c 7e 8a 9c d6 │S×ו××××┊××y×~×××│
│00000030│ c4 be 16 a6 e9 20 f2 63 ┊ a5 07 52 7c 76 e0 48 ae │×ו×× ×c┊וR|v×H×│
.
.
.
│00000fc0│ 86 fa 10 52 f9 62 06 38 ┊ a5 7e a4 f4 2b dd 89 6c │×וR×b•8┊×~××+××l│
│00000fd0│ ab e8 ea a7 17 4e 28 ce ┊ fd e7 17 22 7a 93 54 32 │×××וN(×┊×ו"z×T2│
│00000fe0│ db 4c c9 30 06 b0 9d 55 1c 6a 6b 50 3e 73 e0 d6 │×L×0•××U┊•jkP>s××│
│00000ff0│ 8b bc f3 b7 b3 33 03 18 37 7c d7 d4 62 3e 2e d1 │×××××3••┊7|××b>.×│
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘