🤬
  • Internet Explorer CVE-2021-26411 RCA

    Change-Id: I98858aedf5d80b9544002d6811bd1d85bfa120d3
  • Loading...
  • Maddie Stone committed 3 years ago
    ed7b8106
    1 parent b7f24168
  • ■ ■ ■ ■ ■ ■
    0day-RCAs/2021/CVE-2021-26411.md
     1 +# CVE-2021-26411: Internet Explorer MSHTML Double-Free
     2 +*Maddie Stone*
     3 + 
     4 +## The Basics
     5 + 
     6 +**Disclosure or Patch Date:** 9 March 2021
     7 + 
     8 +**Product:** Microsoft Internet Explorer
     9 + 
     10 +**Advisory:** https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26411
     11 + 
     12 +**Affected Versions:** [KB4601319](https://support.microsoft.com/en-us/topic/february-9-2021-kb4601319-os-builds-19041-804-and-19042-804-87fc8417-4a81-0ebb-5baa-40cfab2fbfde) and previous
     13 + 
     14 +**First Patched Version:** [KB5000802](https://support.microsoft.com/en-us/topic/march-9-2021-kb5000802-os-builds-19041-867-and-19042-867-63552d64-fe44-4132-8813-ef56d3626e14)
     15 + 
     16 +**Issue/Bug Report:** N/A
     17 + 
     18 +**Patch CL:** N/A
     19 + 
     20 +**Bug-Introducing CL:** N/A
     21 + 
     22 +**Reporter(s):** yangkang(@dnpushme) & huangyi(@C0rk1_H) & Enki
     23 + 
     24 +## The Code
     25 + 
     26 +**Proof-of-concept:**
     27 + 
     28 +```javascript
     29 +<!-- saved from url=(0014)about:internet -->
     30 +<script>
     31 + 
     32 +String.prototype.repeat = function (size) { return new Array(size + 1).join(this) }
     33 + 
     34 +var ele = document.createElement('element')
     35 +var attr1 = document.createAttribute('attribute')
     36 +attr1.nodeValue = {
     37 + valueOf: function() {
     38 + alert('callback')
     39 + alert(ele.attributes.length)
     40 + ele.clearAttributes()
     41 + alert(ele.attributes.length)
     42 + }
     43 +}
     44 + 
     45 +ele.setAttributeNode(attr1)
     46 +ele.setAttribute('attr2', 'AAAAAAAA')
     47 +ele.removeAttributeNode(attr1)
     48 + 
     49 + 
     50 +</script>
     51 +```
     52 + 
     53 +**Exploit sample:** https://enki.co.kr/blog/2021/02/04/ie_0day.html
     54 + 
     55 +**Did you have access to the exploit sample when doing the analysis?** Yes
     56 + 
     57 +## The Vulnerability
     58 + 
     59 +**Bug class:** Use-after-free
     60 + 
     61 +**Vulnerability details:**
     62 + 
     63 +A value of an attribute is able to be freed twice.
     64 + 
     65 +When calling `removeAttributeNode`, `mshtml!CElement::ie9_removeAttributeNodeInternal` is called. `ie9_removeAttributeNodeInternal` first finds the 2 indices for the node entry in the attribute array for the element. (Attribute nodes have 2 entries in the attribute array whereas non-node attributes only have one.) The use-after-free occurs because there is a user-controlled callback between the calculating the indices and when they are used. The backing store buffer can be changed during this callback and the code doesn’t verify that the index is still valid.
     66 + 
     67 +In the case of the above crash POC, the backing store buffer of the array is cleared using `clearAttributes` in the callback. `mshtml!CElement::clearAttributes` clears the attributes backing array by deleting/freeing the first element in the array and memmoving the following entries into that space. This means that when `clearAttributes` is finished and the code path returns to `removeAttributeNodeInternal`, we have now filled the freed space with whatever attribute was at the end of the attribute array and that attribute has also been freed. This can be a pointer to the user-controlled string object. In this case the “use” is a double free on the String object that holds the value for the second attribute added to the element.
     68 + 
     69 +**Patch analysis:**
     70 + 
     71 +The patch modified `CAttrArray::Destroy`. At the beginning of the function, it checks that the index passed in as an argument of the attribute to be deleted is less than the number of elements in the AttrArray. If it's not, a `ReleaseAssert` is called.
     72 + 
     73 +**Thoughts on how this vuln might have been found _(fuzzing, code auditing, variant analysis, etc.)_:**
     74 + 
     75 +It seems equally plausible that this vulnerability was found with a fuzzer or by manually auditing places where `CBase::GetIntoBSTRAt`/`VariantChangeTypeSpecial` is called. That is the call which triggers the callback.
     76 + 
     77 +**(Historical/present/future) context of bug:**
     78 + 
     79 +In January 2021, [Google TAG published](https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/) that North Korean hackers were targeting security researchers. 10 days later on February 4th, [Enki published](https://enki.co.kr/blog/2021/02/04/ie_0day.html) that some of their researchers had been targeted by the same actor, but with a `.mht` file. This exploit was contained within that file. Microsoft patched on March 9th, 2021.
     80 + 
     81 +## The Exploit
     82 + 
     83 +(The terms *exploit primitive*, *exploit strategy*, *exploit technique*, and *exploit flow* are [defined here](https://googleprojectzero.blogspot.com/2020/06/a-survey-of-recent-ios-kernel-exploits.html).)
     84 + 
     85 +**Exploit strategy (or strategies):**
     86 + 
     87 +The double free is used to have two objects, one array of Dictionary items and one BSTR, allocated to the same block of memory on the heap. These two objects are able to be allocated to the same spot because a BSTR has the structure of: first 4 bytes is the length and the rest is teh string data. The array of dictionary items is a VARIANT struct so it has the type in the first four bytes. The type is (VT_ARRAY | VT_VARIANT) = 0x200C. The BSTR also has a length of 0x200C, making them both valid objects.
     88 + 
     89 +The exploit uses this type confusion to leak the addresses of objects stored in the Dictionary by reading the bytes at the equivalent indices in the BSTR. It then uses the Dictionary to read and write to different memory values using a trick described in the "Exploitation, Part 1: From Arbitrary Write to Arbitrary Read" section of [this blog post](https://www.thezdi.com/blog/2019/5/21/rce-without-native-code-exploitation-of-a-write-what-where-in-internet-explorer) by Simon Zuckerbraun, including creating an ArrayBuff whose address begins at 0x00000000 and its length is 0xFFFFFFFF, yielding an arbitrary read-write primitive.
     90 + 
     91 +The exploit bypasses Control Flow Guard (CFG) by overwriting the export address table entry in rpcrt4.dll for `___guard_check_icall_fptr` with `KiFastSystemCallRet`.
     92 + 
     93 +**Exploit flow:**
     94 + 
     95 +Two objects are allocated to the same block of memory thanks to the double free. This is used to first leak the address of objects using the VBArray objects for dereferencing. Then the exploits overwrites the length and starting address of an ArrayBuff to have an arbitrary read-write primitive from 0x00000000 - 0xFFFFFFFF.
     96 + 
     97 +**Known cases of the same exploit flow:**
     98 + 
     99 +* The technique for leaking object addresses using teh `Scripting.Dictionary`/VBArray object is documented by Simon Zuckerbraun in [this blog post](https://www.thezdi.com/blog/2019/5/21/rce-without-native-code-exploitation-of-a-write-what-where-in-internet-explorer).
     100 +* Getting arbitrary read-write via changing the length of an Array is very common, but [this blog post](https://www.trendmicro.com/en_us/research/19/i/from-bindiff-to-zero-day-a-proof-of-concept-exploiting-cve-2019-1208-in-internet-explorer.html) by Elliot Cao is roughly similar to this exploit.
     101 + 
     102 +**Part of an exploit chain?** Unknown
     103 + 
     104 +## The Next Steps
     105 + 
     106 +### Variant analysis
     107 + 
     108 +**Areas/approach for variant analysis (and why):**
     109 + 
     110 +* Audit anywhere that a callback occurs between where an index is calculated and when it's used.
     111 +* Fuzz HTML attributes, potentially with a tool like [Domato](https://github.com/googleprojectzero/domato)
     112 + 
     113 +**Found variants:** N/A
     114 + 
     115 +### Structural improvements
     116 + 
     117 +What are structural improvements such as ways to kill the bug class, prevent the introduction of this vulnerability, mitigate the exploit flow, make this type of vulnerability harder to exploit, etc.?
     118 + 
     119 +**Ideas to kill the bug class:**
     120 + 
     121 +* Verify the state of the objects being operated on after the callback. In this case it could be simplified to don't use indices that were calculated prior to a callback.
     122 +* Internet Explorer is now considered “legacy” software. Removing it from being accessible by default in the Windows operating system would reduce the attack surface.
     123 + 
     124 +**Ideas to mitigate the exploit flow:**
     125 + 
     126 +* Remove Internet Explorer from being enabled by default.
     127 + 
     128 +**Other potential improvements:**
     129 + 
     130 +### 0-day detection methods
     131 + 
     132 +What are potential detection methods for similar 0-days? Meaning are there any ideas of how this exploit or similar exploits could be detected **as a 0-day**?
     133 + 
     134 +* To detect the type confusion, look for BSTRs of lengths that equal types of common [VARIANT types](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f): 0x200C (VT_ARRAY | VT_VARIANT), 0x400C (VT_BYREF | VT_I4). This would likely have lots of false positives, but maybe it could be further refined.
     135 + 
     136 +## Other References
     137 +* February 2021: [Internet Explorer 0-day 분석](https://enki.co.kr/blog/2021/02/04/ie_0day.html) by Enki. This blog post was the original report and disclosure about the exploit.
Please wait...
Page is in error, reload to recover