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/phpmyadmin.rb
Views: 1904
1
require 'metasploit/framework/login_scanner/http'
2
3
module Metasploit
4
module Framework
5
module LoginScanner
6
class PhpMyAdmin < HTTP
7
8
PRIVATE_TYPES = [ :password ]
9
LOGIN_STATUS = Metasploit::Model::Login::Status
10
11
def check_setup
12
version = "Not Detected"
13
res = send_request({ 'uri' => uri })
14
15
if res && res.body.include?('phpMyAdmin')
16
if res.body =~ /PMA_VERSION:"(\d+\.\d+\.\d+)"/
17
version = Rex::Version.new($1)
18
end
19
return version.to_s
20
end
21
22
false
23
end
24
25
def get_session_info
26
res = send_request({'uri' => uri})
27
no_connect = { status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: 'Cannot retrieve session info' }
28
return { status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: 'Unable to access PhpMyAdmin login page' } unless res
29
30
return no_connect if (res.get_cookies.scan(/phpMyAdmin=(\w+);*/).flatten[0].nil? || res.body.scan(/token"\s*value="(.*?)"/).flatten[0].nil? || res.get_cookies.split[-2..-1].nil?)
31
session_id = res.get_cookies.scan(/phpMyAdmin=(\w+);*/).flatten[0]
32
token = Rex::Text.html_decode(res.body.scan(/token"\s*value="(.*?)"/).flatten[0])
33
cookies = res.get_cookies.split[-2..-1].join(' ')
34
35
info = [session_id, token, cookies]
36
return no_connect if (info.empty? || session_id.empty? || token.empty? || cookies.empty?)
37
38
return info
39
end
40
41
def do_login(username, password)
42
session_info = get_session_info
43
# Failed to retrieve session info
44
return session_info if session_info.is_a?(Hash)
45
46
protocol = ssl ? 'https' : 'http'
47
peer = "#{host}:#{port}"
48
49
res = send_request(
50
'uri' => uri,
51
'method' => 'POST',
52
'cookie' => session_info.last,
53
'vars_post' => {
54
'set_session' => session_info[0],
55
'pma_username' => username,
56
'pma_password' => password,
57
'target' => 'index.php',
58
'server' => 1,
59
'token' => session_info[1]
60
}
61
)
62
63
if res && res.code == 302 && res.headers['Location'].to_s.include?('index.php')
64
return { :status => LOGIN_STATUS::SUCCESSFUL, :proof => res.to_s }
65
end
66
67
{:status => LOGIN_STATUS::INCORRECT, :proof => res.to_s}
68
end
69
70
def attempt_login(credential)
71
result_opts = {
72
credential: credential,
73
status: LOGIN_STATUS::INCORRECT,
74
proof: nil,
75
host: host,
76
port: port,
77
protocol: 'tcp'
78
}
79
80
result_opts.merge!(do_login(credential.public, credential.private))
81
82
Result.new(result_opts)
83
end
84
end
85
end
86
end
87
end
88
89