CVE-2022-22629 Proof of Concept

Overview

CVE-2022-22629 Proof of concept

This post is about the poc for the WebGL bug that was patched in Safari 15.4 security updates.

bug

If you want to learn in detail about how WebGL works, you can use this official resource since we are going to discuss bug specific details here :

https://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html

This poc is not about how to get the primitives to exploit this bug, we will just discuss about vulnerablity analysis and how to crash the webcontent : )

Introduction

WebGL is a javascript API that is used in browsers to render 2D and 3D graphics. It uses ANGLE component as its primary WebGL backend, significantly improving compatibility with other browsers, and enabling a conformant WebGL 2.0 in WebKit. WebGL offers a lot of extensions for a developer to perform the rendering with optimisations. So, we will look into the extension of which we are concerned about.

Extensions in WebGL

extension

So, this api provides several extensions for different intents. The bug we are going to discuss is in EXT_.

You can read more in detail about the extensions from here :

https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions

Anyway, let's move towards the bug :)

Vulnerability Analysis

WEBGL_multi_draw extension

The WEBGL_multi_draw extension is part of the WebGL API and allows to render more than one primitive with a single function call. This can improve a WebGL application's performance as it reduces binding costs in the renderer and speeds up GPU thread time with uniform data.

This extension exposes the Multi* draw call variants in EXT_multi_draw_arrays functionality in addition to the vertex shader builtin gl_DrawID exposed by ARB_shader_draw_parameters for OpenGL.

These functions behave identically to the standard functions DrawArrays() and DrawElements() except they handle multiple lists of vertices in one call. Their main purpose is to allow one function call to render more than one primitive such as triangle strip, triangle fan, etc.

Additionally, this extension adds a further built-in variable, gl_DrawID to the shading language. This variable contains the index of the draw currently being processed by a Multi* variant of a drawing command.

https://github.com/WebKit/WebKit/blob/a7f8eacef337cb6691dca0b742d00f80d4f3dd0f/Source/ThirdParty/ANGLE/extensions/ANGLE_multi_draw.txt

You can read more details about the extension here :

https://registry.khronos.org/webgl/extensions/WEBGL_multi_draw/

This extension is similar to the webgl api WebGLRenderingContext.drawArrays() and WebGLRenderingContext.drawElements() etc, that renders primitives from array data. The only difference is that we can render using this extension using multiple arrays.

We can perform these operations using this extension: [1]

  1. ext.multiDrawArraysWEBGL() renders multiple primitives from array data (identical to multiple calls to drawArrays).

  2. ext.multiDrawElementsWEBGL() renders multiple primitives from element array data (identical to multiple calls to drawElements).

  3. ext.multiDrawArraysInstancedWEBGL() renders multiple primitives from array data (identical to multiple calls to drawArraysInstanced).

  4. ext.multiDrawElementsInstancedWEBGL() renders multiple primitives from element array data (identical to multiple calls to drawElementsInstanced).

Patch

patch

https://github.com/WebKit/WebKit/commit/c087ca07c9125093ca62e8e44024b738bb7d46dc

The vulnerability exist only from Safari 15.0 to 15.3 because this extension is only supported in Safari 15 (ios) in case of apple.

The patch is very easy to understand and it clearly states that it is a heap buffer overflow while rendering. This function is called here in WebGLMultiDraw.cpp in all the operations we mentioned above [1]. Let's understand what's happening before this function being called. We may look into one of the above function's implementation :

void WebGLMultiDraw::multiDrawArraysWEBGL(GCGLenum mode, Int32List firstsList, GCGLuint firstsOffset, Int32List countsList, GCGLuint countsOffset, GCGLsizei drawcount)
{
    if (!m_context || m_context->isContextLost())
        return;

    if (!validateDrawcount("multiDrawArraysWEBGL", drawcount)
        || !validateOffset("multiDrawArraysWEBGL", "firstsOffset out of bounds", firstsList.length(), firstsOffset, drawcount)
        || !validateOffset("multiDrawArraysWEBGL", "countsOffset out of bounds", countsList.length(), countsOffset, drawcount)) {
        return;
    }

    m_context->graphicsContextGL()->multiDrawArraysANGLE(mode, makeSpanWithOffset(firstsList, firstsOffset), makeSpanWithOffset(countsList, countsOffset), drawcount);
}

In JS, the function specifications are defined like this :

void ext.multiDrawArraysWEBGL(mode,
    firstsList, firstsOffset,
    countsList, countsOffset,
    drawCount);
  • mode:

    • gl.POINTS: Draws a single dot.
    • gl.TRIANGLES: Draws a triangle for a group of three vertices.
  • firstsList:

    • An Int32Array or Array (of GLint) specifying a list of starting indices for the arrays of vector points.
  • firstsOffset:

    • A GLuint defining the starting point into the firstsLists array.
  • countsList:

    • An Int32Array or Array (of GLsizei) specifying a list of numbers of indices to be rendered.
  • countsOffset:

    • A GLuint defining the starting point into the countsList array.
  • drawCount:

    • A GLsizei specifying the number of instances of the range of elements to execute.

Looking into the implementation, we can see that we can control the offset and drawcount to draw mode past the size of buffer : )

So, our POC goes here ...

Test

11pro

As you can see, our webpage just crashed since the validateOffset() called in multiDrawArraysWEBGL() doesn't check if our firstsOffset is in the range of [0, size-drawcount] and we are drawing past the size of of actual buffer. The function call m_context->graphicsContextGL()->multiDrawArraysANGLE() is implemented in third party components for WebKit known as ANGLE and it doesn't have any checks before rendering, so we crash writing some bad value to the memory region.

FYI, multiDrawArraysANGLE() pseudocode works like this:

      for(i=0; i<drawcount; i++) {
        if (*(counts+i)>0) DrawArrays(mode, *(firsts+i), *(counts+i));
      }

And with the patch applied, it won't render anything and return false through the validateOffset() function call:

12pro

js) ...

Credits

PARS Defense Team

We're hiring new team members, contact us: info[at]parsdefense.com

You might also like...

Been interested, studying, and developing blockchain security with a Zero Knowledge Proof (ZKP) and create a prototype on the current issue with Philippine's upcoming election. 📥

Been interested, studying, and developing blockchain security with a Zero Knowledge Proof (ZKP) and create a prototype on the current issue with Philippine's upcoming election. 📥

Implementation of Zero Knowledge Proofs in Cryptographic Voting 😎 Reference: Cryptographic Voting – A Gentle Introduction Overview 👨🏻‍💻 The main i

Apr 11, 2022

☕️ A coffee delivery app concept

☕️  A coffee delivery app concept

Coffee Delivery ☕️ Layout • Technologies • Getting started • License 🔖 Layout The author of this layout is Nickelfox Design. You can view the project

Dec 19, 2022

Ektogamat Three Graces Design Concept using threejs

Ektogamat Three Graces Design Concept using threejs

In this project, I wanted to show that creating a fancy design like this using #threejs is not as difficult as it looks.

Dec 18, 2022

Privacy preserving governance mechanism using zero knowledge for proof of merkle inclusion.

Privacy preserving governance mechanism using zero knowledge for proof of merkle inclusion.

Zero Knowledge Private Voting V1 Motivation On-chain governance today is fully transparent at the cost of privacy. This means that every proposal and

Dec 16, 2022

Privacy preserving governance mechanism using zero knowledge for proof of merkle inclusion.

Privacy preserving governance mechanism using zero knowledge for proof of merkle inclusion.

Zero Knowledge Private Voting V1 Motivation On-chain governance today is fully transparent at the cost of privacy. This means that every proposal and

Jun 7, 2022

we learn the whole concept of JS including Basics like Object, Functions, Array etc. And Advance JS - Understanding DOMs, JQuery, Ajax, Prototypes etc.

JavaScript-for-Complete-Web Development. we learn the whole concept of JS including Basics like Object, Functions, Array etc. And Advance JS - Underst

Jul 22, 2022

Proofie is an experimental proof-reader for VSCode that helps you write better.

Proofie is an experimental proof-reader for VSCode that helps you write better.

Proofie Proofie is an experimental proof-reader for VSCode that helps you write better. Install You can install proofie from the VSCode Marketplace. O

Jul 25, 2022

Collection of benchmarks of functional programming languages and proof assistants.

Collection of benchmarks of functional programming languages and proof assistants.

Functional Benchmarks This repository contains a collection of benchmarks of functional programming languages and proof assistants. It is split in two

Dec 12, 2022

An Opensource Peer-to-peer Social Network with Zero-Knowledge-Proof based authentication.

HexHoot This is an attempt to create an Opensource Peer-to-peer Social Network with Zero-Knowledge-Proof based authentication. The objective is to dem

Dec 28, 2022
Owner
PARS Defense
Advanced Security Research
PARS Defense
Challenge for you all to prove that CVE-2022–29622 is not false

CVE-2022–29622: (In)vulnerability Analysis This codebase was created to help security professionals and developers to understand why I think Formidabl

Zsolt Imre 2 Jul 20, 2022
POC OF CVE-2022-21970

CVE-2022-21970 Description Microsoft Edge (Chromium-based) Elevation of Privilege Vulnerability. This vulnerability allows an attacker to execute java

Warmonger 8 Dec 9, 2022
A Web UI toolkit for creating rapid prototypes, experiments and proof of concept projects.

MinimalComps2 A Web UI tookkit for creating rapid prototypes, experiments and proof of concept projects. The site: https://www.minimalcomps2.com/ Full

Keith Peters 32 Apr 18, 2022
NFT vending machine proof of concept built on Solana Pay, Metaplex, Phantom Mobile and Next.js.

Solana NFT Vending Machine This is a proof of concept of an NFT vending machine built using Solana Pay, Metaplex, Phantom Mobile, and Next.js. This wa

Matt Rosenzweig 55 Dec 15, 2022
True P2P concept for your p2p powered website/app/client. MSC/MEP (Multiple Strategy Concept/Multiple Entry Points)

TRUE P2P CONCEPT - Lets redecentralize the web This repo is just conceptual. Active development of the endproduct (TRUE P2P) happens here https://gith

Bo 6 Mar 29, 2022
Proof of concept: support immutable trpc servers using lambdas to ensure client/server compatibility

auto-versioned-trpc-aws-lambda Proof of concept to support an automatically versioned AWS Lambda running tRPC to ensure a somewhat graceful and automa

Kenneth Skovhus 5 Aug 30, 2022
Simple Jai to WASM Proof-of-Concept

Simple Jai to WASM Proof-of-Concept Jai does not officially support WebAssembly compilation target. BUT! It allows you to dump LLVM IR via the llvm_op

Tsoding 52 Dec 14, 2022
A proof-of-concept malicious Chrome extension

Crux: Demonstration Malicious Chrome Extension This repository is for educational purposes only. If you use this outside of security research or autho

Michael Taggart 18 Nov 9, 2022
A boilerplate project to build proof of concept paywalls with lightning service authentication tokens (LSATs)

lsat-workshop-boilerplate A boilerplate project to build proof of concept paywalls with lightning service authentication tokens (LSATs) Install Setup

Buck Perley 2 Oct 13, 2022
Second-challinge - Frontend Mentor - Social proof section

Frontend Mentor - Social proof section Welcome! ?? Thanks for checking out this

Ahmed-Abdalmagid 1 Feb 8, 2022