Recently I contributed a challenge to the SOURCE Boston CTF competition. The challenge was entitled “Dump Sector Blue” and involved manipulating a crash dump filter driver I wrote to leverage crash context structures used by crashdmp.sys. I will be delivering a presentation at No Such Con (Paris, France) that discusses the techniques and research behind this challenge, as well as releasing the source code. If I have time at the conference, I will do a short walk-through of the code after my presentation.
I will post all related materials to this website by the end of May when the conference is over, but below is a snippet to pique your interest.
The ultimate goal is for the user to coerce a custom crash dump filter driver (storport_lsi.sys) to read the key off disk using the crash dump I/O path. This coercion is possible through manipulating the contents of the undocumented DumpStack.log.tmp file, which is exposed to the user by storport_lsi.sys. As part of solving the challenge, this manipulation causes the dump filter driver to leverage internal logging functions in crashdmp.sys to read and write arbitrary locations on disk (through the crash dump I/O path). A more detailed explanation is in the Challenge Technical Background section.
The contestant will need to research and understand various aspects of the crash dump mechanism in order to progress through the challenge. The primary goals of the challenge are to:
- Educate the user on how the crash dump stack works
- Illustrate that the crash path represents a completely separate path to disk than normal system operation
- Demonstrate that the crash path can be used outside of the normal crash mechanism
Challenge Technical Background
The crashdmp.sys driver maintains a context structure that holds state information critical to operating the crash and hibernate features of the operating system. This context structure is initialized when the kernel initializes itself early in the boot process. As part of initialization, the crash dump stack (which contains all of the drivers involved in crash/hibernation including crashdmp.sys, a dump port driver, a dump miniport driver, and any crash dump filter drivers such as whole disk encryption drivers) is initialized and all filter drivers are loaded. When a crash dump filter driver is loaded by the operating system, it is passed a pointer to a FILTER_INITIALIZATION_DATA structure, which is actually the address of a structure embedded in an undocumented parent structure. This undocumented parent structure contains a pointer to the crashdmp.sys driver’s context state structure mentioned previously. Therefore, all filter drivers have access to (and can therefore read and/or modify) this structure. One of the many useful things embedded in this context structure is a handle to its log file (DumpStack.log.tmp) and a disk run structure that describes the physical location of the log file on disk. The way the logging path works in crashdmp.sys makes it easy to call its internal Read/Write functions directly to modify the file referenced by the disk run structure. By modifying this disk run structure to reference a completely different file, and simply invoking the read or write routine, we can read/write any arbitrary location on disk.