MS07-035: Win32 API Code Execution Vulnerability
One of the strangest bugs patched by Microsoft on June 12th was the "Vulnerability in Win 32 API Could Allow Remote Code Execution" issue addressed in MS07-035 (CVE-2007-2219). The description provided by Microsoft is somewhat vague:
"This critical security update resolves a privately reported vulnerability in a Win32 API. This vulnerability could allow remote code execution or elevation of privilege if the affected API is used locally by a specially crafted application. Therefore applications that use this component of the Win32 API could be used as a vector for this vulnerability. For example, Internet Explorer uses this Win32 API function when parsing specially crafted Web pages."Fortunately, a friend of mine was working on the same issue, and after reviewing the differences between the patched and unpatched versions, discovered the trigger. The vulnerability occurs when an application tries to locate a resource within an EXE or DLL using a numerical ID. A logic error results in the resource ID being treated as a resource handle if the ID supplied is greater than 65535. An attacker can exploit this flaw through Internet Explorer by redirecting the victim to a res://existing.dll resource URL that contains a hash character (#) followed by a decimal integer value greater than 65535.
This logic error eventually leads to an attempt to free the resource handle. Since the attacker controls the pointer value of the handle, the end result is a call to RtlFreeHeap() with an attacker-supplied parameter. Exploiting this to execute arbitrary code is tricky, since the attacker would need to create a fake heap structure in memory and then pass the decimal value of a pointer to this structure in the URL. In the following stack trace, the value 65536 (0x10000) was supplied as the resource ID to Internet Explorer 7.
eax=0173b8a8 ebx=00000000 ecx=0019f1e8In the crash above, an exception was thrown because the address 0x10000-1 (0xffff) does not map to a valid address. If we pass an argument that contains a valid address, then we reach the following block of code:
edx=7cbf4418 esi=00010000 edi=00140000
eip=7c931c6b esp=0173b7fc ebp=0173b8b8 iopl=0 cs=001b
ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ntdll!RtlFreeHeap+0x44:
cmp byte ptr [esi-0x1],0xff ds:0023:0000ffff=??
ChildEBP RetAddr
0173b8b8 7c9109bc ntdll!RtlFreeHeap+0x44
0173b8cc 7c910992 ntdll!RtlpFreeAtom+0x1b
0173b8dc 7c832545 ntdll!RtlFreeUnicodeString+0x17
0173b8f0 7c80bc44 kernel32!BaseDllFreeResourceId+0x2d
0173b938 7e86e4d9 kernel32!FindResourceW+0x96
0173b970 7e942228 mshtml!GetResource+0x1c
0173bc14 7e94209d mshtml!CResProtocol::DoParseAndBind+0x2fc
0173bc30 7e941f71 mshtml!CResProtocol::ParseAndBind+0x26
0173bc54 6142d78a mshtml!CResProtocol::Start+0xa4
0173bc88 61421eab urlmon!COInetProt::StartEx+0xf1
ntdll!RtlFreeHeap+0x44The first thing we notice is that the byte before the address we pass is used to determine what type of free operation to perform. If this byte is not 0xff, then the normal free routines are used. If this byte is 0xff, then the low fragmentation heap code is called instead. This is good news for us, since it lets us hit two different code paths in search of a way to control execution. If we take the first path and point the resource ID at a block of NULL bytes, the free operation completes without an exception being raised. If we point it immediately before a byte set to 0xff, a new exception is raised from inside the low fragmentation heap code. Playing with these values should eventually lead to an exploitable condition, but so far have we not found a clean way to trigger code execution.
cmp byte ptr [esi-0x1],0xff ds:0023:0000ffff=??
jb ntdll!RtlFreeHeap+0xe1 (7c91047d) mov edx,esi call ntdll!RtlpLowFragHeapFree (7c93212e)
StrikePack 11995 included coverage for this vulnerability (ms07_035_windows_api.xml), which can be found in the /strikes/exploits/browser/ directory of the strike tree.
Posted by HD Moore (2007-06-26 14:37:24)
