Recently, we came across the BthPan.sys driver while researching
Microsoft's Bluetooth implementation within 32-bit Windows XP (SP3),
and after conducting a number of fuzzing tests, we discovered that
this driver has a vulnerability known as a write-what-where condition.
It should be noted that the BthPan.sys driver is not enabled or even
installed by default. Thus, the attack described below will only
function if the end user or operating system administrator has
installed the driver, such as via 'Add/Remove Programs' within the
Control Panel, or installing some hardware driver that implicitly
enables it.

Once installed, the BthPan.sys driver is loaded into the kernel
the next time a Bluetooth device is inserted in the target computer.
After that, a process (svchost) is spawned to support Bluetooth
operations. By monitoring the IOCTL calls made by this process as
a result of various fuzzing runs, we were able to derive portions
of the available attack surface within the driver, and that's what
led to the discovery of the write-what-where condition.

Example Python code that triggers this vulnerability can be found
below. The important piece of information within this code is not
the \x90 but rather the OutputAddress (0xffff0000) used within the
DeviceIoControlFile function call. Since no memory had been previously
allocated at this address, the kernel will throw an error as soon as
any attempt is made to write to it.

A complete memory dump from the target computer during the blue
screen of death was taken. By analyzing the context of the crash,
we could see the OuputAddress (0xffff0000) had a write attempt
that failed.

PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except, it must be protected by a Probe. Typically the address is just plain bad or it is pointing at freed memory.
Arguments:
Arg1: ffff0000, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: 804f3b76, If non-zero, the instruction address which referenced the bad memory address.
Arg4: 00000000, (reserved)

The CPU registers from the TRAP_FRAME at the time of the crash show a
MOVS instruction with the EDI register set to the value that we
provided to the DeviceIoControlFile() function.

The DWORD at 0x8054593c is the memory address for the first
entry within the HalDispatchTable. This entry corresponds to the
ntdll!NtQueryIntervalProfile() function found below, which issues a CALL
instruction on the pointer found within the EDX CPU register.