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