On September 13th, 2016 Microsoft released security bulletin MS16-104 , which addresses several vulnerabilities affecting Internet Explorer. One of those vulnerabilities is CVE-2016-3353, a security feature bypass bug in the way .URL files are handled. This security issue does not allow for remote code execution by itself; instead, it allows attackers to bypass a security warning in attacks involving user interaction. In this blogpost we discuss the whole process, from reverse engineering the patch to building a Proof-of-Concept for this vulnerability.

Analysis Notes

This 1-day analysis was performed using the following versions of IE 11 for Windows 8.1 x64:

Vulnerable version: ieframe.dll 11.0.9600.18427

11.0.9600.18427 Patched version: ieframe.dll 11.0.9600.18450

Determining the relevant module Microsoft Security Bulletin MS16-104 (September 2016) provides KB3185319 as the patched version of IE 11 on Windows 8.1 x64. This patch replaces KB3175443 (released on August 2016 as part of Security Bulletin MS16-095). Therefore, the diffing process will be performed between the mentioned new and old versions. The September patch (KB3185319) ships 45 DLL files and 7 EXE files, so the first step is to determine which one of the patched binaries contains the fix for the specific vulnerability we are analyzing. The Microsoft advisory mentions that: the attacker could send the targeted user a specially crafted .URL file that is designed to exploit the bypass This hint is all we need to determine the affected module among a total of 52 shipped binaries. We start by looking for the .URL file extension within the Windows Registry, under the HKEY_CLASSES_ROOT\.url key. The default value for this key is InternetShortcut , so we need to check out the HKEY_CLASSES_ROOT\InternetShortcut\shell\Open\Command key to find out which binary opens this file extension. The default value for this key is "C:\WINDOWS\system32\rundll32.exe" "C:\WINDOWS\system32\ieframe.dll",OpenURL %l . That means that ieframe.dll is the module we are looking for, and more precisely, ieframe!OpenURL is the function in charge of processing .URL files when they are launched from the Windows Explorer. By inspecting the ieframe!OpenURL function in IDA Pro we can see that the actual work is mostly delegated to the CInternetShortcut class: [ ieframe.dll version 11 .0.9600.18427 ] .text: 102 FBAC0 ; __stdcall OpenURL(x, x, x, x) .text: 102 FBAC0 public _OpenURL@16 [ ... ] .text: 102 FBADE push 334 h ; dwBytes .text: 102 FBAE3 push 8 ; dwFlags .text: 102 FBAE5 mov [ ebp + var_214 ], esi .text: 102 FBAEB call ds : __imp__GetProcessHeap@0 ; GetProcessHeap() .text: 102 FBAF1 push eax ; hHeap .text: 102 FBAF2 call ds : __imp__HeapAlloc@12 ; HeapAlloc(x,x,x) .text: 102 FBAF8 test eax , eax .text: 102 FBAFA jz short loc_102FBB07 .text: 102 FBAFC mov ecx , eax ; this .text: 102 FBAFE call ?? 0 CInternetShortcut@@QAE@XZ ; CInternetShortcut::CInternetShortcut(void) [ ... ] .text: 102 FBB3B push 2 ; this .text: 102 FBB3D lea edx , [ ebp + pwszDst ] .text: 102 FBB43 mov ecx , ebx .text: 102 FBB45 call ? LoadFromFileW@CInternetShortcut@@QAGJPBGK@Z ; CInternetShortcut::LoadFromFileW(ushort const *,ulong) [ ... ] .text: 102 FBBC0 push ebx ; this .text: 102 FBBC1 call ? Release@CInternetShortcut@@UAGKXZ ; CInternetShortcut::Release(void) [ ... ] Knowing that the CInternetShortcut class is involved in the processing of .URL files, now we can perform binary diffing between the old and the new versions of ieframe.dll , paying special attention to modifications in methods belonging to the CInternetShortcut class.

Binary diffing After loading and analyzing both the vulnerable and the patched versions of ieframe.dll in IDA Pro, we diffed the two IDA databases using BinDiff. Ordering the matched functions in BinDiff by ascending similarity we can see that the first method of the CInternetShortcut class with significant changes is CInternetShortcut::InvokeCommand(_CMINVOKECOMMANDINFO *) , with a similarity ratio of 0.84. When comparing the flow-graphs of said method, we can determine that this is the function with a security fix indeed. The new (fixed) version includes additional checks before calling CInternetShortcut::_InvokeCommand . If we dig into the right part of the screen (the patched version) we can see the checks that have been added: If the CL register is 0 , then the CInternetShortcut::_InvokeCommand method is invoked as usual. However, when CL != 0 , the function will call CDownloadUtilities::OpenSafeDialog . If said security dialog is accepted by the user, then CInternetShortcut::_InvokeCommand is called. So we move on to determine where the value of the CL register is set: From that code snippet we can conclude that CL is set to 1 when the processed file has .URL extension and also contains the Mark Of The Web (MOTW) Alternate Data Stream. In that case, the user will be presented with a security warning before proceeding to process the .URL file.

Determining impact of the bug Microsoft's bulletin doesn't give much precision on what the attacker can achieve by exploiting this bug; it only mentions that "the attacker could send the targeted user a specially crafted .URL file that is designed to exploit the bypass". On the other hand, ZDI advisory ZDI-16-506 mentions that "If the victim opens the .URL file, the attacker can execute arbitrary code on the victim's machine under the context of the user". Also, ZDI mentions that the bug has been discovered by Eduardo Braun Prado. By looking at other security advisories published by Eduardo , we can see that he specializes in exploiting "link-like" file formats (.MCL, .LNK) to execute arbitrary programs without a security warning being shown to the user. So we decided to follow this clue and work with the hypothesis that this vulnerability would allow us to execute an arbitrary program if we can convince a user to open a specially crafted .URL file, with no security warning being shown to the user.

Exploitation This is the content of a typical .URL file: [{000214A0-0000-0000-C000-000000000046}] Prop3=19,2 [InternetShortcut] IDList= URL=https://www.microsoft.com/ In order to understand how to exploit the bug, let's see how CInternetShortcut::_InvokeCommand (the function that, on the patched version, is only called after the additional security checks) works. The function calls CInternetShortcut::CExecHelper::Init , which initializes a SHELLEXECUTEINFO structure. Then it calls CInternetShortcut::CExecHelper::ResolveProtocol to verify if the protocol specified in the URL key of the .URL file is properly registered in the current machine. Then it calls CInternetShortcut::CExecHelper::IEDirectExec , which tries to open the destination URL in Internet Explorer, if possible at all. If that's not possible, then CInternetShortcut::CExecHelper::Execute is invoked. CInternetShortcut::CExecHelper::Execute just calls the ShellExecuteEx API, with the SHELLEXECUTEINFO structure initialized before as its parameter. Therefore we can make the URL key of a .URL file point to an executable file, and it will be executed via ShellExecuteEx . However, when initializing the SHELLEXECUTEINFO structure, the lpParameters field is set to NULL , therefore we cannot provide arbitrary arguments to the file to be executed. That means that we aren't able to abuse local interpreters like cscript, wscript or powershell, and we need to provide the file to be executed instead. Looking for exploitation possibilities under similar scenarios, we stumbled upon Google Project Zero bug #693 (which describes a vulnerability in a TrendMicro product), in which Tavis Ormandy mentions the idea of auto-downloading a .ZIP file containing an .HTA file with arbitrary code, and taking advantage of the Windows Explorer feature that treats .ZIP files as folders to execute the .HTA file inside the .ZIP via ShellExecute by specifying a path like this: C:/Users/someone/Downloads/test.zip/test.hta . His scenario is pretty similar to ours, since he also mentions that he's able to avoid MOTW security warnings using this trick. Further tests revealed that this trick will also work if the .ZIP file containing the .HTA file is hosted in an SMB share.