April 1, 2013 By Mark Yason 6 min read

If you look at the last few Internet Explorer security bulletins, you’ll notice that many of the patched vulnerabilities were use-after-frees (or UAFs) [1, 2]. Use-after-free is still a common bug class because the task of manually identifying them, especially in large and complex codebases is a challenge. The reason is that their existence is a result of the combined actions from different parts of an application – namely, the parts of the code that can cause the freeing of the object and the parts of the code that use the object. Therefore, inferring that a UAF condition may occur by looking at the code will not always be a straightforward task.  In this blog post, I’ll briefly explain UAFs, cite two UAF examples, and finally mention some runtime tools that can help you detect UAFs.

UAFs and Dangling Pointers

Use-after-free is the result of dereferencing a pointer that points to an object that had already been freed (also called a dangling pointer):

Two common reasons that lead to dangling pointers are:

  • Not updating the reference count of a currently in-use object. This results in the object currently in-use to be prematurely freed.
  • Not updating a pointer value once the object it points to is freed.

Typically, exploits that leverage UAFs will attempt to reallocate the memory previously allocated to the freed object. This causes the dangling pointer to point to an attacker-controlled data. The application’s execution flow is then controlled when an attacker-controlled data obtained via the dangling pointer is used within the application.

Example 1: CVE-2012-4969 (IE CMshtmlEd UAF)

One prominent example of a UAF vulnerability is CVE-2012-4969 [3], a zero-day Internet Explorer vulnerability found exploited in-the-wild last September 2012.  Consider the following simplified diagram (functions called in between are removed for brevity) which shows the use-after-free condition:

In the above scenario, the use-after-free occurred inside the CMshtmlEd::Exec() function and the freed object was the object pointed to by the this pointer. The CMshtmlEd::Exec() function is reachable via the execCommand() JavaScript DOM method. To free the CMshtmlEd object, the attack invoked execCommand() in a way that a JavaScript event will be triggered, this allowed an attacker-controlled JavaScript event handler to be invoked in the execution path of CMshtmlEd::Exec(). The freeing of the CMshtmlEd object occurred when the attacker-controlled JavaScript event handler invoked document.write() which in turn results in the freeing of several objects, one of which is the currently in-use CMshtmlEd object. When execution finally returns to CMshtmlEd::Exec(), the this pointer, which became dangling pointer, is dereferenced resulting to a use-after-free condition.

The root cause in this particular example is an incorrect reference count of the CMshtmlEd object which allowed the attack to prematurely free it while it is in-use.

Interestingly, while looking at this zero-day vulnerability, I realized the possibility that there might be similar use-after-free scenarios (i.e. an event handler can trigger a free of currently in-use objects). So just to find similar potentially low-hanging bugs, via ad hoc manual fuzzing, I tried different combinations of JavaScript methods and JavaScript events.  After several unsuccessful attempts, I eventually stumbled across a similar UAF vulnerability which essentially was due to the CPasteCommand object being freed while currently in-use. The root cause of the bug was also due to an incorrect reference count of an object. We reported this vulnerability to Microsoft and it was patched last February 2013 [1].

Example 2: CVE-2012-4792 (IE CButton UAF)

Another example of a use-after-free vulnerability is CVE-2012-4792 [4], another zero-day Internet Explorer vulnerability found exploited in the wild last December 2012. The simplified diagram below shows the use-after-free condition:

In this particular case, a pointer to a CButton object was stored in the CDoc object; however, the reference count of the CButton object was never updated. Additionally, when the CButton object was later removed from the DOM tree (via the .outerText=”” construct), its pointer in the CDoc object was never updated. Afterwards, when the CButton object was garbage-collected, the CButton pointer stored in the CDoc object became a dangling pointer. The use-after-free condition was then triggered when the dangling CButton pointer stored in the CDoc object was dereferenced.

Tools for Detecting UAFs

Without the right tools in place, it would be difficult to reliability detect UAF conditions since there will be instances where the memory previously occupied by the freed object is not immediately re-occupied by another object, thereby leaving some of its contents still intact. In these cases, the UAF condition may only randomly manifest itself through access violations.

Additionally, the location of access violations resulting from UAFs will probably be different from the location where the initial dereferencing of the dangling pointer occurred. This is because, unless the memory pointed to by the dangling pointer is released, the dereferencing of the dangling pointer will not trigger the access violation by itself; it is the use of the unexpected values obtained using (or written via) the dangling pointer which will potentially trigger the access violations.

Fortunately, there are tools available [5] to detect different classes of memory corruption bugs including UAFs at runtime. Since I mostly look at closed-sourced Windows applications, the tool I mainly use is the page heap feature of Windows [6] which can be enabled using the GFlags tool [7] or the Application Verifier tool [8].

I usually enable full page heap verification for an application before analyzing a simplified version (minimum code/fields required to trigger the vulnerability) of an exploit. In the case of UAFs, if full page heap verification is enabled, the memory where the freed object was stored will become inaccessible since its page protection will be set to PAGE_NOACCESS, this means that the first instruction that attempts to dereference the dangling pointer will trigger an access violation.

As an example, when full page heap verification is enabled for Internet Explorer, a simplified version of the exploit for CVE-2012-4969 (IE CMshtmlEd UAF) will immediately trigger an access violation in CMshtmlEd::Exec(), exactly when the code that first dereferences the dangling pointer (this pointer stored in the edi register) is executed:

(270.784): Access violation – code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00000000 ebx=0000001f ecx=05b29f30 edx=0000000c esi=00000000 edi=06070f78 eip=3d0e107d esp=02d29de4 ebp=02d29df0 […] mshtml!CMshtmlEd::Exec+0x131: 3d0e107d 8b7f08          mov     edi,dword ptr [edi+8] ds:0023:06070f80=????????

Additionally, if debug symbols are available, the stack trace of when the object was freed can also be dumped via the “!heap -p” command in WinDbg:

0:008> !heap -p -a edi    address 06070f78 found in    _DPH_HEAP_ROOT @ 141000    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)                                            55a8418:          6070000             2000    7c927553 ntdll!RtlFreeHeap+0x000000f9    3d0602c4 mshtml!CMshtmlEd::Release+0x00000025    3d2fec6c mshtml!CHTMLEditor::DeleteCommandTarget+0x00000034    3d2fa581 mshtml!CHTMLEditor::RemoveContainer+0x00000167    3d16b500 mshtml!CHTMLEditor::Notify+0x00000026    3cf347c0 mshtml!CHTMLEditorProxy::Notify+0x00000021    3cf34682 mshtml!CDoc::NotifySelection+0x00000059    3d0f1691 mshtml!COmWindowProxy::SwitchMarkup+0x00000347    3d074d6c mshtml!CDocument::open+0x00000471    3d073c42 mshtml!CDocument::write+0x00000081    […]

The stack trace will be useful in investigating what caused the free operation along with the information that can help you deduce the type of the freed object.

Conclusion

Use-after-free bugs require a thorough code review to be identified manually especially in complex and large codebases. Fortunately, tools are available to assist you in catching use-after-frees and other memory corruption bugs at runtime. It is a good idea to enable these runtime tools when fuzzing or testing software so that memory corruption bugs will manifest themselves when they occur.

References

[1] “Microsoft Security Bulletin MS13-009 – Critical : Cumulative Security Update for Internet Explorer (2792100),” [Online]. Available: http://technet.microsoft.com/en-us/security/bulletin/MS13-009
[2] “Microsoft Security Bulletin MS13-021 – Critical : Cumulative Security Update for Internet Explorer (2809289),” [Online]. Available: http://technet.microsoft.com/en-us/security/bulletin/MS13-021
[3] “Microsoft Security Bulletin MS12-063 – Critical : Cumulative Security Update for Internet Explorer (2744842),” [Online]. Available: http://technet.microsoft.com/en-us/security/bulletin/MS12-063
[4] “Microsoft Security Bulletin MS13-008 – Critical : Security Update for Internet Explorer (2799329),” [Online]. Available: http://technet.microsoft.com/en-us/security/bulletin/MS13-008
[5] “Comparison of various memory error detectors,” [Online]. Available: https://code.google.com/p/address-sanitizer/wiki/ComparisonOfMemoryTools
[6] “How to use Pageheap.exe in Windows XP, Windows 2000, and Windows Server 2003,” [Online]. Available: http://support.microsoft.com/kb/286470
[7] “GFlags and PageHeap,” [Online]. Available: http://msdn.microsoft.com/en-us/library/windows/hardware/ff549561(v=vs.85).aspx
[8] “Application Verifier,” [Online]. Available: http://msdn.microsoft.com/en-us/library/windows/desktop/dd371695(v=vs.85).aspx
[*] “Happy New Year Analysis of CVE-2012-4792,” [Online]. Available: http://blog.exodusintel.com/2013/01/02/happy-new-year-analysis-of-cve-2012-4792/
[*] “Undangle: Early Detection of Dangling Pointers in Use-After-Free and Double-Free Vulnerabilities,” [Online]. Available: http://software.imdea.org/~juanca/papers/undangle_issta12_av.pdf

More from X-Force

Strela Stealer: Today’s invoice is tomorrow’s phish

12 min read - As of November 2024, IBM X-Force has tracked ongoing Hive0145 campaigns delivering Strela Stealer malware to victims throughout Europe - primarily Spain, Germany and Ukraine. The phishing emails used in these campaigns are real invoice notifications, which have been stolen through previously exfiltrated email credentials. Strela Stealer is designed to extract user credentials stored in Microsoft Outlook and Mozilla Thunderbird. During the past 18 months, the group tested various techniques to enhance its operation's effectiveness. Hive0145 is likely to be…

Hive0147 serving juicy Picanha with a side of Mekotio

17 min read - IBM X-Force tracks multiple threat actors operating within the flourishing Latin American (LATAM) threat landscape. X-Force has observed Hive0147 to be one of the most active threat groups operating in the region, targeting employee inboxes at scale, with a primary focus on phishing and malware distribution. After a 3-month break, Hive0147 returned in July with even larger campaign volumes, and the debut of a new malicious downloader X-Force named "Picanha,” likely under continued development, deploying the Mekotio banking trojan. Hive0147…

FYSA – Critical RCE Flaw in GNU-Linux Systems

2 min read - Summary The first of a series of blog posts has been published detailing a vulnerability in the Common Unix Printing System (CUPS), which purportedly allows attackers to gain remote access to UNIX-based systems. The vulnerability, which affects various UNIX-based operating systems, can be exploited by sending a specially crafted HTTP request to the CUPS service. Threat Topography Threat Type: Remote code execution vulnerability in CUPS service Industries Impacted: UNIX-based systems across various industries, including but not limited to, finance, healthcare,…

Topic updates

Get email updates and stay ahead of the latest threats to the security landscape, thought leadership and research.
Subscribe today