Class: Metasploit::Framework::LoginScanner::HTTP

Inherits:
Object
  • Object
show all
Includes:
Base, RexSocket, Msf::Auxiliary::Report
Defined in:
lib/metasploit/framework/login_scanner/http.rb

Overview

HTTP-specific login scanner.

Constant Summary collapse

AUTHORIZATION_HEADER =
'WWW-Authenticate'.freeze
DEFAULT_REALM =
nil
DEFAULT_PORT =
80
DEFAULT_SSL_PORT =
443
DEFAULT_HTTP_SUCCESS_CODES =
[200, 201].append(*(300..309))
DEFAULT_HTTP_NOT_AUTHED_CODES =
[401]
LIKELY_PORTS =
[80, 443, 8000, 8080]
LIKELY_SERVICE_NAMES =
%w[http https]
PRIVATE_TYPES =
[:password]
REALM_KEY =
Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Msf::Auxiliary::Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Instance Attribute Details

#digest_auth_iisBoolean

Returns Whether to conform to IIS digest authentication mode.

Returns:

  • (Boolean)

    Whether to conform to IIS digest authentication mode.



173
174
175
# File 'lib/metasploit/framework/login_scanner/http.rb', line 173

def digest_auth_iis
  @digest_auth_iis
end

#evade_header_foldingBoolean

Returns Whether to enable folding of HTTP headers.

Returns:

  • (Boolean)

    Whether to enable folding of HTTP headers



141
142
143
# File 'lib/metasploit/framework/login_scanner/http.rb', line 141

def evade_header_folding
  @evade_header_folding
end

#evade_method_random_caseBoolean

Returns Whether to use random casing for the HTTP method.

Returns:

  • (Boolean)

    Whether to use random casing for the HTTP method



77
78
79
# File 'lib/metasploit/framework/login_scanner/http.rb', line 77

def evade_method_random_case
  @evade_method_random_case
end

#evade_method_random_invalidBoolean

Returns Whether to use a random invalid, HTTP method for request.

Returns:

  • (Boolean)

    Whether to use a random invalid, HTTP method for request



73
74
75
# File 'lib/metasploit/framework/login_scanner/http.rb', line 73

def evade_method_random_invalid
  @evade_method_random_invalid
end

#evade_method_random_validBoolean

Returns Whether to use a random, but valid, HTTP method for request.

Returns:

  • (Boolean)

    Whether to use a random, but valid, HTTP method for request



69
70
71
# File 'lib/metasploit/framework/login_scanner/http.rb', line 69

def evade_method_random_valid
  @evade_method_random_valid
end

#evade_pad_fake_headersBoolean

Returns Whether to insert random, fake headers into the HTTP request.

Returns:

  • (Boolean)

    Whether to insert random, fake headers into the HTTP request



101
102
103
# File 'lib/metasploit/framework/login_scanner/http.rb', line 101

def evade_pad_fake_headers
  @evade_pad_fake_headers
end

#evade_pad_fake_headers_countInteger

Returns How many fake headers to insert into the HTTP request.

Returns:

  • (Integer)

    How many fake headers to insert into the HTTP request



105
106
107
# File 'lib/metasploit/framework/login_scanner/http.rb', line 105

def evade_pad_fake_headers_count
  @evade_pad_fake_headers_count
end

#evade_pad_get_paramsBoolean

Returns Whether to insert random, fake query string variables into the request.

Returns:

  • (Boolean)

    Whether to insert random, fake query string variables into the request



109
110
111
# File 'lib/metasploit/framework/login_scanner/http.rb', line 109

def evade_pad_get_params
  @evade_pad_get_params
end

#evade_pad_get_params_countInteger

Returns How many fake query string variables to insert into the request.

Returns:

  • (Integer)

    How many fake query string variables to insert into the request



113
114
115
# File 'lib/metasploit/framework/login_scanner/http.rb', line 113

def evade_pad_get_params_count
  @evade_pad_get_params_count
end

#evade_pad_method_uri_countInteger

Returns How many whitespace characters to use between the method and uri.

Returns:

  • (Integer)

    How many whitespace characters to use between the method and uri



53
54
55
# File 'lib/metasploit/framework/login_scanner/http.rb', line 53

def evade_pad_method_uri_count
  @evade_pad_method_uri_count
end

#evade_pad_method_uri_typeString

Returns What type of whitespace to use between the method and uri.

Returns:

  • (String)

    What type of whitespace to use between the method and uri



61
62
63
# File 'lib/metasploit/framework/login_scanner/http.rb', line 61

def evade_pad_method_uri_type
  @evade_pad_method_uri_type
end

#evade_pad_post_paramsBoolean

Returns Whether to insert random, fake post variables into the request.

Returns:

  • (Boolean)

    Whether to insert random, fake post variables into the request



117
118
119
# File 'lib/metasploit/framework/login_scanner/http.rb', line 117

def evade_pad_post_params
  @evade_pad_post_params
end

#evade_pad_post_params_countInteger

Returns How many fake post variables to insert into the request.

Returns:

  • (Integer)

    How many fake post variables to insert into the request



121
122
123
# File 'lib/metasploit/framework/login_scanner/http.rb', line 121

def evade_pad_post_params_count
  @evade_pad_post_params_count
end

#evade_pad_uri_version_countInteger

Returns How many whitespace characters to use between the uri and version.

Returns:

  • (Integer)

    How many whitespace characters to use between the uri and version



57
58
59
# File 'lib/metasploit/framework/login_scanner/http.rb', line 57

def evade_pad_uri_version_count
  @evade_pad_uri_version_count
end

#evade_pad_uri_version_typeString

Returns What type of whitespace to use between the uri and version.

Returns:

  • (String)

    What type of whitespace to use between the uri and version



65
66
67
# File 'lib/metasploit/framework/login_scanner/http.rb', line 65

def evade_pad_uri_version_type
  @evade_pad_uri_version_type
end

#evade_shuffle_get_paramsBoolean

Returns Randomize order of GET parameters.

Returns:

  • (Boolean)

    Randomize order of GET parameters



125
126
127
# File 'lib/metasploit/framework/login_scanner/http.rb', line 125

def evade_shuffle_get_params
  @evade_shuffle_get_params
end

#evade_shuffle_post_paramsBoolean

Returns Randomize order of POST parameters.

Returns:

  • (Boolean)

    Randomize order of POST parameters



129
130
131
# File 'lib/metasploit/framework/login_scanner/http.rb', line 129

def evade_shuffle_post_params
  @evade_shuffle_post_params
end

#evade_uri_dir_fake_relativeBoolean

Returns Whether to insert fake relative directories into the uri.

Returns:

  • (Boolean)

    Whether to insert fake relative directories into the uri



93
94
95
# File 'lib/metasploit/framework/login_scanner/http.rb', line 93

def evade_uri_dir_fake_relative
  @evade_uri_dir_fake_relative
end

#evade_uri_dir_self_referenceBoolean

Returns Whether to insert self-referential directories into the uri.

Returns:

  • (Boolean)

    Whether to insert self-referential directories into the uri



89
90
91
# File 'lib/metasploit/framework/login_scanner/http.rb', line 89

def evade_uri_dir_self_reference
  @evade_uri_dir_self_reference
end

#evade_uri_encode_modeString

Returns The type of URI encoding to use.

Returns:

  • (String)

    The type of URI encoding to use



45
46
47
# File 'lib/metasploit/framework/login_scanner/http.rb', line 45

def evade_uri_encode_mode
  @evade_uri_encode_mode
end

#evade_uri_fake_endBoolean

Returns Whether to add a fake end of URI (eg: /%20HTTP/1.0/../../).

Returns:

  • (Boolean)

    Whether to add a fake end of URI (eg: /%20HTTP/1.0/../../)



133
134
135
# File 'lib/metasploit/framework/login_scanner/http.rb', line 133

def evade_uri_fake_end
  @evade_uri_fake_end
end

#evade_uri_fake_params_startBoolean

Returns Whether to add a fake start of params to the URI (eg: /%3fa=b/../).

Returns:

  • (Boolean)

    Whether to add a fake start of params to the URI (eg: /%3fa=b/../)



137
138
139
# File 'lib/metasploit/framework/login_scanner/http.rb', line 137

def evade_uri_fake_params_start
  @evade_uri_fake_params_start
end

#evade_uri_full_urlBoolean

Returns Whether to use the full URL for all HTTP requests.

Returns:

  • (Boolean)

    Whether to use the full URL for all HTTP requests



49
50
51
# File 'lib/metasploit/framework/login_scanner/http.rb', line 49

def evade_uri_full_url
  @evade_uri_full_url
end

#evade_uri_use_backslashesBoolean

Returns Whether to use back slashes instead of forward slashes in the uri.

Returns:

  • (Boolean)

    Whether to use back slashes instead of forward slashes in the uri



97
98
99
# File 'lib/metasploit/framework/login_scanner/http.rb', line 97

def evade_uri_use_backslashes
  @evade_uri_use_backslashes
end

#evade_version_random_invalidBoolean

Returns Whether to use a random invalid, HTTP version for request.

Returns:

  • (Boolean)

    Whether to use a random invalid, HTTP version for request



85
86
87
# File 'lib/metasploit/framework/login_scanner/http.rb', line 85

def evade_version_random_invalid
  @evade_version_random_invalid
end

#evade_version_random_validBoolean

Returns Whether to use a random, but valid, HTTP version for request.

Returns:

  • (Boolean)

    Whether to use a random, but valid, HTTP version for request



81
82
83
# File 'lib/metasploit/framework/login_scanner/http.rb', line 81

def evade_version_random_valid
  @evade_version_random_valid
end

#http_passwordString

Returns:

  • (String)


181
182
183
# File 'lib/metasploit/framework/login_scanner/http.rb', line 181

def http_password
  @http_password
end

#http_success_codesArray

Returns [Int] list of valid http response codes.

Returns:

  • (Array)
    Int

    list of valid http response codes



193
194
195
# File 'lib/metasploit/framework/login_scanner/http.rb', line 193

def http_success_codes
  @http_success_codes
end

#http_usernameString

Returns:

  • (String)


177
178
179
# File 'lib/metasploit/framework/login_scanner/http.rb', line 177

def http_username
  @http_username
end

#keep_connection_aliveBoolean

Returns Whether to keep the connection open after a successful login.

Returns:

  • (Boolean)

    Whether to keep the connection open after a successful login



189
190
191
# File 'lib/metasploit/framework/login_scanner/http.rb', line 189

def keep_connection_alive
  @keep_connection_alive
end

#kerberos_authenticator_factoryFunc<username, password, realm> : Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::HTTP

Returns A factory method for creating a kerberos authenticator.

Returns:



185
186
187
# File 'lib/metasploit/framework/login_scanner/http.rb', line 185

def kerberos_authenticator_factory
  @kerberos_authenticator_factory
end

#methodObject

Returns the value of attribute method.



33
34
35
# File 'lib/metasploit/framework/login_scanner/http.rb', line 33

def method
  @method
end

#ntlm_domainString

Returns The NTLM domain to use during authentication.

Returns:

  • (String)

    The NTLM domain to use during authentication



169
170
171
# File 'lib/metasploit/framework/login_scanner/http.rb', line 169

def ntlm_domain
  @ntlm_domain
end

#ntlm_send_lmBoolean

Returns Whether to always send the LANMAN response (except when NTLMv2_session is specified).

Returns:

  • (Boolean)

    Whether to always send the LANMAN response (except when NTLMv2_session is specified)



153
154
155
# File 'lib/metasploit/framework/login_scanner/http.rb', line 153

def ntlm_send_lm
  @ntlm_send_lm
end

#ntlm_send_ntlmBoolean

Returns Whether to activate the ‘Negotiate NTLM key’ flag, indicating the use of NTLM responses.

Returns:

  • (Boolean)

    Whether to activate the ‘Negotiate NTLM key’ flag, indicating the use of NTLM responses



157
158
159
# File 'lib/metasploit/framework/login_scanner/http.rb', line 157

def ntlm_send_ntlm
  @ntlm_send_ntlm
end

#ntlm_send_spnBoolean

Returns Whether to send an avp of type SPN in the NTLMv2 client blob.

Returns:

  • (Boolean)

    Whether to send an avp of type SPN in the NTLMv2 client blob.



161
162
163
# File 'lib/metasploit/framework/login_scanner/http.rb', line 161

def ntlm_send_spn
  @ntlm_send_spn
end

#ntlm_use_lm_keyBoolean

Returns Activate the ‘Negotiate Lan Manager Key’ flag, using the LM key when the LM response is sent.

Returns:

  • (Boolean)

    Activate the ‘Negotiate Lan Manager Key’ flag, using the LM key when the LM response is sent



165
166
167
# File 'lib/metasploit/framework/login_scanner/http.rb', line 165

def ntlm_use_lm_key
  @ntlm_use_lm_key
end

#ntlm_use_ntlmv2Boolean

Returns Whether to use NTLMv2 instead of NTLM2_session when ‘Negotiate NTLM2’ is enabled.

Returns:

  • (Boolean)

    Whether to use NTLMv2 instead of NTLM2_session when ‘Negotiate NTLM2’ is enabled



149
150
151
# File 'lib/metasploit/framework/login_scanner/http.rb', line 149

def ntlm_use_ntlmv2
  @ntlm_use_ntlmv2
end

#ntlm_use_ntlmv2_sessionBoolean

Returns Whether to activate the ‘Negotiate NTLM2 key’ flag, forcing the use of a NTLMv2_session.

Returns:

  • (Boolean)

    Whether to activate the ‘Negotiate NTLM2 key’ flag, forcing the use of a NTLMv2_session



145
146
147
# File 'lib/metasploit/framework/login_scanner/http.rb', line 145

def ntlm_use_ntlmv2_session
  @ntlm_use_ntlmv2_session
end

#uriString

Returns HTTP method, e.g. “GET”, “POST”.

Returns:

  • (String)

    HTTP method, e.g. “GET”, “POST”



29
30
31
# File 'lib/metasploit/framework/login_scanner/http.rb', line 29

def uri
  @uri
end

#user_agentString

Returns the User-Agent to use for the HTTP requests.

Returns:

  • (String)

    the User-Agent to use for the HTTP requests



37
38
39
# File 'lib/metasploit/framework/login_scanner/http.rb', line 37

def user_agent
  @user_agent
end

#vhostString

Returns the Virtual Host name for the target Web Server.

Returns:

  • (String)

    the Virtual Host name for the target Web Server



41
42
43
# File 'lib/metasploit/framework/login_scanner/http.rb', line 41

def vhost
  @vhost
end

Instance Method Details

#attempt_login(credential) ⇒ Result

Attempt a single login with a single credential against the target.

Parameters:

  • credential (Credential)

    The credential object to attempt to login with.

Returns:

  • (Result)

    A Result object indicating success or failure



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/metasploit/framework/login_scanner/http.rb', line 276

def (credential)
  result_opts = {
    credential: credential,
    status: Metasploit::Model::Login::Status::INCORRECT,
    **service_as_result(build_http_service_opts)
  }

  request_opts = {'credential'=>credential, 'uri'=>uri, 'method'=>method}
  if keep_connection_alive
    request_opts[:http_client] = create_client(request_opts)
  end

  begin
    response = send_request(request_opts)
    if response && http_success_codes.include?(response.code)
      result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: response.headers)
    end
  rescue Rex::ConnectionError => e
    result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
  rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError => e
    mapped_err = Metasploit::Framework::LoginScanner::Kerberos.(e)
    result_opts.merge!(status: mapped_err, proof: e)
  ensure
    if request_opts.key?(:http_client)
      if result_opts[:status] == Metasploit::Model::Login::Status::SUCCESSFUL
        result_opts[:connection] = request_opts[:http_client]
      else
        request_opts[:http_client].close
      end
    end
  end

  Result.new(result_opts)
end

#authentication_required?(response) ⇒ Boolean (protected)

Returns a boolean value indicating whether the request requires authentication or not.

Parameters:

Returns:

  • (Boolean)

    True if the request required authentication; otherwise false.



317
318
319
320
321
322
# File 'lib/metasploit/framework/login_scanner/http.rb', line 317

def authentication_required?(response)
  return false unless response

  self.class::DEFAULT_HTTP_NOT_AUTHED_CODES.include?(response.code) &&
    response.headers[self.class::AUTHORIZATION_HEADER]
end

#build_http_service_optsObject (protected)



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/metasploit/framework/login_scanner/http.rb', line 324

def build_http_service_opts
  if ssl
    {
      name: 'https',
      host: host,
      port: port,
      proto: 'tcp',
      parents: [
        {
          name: 'ssl',
          host: host,
          port: port,
          proto: 'tcp',
          parents: [
            {
              name: 'tcp',
              host: host,
              port: port,
              proto: 'tcp'
            }
          ]
        }
      ]
    }
  else
    {
      name: 'http',
      host: host,
      port: port,
      proto: 'tcp',
      parents: [
        {
          name: 'tcp',
          host: host,
          port: port,
          proto: 'tcp'
        }
      ]
    }
  end
end

#build_service_opts(software_name) ⇒ Object (protected)



380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/metasploit/framework/login_scanner/http.rb', line 380

def build_service_opts(software_name)
  parents = build_http_service_opts

  {
    name: software_name.downcase,
    host: host,
    port: port,
    proto: 'tcp',
    resource: uri,
    parents: [ parents ]
  }
end

#check_setupObject



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/metasploit/framework/login_scanner/http.rb', line 204

def check_setup
  http_client = Rex::Proto::Http::Client.new(
    host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies, http_username, http_password
  )
  request = http_client.request_cgi(
    'uri' => uri,
    'method' => method
  )

  begin
    # Use _send_recv instead of send_recv to skip automatic
    # authentication
    response = http_client._send_recv(request)
  rescue ::EOFError, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError, Rex::ConnectionError, ::Timeout::Error
    return 'Unable to connect to target'
  end

  if authentication_required?(response)
    # TODO: we might be able to do this, but look into potential false positives first.
    # report_service(service)
    return false
  end

  'No authentication required'
end

#dbObject (protected)



376
377
378
# File 'lib/metasploit/framework/login_scanner/http.rb', line 376

def db
  framework&.db&.active
end

#send_request(opts) ⇒ Rex::Proto::Http::Response, NilClass

Sends a HTTP request with Rex

Parameters:

  • opts (Hash)

    native support includes the following (also see Rex::Proto::Http::Request#request_cgi)

Options Hash (opts):

  • 'host' (String)

    The remote host

  • 'port' (Integer)

    The remote port

  • 'ssl' (Boolean)

    The SSL setting, TrueClass or FalseClass

  • 'proxies' (String)

    The proxies setting

  • 'credential' (Credential)

    A credential object

  • 'http_client' (Rex::Proto::Http::Client)

    object that can be used by the function

  • 'context' ('Hash')

    A context

Returns:

  • (Rex::Proto::Http::Response)

    The HTTP response

  • (NilClass)

    An error has occurred while reading the response (see #Rex::Proto::Http::Client#read_response)

Raises:

  • (Rex::ConnectionError)

    One of these errors has occurred: EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/metasploit/framework/login_scanner/http.rb', line 243

def send_request(opts)
  close_client = !opts.key?(:http_client)
  cli = opts.fetch(:http_client) { create_client(opts) }

  begin
    cli.connect
    req = cli.request_cgi(opts)

    # Authenticate by default
    res = if opts['authenticate'].nil? || opts['authenticate']
            cli.send_recv(req)
          else
            cli._send_recv(req)
          end
  rescue ::EOFError, Errno::ETIMEDOUT, Errno::ECONNRESET, Rex::ConnectionError, OpenSSL::SSL::SSLError, ::Timeout::Error => e
    raise Rex::ConnectionError, e.message
  ensure
    # If we didn't create the client, don't close it
    if close_client
      cli.close
    end
  end

  res
end

#service_as_result(service) ⇒ Object (protected)



366
367
368
369
# File 'lib/metasploit/framework/login_scanner/http.rb', line 366

def service_as_result(service)
  transform_map = { name: :service_name, proto: :protocol }
  service.transform_keys { |key| transform_map[key] || key }
end

#service_optsObject (protected)

Raises:

  • (NotImplementedError)


371
372
373
# File 'lib/metasploit/framework/login_scanner/http.rb', line 371

def service_opts
  raise NotImplementedError
end