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

Forensics
Cropped - Writeup#
Thông tin Challenge#
- Thể loại: Forensics
- Tệp:
flag.png(1409×1004, kích thước 1.7 MB) - Lỗ hổng: Acropalypse (CVE-2023-21036)
Acropalypse là gì?#
Lỗ hổng xuất hiện trong một số công cụ cắt/screenshot (ví dụ Google Pixel, Windows Snipping Tool):
- Khi ảnh bị cắt rồi lưu đè lên file gốc
- Công cụ không cắt (truncate) đúng phần cuối file
- Dữ liệu gốc vẫn còn tồn tại trong phần "trailing bytes" sau chunk
IENDcủa PNG - Từ dữ liệu thừa này có thể tái tạo lại ảnh gốc chưa bị crop!
Xác minh#
pythonwith 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")
Kết quả: 1,379,551 bytes trailing data! ✓
Thuật toán khôi phục#
- Lấy phần trailing data nằm sau chunk
IEND. - Tìm các chunk
IDAT(dữ liệu nén zlib) trong phần trailing. - Giải nén dữ liệu zlib kèm thử các bit-shift (thử các canh lệch bit để tìm alignment đúng).
- Dùng dữ liệu giải nén để dựng lại PNG/bitmap với kích thước gốc (ví dụ 2560×1600).
Triển khai (mô tả)#
pythondef reconstruct_image(cropped, output, orig_width, orig_height):
# Mở PNG đã bị crop
f = open(cropped, 'rb')
magic = f.read(8) # PNG signature
# Duyệt các chunk đến khi gặp IEND
while True:
ctype, body = parse_png_chunk(f)
if ctype == b"IEND":
break
# Đọc phần trailing (dữ liệu nằm sau IEND)
trailer = f.read()
# Tìm các chunk IDAT trong trailer
idat = extract_idat_from_trailer(trailer)
# Xây bitstream từ IDAT để thử các alignment khác nhau
bitstream = build_bitstream(idat)
# Thử các bit offsets / byte shifts khác nhau để tìm prefix hợp lệ
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
# Dùng dữ liệu giải nén để tạo ảnh đầu ra với kích thước gốc
create_bmp(decompressed, orig_width, orig_height, output)
Ghi chú: thực tế việc khôi phục cần thử nhiều alignment (cả mức bit và byte), kiểm tra header PNG hợp lệ sau khi ghép và xác thực hình ảnh đầu ra.
Kết quả#
Chạy script đã khôi phục được ảnh gốc kích thước 2560×1600 và flag hiển thị rõ ràng trên ảnh!
Flag#
BPCTF{3v3ryth1ng_c0uld_be_4_CVE_i_gU355}
Thông điệp: "Mọi thứ đều có thể thành CVE" — ngay cả những lỗi nhỏ trong công cụ chụp ảnh màn hình!
Những bài học rút ra#
- Bất thường kích thước file: Luôn kiểm tra kích thước file — file PNG quá lớn/không đúng kích thước có thể chứa dữ liệu thừa.
- CVE thực tế: CVE-2023-21036 (Google Pixel), CVE-2023-28303 (Windows Snipping Tool).
- Hiểu cấu trúc PNG: Nắm rõ chunk (IHDR/IDAT/IEND) rất quan trọng để phục hồi.
- Bit-shifting: Việc khôi phục đôi khi cần thử nhiều alignment bit/byte để giải nén thành công.
- Tác động bảo mật: Lỗi nhỏ ở công cụ desktop có thể làm lộ dữ liệu nhạy cảm.
Tài liệu tham khảo#
- Bài viết giải thích 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