Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/login_scanner/directadmin.rb
31165 views
1
require 'metasploit/framework/login_scanner/http'
2
3
module Metasploit
4
module Framework
5
module LoginScanner
6
7
class DirectAdmin < HTTP
8
9
DEFAULT_PORT = 443
10
PRIVATE_TYPES = [ :password ]
11
12
13
# Checks if the target is correct
14
#
15
# @return [false] Indicates there were no errors
16
# @return [String] a human-readable error message describing why
17
# this scanner can't run
18
def check_setup
19
login_uri = normalize_uri("#{uri}/CMD_LOGIN")
20
res = send_request({'uri'=> login_uri})
21
22
if res && res.body.include?('DirectAdmin Login')
23
return false
24
end
25
26
'Unable to locate "DirectAdmin Login" in body. (Is this really DirectAdmin?)'
27
end
28
29
30
# Returns the latest sid from DirectAdmin Control Panel
31
#
32
# @return [String] The PHP Session ID for DirectAdmin Web Control login
33
def get_last_sid
34
@last_sid ||= lambda {
35
# We don't have a session ID. Well, let's grab one right quick from the login page.
36
# This should probably only happen once (initially).
37
login_uri = normalize_uri("#{uri}/CMD_LOGIN")
38
res = send_request({'uri' => login_uri})
39
40
return '' unless res
41
42
cookies = res.get_cookies
43
@last_sid = cookies.scan(/(session=\w+);*/).flatten[0] || ''
44
}.call
45
end
46
47
48
# Actually doing the login. Called by #attempt_login
49
#
50
# @param username [String] The username to try
51
# @param password [String] The password to try
52
# @return [Hash]
53
# * :status [Metasploit::Model::Login::Status]
54
# * :proof [String] the HTTP response body
55
def get_login_state(username, password)
56
# Prep the data needed for login
57
sid = get_last_sid
58
protocol = ssl ? 'https' : 'http'
59
peer = "#{host}:#{port}"
60
login_uri = normalize_uri("#{uri}/CMD_LOGIN")
61
62
res = send_request({
63
'uri' => login_uri,
64
'method' => 'POST',
65
'cookie' => sid,
66
'headers' => {
67
'Referer' => "#{protocol}://#{peer}/#{login_uri}"
68
},
69
'vars_post' => {
70
'username' => username,
71
'password' => password,
72
'referer' => '%2F'
73
}
74
})
75
76
unless res
77
return {:status => Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, :proof => res.to_s}
78
end
79
80
# After login, the application should give us a new SID
81
cookies = res.get_cookies
82
sid = cookies.scan(/(session=\w+);*/).flatten[0] || ''
83
@last_sid = sid # Update our SID
84
85
if res.headers['Location'].to_s.include?('/') && !sid.blank?
86
return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.to_s}
87
end
88
89
{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.to_s}
90
end
91
92
93
# Attempts to login to DirectAdmin Web Control Panel. This is called first.
94
#
95
# @param credential [Metasploit::Framework::Credential] The credential object
96
# @return [Result] A Result object indicating success or failure
97
def attempt_login(credential)
98
result_opts = {
99
credential: credential,
100
status: Metasploit::Model::Login::Status::INCORRECT,
101
proof: nil,
102
host: host,
103
port: port,
104
protocol: 'tcp',
105
service_name: ssl ? 'https' : 'http'
106
}
107
108
begin
109
result_opts.merge!(get_login_state(credential.public, credential.private))
110
rescue ::Rex::ConnectionError => e
111
# Something went wrong during login. 'e' knows what's up.
112
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e.message)
113
end
114
115
Result.new(result_opts)
116
end
117
118
end
119
end
120
end
121
end
122
123