Class: Metasploit::Framework::LoginScanner::OPNSense
- Defined in:
- lib/metasploit/framework/login_scanner/opnsense.rb
Overview
This is the LoginScanner class for dealing with Deciso B.V. OPNSense instances. It is responsible for taking a single target, and a list of credentials and attempting them. It then saves the results.
Constant Summary
Constants inherited from HTTP
HTTP::AUTHORIZATION_HEADER, HTTP::DEFAULT_HTTP_NOT_AUTHED_CODES, HTTP::DEFAULT_HTTP_SUCCESS_CODES, HTTP::DEFAULT_PORT, HTTP::DEFAULT_REALM, HTTP::DEFAULT_SSL_PORT, HTTP::LIKELY_PORTS, HTTP::LIKELY_SERVICE_NAMES, HTTP::PRIVATE_TYPES, HTTP::REALM_KEY
Instance Attribute Summary
Attributes inherited from HTTP
#digest_auth_iis, #evade_header_folding, #evade_method_random_case, #evade_method_random_invalid, #evade_method_random_valid, #evade_pad_fake_headers, #evade_pad_fake_headers_count, #evade_pad_get_params, #evade_pad_get_params_count, #evade_pad_method_uri_count, #evade_pad_method_uri_type, #evade_pad_post_params, #evade_pad_post_params_count, #evade_pad_uri_version_count, #evade_pad_uri_version_type, #evade_shuffle_get_params, #evade_shuffle_post_params, #evade_uri_dir_fake_relative, #evade_uri_dir_self_reference, #evade_uri_encode_mode, #evade_uri_fake_end, #evade_uri_fake_params_start, #evade_uri_full_url, #evade_uri_use_backslashes, #evade_version_random_invalid, #evade_version_random_valid, #http_password, #http_success_codes, #http_username, #keep_connection_alive, #kerberos_authenticator_factory, #method, #ntlm_domain, #ntlm_send_lm, #ntlm_send_ntlm, #ntlm_send_spn, #ntlm_use_lm_key, #ntlm_use_ntlmv2, #ntlm_use_ntlmv2_session, #uri, #user_agent, #vhost
Instance Method Summary collapse
- #attempt_login(credential) ⇒ Object
-
#check_setup ⇒ Boolean, String
Checks if the target is OPNSense.
-
#get_cookie_value(response, wanted_cookie_name) ⇒ Object
Retrieve the wanted cookie value by name from the HTTP response.
-
#query_magic_value_and_cookies ⇒ Hash<Symbol, Object>
Query the magic value and cookies from the OPNSense login page.
-
#try_login(username, password, magic_value, cookies) ⇒ Object
Each individual login needs their own magic name and value.
Methods inherited from HTTP
#authentication_required?, #send_request
Instance Method Details
#attempt_login(credential) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/metasploit/framework/login_scanner/opnsense.rb', line 97 def attempt_login(credential) = { credential: credential, host: @host, port: @port, protocol: 'tcp', service_name: 'opnsense' } # Each login needs its own magic name and value = if [:status] != :success .merge!(status: ::Metasploit::Model::Login::Status::UNTRIED, proof: [:error]) return Result.new() end login_result = try_login(credential.public, credential.private, [:result][:magic_value], [:result][:cookies]) if login_result[:result].nil? .merge!(status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Unable to connect to OPNSense') return Result.new() end # 200 is incorrect result if login_result[:result].code == 200 || login_result[:result].body.include?('Username or Password incorrect') .merge!(status: ::Metasploit::Model::Login::Status::INCORRECT, proof: 'Username or Password incorrect') return Result.new() end login_status = login_result[:result].code == 302 ? ::Metasploit::Model::Login::Status::SUCCESSFUL : ::Metasploit::Model::Login::Status::INCORRECT .merge!(status: login_status, proof: login_result[:result]) Result.new() rescue ::Rex::ConnectionError => _e .merge!(status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Unable to connect to OPNSense') return Result.new() end |
#check_setup ⇒ Boolean, String
Checks if the target is OPNSense. The login module should call this.
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/metasploit/framework/login_scanner/opnsense.rb', line 23 def check_setup request_params = { 'method' => 'GET', 'uri' => normalize_uri(@uri.to_s) } res = send_request(request_params) if res && res.code == 200 && res.body&.include?('Login | OPNsense') return false end "Unable to locate \"Login | OPNsense\" in body. (Is this really OPNSense?)" end |
#get_cookie_value(response, wanted_cookie_name) ⇒ Object
Retrieve the wanted cookie value by name from the HTTP response.
16 17 18 |
# File 'lib/metasploit/framework/login_scanner/opnsense.rb', line 16 def (response, ) response..split('; ').find { || .start_with?() }.split('=').last end |
#query_magic_value_and_cookies ⇒ Hash<Symbol, Object>
Query the magic value and cookies from the OPNSense login page.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/metasploit/framework/login_scanner/opnsense.rb', line 40 def request_params = { 'method' => 'GET', 'uri' => normalize_uri(@uri.to_s) } res = send_request(request_params) if res.nil? return { status: :failure, error: 'Did not receive response to a GET request' } end if res.code != 200 return { status: :failure, error: "Unexpected return code from GET request - #{res.code}" } end if res.body.nil? return { status: :failure, error: 'Received an empty body from GET request' } end # The magic name and value are hidden on the login form, so we extract them using get_html_document form_input = res.get_html_document&.at('input') if form_input.nil? || form_input['type'] != 'hidden' return { status: :failure, error: 'Could not find hidden magic field in the login form.' } end magic_value = { name: form_input['name'], value: form_input['value'] } = "PHPSESSID=#{(res, 'PHPSESSID')}; cookie_test=#{(res, 'cookie_test')}" { status: :success, result: { magic_value: magic_value, cookies: } } end |
#try_login(username, password, magic_value, cookies) ⇒ Object
Each individual login needs their own magic name and value. This magic value comes from the login form received in response to a GET request to the login page. Each login attempt also requires specific cookies to be set, otherwise an error is returned.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/metasploit/framework/login_scanner/opnsense.rb', line 80 def try_login(username, password, magic_value, ) request_params = { 'method' => 'POST', 'uri' => normalize_uri(@uri.to_s), 'cookie' => , 'vars_post' => { magic_value[:name] => magic_value[:value], 'usernamefld' => username, 'passwordfld' => password, 'login' => '1' } } { status: :success, result: send_request(request_params) } end |