When parsing a specially crafted BMP file, an erroneous memory copy operation can cause a heap buffer overflow leading to arbitrary code execution.
While parsing a specially crafted BMP file, an unchecked value specifying bitmap width is used to calculate the size for the memory write operation. Compression method must be set to 0x01 or BI_RLE8. While reading the file, a piece of memory on the heap is effectively overwritten by zeros. The size of this overwrite is unchecked and comes straight from the bitmap width. This can lead to heap data structures overwrite with NULL bytes. In the supplied testcase, the out of bounds null byte write overwrites a function pointer which leads to a crash. By carefully tweaking the size of the overwrite, a function pointer on the heap can be manipulated and arbitrary code execution achieved.
The supplied testcase has compression method bit set to 0x1 at offset 0x1E. BMP image data has the width field set to 0x4141 which gets used in the size of the overflow. The overflow happens in the function VwStreamRead in libvs_bmp.so (image base being 0xb7f80000), specifically in the following basic block:
` .text:B7F826A9 loc_B7F826A9: .text:B7F826A9 mov byte ptr [ebp+0], 0 .text:B7F826AD add ebp, 1 .text:B7F826B0 lea eax, [edx+ebp] .text:B7F826B3 cmp word ptr [esp+1DCh+var_150], ax .text:B7F826BB ja short loc_B7F82 `
Notice that the basic block loops back to itself as long as
ax is less than
esp+1DCh+var_150 which contains
the bitmap width value. Initial value of
ebp is a heap pointer and memory starting at
overwritten by zeros without bounds checking, resulting in heap corruption.
The vulnerability can be triggered with the supplied testcase in the
supplied with the SDK. The same vulnerability can be triggered through a specially crafted ICO
file that contains the same BMP data.
2015-10-19 - Discovery
2016-04-20 - Initial Vendor Communication
2016-07-19 - Public Release
Discovered by Aleksandar Nikolic of Cisco Talos.