Windows Animated Cursor Stack Overflow Vulnerability

Systems Affected:

Windows NT

Windows 2000

Windows XP

Windows 2003

Windows Vista

Overview:

Determina Security Research has discovered a vulnerability in the USER32.DLL
code responsible for loading animated cursor (.ANI) files. This vulnerability
can be exploited by a malicious web page or HTML email message and results in
remote code execution with the privileges of the logged-in user. The vulnerable
code is present in all versions of Windows up to and including Windows Vista.
All applications that use the standard Windows API for loading cursors and icons
are affected. This includes Windows Explorer, Internet Explorer, Mozilla
Firefox, Outlook and others.

Microsoft fixed a closely related vulnerability with the MS05-002
security update, but their fix was incomplete. Determina Security Research was
able to bypass the MS05-002 patch and develop a proof-of-concept exploit that
works on fully-patched Windows systems.

Technical Details:

The ANI file format is used for storing animated cursors. The format is based
on the RIFF multimedia file format and consists of a series of tagged chunks
containing variable sized data. Each chunk starts with a 4 byte ASCII tag,
followed by a dword specifying the size of the data contained in the chunk.

One of the chunks in an ANI file is the anih chunk,
which contains a 36-byte animation header structure. The buffer overflow fixed
in MS05-002 was in the LoadCursorIconFromFileMap function. The vulnerable code
did not validate the length of the anih chunk before
reading the chunk data into fixed size buffer on the stack. The pseudocode of
the vulnerable function is given below:

For more information about the MS05-002 vulnerability, please refer to the eEye
advisory that describes the issue in great detail.

If the animation header is valid, LoadCursorIconFromFileMap will call the
LoadAniIcon function to process the rest of the chunks in the ANI file.
LoadAniIcon uses the same ReadTag and ReadChunk functions as
LoadCursorIconFromFileMap and contains the same vulnerability in the code that
reads the anih header. This vulnerability was left
unpatched in the MS05-002 security update.

This code relies on the check in LoadCursorIconFromFileMap to catch the
malformed anih chunk before it reaches the LoadAniIcon
function. Unfortunately, LoadCursorIconFromFileMap validates only the first
anih chunk, but LoadAniIcon processes all chunks in the
file. By creating a file with two anih chunks, one valid
and one malformed, it is possible to reach the vulnerable code in
LoadAniIcon.

Reading the second anih chunk with the ReadChunk
function will result in a classic buffer overflow, overwriting the return
address of LoadAniChunk and allowing the attacker to take control of the code
execution.

Proof of Concept:

The following .ANI file will trigger the vulnerability when the folder
containing it is opened in Windows Explorer:

Exploitation:

The exploitation of this vulnerability is interesting in light of the
protection features built in the latest versions of Windows XP, 2003 and Vista.
It is a stack overflow and should be detected by the /GS security check.
Unfortunately, the Visual Studio compiler adds the /GS check only to functions
that contain certain types of arrays, assuming that most buffer overflows are a
result of out-of-bounds array access. The LoadAniIcon function uses a structure
as a destination buffer for the data it reads and as a result its return address
is not protected by the /GS stack check. This allows an attacker to overwrite
the return address and take control of the program execution on Windows XP SP2,
2003 and Vista in the same way as on Windows 2000.

In addition to the missing /GS check, the vulnerable code in USER32.DLL is
wrapped in an exception handler that can recover from access violations. If the
exploit is unsuccessful, for example due to the Vista ASLR, the process will not
terminate and the attacker can simply try again. This gives the attacker an easy
way to bypass the ASLR protection and increase the reliability of the
exploit.

Solution:

The call to ReadChunk in the LoadAniIcon function should be preceeded by a
check similar to the one introduced in MS05-002: