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 Threat Research

Poor Communication During a Data Breach Can Cost You — Here’s How to Avoid It

5 min read - No one needs to tell you that data breaches are costly. That data has been quantified and the numbers are staggering. In fact, the IBM Security Cost of a Data Breach estimates that the average cost of a data breach in 2022 was $4.35 million, with 83% of organizations experiencing one or more security incidents. But what’s talked about less often (and we think should be talked about more) is how communication — both good and bad — factors into…

5 min read

Ransomware Renaissance 2023: The Definitive Guide to Stay Safer

2 min read - Ransomware is experiencing a renaissance in 2023, with some cybersecurity firms reporting over 400 attacks in the month of March alone. And it shouldn’t be a surprise: the 2023 X-Force Threat Intelligence Index found backdoor deployments — malware providing remote access — as the top attacker action in 2022, and aptly predicted 2022’s backdoor failures would become 2023’s ransomware crisis. Compounding the problem is the industrialization of the cybercrime ecosystem, enabling adversaries to complete more attacks, faster. Over the last…

2 min read

BlackCat (ALPHV) Ransomware Levels Up for Stealth, Speed and Exfiltration

9 min read - This blog was made possible through contributions from Kat Metrick, Kevin Henson, Agnes Ramos-Beauchamp, Thanassis Diogos, Diego Matos Martins and Joseph Spero. BlackCat ransomware, which was among the top ransomware families observed by IBM Security X-Force in 2022, according to the 2023 X-Force Threat Intelligence Index, continues to wreak havoc across organizations globally this year. BlackCat (a.k.a. ALPHV) ransomware affiliates' more recent attacks include targeting organizations in the healthcare, government, education, manufacturing and hospitality sectors. Reportedly, several of these incidents resulted…

9 min read

Expert Insights on the X-Force Threat Intelligence Index

5 min read - Top insights are in from this year’s IBM Security X-Force Threat Intelligence Index, but what do they mean? Three IBM Security X-Force experts share their thoughts on the implications of the most pressing cybersecurity threats, and offer guidance for what organizations can do to better protect themselves. Moving Left of Boom: Early Backdoor Detection Andy Piazza, Global Head of Threat Intelligence at IBM Security X-Force, sat down with Security Intelligence to chat with us about the rise in the deployment…

5 min read