Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2023-6702 — Chrome Renderer 1day RCE durch Type Confusion im Async Stack Trace (v8ctf-Einreichung) | Kitploit
Tools/GitHubGitHub/kaist-hacking/cve-2023-6702
SchwachstellenanalyseExploitationWebanwendungs-ExploitationCTFLernen & BildungBinary-Exploitation
GitHubkaist-hacking/cve-2023-6702

CVE-2023-6702

Chrome Renderer 1day RCE durch Type Confusion im Async Stack Trace (v8ctf-Einreichung)

Repository anzeigen
8697vor 2 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Chrome Renderer 1-Day-RCE durch Typverwechslung im asynchronen Stack-Trace (CVE-2023-6702)

Zusammenfassung

Diese Schwachstelle erlaubte es einem entfernten Angreifer, beliebigen Code im Chrome-Renderer-Prozess auszuführen.

In der Verarbeitung der asynchronen Stack-Traces fehlte eine ausreichende Typprüfung. Dies führt zu einer Typverwechslung zwischen FunctionContext und NativeContext, die einen unerlaubten Zugriff auf den JSGlobalProxy->hash-Wert verursacht. Durch Heap-Spraying konnte der Angreifer einen gefälschten asynchronen Stack-Frame einschleusen und die fakeobj-Primitive konstruieren. Mit der fakeobj-Primitive konnte der Angreifer beliebigen Code im Chrome-Renderer-Prozess ausführen.

Du kannst dir unsere TyphoonCon-2024-Folien ansehen.

Hersteller / Produkt / Version

  • Google Chrome
  • Betroffene Versionen: vor 120.0.6099.109
  • Behobene Version: 120.0.6099.109

Zeitleiste

  • 2020-05-13: Bug eingeführt - [Promise.any] Implment async stack traces for Promise.any
  • 2023-11-10: Bug-Report - Security: V8 Debug check failed: LAST_TYPE >= value
  • 2023-11-15: Patch - [promises, async stack traces] Fix the case when the closure has run
  • 2023-12-12: Sicherheitshinweis - https://chromereleases.googleblog.com/2023/12/stable-channel-update-for-desktop_12.html
  • 2024-01-12: v8CTF-Einreichung <-- Der Zeitpunkt, an dem wir an dieser Schwachstelle gearbeitet haben
  • 2024-02-23: Bug-Report offengelegt

Hintergrund

Asynchroner Stack-Trace

Asynchrone Programmierung ist eines der wichtigsten Features in JavaScript. Früher war es schwierig, asynchronen Code mit dem Fehler-Stack zu debuggen, da asynchrone Funktionen nicht im Fehler-Stack erfasst wurden. Suspendierte asynchrone Funktionen werden in der Callback-Queue der Ereignisschleife gespeichert, nicht im Aufrufstapel, daher enthält der Fehler-Stack die asynchrone Funktion nicht. Um dieses Problem zu lösen, bietet V8 die Funktion „async stack trace“ (standardmäßig seit V8 v7.3), um asynchrone Funktionen im Fehler-Stack zu erfassen. ([v8-Blog], [v8-Dokumentation])

Promise.all Resolve Element Closure

„Promise.all Resolve Element Closure“ ist eine Hilfsfunktion zum Auflösen der eingehenden Promises in der Promise.all-Funktion. Die Promise.all-Funktion nimmt ein Array von Promises entgegen und gibt ein Promise zurück, das aufgelöst wird, wenn alle eingegebenen Promises aufgelöst sind. „Promise.all Resolve Element Closure“ ist ein Resolve-Handler für jedes eingehende Promise in der Promise.all-Funktion. Die Funktion hat die Aufgabe, das eingehende Promise aufzulösen und den Erfüllungswert im Ergebnis-Array zu speichern.

Es gibt 2 Punkte, die man bei dieser Funktion beachten sollte:

  1. Es ist eine intrinsische Built-in-Funktion und aus dem JavaScript-Code nicht direkt zugänglich.
  2. Der Kontext der Funktion wird als Marker verwendet, um zu prüfen, ob die Funktion bereits ausgeführt wurde. Sie hat FunctionContext, bis sie aufgerufen wurde, und nach dem Aufruf hat sie NativeContext. (v8-Code)

Die Schwachstelle

Bug-Klasse: Typverwechslung zwischen FunctionContext und NativeContext

Details zur Schwachstelle:

Die Schwachstelle kann ausgelöst werden, indem ein asynchroner Stack-Trace mit der bereits ausgeführten Funktion „Promise.all Resolve Element Closure“ oder ähnlichen intrinsischen Built-in-Funktionen erfasst wird. In diesem Exploit habe ich die Funktion „Promise.all Resolve Element Closure“ als Beispiel verwendet.

Wenn im JavaScript-Code ein Fehler ausgelöst wird, erfasst V8 den Fehler-Stack aus dem Aufrufstapel und hängt die asynchronen Stack-Frames aus der aktuellen Mikrotask an [1].

CallSiteBuilder builder(isolate, mode, limit, caller);
VisitStack(isolate, &builder);

// If --async-stack-traces are enabled and the "current microtask" is a
// PromiseReactionJobTask, we try to enrich the stack trace with async
// frames.
if (v8_flags.async_stack_traces) {
    CaptureAsyncStackTrace(isolate, &builder);
}

Die Funktion CaptureAsyncStackTrace [[2]] durchsucht die Promise-Kette und hängt den asynchronen Stack-Frame gemäß dem asynchronen Aufruftyp an (z. B. await, Promise.all, Promise.any).

Unten ist der Ausschnitt der Funktion CaptureAsyncStackTrace, der den Fall Promise.all behandelt:

} else if (IsBuiltinFunction(isolate, reaction->fulfill_handler(),
                                Builtin::kPromiseAllResolveElementClosure)) {
    Handle<JSFunction> function(JSFunction::cast(reaction->fulfill_handler()),
                                isolate);
    Handle<Context> context(function->context(), isolate);
    Handle<JSFunction> combinator(context->native_context()->promise_all(),
                                isolate);
    builder->AppendPromiseCombinatorFrame(function, combinator);

    // Now peak into the Promise.all() resolve element context to
    // find the promise capability that's being resolved when all
    // the concurrent promises resolve.
    int const index =
        PromiseBuiltins::kPromiseAllResolveElementCapabilitySlot;
    Handle<PromiseCapability> capability(
        PromiseCapability::cast(context->get(index)), isolate);
    if (!IsJSPromise(capability->promise())) return;
    promise = handle(JSPromise::cast(capability->promise()), isolate);
} else if (

Wenn beim Durchsuchen der Promise-Kette reaction->fulfill_handler die Built-in-Funktion „Promise.all Resolve Element Closure“ ist, wird der asynchrone Promise-Combinator-Frame an den Fehler-Stack angehängt. Danach wechselt es zum nächsten Promise, indem es auf function->context->capability->promise zugreift.

Das Problem ist, dass die Funktion davon ausgeht, dass die „Promise.all Resolve Element Closure“-Funktion noch nicht ausgeführt wurde. Wenn die „Promise.all Resolve Element Closure“-Funktion bereits ausgeführt wurde, ändert sich der Kontext von FunctionContext zu NativeContext. Das führt zu einer Typverwechslung zwischen FunctionContext und NativeContext in der Funktion CaptureAsyncStackTrace.

Erstellung des PoC:

Die Strategie zum Auslösen der Schwachstelle ist wie folgt:

  1. Die Funktion „Promise.all Resolve Element Closure“ besorgen, eine intrinsische Built-in-Funktion.
  2. Die Funktion „Promise.all Resolve Element Closure“ explizit aufrufen, um den Kontext von FunctionContext zu NativeContext zu ändern.
  3. Die Funktion „Promise.all Resolve Element Closure“ als Fulfill-Handler eines Promises mit einer neuen Promise-Kette festlegen.
  4. Einen Fehler in der Promise-Kette auslösen und den asynchronen Stack-Trace erfassen.

Ich habe das synchrone Promise-Auflösungsmuster für Promise.all verwendet, um die Funktion „Promise.all Resolve Element Closure“ auf JS-Skriptebene zu erhalten. Das Muster habe ich aus den test262-Testfällen übernommen.

Nachdem ich die Funktion explizit aufgerufen hatte, habe ich zum Auslösen der Schwachstelle den Beispielcode aus der [Dokumentation zu Zero-Cost-Async-Stack-Traces][v8-Dokumentation] verwendet, um eine neue Promise-Kette vorzubereiten, und die intrinsische Built-in-Funktion als Fulfill-Handler eines der Promises festgelegt.

Tool herunterladen