diff --git a/lib/metasploit/framework/login_scanner/brocade_telnet.rb b/lib/metasploit/framework/login_scanner/brocade_telnet.rb deleted file mode 100644 index 40aa3e31c1..0000000000 --- a/lib/metasploit/framework/login_scanner/brocade_telnet.rb +++ /dev/null @@ -1,122 +0,0 @@ -require 'msf/core' -require 'metasploit/framework/telnet/client' -require 'metasploit/framework/login_scanner/base' -require 'metasploit/framework/login_scanner/rex_socket' -module Metasploit - module Framework - module LoginScanner - # This is based off of the telnet LoginScanner. We had to role our own, - # based on hdm's recommendation, since we're not trying to login to telnet, - # but we're actually doing the escalated privileges (enable) login. - class Brocade_Telnet - include Metasploit::Framework::LoginScanner::Base - include Metasploit::Framework::LoginScanner::RexSocket - include Metasploit::Framework::Telnet::Client - - CAN_GET_SESSION = true - DEFAULT_PORT = 23 - LIKELY_PORTS = [ DEFAULT_PORT ] - LIKELY_SERVICE_NAMES = [ 'telnet' ] - PRIVATE_TYPES = [ :password ] - REALM_KEY = nil - - # @!attribute verbosity - # The timeout to wait for the telnet banner. - # - # @return [Fixnum] - attr_accessor :banner_timeout - # @!attribute verbosity - # The timeout to wait for the response from a telnet command. - # - # @return [Fixnum] - attr_accessor :telnet_timeout - - validates :banner_timeout, - presence: true, - numericality: { - only_integer: true, - greater_than_or_equal_to: 1 - } - - validates :telnet_timeout, - presence: true, - numericality: { - only_integer: true, - greater_than_or_equal_to: 1 - } - - # (see {Base#attempt_login}) - def attempt_login(credential) - result_options = { - credential: credential, - host: host, - port: port, - protocol: 'tcp', - service_name: 'telnet' - } - - begin - if connect_reset_safe == :refused - result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT - else - if busy_message? - self.sock.close unless self.sock.closed? - result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT - end - end - - unless result_options[:status] - raw_send("enable\r\n") #send the enable command - unless password_prompt? - send_user(credential.public) - end - - recvd_sample = @recvd.dup - # Allow for slow echos - 1.upto(10) do - recv_telnet(self.sock, 0.10) unless @recvd.nil? or @recvd[/#{@password_prompt}/] - end - - if password_prompt?(credential.public) - send_pass(credential.private) - - # Allow for slow echos - 1.upto(10) do - recv_telnet(self.sock, 0.10) if @recvd == recvd_sample - end - end - - if login_succeeded? - result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL - else - result_options[:status] = Metasploit::Model::Login::Status::INCORRECT - end - - end - rescue ::EOFError, Errno::ECONNRESET, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error - result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT - end - - ::Metasploit::Framework::LoginScanner::Result.new(result_options) - end - - private - - # This method sets the sane defaults for things - # like timeouts and TCP evasion options - def set_sane_defaults - self.connection_timeout ||= 30 - self.port ||= DEFAULT_PORT - self.banner_timeout ||= 25 - self.telnet_timeout ||= 10 - self.connection_timeout ||= 30 - self.max_send_size ||= 0 - self.send_delay ||= 0 - # Shim to set up the ivars from the old Login mixin - create_login_ivars - end - - end - end - end -end diff --git a/lib/metasploit/framework/login_scanner/telnet.rb b/lib/metasploit/framework/login_scanner/telnet.rb index f104cdf708..2ba5c388bf 100644 --- a/lib/metasploit/framework/login_scanner/telnet.rb +++ b/lib/metasploit/framework/login_scanner/telnet.rb @@ -30,6 +30,11 @@ module Metasploit # # @return [Fixnum] attr_accessor :telnet_timeout + # @!attribute verbosity + # Prepend code to call before checking for a user login + # + # @return [Proc] + attr_accessor :pre_login validates :banner_timeout, presence: true, @@ -66,6 +71,10 @@ module Metasploit end unless result_options[:status] + if pre_login + pre_login.call(self) + end + unless password_prompt? send_user(credential.public) end @@ -108,6 +117,7 @@ module Metasploit self.port ||= DEFAULT_PORT self.banner_timeout ||= 25 self.telnet_timeout ||= 10 + self.pre_login ||= nil self.connection_timeout ||= 30 self.max_send_size ||= 0 self.send_delay ||= 0 @@ -115,6 +125,10 @@ module Metasploit create_login_ivars end + def print_error( message ) + return if !@parent + @parent.print_error message + end end end end diff --git a/modules/auxiliary/scanner/telnet/brocade_enable_login.rb b/modules/auxiliary/scanner/telnet/brocade_enable_login.rb index 1fe131721f..a4ed99c027 100644 --- a/modules/auxiliary/scanner/telnet/brocade_enable_login.rb +++ b/modules/auxiliary/scanner/telnet/brocade_enable_login.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rex' require 'metasploit/framework/credential_collection' -require 'metasploit/framework/login_scanner/brocade_telnet' +require 'metasploit/framework/login_scanner/telnet' class Metasploit4 < Msf::Auxiliary @@ -20,16 +20,14 @@ class Metasploit4 < Msf::Auxiliary super( 'Name' => 'Brocade Enable Login Check Scanner', 'Description' => %q{ - This module will test a Brocade network device for a privilged - (Enable) login on a range of machines and report successful - logins. If you have loaded a database plugin and connected - to a database this module will record successful - logins and hosts so you can track your access. - This is not a login/telnet authentication. Config should NOT - have 'enable telnet authentication' in it. This will test the - config that contains 'aaa authentication enable default local' - Tested against: - ICX6450-24 SWver 07.4.00bT311 + This module will test a range of Brocade network devices for a + privileged logins and report successes. The device authentication mode + must be set as 'aaa authentication enable default local'. + Telnet authentication, e.g. 'enable telnet authentication', should not + be enabled in the device configuration. + + This module has been tested against the following devices: + ICX6450-24 SWver 07.4.00bT311, FastIron WS 624 SWver 07.2.02fT7e1 }, 'Author' => 'h00die ', @@ -48,25 +46,29 @@ class Metasploit4 < Msf::Auxiliary end def get_username_from_config(un_list,ip) - ["config","running-config"].each do |command| + ["config", "running-config"].each do |command| print_status(" Attempting username gathering from #{command} on #{ip}") - sock.puts("\r\n") #ensure the buffer is clear + sock.puts("\r\n") # ensure that the buffer is clear config = sock.recv(1024) sock.puts("show #{command}\r\n") + + # pull the entire config while true do - sock.puts(" \r\n") #paging + sock.puts(" \r\n") # paging config << sock.recv(1024) - #there seems to be some buffering issues. so we want to match that we're back at a prompt, as well as received the 'end' of the config. + # Read until we are back at a prompt and have received the 'end' of + # the config. break if config.match(/>$/) and config.match(/end/) - end #pull the entire config + end + config.each_line do |un| if un.match(/^username/) found_username = un.split(" ")[1].strip un_list.push(found_username) print_status(" Found: #{found_username}@#{ip}") - end #username match - end #each line in config - end #end config/running-config loop + end + end + end end attr_accessor :no_pass_prompt @@ -99,7 +101,7 @@ class Metasploit4 < Msf::Auxiliary cred_collection = prepend_db_passwords(cred_collection) - scanner = Metasploit::Framework::LoginScanner::Brocade_Telnet.new( + scanner = Metasploit::Framework::LoginScanner::Telnet.new( host: ip, port: rport, proxies: datastore['PROXIES'], @@ -111,6 +113,7 @@ class Metasploit4 < Msf::Auxiliary send_delay: datastore['TCP::send_delay'], banner_timeout: datastore['TelnetBannerTimeout'], telnet_timeout: datastore['TelnetTimeout'], + pre_login: lambda{ |s| raw_send("enable\r\n", nsock = s.sock) }, framework: framework, framework_module: self, ) @@ -121,6 +124,7 @@ class Metasploit4 < Msf::Auxiliary module_fullname: self.fullname, workspace_id: myworkspace_id ) + if result.success? credential_core = create_credential(credential_data) credential_data[:core] = credential_core @@ -132,7 +136,7 @@ class Metasploit4 < Msf::Auxiliary print_error("#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})") end end - end #end un loop + end end def start_telnet_session(host, port, user, pass, scanner)