Google’s CVR team discovered memory corruption vulnerabilities in the Kakadu JPEG 2000 image library, where exploiting these vulnerabilities in an unknown environment is challenging due to the lack of information about the binary and its execution environment.
To overcome this, the team developed a “Conditional Corruption” technique that allowed them to create a self-modifying image for exploitation, which enabled remote code execution on affected systems, including major companies and a Google service.
The JPEG 2000 standard divides images into boxes and codestream segments, where boxes store metadata like image dimensions and color information, while codestream segments contain the actual image data.
The codestream is divided into tiles, which are rectangular sections of the image compressed independently. Each tile has a tile index, which determines its position within the image. The tile index, image dimensions, and tile dimensions can be used to calculate the exact location of a tile.
Researchers discovered two vulnerabilities in Kakadu, a JPEG 2000 image processing library. The first vulnerability allows arbitrary file reading by exploiting the JPEG 2000 standard’s JPX extension, which allows for codestream fragmentation across multiple files.
By crafting carefully constructed JPX images, the researchers were able to inject bytes from local files into the codestream and exfiltrate them. The second vulnerability is an out-of-bounds heap write due to signed integer multiplication, which could potentially be exploited to execute arbitrary code.
The Kakadu image decoder suffers from an integer overflow vulnerability during the writing of multi-row tiles. The overflow occurs when a 4-byte signed integer is used to calculate the row gap, which is then added to a pointer to the next row.
It can lead to the pointer pointing outside the image buffer, resulting in an out-of-bounds write. The vulnerability can be exploited by controlling the width of the image, allowing attackers to write controlled data backwards in memory.
The 808080 Apocalypse, caused by uninitialized data, was resolved using the SOT marker and explored various techniques to achieve a reliable write primitive, including global heap pointers and large allocation arrays.
Ultimately found a primitive using the Composition Layer Extensions Box, which allowed to overwrite controlled data in the heap.
The Kha-Kha Slide is a novel technique that dynamically adapts the tile data written in a heap overflow based on the heap contents, which involves creating a series of lookup tables to search for a specific byte value that indicates the object offset.
Each table contains markers that jump to different locations depending on the found byte value. By iterating through these tables, the exploit can eventually find the correct offset and trigger the heap overflow with the desired tile data.
Bug Hunters initially exploited a file-read vulnerability in Kakadu to gather information about the server environment. Using this information, they employed the “Conditional Corruption” technique to target a specific worker process and ensure reliable exploitation.
By carefully verifying the payload’s effectiveness, they obtained a write-what-where primitive, which allowed them to manipulate global variables and ultimately hijack the process’s control flow, executing arbitrary code without affecting users.