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

Inherits:
Object
  • Object
show all
Includes:
Base, RexSocket
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

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.



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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/../../)



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

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/../)



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

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



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

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



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

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



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

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



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

def evade_version_random_valid
  @evade_version_random_valid
end

#http_passwordString

Returns:

  • (String)


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

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



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

def http_success_codes
  @http_success_codes
end

#http_usernameString

Returns:

  • (String)


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

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



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

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:



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

def kerberos_authenticator_factory
  @kerberos_authenticator_factory
end

#methodObject

Returns the value of attribute method.



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

def method
  @method
end

#ntlm_domainString

Returns The NTLM domain to use during authentication.

Returns:

  • (String)

    The NTLM domain to use during authentication



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

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)



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

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



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

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.



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

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



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

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



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

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



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

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”



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

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



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

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



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

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



273
274
275
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
310
311
312
313
314
315
# File 'lib/metasploit/framework/login_scanner/http.rb', line 273

def (credential)
  result_opts = {
    credential: credential,
    status: Metasploit::Model::Login::Status::INCORRECT,
    proof: nil,
    host: host,
    port: port,
    protocol: 'tcp'
  }

  if ssl
    result_opts[:service_name] = 'https'
  else
    result_opts[:service_name] = 'http'
  end

  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.



323
324
325
326
327
328
# File 'lib/metasploit/framework/login_scanner/http.rb', line 323

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

#check_setupObject



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

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)
    return false
  end

  'No authentication required'
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



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

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