Forensics
Medium
250 points
Cropped
Recuite 2025 - HCMUS
6 tháng 10, 2025
Acropalypse
CVE-2023-21036
PNG
Screenshot

Forensics
Cropped - Writeup
Challenge Information
- Category: Forensics
- File:
flag.png(1409×1004, size 1.7 MB) - Vulnerability: Acropalypse (CVE-2023-21036)
What is Acropalypse?
The vulnerability appears in some cropping/screenshot tools (e.g. Google Pixel, Windows Snipping Tool):
- When an image is cropped and overwritten on the original file
- The tool does not properly truncate the end of the file
- Original data still exists in the "trailing bytes" after the PNG
IENDchunk - From this redundant data, the original uncropped image can be reconstructed!
Verification
with open('flag.png', 'rb') as f:
data = f.read()
iend_pos = data.find(b'IEND')
iend_chunk_end = iend_pos + 8
trailing_size = len(data) - iend_chunk_end
print(f"Trailing data: {trailing_size} bytes")
Result: 1,379,551 bytes trailing data! ✓
Recovery Algorithm
- Extract trailing data located after
IENDchunk. - Find
IDATchunks (zlib compressed data) in the trailing part. - Decompress zlib data while trying bit-shifts (trying bit alignments to find correct prefix).
- Use decompressed data to reconstruct PNG/bitmap with original dimensions (e.g. 2560×1600).
Implementation (Conceptual)
def reconstruct_image(cropped, output, orig_width, orig_height):
# Open cropped PNG
f = open(cropped, 'rb')
magic = f.read(8) # PNG signature
# Iterate chunks until IEND
while True:
ctype, body = parse_png_chunk(f)
if ctype == b"IEND":
break
# Read trailing part (data after IEND)
trailer = f.read()
# Find IDAT chunks in trailer
idat = extract_idat_from_trailer(trailer)
# Build bitstream from IDAT to try different alignments
bitstream = build_bitstream(idat)
# Try different bit offsets / byte shifts to find valid prefix
for i in range(len(idat)):
truncated = byte_offsets[i%8][i//8:]
try:
decompressed = decompress_with_prefix(truncated)
if valid_parse(decompressed):
break
except:
pass
# Use decompressed data to create output image with original dimensions
create_bmp(decompressed, orig_width, orig_height, output)
Note: In practice, recovery requires trying multiple alignments (both bit and byte level), validating PNG header after assembly, and verifying output image.
Result
Running the script recovered the original image with dimensions 2560×1600, and the flag is clearly visible on the image!
White Background Image
Flag
BPCTF{3v3ryth1ng_c0uld_be_4_CVE_i_gU355}
Message: "Everything could be a CVE" — even small bugs in screenshot tools!
Key Takeaways
- File Size Anomalies: Always check file size — PNG files too large/not matching dimensions might contain trailing data.
- Real-world CVEs: CVE-2023-21036 (Google Pixel), CVE-2023-28303 (Windows Snipping Tool).
- Understand PNG Structure: Knowing chunks (IHDR/IDAT/IEND) is crucial for recovery.
- Bit-shifting: Recovery sometimes requires testing multiple bit/byte alignments to decompress successfully.
- Security Impact: Small bugs in desktop tools can leak sensitive data.
References
- Article explaining Acropalypse: https://www.da.vidbuchanan.co.uk/blog/exploiting-acropalypse.html
- CVE-2023-21036 (Google Pixel)
- CVE-2023-28303 (Windows Snipping Tool)
250
Points
Medium
Difficulty
Forensics
Category