CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/login_scanner/gitlab.rb
Views: 1904
1
require 'metasploit/framework/login_scanner/http'
2
3
module Metasploit
4
module Framework
5
module LoginScanner
6
# GitLab login scanner
7
class GitLab < HTTP
8
# Inherit LIKELY_PORTS,LIKELY_SERVICE_NAMES, and REALM_KEY from HTTP
9
CAN_GET_SESSION = false
10
DEFAULT_PORT = 80
11
PRIVATE_TYPES = [ :password ]
12
13
# (see Base#set_sane_defaults)
14
def set_sane_defaults
15
self.uri = '/users/sign_in' if uri.nil?
16
self.method = 'POST' if method.nil?
17
18
super
19
end
20
21
def attempt_login(credential)
22
result_opts = {
23
credential: credential,
24
host: host,
25
port: port,
26
protocol: 'tcp',
27
service_name: ssl ? 'https' : 'http'
28
}
29
begin
30
# Get a valid session cookie and authenticity_token for the next step
31
res = send_request(
32
'method' => 'GET',
33
'cookie' => 'request_method=GET',
34
'uri' => uri
35
)
36
37
if res.body.include? 'user[email]'
38
user_field = 'user[email]'
39
elsif res.body.include? 'user[login]'
40
user_field = 'user[login]'
41
else
42
fail RuntimeError, 'Not a valid GitLab login page'
43
end
44
45
local_session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0]
46
auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]
47
48
# New versions of GitLab use an alternative scheme
49
# Try it, if the old one was not successful
50
auth_token = res.body.scan(/<input type="hidden" name="authenticity_token" value="(.*?)"/).flatten[0] unless auth_token
51
52
fail RuntimeError, 'Unable to get Session Cookie' unless local_session_cookie
53
fail RuntimeError, 'Unable to get Authentication Token' unless auth_token
54
55
# Perform the actual login
56
res = send_request(
57
'method' => 'POST',
58
'cookie' => local_session_cookie,
59
'uri' => uri,
60
'vars_post' =>
61
{
62
'utf8' => "\xE2\x9C\x93",
63
'authenticity_token' => auth_token,
64
"#{user_field}" => credential.public,
65
'user[password]' => credential.private,
66
'user[remember_me]' => 0
67
}
68
)
69
70
if res && res.code == 302
71
result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: res.headers)
72
else
73
result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: res)
74
end
75
rescue ::EOFError, Errno::ETIMEDOUT ,Errno::ECONNRESET, Rex::ConnectionError, OpenSSL::SSL::SSLError, ::Timeout::Error => e
76
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
77
end
78
Result.new(result_opts)
79
end
80
end
81
end
82
end
83
end
84
85