By Carsten Eiram
Last week, we finished off the final BAs for the latest round of vulnerabilities fixed by the Microsoft security bulletin releases.
There were some very interesting vulnerabilities fixed this time and two of these were the PowerPoint Viewer 2003 vulnerabilities (CVE-2010-0033 and CVE-2010-0034). As such the vulnerabilities and analysis were simple and very straight-forward, however, an interesting case of how the "CExpParameterValidate::Read(..)" function in ole32.dll is implemented differently across versions of Windows has a big impact on the exploitability and even existence of the vulnerabilities.
While Microsoft rates the exploitability rating as "1" for these two vulnerabilities on their monthly index, then it's somewhat misleading as it depends on the OS that PowerPoint Viewer 2003 is installed on. If installed on e.g. Windows Server 2003 or Windows 7, then the two errors in the code do lead to stack-based buffer overflows, however, if installed on Windows XP (and possible earlier versions), no buffer overflows occur.
We have made the BA that describes the two vulnerabilities in technical details publicly available, but let me briefly sum up the problem here: The unpatched version has two signed comparisons used to determine if a TextBytesAtom or TextCharsAtom record size is greater than 127 before copying the record content into a 128-byte stack buffer via a call to CExposedStream::Read(..), provided by ole32.dll. However, since the comparison is signed, a value greater than 7FFFFFFFh is considered negative and passes the check, causing CExposedStream::Read(..) to be unintentionally called with a 128-byte destination buffer and an overly large size as arguments.
In all versions of Windows, CExposedStream::Read(..) calls CExpParameterValidate::Read(..) to validate the supplied arguments before reading in the record data from the stream. However, the number of validation checks performed and how the checks are performed differs.
In older versions of Windows (e.g. Windows XP), one of the checks determines if it is possible to actually write the supplied number of bytes into the destination memory via a call to IsBadHugeWritePtr(..). Since it won't be possible to write between 80000000h and FFFFFFFFh bytes of data into the stack space, the check eventually throws an exception, causing CExposedStream::Read(..) to return without writing data into the buffer. This, in turn, causes PowerPoint Viewer to throw an exception and display a message box, stating that the file is corrupted and that's that.
In newer versions of Windows (including at least Windows Server 2003 and Windows 7), CExpParameterValidate::Read(..) no longer performs the check to ensure that it's possible to actually write all the data to the buffer before doing so. Instead, a couple of cursory checks are performed that won't detect that the supplied size is much too big before writing the data. The result is a stack-based buffer overflow on the later versions of Windows that are usually considered to be safer than the older versions - you have to appreciate the irony in that.
Chief Security Specialist