I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
-
Upload
crowdstrike -
Category
Technology
-
view
7.624 -
download
3
description
Transcript of I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
![Page 1: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/1.jpg)
I/O, YOU OWN:
REGAINING CONTROL
OF YOUR DISK IN THE
PRESENCE OF
BOOTKITS
Aaron LeMasters @lilhoser
![Page 2: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/2.jpg)
Introduction2
My background
Your background
Brief history of this presentation
Disclaimer: some of this might be wrong…
Please read white paper for details
![Page 3: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/3.jpg)
Agenda3
Technical Background What is the crash dump stack in Windows?
How the operating system initializes and uses the crash dump stack (post Windows Vista) Pre Vista is in Appendix A
Bootkit Defeat Technique for SCSI drives How we can use this stack outside of the operating
system’s normal activity
IDE drive technique in Appendix B
Sneak peak at Windows 8 Release Preview changes
Demo – Defeating TDL4
![Page 4: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/4.jpg)
Terminology and Concepts
Technical Background 4
![Page 5: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/5.jpg)
Basics
Port driver – abstraction interface provided by OS, hides underlying protocol details from class driver
Miniport driver – manufacturer-supplied driver to interface with hardware (Host Bus Adapter/HBA); linked against port driver for specific transport technology
Class driver – a driver that abstracts the underlying technology of a category of devices that share similar qualities (e.g., cdrom.sys)
Normal I/O path – the route an I/O request takes during regular system operation
Crash dump I/O path – the route the kernel uses to write a crash dump file to disk during a crash
5
![Page 6: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/6.jpg)
Normal I/O Path6
![Page 7: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/7.jpg)
Crash Dump I/O Path7
![Page 8: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/8.jpg)
Why two paths?8
When a bugcheck occurs, the OS has no idea
where the problem occurred – it could have
happened inside a driver in the normal I/O
path.
What differs between the two paths?
Normal I/O Path Crash Dump I/O Path
Primary drivers Many, layered Modified port and miniport
Filter drivers Many, layered Crash dump filters only
Controlled by I/O manager Kernel or crashdmp.sys
Documented? Yes *cough*
![Page 9: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/9.jpg)
The Crash Dump Mechanism9
Encompasses the entire crash dump process
From when it is initialized during system boot up to when it is used after KeBugCheck2()
Primary components:
The kernel
Crashdmp.sys (Vista+)
The crash dump driver stack or just “crash dump stack”
Goal: Write a crash dump file to boot device or save state in a hibernation file
![Page 10: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/10.jpg)
The Crash Dump Stack10
A “stack” of drivers, consisting of:
A dump port driver
A dump miniport driver
One or more crash dump filter drivers
Initialized in two phases:
System startup/page file creation (pre-initialization)
System crash (post-initialization)
Used when:
A bug check occurs
The system is about to hibernate
![Page 11: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/11.jpg)
The Crash Dump Stack – Common Drivers
11
Driver Name On Disk Driver Base Name in
Memory
Purpose
diskdump.sys dump_diskdump SCSI/Storport dump port
driver with required exports
from scsiport.sys and
storport.sys. This driver is
unloaded.
dumpata.sys dump_dumpata IDE/ATA dump port driver with
required ataport.sys exports.
This driver is unloaded.
scsiport.sys dump_scsiport The final SCSI/Storport dump
port driver.
ataport.sys dump_ataport The final IDE/ATA dump port
driver.
atapi.sys dump_atapi An older, generic ATAPI
miniport driver provided by the
OS for IDE/ATA drives
vmscsi.sys dump_vmscsi The miniport driver provided
by VMWare for SCSI drives.
LSI_SAS.sys dump_LSI_SAS The miniport driver provided
by LSI Corporation for serial-
attached storage drives.
dumpfve.sys dump_dumpfve Windows full volume
encryption crash dump filter
driver
![Page 12: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/12.jpg)
Crash Dump Environment12
Normal I/O path is disabled
All processors are disabled except the one the
current thread is executing on
Active CPU becomes single-threaded (IRQL is
raised to HIGH_LEVEL) and uninterruptible
I/O sent to the crash dump stack is
synchronous
If IDE controller, only the channel containing
the device with the paging file is enabled
![Page 13: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/13.jpg)
Crash Dump Stack Initialization and Usage
after Windows Vista
Technical Background13
![Page 14: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/14.jpg)
Crash Dump Stack Configuration14
Crash dump is configured via IoConfigureCrashDump()
Reads in registry settings to control dump
behavior
Passes handle to system paging file to IopInitializeCrashDump()
Triggered via NtSetSystemInformation()
or PoBroadcastSystemState() or
PoShutdownBugCheck()
![Page 15: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/15.jpg)
Initialization15
![Page 16: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/16.jpg)
Load and Call Entry Point of Crashdmp.sys
16
Nearly all of crash dump code was removed from kernel and put in crashdmp.sys
KiInitializeKernel() IoInitSystem() OR NtCreatePagingFile()
IoInitializeCrashDump(HANDLE PageFile)
IopLoadCrashDumpDriver() – loads crashdmp.sys
Crashdmp!DriverEntry() – fills crash dump call table
Entry point called with two arguments:
Name of the arc boot device
Pointer to a global crashdmp callback table
![Page 17: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/17.jpg)
Crashdmp.sys Call Table17
Table Offset* Value
0x0 1
0x4 1
0x8 CrashdmpInitialize
0xC CrashdmpLoadDumpStack
0x10 CrashdmpInitDumpStack
0x14 CrashdmpFreeDumpStack
0x18 CrashdmpDisable
0x1C CrashdmpNotify
0x20 CrashdmpWrite
0x24 CrashdmpUpdatePhysicalRange
*Pointer width is 8 bytes on 64-bit systems
![Page 18: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/18.jpg)
Identify and Initialize Crash Dump Drivers
18
KiInitializeKernel()
IoInitSystem() OR
NtCreatePagingFile()
IoInitializeCrashDump()
Crashdmp!CrashDmpInitialize():
Crashdmp!CrashdmpLoadDumpStack():
Crashdump!QueryPortDriver()
Crashdmp!LoadPortDriver()
Crashdmp!LoadFilterDrivers()
Crashdmp!InitializeFilterDrivers()
![Page 19: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/19.jpg)
CrashdmpInitialize() 19
References boot device’s FILE_OBJECT
Read registry for crash dump settings
Stored in local crashdump control block
Initializes crashdump control block
Registers a KbCallbackSecondaryDumpData
bugcheck callback
Calls CrashdmpLoadDumpStack()…
![Page 20: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/20.jpg)
CrashdmpLoadDumpStack() 20
Queries port driver capabilities using IOCTL_SCSI_GET_DUMP_POINTERS, IOCTL_SCSI_GET_ADDRESS, IOCTL_SCSI_GET_PARTITION_INFO, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IOCTL_SCSI_GET_DRIVE_GEOMETRY_EX
Locates all crash dump drivers: port, miniport and crash dump filter drivers Copies them into memory with “dump_” prefix
No DRIVER_OBJECT or DEVICE_OBJECT!
Port driver will be one of dump_scsiport, dump_ataport or dump_storport; on disk either diskdump.sys (scsi/storport) or dumpata.sys (ataport)
Miniport can be named anything
![Page 21: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/21.jpg)
Usage
21
![Page 22: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/22.jpg)
Call Dump Driver Entry Points22
KeBugCheck2() IoWriteCrashDump():
Calls the eighth entry in the CrashDmpCallTable table,
CrashDmpNotify() - displays the string
“collecting data for crash dump”
Fills dump block with bug check codes and other
debug information
Appends a triage dump if necessary
![Page 23: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/23.jpg)
Call Dump Driver Entry Points and
Dump Port Driver Callbacks23
KeBugCheck2() IoWriteCrashDump():
Calls the ninth entry in the CrashDmpCallTable
table, CrashDmpWrite():
CrashdmpInitDumpStack():
StartFilterDrivers() – calls the DumpStart
callback of each crash dump filter driver
InitializeDumpDriver() – calls the dump driver
entry point; calls the DiskDumpOpen callback provided by
the dump port driver; fills dump context structure with callback pointers CrashdmpWriteRoutine,
CrashdmpWritePendingRoutine,
CrashdmpFinishRoutine
![Page 24: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/24.jpg)
Data Written to Dump File24
KeBugCheck2() IoWriteCrashDump(): CrashDmpWrite():
CrashdmpInitDumpStack():
DumpWrite() – creates dump file based on configuration: FillDumpHeader()
Calls one of: WriteFullDump()
WriteKernelDump()
WriteMiniDump()
InvokeSecondaryDumpCallbacks() - Invokes all BugCheckSecondaryDumpDataCallback callbacks to allow drivers to append data to the completed crash dump file.
InvokeDumpCallbacks() - Invokes all BugCheckDumpIoCallback callbacks, informing them crash dump is complete.
![Page 25: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/25.jpg)
How to bypass the Normal I/O Path and
use the Crash Dump I/O Path to read and
write to disk
Bootkit Defeat Technique25
![Page 26: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/26.jpg)
Inspiration26
Restrictions on Miniport Drivers that Manage the Boot Drive:
“A storage miniport driver that manages an adapter for a boot device is subject to special restrictions during a system crash. While dumping the system's memory image to disk, the miniport driver must operate within a different environment. The usual communication between the miniport driver, the port driver, and disk class driver is interrupted. The kernel does disk I/O by direct calls to the disk dump port driver (diskdump.sys for SCSI adapters or dumpata.sys for ATA controllers), bypassing file systems, and the normal I/O stack. The disk dump driver, in turn, calls the boot device's miniport driver to handle all I/O operations, and the disk dump driver intercepts all of the miniport driver's calls to the port driver.” [1]
![Page 27: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/27.jpg)
Leveraging the Crash Dump I/O
Path27
The crash dump mechanism provides a
pristine path to disk
But it only provides write capabilities
Leverage knowledge of the crash dump
mechanism and internals of the port/miniport
relationship to coerce read/write
Here’s how…
![Page 28: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/28.jpg)
..sort of like the O/S does…28
![Page 29: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/29.jpg)
…but more like this29
![Page 30: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/30.jpg)
Identify Crash Dump Port/Miniport
Drivers30
Walk loaded module list
Single out dump drivers easily via “dump_” prefix
Port driver will be one of dump_scsiport, dump_storport or dump_ataport
Miniport driver name: open a handle to the class driver’s device object, walk
attached devices to the lowest one
Vista+ DUMP_POINTERS_EX.DriverList
Once drivers have been found, call their entry points with the appropriate arguments Dump port: DriverEntry(NULL, DumpInit*)
Dump miniport: DriverEntry(NULL, NULL)
![Page 31: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/31.jpg)
Get Boot Device Information31
IOCTL to get hardware register mapping and port configuration information (IOCTL_SCSI_GET_DUMP_POINTERS); data returned in DUMP_POINTERS or DUMP_POINTERS_EX structure
IOCTL to get boot device location such as Target id, path Id, and Lun (IOCTL_GET_SCSI_ADDRESS); data returned in a SCSI_ADDRESS structure
Resulting information is stored in the DUMP_INITIALIZATION_CONTEXT structure before calling the dump port driver’s DriverEntry
![Page 32: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/32.jpg)
Find StartIo or DispatchCrb32
How do we send I/O requests?
There is no device object for dump port driver
Use internal functions
StartIo (SCSI) – accepts a single
SCSI_REQUEST_BLOCK (SRB) as argument
DispatchCrb (IDE) – accepts a single
argument, a channel extension structure
Find functions by scanning dump port driver’s
image’s text section for “magic bytes”
![Page 33: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/33.jpg)
Find the Dump Port Driver’s Device Extension (1/2)
33
Can’t simply call the internal functions, more initialization required
Port/miniport share a device extension structure that must be properly initialized An internal variable of the port driver
Most critical fields are filled in by dump port driver/miniport driver’s DriverEntry routines
Two methods to find Device Extension Call a dump port function that leaks a pointer to it
Use DumpInit.MemoryBlock + 16 Dump port’s DriverEntry()assigns Device Extension to DumpInit->MemoryBlock+16, which we control and pass as second argument to DriverEntry() when we call it
Both methods work for all transports all the way through Windows 8
![Page 34: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/34.jpg)
Find the Dump Port Driver’s Device Extension (2/2)
34
Function pointer leak example: Diskdump.sys leaks in ecx register in
DiskDumpOpen()
Transport Leaking Function Leaked in Register Architecture
SCSI/Storoprt
(diskdump.sys)
DiskDumpOpen ecx x86
SCSI/Storport
(diskdump.sys)
DriverEntry rdx x64
IDE (dumpata.sys)* IdeDumpOpen ecx x86
IDE (dumpata.sys)* IdeDumpOpen rcx x64
![Page 35: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/35.jpg)
Send SRB (SCSI) (1/2)35
Mimic DiskDumpWrite()
Allocate an MDL at offset 0xD0 (0x118 x64) into the
device extension structure – MDL describes the SRB.DataBuffer
Call StartIo()
![Page 36: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/36.jpg)
Send SRB (SCSI) (2/2)36
After MDL is created, send an SRB as follows: SRB.Function - SRB_FUNCTION_EXECUTE_SCSI
SRB.PathId, SRB.TargetId, SRB.Lun – set to corresponding fields in SCSI_ADDRESS
SRB.CdbLength - 10 for 10-byte SCSI-2 command
SRB.SrbFlags - specify flags for a read operation
SRB.DataTransferLength - 512
SRB.DataBuffer - allocate 512 bytes NonPagedPool – result stored here
SRB.Cdb – the SCSI-2 command descriptor block (cdb) Describes the location on disk to read
![Page 37: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/37.jpg)
Overview
Demo37
![Page 38: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/38.jpg)
Recent Bootkits38
Alureon/TDL4 has gained popularity in the last few years
Abuses driver trust chain by hooking the port and miniport drivers, which are at the bottom of the disk driver stack trust chain
Modifies I/O requests in various ways to hide its rootkit file system, as well as return a clean MBR
Similar MBR/VBR rootkits include Popureb, Stoned, Hasta La Vista, Zeroaccess
Completely new strains, as well as variants, emerging constantly
![Page 39: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/39.jpg)
TDL4 Bootkit Infection39
Modifies the miniport’s device object and driver object
DRIVER_OBJECT.DriverStartIo hooked
DEVICE_OBJECT.DriverObject hooked
Lowest attached device is unlinked from the miniport device by hooking DEVICE_OBJECT.NextDevice
Monitors for read or write attempts to the boot sector and its hidden file system
If boot sector, return original, clean MBR
If hidden file system, return zeroes
For more info, see [2]
![Page 40: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/40.jpg)
Defeating TDL4
Demo40
![Page 41: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/41.jpg)
Results – Full Disclosure!41
SCSI – working from Windows XP – 7 (tested)
IDE – polling is hard
Method 1: IRB sent, garbage returned
Either the port driver is messing up the IRB somewhere
during polling or we are missing a field in dump extension
Method 2: IRB sent, nothing returned , IRB status 2
(data length mismatch), ATA status 0x20 (?)
IRB.TaskFile might have invalid values
IDE_TASK_FILE: No examples anywhere!
Dump extension field missing – data length?
![Page 42: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/42.jpg)
PoC Improvements42
POCs for both transports can cause
momentary lag or event deadlock, because
normal I/O path is not properly “shutdown”
Solution:
SCSIPort (push model, port driver controls
queuing I/O) - Need to send flush and lock
request SRB’s
StorPort – (pull model, miniport driver controls queuing I/O) – StorPortPauseDevice()
![Page 43: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/43.jpg)
A Sneak Peak at Exciting New Changes
Windows 8 Release Preview43
![Page 44: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/44.jpg)
Core Kernel Changes44
Synchronization changes suggest crash dump
stack can be used in multiple places
New function IopInitializeCrashDump()
Contents of IoInitializeCrashDump() moved
here
only called if a prior initialize attempt fails and it guards call to IopInitializeCrashDump()with critical region
IopCrashDumpLock previously only used when
crash dump stack is (re)configured; now
additionally used when (re)initialized
![Page 45: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/45.jpg)
Crashdmp Call Table Changes45
Table Offset* Windows 7 Value Windows 8 RP Value
0x0 1 1
0x4 1 4
0x8 CrashdmpInitialize
0xC CrashdmpLoadDumpStack
0x10 CrashdmpInitDumpStack
0x14 CrashdmpFreeDumpStack
0x18 CrashdmpDisable
0x1C CrashdmpNotify
0x20 CrashdmpWrite
0x24 CrashdmpUpdatePhysicalRange
0x28 CrashdmpResumeCapable
0x2C CrashdmpGetTransferSizes
0x30 CrashdmpLogStatusData
0x34 CrashdmpReady
*Pointer width is 8 bytes on 64-bit systems
![Page 46: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/46.jpg)
Crashdmp.sys Changes (1/6)46
GetLegacyPortDriverName() no longer uses static dump port driver names (e.g, “diskdump.sys”, “storport.sys”, “scsiport.sys”)
After loading a crash dump driver in CrashdmpLoadDriver()via MmLoadSystemImage(), it uses RtlImageNtHeader on imageBase instead of direct return value – possible bug fix
New hiber functions, ResumeCapable
ETW tracing, performance counters
Enhanced logging in c:\DumpStack.log.tmp
Crashdmp.sys “drive telemetry” callback
New dump type: bitmap dump
![Page 47: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/47.jpg)
Crashdmp.sys Changes (2/6)47
New security checks using __fastfail
intrinsic [3]
CORRUPT_LIST_ENTRY cases
DumpWrite function used by call table’s
CrashdmpWrite is not handled by IDA auto
analysis – you must undefine bogus
data/code, restart analysis or force code
generation on block, and recreate the function
Several other functions have this issue
![Page 48: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/48.jpg)
Crashdmp.sys Changes (3/6)48
![Page 49: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/49.jpg)
Crashdmp.sys Changes (4/6)49
CrashdmpWrite behavior changed:
Checks that dump device is ready (eg, supported firmware); if so, call DumpWrite; if not, call
DumpWriteCapsule which simulates the write
by calling special “dump capsule” dump filters but
does not write actual dump to disk
“Dump capsule” concept not documented
![Page 50: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/50.jpg)
Crashdmp.sys Changes (5/6)50
Dump port driver DriverEntry() prototype
has changed
Old: DriverEntry(NULL, DumpInit*)
New: DriverEntry(NULL,
CrashdmpContext*)
This will affect our PoC (it won’t work on Win8)
New PoC coming soon…
![Page 51: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/51.jpg)
Crashdmp.sys Changes (6/6)51
New CrashdmpReadRoutine populated in
dump context structure by InitializeDumpDriver()
Wrapper around a call to new dump port driver function Diskdump!DiskDumpRead()
Calls new function DiskDumpIoIssue() which sets
up SCSI read SRB and performs all of the hard tasks
that the POC in this paper had to hack
![Page 52: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/52.jpg)
Why a New Read Capability?52
Not to make my research irrelevant
Internally: supports logging and new hibernation resume feature
Externally: crash dump filter drivers now have the ability to filter read requests to dump port driver Define a DUMP_READ callback [4]
Provide a pointer to the callback in FILTER_INITIALIZATION_CONTEXT [5]
“Filter drivers can modify the contents of the data buffer contained in Mdl to revert any changes made to the data when it was written to disk” [4] Probably to support hibernation resume; for example,
encryption drivers need to decrypt
![Page 53: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/53.jpg)
How to Use It (1/3)53
Filter read callback is cool, but not helpful to the goal of
this research
We can only see read requests initiated by kernel/dump port
driver; not useful for controlling what is read
But the point is the Crash Dump I/O Path now supports
reading – we don’t need to hack it
At least not as bad as before
Contention issues with normal I/O path still exist
![Page 54: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/54.jpg)
How to Use It (2/3)54
We have two options:
1. CrashdmpReadRoutine(Type, Offset, Mdl): just a
wrapper for port read routine; only adds functionality to call
filter read callbacks
2. Diskdump!DumpRead(Type, Offset, Mdl): does the
actual work with miniport to complete I/O
The first option adds no value for us
Best option: call the port driver’s DumpRead() routine
directly
Determine any pre-requisites
![Page 55: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/55.jpg)
How to Use It (3/3)55
The dump port driver read routine is a simple wrapper:
DiskDumpIoIssue() kindly handles the entire I/O
issuing process for us (i.e, our POC’s hack):
SRB initialization for a read operation
Mapping the MDL if required
Calling StartIo(), which calls the dump miniport
Polling to wait on result
Can we call DiskDumpRead() directly?
Stay tuned…
![Page 56: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/56.jpg)
Conclusions56
![Page 57: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/57.jpg)
Takeaways57
Why is this important?
We have a separate path to disk which is not currently hooked by any malware I am aware of
Tampering with the crash dump mechanism could destabilize the system
We can read AND write to disk this way
The crash dump port driver only provides callbacks to write to disk, but the StartIo function lets us issue any arbitrary SRB
The ability to write to disk with this technique provides us unique remediation (file cleaning) opportunities
New read functionality in Windows 8 makes reading disk via dump port driver officially supported (sort of)!
![Page 58: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/58.jpg)
Stay Tuned…58
Keep an eye on blog.crowdstrike.com
New series on Windows 8 coming soon
Alex Ionescu (author of Windows Internals) covers
new security features and how to break them
I will be posting about crash dump changes related to
this research
Whitepaper coming soon
Windows 8 PoC coming soon
![Page 59: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/59.jpg)
References59
[1] http://msdn.microsoft.com/en-us/library/ff564084(v=VS.85).aspx
[2] http://go.eset.com/us/resources/white-papers/The_Evolution_of_TDL.pdf
[3] http://www.alex-ionescu.com/?m=201110
[4] http://msdn.microsoft.com/en-us/library/windows/hardware/hh439713(v=vs.85).aspx
[5] http://msdn.microsoft.com/en-us/library/windows/hardware/ff553865(v=vs.85).aspx
Special thanks to Alex Ionescu
![Page 61: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/61.jpg)
Crash Dump Stack Initialization and Usage
before Windows Vista
Appendix A61
![Page 62: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/62.jpg)
Initialization62
![Page 63: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/63.jpg)
Initialize IopDumpControlBlock63
KiInitializeKernel()
IoInitSystem() OR
NtCreatePagingFile():
IoInitializeCrashDump():
IopInitializeDCB():
Allocate IopDumpControlBlock structure
Fill in basic debug information - # CPUs, architecture, OS
version, etc
Read registry settings for crash dump configuration
![Page 64: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/64.jpg)
IopDumpControlBlock64
IopDumpControlBlock – global kernel variable typedef struct _DUMP_CONTROL_BLOCK { UCHAR Type; CHAR Flags; USHORT Size; CHAR NumberProcessors; CHAR Reserved; USHORT ProcessorArchitecture; PDUMP_STACK_CONTEXT DumpStack; PPHYSICAL_MEMORY_DESCRIPTOR MemoryDescriptor; ULONG MemoryDescriptorLength; PLARGE_INTEGER FileDescriptorArray; ULONG FileDescriptorSize; … }DUMP_CONTROL_BLOCK, *PDUMP_CONTROL_BLOCK;
![Page 65: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/65.jpg)
Identify and Initialize Crash Dump
Drivers65
IoInitializeCrashDump():
IoGetDumpStack() IopGetDumpStack(): Fills IopDumpControlBlock.DumpInit:
Boot device type, geometry and hardware attributes
Locates all crash dump drivers: port, miniport and crash dump filter drivers Copies them into memory with “dump_” prefix
No DRIVER_OBJECT or DEVICE_OBJECT! Port driver will be one of dump_scsiport, dump_ataport
or dump_storport; on disk either diskdump.sys (scsi/storport) or dumpata.sys (ataport)
Miniport can be named anything
Fills IopDumpControlBlock.DumpStack with linked list of copied drivers
![Page 66: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/66.jpg)
IopDumpControlBlock.DumpStack
66
typedef struct _DUMP_STACK_CONTEXT
{
DUMP_INITIALIZATION_CONTEXT Init;
LARGE_INTEGER PartitionOffset;
PVOID DumpPointers;
ULONG PointersLength;
PWCHAR ModulePrefix;
LIST_ENTRY DriverList;
ANSI_STRING InitMsg;
ANSI_STRING ProgMsg;
ANSI_STRING DoneMsg;
PVOID FileObject;
enum _DEVICE_USAGE_NOTIFICATION_TYPE UsageType;
} DUMP_STACK_CONTEXT, *PDUMP_STACK_CONTEXT;
![Page 67: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/67.jpg)
IopDumpControlBlock.DumpStack
67
DumpPointers - contains hardware-specific information about the disk drive (via IOCTL_SCSI_GET_DUMP_POINTERS) which is used during write I/O operations to the crash dump file.
DriverList - contains a linked list of data structures that describe the driver image of each driver in the crash dump stack; used at actual crash dump time to initialize each driver
Init - of type DUMP_INITIALIZATION_CONTEXT (undocumented but exported), shown below, is only partially filled in during the 1st phase of initialization.
![Page 68: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/68.jpg)
Usage
68
![Page 69: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/69.jpg)
Call Dump Driver Entry Points (1/3)69
During pre-initialization, drivers were only mapped into memory - no management blocks created, no entry points called
Each driver in the dump stack will now have its entry point called
The first driver in the stack is always the dump port and it is always called first
Two arguments: 1. NULL
2. IopDumpControlBlock.DumpInit
![Page 70: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/70.jpg)
Call Dump Driver Entry Points (2/3)70
typedef struct _DUMP_INITIALIZATION_CONTEXT
{
ULONG Length;
ULONG Reserved;
PVOID MemoryBlock;
PVOID CommonBuffer[2];
PHYSICAL_ADDRESS PhysicalAddress[2];
PSTALL_ROUTINE StallRoutine;
PDUMP_DRIVER_OPEN OpenRoutine;
PDUMP_DRIVER_WRITE WriteRoutine;
PDUMP_DRIVER_FINISH FinishRoutine;
struct _ADAPTER_OBJECT *AdapterObject;
PVOID MappedRegisterBase;
PVOID PortConfiguration;
…
} DUMP_INITIALIZATION_CONTEXT,*PDUMP_INITIALIZATION_CONTEXT;
![Page 71: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/71.jpg)
Call Dump Driver Entry Points (3/3)71
OpenRoutine, WriteRoutine and FinishRoutine fields are populated: pointers to functions exported by the dump port driver
which provide the kernel the ability to write the crash dump data to the crash dump file
The dump miniport driver’s DriverEntry is called registers with the dump port driver
All other dump driver’s DriverEntry are called with NULL arguments According to MSDN, this notifies them to operate in
“crash dump mode”
![Page 72: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/72.jpg)
Call Dump Port Driver Callbacks72
KeBugCheck2() IoWriteCrashDump(): IoInitializeDumpStack() – performs post-initialization of
crash dump drivers
DiskDumpOpen() – this port driver export is called to prepare the crash dump file
Displays the dump string “Beginning dump of physical memory”, stored in the DUMP_CONTROL_BLOCK structure
Calculates the dump storage space required based on configuration
Fills a dump header with bug check codes and other debug information
Invokes all BugCheckDumpIoCallback callbacks registered with the kernel via KeRegisterBugCheckReasonCallback(), passing the dump header
![Page 73: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/73.jpg)
Data Written to Dump File73
KeBugCheck2() IoWriteCrashDump(): IoInitializeDumpStack() – performs post-
initialization of crash dump drivers
One of the following functions calls DiskDumpWrite() until all crash dump data is written: IopWriteSummaryHeader()
IopWriteSummaryDump()
IopWriteTriageDump()
Invokes all BugCheckSecondaryDumpDataCallback callbacks to allow drivers to append data to the completed crash dump file
Calls DiskDumpFinish() to close crash dump file
Invokes all BugCheckDumpIoCallback callbacks, informing them crash dump is complete.
![Page 74: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/74.jpg)
Bootkit Defeat Technique for IDE Drives
Appendix B74
![Page 75: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/75.jpg)
Send IRB (IDE) – General Idea75
![Page 76: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/76.jpg)
Send IRB (IDE) – Method 176
Relies on calling port driver internal functions
Mimic IdeDumpWritePending() Allocate a CRB in DUMP_INITIALIZATION_CONTEXT.MemoryBlock at the correct offset (0x120 for x86, 0x1C0 for x64)
Allocate and fill in an IRB at offset 0x288 (0x3E8 for x64) in the CRB
Store a pointer to a callback function in the CRB at offset 0x4, which will be invoked when the dump port driver is notified that the I/O request is complete
Allocate an MDL at offset 0x50 (0x88 for x64) in the CRB
Send the CRB to DispatchCrb()
Wait via IdeDumpWaitOnRequest()function
![Page 77: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/77.jpg)
Send IRB (IDE) – Method 277
Completely bypass dump port driver
Mimic IdeDumpWritePending()
Allocate a CRB in DUMP_INITIALIZATION_CONTEXT.MemoryBlock at the correct offset (0x120 for x86, 0x1C0 for x64)
Store a pointer to a callback function in the CRB at offset 0x4, which will be invoked when the dump port driver is notified that the I/O request is complete
Allocate and fill in an IRB at offset 0x288 (0x3E8 for x64) in the CRB
Replace DispatchCrb() with Call the miniport’s HwStartIo routine, which is stored at offset 0x2E in the
device extension, passing the device extension and the IRB
Replace IdeDumpWaitOnRequest() with:
Poll the device until the IRB status changes from zero by calling the miniport’s HwInterrupt routine which is stored at offset 0x2F in the device extension, passing the device extension only
![Page 78: I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits](https://reader034.fdocuments.net/reader034/viewer/2022051411/5409260b8d7f7267058b46aa/html5/thumbnails/78.jpg)
Send IRB (IDE)78
IRB.Function - IRB_FUNCTION_ATA_COMMAND
IRB.Channel - should be set to the value stored in the channel extension’s Channel field which is at offset 0x8A (0xEA for x64) from the start of the CRB
IRB.TargetId - should be set to the value stored in the channel extension’s TargetId field which is at offset 0x45D (0x6A9 for x64) from the start of the CRB
IRB.Lun - should be set to the value stored in the channel extension’s Lun field which is at offset 0x45E (0x6AA for x64) from the start of the CRB