How to crash EXPLORER.EXE on all Windows versions

Leaked EXPLORER.EXE heap bytes

A nearly year ago, a critical Windows Shell vulnerability was found in the wild (stuxnet & co), making it possible for an attacker to execute arbitrary code on a victim’s computer, by getting the user to list a directory which would contain a specially crafted .LNK file. The sole purpose of files of that type is to provide shortcut functionality – i.e. allow the user to reference various system resources (most often – executable files) through link files, instead of using the full path of the resource. Since EXPLORER.EXE makes every effort to make it even easier for the user to recognize the resource being pointed at, it displays the original resource icon (if any) as the shortcut’s one. In order to obtain the picture in the first place, the Windows Shell would sometimes call LoadLibrary on the referenced module, which would result in the execution of the library’s standard DllMain routine. What should be noted, is that LoadLibrary was usually called on legitimate Control Panel executables, but it turned out that the LNK format allowed to specify virtually any PE image as a CP module, resulting in immediate and 100% reliable execution of potentially malicious code.

What I would like to present today, is a low-impact flaw found in the LNK-parsing routines present in the SHELL32.DLL module, extensively used by EXPLORER.EXE. Exploiting this issue might result in – at most – Denial of Service conditions, or disclosure of random heap bytes from the Windows Shell process memory (which is not a big deal, considering that the user can read EXPLORER.EXE memory, anyway).

A complete specification of the Shell Link file format is available through MSDN (see [MS-SHLLINK] Shell Link (.LNK) Binary File Format). Interestingly, the document has disappeared from the Microsoft servers soon after the public announcement and wide-spread analysis of the .LNK vulnerability, but has been apparently made public, since then. To make a long story short, valid LNK files typically consist of a header structure (called SHELL_LINK_HEADER), and a list of descriptor structures, containing various shortcut characteristics. The definition of one, particular structure we are most interested in, is as follows:

typedef struct tagPIDLCPanelStruct
{
  BYTE dummy;
  DWORD iconIdx;
  WORD offsDispName;
  WORD offsComment;
  WCHAR szName[1];
  WCHAR szDisplay[1];
  WCHAR szComment[1];
} PIDLCPanelStruct;

WINE Project Sources: \wine\dlls\shell32\pidl.h

Upon accessing a shortcut, SHELL32 tries to load the target path (specified by the szName string). After looking up several locations and eventually failing, the library then forms a failure message similar to the following: “%s cannot be found”, with szDisplay being the format parameter. What’s interesting, the szDisplay contents are used, even if no message box is actually displayed, i.e. during directory listing.

The offsDispName and offsComment values are supposed to store information about the beginning of the szDisplay and szComment strings (expressed either in bytes, or wide characters), relative to the beginning of the tagPIDLCPanelStruct structure. Due to the fact that no bounds checks are performed in order to verify whether these values fit in the size of the current ItemID (or even the general file length), it is possible to get the SHELL32.DLL library to execute an out-out-bounds READ operation, resulting in potential application crash. The faulty code resides within the SHELL32!CControlPanelFolder::GetDisplayName and SHELL32!CControlPanelFolder::GetDescription routines, or more precisely, the following assembly snippets:

movzx   ecx, word ptr [eax+14h]
lea     eax, [eax+ecx*2+18h] ; CX fully controlled
push    eax             ; psz2
push    [ebp+psz1]      ; psz1
call    ds:__imp__StrCpyNW@12 ; StrCpyNW(x,x,x)

SHELL32!CControlPanelFolder::GetDisplayName

movzx   ecx, word ptr [eax+16h]
lea     eax, [eax+ecx*2+18h] ; CX fully controlled
push    eax             ; psz2
push    [ebp+psz1]      ; psz1
call    ds:__imp__StrCpyNW@12 ; StrCpyNW(x,x,x)

SHELL32!CControlPanelFolder::GetDescription

Depending on several factors, such as the current process heap layout, the victim application may crash, due to an invalid memory reference exception (STATUS_ACCESS_VIOLATION), or make use of unspecified data, residing outside the legal bounds (current ItemID heap allocation). A shortened, example crash log generated upon listing a folder with the faulty LNK is presented below:

FAULTING_IP: 

SHLWAPI!StrCpyNXW+19
001b:77f66730 668b01          mov     ax,word ptr [ecx]

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 77f66730 (SHLWAPI!StrCpyNXW+0x00000019)
 ExceptionCode: c0000005 (Access violation)
 ExceptionFlags: 00000000
NumberParameters: 2
 Parameter[0]: 00000000
 Parameter[1]: 00171fc6
Attempt to read from address 00171fc6

STACK_TEXT:  
015ee350 77f66776 015ee39c 00171fc6 00000104 SHLWAPI!StrCpyNXW+0x19
015ee364 7cb05006 015ee39c 00171fc6 00000104 SHLWAPI!StrCpyNW+0x13
015ee378 7ca538f2 00151fb0 015ee39c 00000104 SHELL32!CControlPanelFolder::GetDisplayName+0x27
015ee5a8 7c9f1ce9 000f0d80 00151fb0 00008000 SHELL32!CControlPanelFolder::GetDisplayNameOf+0x5e
015ee7e0 7c9ec806 00141180 00151fb0 00008000 SHELL32!CRegFolder::GetDisplayNameOf+0xdc
015ee904 7c9f103e 00141180 00151fb0 00008000 SHELL32!DisplayNameOf+0x29
015eeb58 7c9f0fc2 00151f88 015eeb90 00000002 SHELL32!SHGetPathFromIDListEx+0x7a
015eeb6c 7ca0d103 00151f88 015eeb90 000e4d88 SHELL32!SHGetPathFromIDListW+0x12
015eed9c 7ca0d061 015eedd4 015eefe0 7ca02f20 SHELL32!CShellLink::_LoadFromFile+0x97
015eeda8 7ca02f20 0010c2f4 015eedd4 00000000 SHELL32!CShellLink::Load+0x1e
015eefe0 7ca031f3 000e4d88 025b1478 00000000 SHELL32!CFSFolder::_HandlerCreateInstance+0x7e
015ef298 7ca0321a 000e4d88 00000000 7c9c5178 SHELL32!CFSFolder::_LoadHandler+0xcf
015ef4d8 7ca039bc 000e4d88 11021fff 7c9c809c SHELL32!CFSFolder::_CreatePerInstanceDefExtIcon+0x70
015ef72c 7ca0394d 000e4d88 7c9c809c 015ef7b0 SHELL32!CFSFolder::_CreateDefExtIcon+0x75
015ef740 7c9f2c1d 00000000 015ef7b4 00000001 SHELL32!CFSFolder::_GetExtractIcon+0x13
015ef774 7c9f3bc7 000d2f80 00000000 00000001 SHELL32!CFSFolder::GetUIObjectOf+0x21c
015ef7a4 7c9f65f3 000d2f80 00000000 000e4d88 SHELL32!SHGetIconFromPIDL+0x77
015efe20 7ca02d12 000d2f84 000e4d88 00000000 SHELL32!CFSFolder::GetIconOf+0x24e
015efe40 7ca05d9c 000d2f80 000d2f84 000e4d88 SHELL32!SHGetIconFromPIDL+0x20
015efe68 7c9f31d5 001646b0 00141610 000ebe30 SHELL32!CGetIconTask::RunInitRT+0x47

And… yes, this is pretty much it. Due to the nature of the vulnerability, a potential attacker can either crash the Windows Shell (or any other application making use of SHELL32.DLL), or get the program to reference some trash bytes from successive heap allocations. Most notably, the vulnerability can be triggered remotely (via network shares), and can also be made persistent (by placing the malicious LNK file on the desktop). Furthermore, Gynvael Coldwind has suggested that such types of security flaws (including this one) might be a nice exploitation vector, in the context of Carpet Bombing issues, e.g. when an attacker would be able to store arbitrary files on the desktop through a specially crafted website and buggy web browser, without the user’s knowledge / interaction.

A Proof-of-Concept Shell Link can be downloaded from here (p0c.lnk, 244 bytes).

To my best knowledge, the PoC is compatible with all modern Windows NT-family systems. Since the MSRC team did not consider the bug worth spending time on (agreed), it can still be used to annoy your colleagues. Enjoy, and watch out for the incoming Hack In The Box Magazine #6!

17 thoughts on “How to crash EXPLORER.EXE on all Windows versions”

  1. @Implayer: Hmm? Don’t quite get the point, please elaborate ;)

    @rafael: Thanks! Nice issue as well, though it unfortunately requires the user to launch Explorer.exe “several” times… Interesting, anyway ;)

  2. Sorry )
    The crash take place only at first running and there is no any reaction in the next ones.
    Administrative or User privileges, never mind.
    Tested: XP SP3, 2k3 SP2, Seven SP1, x32 only.

  3. @Implayer: Oh, that’s much better ;)

    Anyway, so here’s the point: whether or not explorer.exe will crash is not directly controllable by the user, since it depends on whether shell32.dll references unmapped memory or not. This, in turn, is dependent on the internal process heap layout, which is always the smallest soon after Explorer’s launch.

    Please note that you can trigger the vulnerability not only by listing the LNK parent directory, but also opening the link itself (this is how I obtained the message box from the post header). If you open the link a fair amount of times, you should eventually crash the explorer.exe process.

    Thanks for confirming the bug btw, cheers!

  4. Pingback: IDELIT
  5. Doesn’t work for me, copied pasted executed a ton of times, just the control panel items get displayed, apart from the peculiarity that nothing happens on double clicking.. have to right click and then select the open location item.

  6. @Petter Ferrie: That’s right, the documentation is a good example of a partially documented format, with some of the hot parts cut out. Fortunately, it contained the basic concept and structures, which was enough to build a reliable Code Execution / Denial of Service exploit (depending on the vuln in consideration).

    @PK: That’s interesting. Could you elaborate more on the version of the Windows platform being tested on?
    Whether the Explorer process will crash or not depends on several factors, most importantly the internal heap layout (mentioned several times before). Consequently, testing the PoC on a “fresh” EXPLORER.EXE instance might give better results, compared to a regular Windows Shell process (running for hours or days).

    @ : See the following:

    To my best knowledge, the PoC is compatible with all modern Windows NT-family systems.

  7. @Peter Ferrie: Haha, another neat trick to crash the shell :-) Although, as long as it’s only available for local authenticated users, no big deal.

  8. Tested just seconds after a restart, and the similar behavior on accessing its properties and double clicking (nothing happens), however when i copied and pasted to another location and double clicked, windows cannot open the selected file type was displayed (it still opened the control panel upon clicking open file location with the right click menu).

  9. @PK: To be honest, I have no idea about the reason of your exploitation failure, it’s weird. On every Windows 7 platform I have access to, the Shell says

    [Window Title]
    explorer.exe

    [Content]
    耀Žayoutpos cannot be found.

    [OK]

    or similar. Also “open file location” results in opening the original LNK’s directory, and not Control Panel.

Comments are closed.