Sunday, August 13, 2023

Creating Disks Without Disks

 If you are playing around with disk forensics and want to look at tools like SleuthKit and Autopsy, along with other commercial tools, you need disk images to play with. While it's easy enough to get external disks to tinker with, you can also create virtual disks in Linux that will give you an image without having to generate one from a real disk. The first thing you need to do is to generate a file. We can use the disk dump command in Linux, dd, to do that. We're going to use a pseudodevice that generates random numbers, /dev/urandom, though you could also easily use /dev/zero. 

kilroy@badmilo ~ $ dd if=/dev/urandom of=mydisk.img bs=1M count=128

128+0 records in

128+0 records out

134217728 bytes (134 MB, 128 MiB) copied, 0.269739 s, 498 MB/s

kilroy@badmilo ~ $ 

Once we have a file, we can partition it just as you would an actual device. While you can use any disk partitioning program you want, you can see the use of fdisk here. 

kilroy@badmilo ~ $ fdisk mydisk.img 

Welcome to fdisk (util-linux 2.39.1).                                        

Changes will remain in memory only, until you decide to write them.          

Be careful before using the write command.

Device does not contain a recognized partition table.

Created a new DOS (MBR) disklabel with disk identifier 0x1ecaf971.

Command (m for help): n

Partition type

   p   primary (0 primary, 0 extended, 4 free)

   e   extended (container for logical partitions)

Select (default p): p

Partition number (1-4, default 1): 

First sector (2048-262143, default 2048): 

Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-262143, default 262143): 

Created a new partition 1 of type 'Linux' and of size 127 MiB.

Command (m for help): w

The partition table has been altered.

Syncing disks.

You'll want to pay attention to the location of the first sector. The program fdisk defaults the first partition to start at the 2048th block. We're going to use that information shortly, since we need to format the partition. When you format a disk, if you don't provide an offset, it will write over the first blocks on the disk, virtual or otherwise. Writing over the first blocks blows away the partition table, which means you don't have any partitions after you have formatted the disk. We just want to format a partition and not an entire disk. Here, we are going to format the disk as an EXT4 partition and provide the starting block for the partition. 

kilroy@badmilo ~ $ mkfs.ext4 mydisk.img -E offset=$((2048 * 512))
mke2fs 1.47.0 (5-Feb-2023)

Warning: offset specified without an explicit file system size.
Creating a file system with 130048 blocks but this might
not be what you want.

Discarding device blocks: done                            
Creating filesystem with 130048 1k blocks and 32512 inodes
Filesystem UUID: eb9e3f13-66c8-4fe8-9922-69b32ded088c
Superblock backups stored on blocks: 
        8193, 24577, 40961, 57345, 73729

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done 

While you could provide the actual byte offset, in this case we are calculating the byte offset. There are 512 bytes in a block and the block offset was 2048 so we multiply one by the other to figure out the actual byte location on the disk. Because everything we are doing so far has been on files I own, there has been no need to elevate privileges. What we do next, however, will require privilege elevation. We're going to mount the disk. 

In this case, I've created a mountpoint, which is an empty directory, in my home directory to mount to. We're going to loopback mount, which is a way of mounting a file as though it were a block device, like an actual hard disk. A file is a character device, but we can't mount character devices and use them as though they were disks. So, we use a loopback mount and the file acts as though it's an actual disk. 

kilroy@badmilo ~ $ sudo mount -o loop -o offset=$((2048*512)) mydisk.img mnt

Now we have our file mounted as though it were a disk, we can use it as though it were a disk. You can copy files to and from, though since it's a new disk there is nothing on it to copy from at this point. 

Once you have this mounted device, you can use any forensics tools on it you like. Or just use it as a way to store files in a single place that can be copied around or compressed. As it's just a file, maybe no one will think to check it for actual content. The giveaway will be if someone uses the file utility on it, since it looks like a boot record to file, as you can see here. 

kilroy@badmilo ~ $ file mydisk.img
mydisk.img: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x0,32,33), end-CHS (0x10,81,1), startsector 2048, 260096 sectors, extended partition table (last)