Skip to content
All posts
forensicsrevised March 24, 20264 min read

The boot process as a target: MBR, VBR, and bootkits

Before the OS loads, a chain of tiny programs runs from the first sectors of the disk - and a forensics challenge can hide a flag, or a bootkit, right there. How the boot chain works and how to analyse the sectors it lives in.

There is a sliver of a computer's life between power-on and the operating system taking over, and it runs code from the very first sectors of the disk. Most people never think about it. Challenge authors do, because it is a place to hide things that ordinary filesystem forensics walks right past - a flag tucked in the boot sector, a message in the gap before the first partition, or a simulated bootkit that rewrote the boot chain to run its own code first.

This article is the map of that early territory: what runs, in what order, where it lives on disk, and how to pull those regions out and read them. It pairs with the disk image forensics post - that one handles the filesystem; this one handles everything before the filesystem exists.

The legacy boot chain

On a BIOS/MBR system the sequence is short and every step is a known location on disk. Knowing the chain tells you exactly where to look.

  1. The MBR lives in sector 0 - the first 512 bytes of the disk. It holds a tiny bootloader (the first 446 bytes), the partition table (64 bytes, four 16-byte entries), and the signature 55 AA. The BIOS loads and runs it.
  2. The VBR (Volume Boot Record) is the first sector of the active partition. The MBR code hands off to it, and it knows how to load the OS's bootloader from that specific filesystem.
  3. The bootloader (GRUB, the Windows Boot Manager) is a real program on the filesystem that loads the kernel.
  4. The kernel takes over and the OS boots.
# Dump and read sector 0 (the MBR):
dd if=disk.img bs=512 count=1 2>/dev/null | xxd | tail -5
# The last line should end in ... 55aa  -- the boot signature.

# Parse the partition table with Sleuth Kit:
mmls disk.img
The four partition entries start at offset 0x1BE. Each entry's bytes tell you the partition type, and whether it is marked active (bootable) with 0x80.

Where flags and bootkits hide

The boot region has several nooks that no filesystem indexes, which is precisely why they are useful hiding places.

  • The MBR bootstrap code itself. 446 bytes of executable code that authors can replace with a message, a small program, or shellcode to reverse. If the bytes before the partition table are not standard boot code, something was planted.
  • The MBR gap / boot track. The space between sector 0 and the first partition (traditionally partition 1 starts at sector 2048) is unallocated by any filesystem - 1MB of room for a payload. Real bootkits store their extra code here.
  • VBR and IPL slack. The volume boot record and its loader have unused bytes that can carry data.
  • Inter-partition gaps. As in ordinary disk forensics, the space between partitions holds raw bytes outside any filesystem.
# Carve the MBR gap (sector 1 up to the first partition at 2048):
dd if=disk.img bs=512 skip=1 count=2047 of=gap.bin 2>/dev/null
strings gap.bin | grep -iE 'flag|ctf\{'
# Disassemble the MBR bootstrap as 16-bit real-mode code:
dd if=disk.img bs=1 count=446 2>/dev/null | ndisasm -b16 -
Boot code runs in 16-bit real mode, so disassemble it with -b16. A jump near the start followed by odd bytes is the shape of a bootkit that hooked the chain.

UEFI: the modern boot path

Newer systems boot via UEFI instead of the MBR, and the shape is different: a GPT partition table instead of the MBR's four entries, and an EFI System Partition (a small FAT filesystem) holding .efi bootloader applications instead of raw boot-sector code. A UEFI-flavoured challenge hands you an ESP or a firmware image; the boot code is now a normal PE file (a .efi) you can pull out and reverse like any other binary, and the modern equivalent of a bootkit lives as a malicious EFI application or a firmware module. The concept is identical - run before the OS - but the artifacts are files, not sectors.

The approach

  1. Read sector 0: confirm the 55 AA signature, parse the partition table at 0x1BE.
  2. Check whether the 446-byte bootstrap is standard code or something planted - disassemble it as 16-bit.
  3. Carve the MBR gap and inter-partition space; strings and disassemble them.
  4. Look for a hidden copy of the original MBR in a later sector - the bootkit's giveaway.
  5. If it is UEFI: mount the EFI System Partition and reverse the .efi files as ordinary PE binaries.