Microsoft Windows - 'gdi32.dll' EMR_SETDIBITSTODEVICE Heap Out-of-Bounds Reads / Memory Disclosure

EDB-ID:

41363




Platform:

Windows

Date:

2017-02-15


Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=992

In issue #757, I described multiple bugs related to the handling of DIBs (Device Independent Bitmaps) embedded in EMF records, as implemented in the user-mode Windows GDI library (gdi32.dll). As a quick reminder, the DIB-embedding records follow a common scheme: they include four fields, denoting the offsets and lengths of the DIB header and DIB data (named offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc). A correct implementation should verify that:

1) cbBmiSrc is within expected bounds, accounting for the DIB header, color palette etc.
2) the (offBmiSrc, offBmiSrc + cbBmiSrc) region resides within the record buffer's area.
3) cbBitsSrc is within expected bounds, and especially that it is larger or equal the expected number of bitmap bytes.
4) the (offBitsSrc, offBitsSrc + cbBitsSrc) region resides within the record buffer's area.

In the previous bug, I listed various combinations of missing checks in at least 10 different records:

- EMR_ALPHABLEND
- EMR_BITBLT
- EMR_MASKBLT
- EMR_PLGBLT
- EMR_STRETCHBLT
- EMR_TRANSPARENTBLT
- EMR_SETDIBITSTODEVICE
- EMR_STRETCHDIBITS
- EMR_CREATEMONOBRUSH
- EMR_EXTCREATEPEN

As part of MS16-074, some of the bugs were indeed fixed, such as the EMR_STRETCHBLT record, which the original proof-of-concept image relied on. However, we've discovered that not all of the DIB-related problems are gone. For instance, the implementation of EMR_SETDIBITSTODEVICE (residing in the MRSETDIBITSTODEVICE::bPlay function) still doesn't enforce condition #3. As a result, it is possible to disclose uninitialized or out-of-bounds heap bytes via pixel colors, in Internet Explorer and other GDI clients which allow the extraction of displayed image data back to the attacker.

The proof-of-concept file attached here consists of a single EMR_SETDIBITSTODEVICE record (excluding the header/EOF records), which originally contained a 1x1 bitmap. The dimensions of the DIB were then manually altered to 16x16, without adding any more actual image data. As a consequence, the 16x16/24bpp bitmap is now described by just 4 bytes, which is good for only a single pixel. The remaining 255 pixels are drawn based on junk heap data, which may include sensitive information, such as private user data or information about the virtual address space. I have confirmed that the vulnerability reproduces both locally in Internet Explorer, and remotely in Office Online, via a .docx document containing the specially crafted EMF file.

It is strongly advised to perform a careful audit of all EMF record handlers responsible for dealing with DIBs, in order to make sure that each of them correctly enforces all four conditions necessary to prevent invalid memory access (and subsequent memory disclosure) while processing the bitmaps.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41363.zip