Class: Metasploit::Framework::LoginScanner::GitLab

Inherits:
HTTP
  • Object
show all
Defined in:
lib/metasploit/framework/login_scanner/gitlab.rb

Overview

GitLab login scanner

Constant Summary collapse

CAN_GET_SESSION =

Inherit LIKELY_PORTS,LIKELY_SERVICE_NAMES, and REALM_KEY from HTTP

false
DEFAULT_PORT =
80
PRIVATE_TYPES =
[ :password ]

Constants inherited from HTTP

HTTP::AUTHORIZATION_HEADER, HTTP::DEFAULT_HTTP_NOT_AUTHED_CODES, HTTP::DEFAULT_HTTP_SUCCESS_CODES, HTTP::DEFAULT_REALM, HTTP::DEFAULT_SSL_PORT, HTTP::LIKELY_PORTS, HTTP::LIKELY_SERVICE_NAMES, 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

Methods inherited from HTTP

#authentication_required?, #build_http_service_opts, #build_service_opts, #db, #send_request, #service_as_result

Methods included from Msf::Auxiliary::Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #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 Method Details

#attempt_login(credential) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/metasploit/framework/login_scanner/gitlab.rb', line 50

def (credential)
  result_opts = {
    credential: credential,
    **service_as_result(service_opts)
  }
  begin
    # Get a valid session cookie and authenticity_token for the next step
    res = send_request(
      'method' => 'GET',
      'cookie' => 'request_method=GET',
      'uri'    => uri
    )

    if res.body.include? 'user[email]'
      user_field = 'user[email]'
    elsif res.body.include? 'user[login]'
      user_field = 'user[login]'
    else
      fail RuntimeError, 'Not a valid GitLab login page'
    end

    local_session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0]
    auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]

    # New versions of GitLab use an alternative scheme
    # Try it, if the old one was not successful
    auth_token = res.body.scan(/<input type="hidden" name="authenticity_token" value="(.*?)"/).flatten[0] unless auth_token

    fail RuntimeError, 'Unable to get Session Cookie' unless local_session_cookie
    fail RuntimeError, 'Unable to get Authentication Token' unless auth_token

    # Perform the actual login
    res = send_request(
                            'method' => 'POST',
                            'cookie' => local_session_cookie,
                            'uri'    => uri,
                            'vars_post' =>
                              {
                                'utf8' => "\xE2\x9C\x93",
                                'authenticity_token' => auth_token,
                                "#{user_field}" => credential.public,
                                'user[password]' => credential.private,
                                'user[remember_me]' => 0
                              }
    )

    if res && res.code == 302
      result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: res.headers)
    else
      result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: res)
    end
  rescue ::EOFError, Errno::ETIMEDOUT ,Errno::ECONNRESET, Rex::ConnectionError, OpenSSL::SSL::SSLError, ::Timeout::Error => e
    result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
  end
  Result.new(result_opts)
end

#check_setupfalse, String

Checks if the target is a GitLab instance

Returns:

  • (false)

    if the target looks like GitLab

  • (String)

    a human-readable error message if it doesn't



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/metasploit/framework/login_scanner/gitlab.rb', line 17

def check_setup
  res = send_request(
    'method' => 'GET',
    'cookie' => 'request_method=GET',
    'uri'    => uri
  )

  return 'Unable to connect to the GitLab login page' unless res
  return 'Unable to locate GitLab login page (Is this really GitLab?)' unless res.code == 200 && (res.body.include?('user[email]') || res.body.include?('user[login]'))

  if res.body.include?('user[email]')
    framework_module&.vprint_status('GitLab v5 login page')
  elsif res.body.include?('user[login]')
    framework_module&.vprint_status('GitLab v7 login page')
  end

  report_service(service_opts)

  false
end

#service_optsObject



38
39
40
# File 'lib/metasploit/framework/login_scanner/gitlab.rb', line 38

def service_opts
  build_service_opts('gitlab')
end

#set_sane_defaultsObject



43
44
45
46
47
48
# File 'lib/metasploit/framework/login_scanner/gitlab.rb', line 43

def set_sane_defaults
  self.uri = '/users/sign_in' if uri.nil?
  self.method = 'POST' if method.nil?

  super
end