source: trollforge/unsorted/vncscan.pl @ 624

Revision 623, 3.4 KB checked in by literalka, 16 months ago (diff)

DOES IT FUCKING WORK YET

Line 
1#!/usr/bin/perl
2use strict;
3
4my $target = shift;
5die "Usage: $0 host\n" unless $target;
6
7my $scanner = VNCScanner->new;
8$scanner->scan($target);
9
10package VNCScanner;
11use IO::Socket::INET;
12
13sub new {
14    my ($class) = @_;
15
16    my $self = {};
17    return bless $self, $class;
18}
19
20*socket = \&sock;
21sub sock { $_[0]->{sock} }
22
23sub scan {
24    my ($self, $host) = @_;
25
26    my $socket = IO::Socket::INET->new(
27                                       PeerAddr => $host,
28                                       PeerPort => '5900',
29                                       Proto    => 'tcp',
30                                       ) or warn "Error connecting to $host: $!\n";
31
32    if ($socket && $socket->connected) {
33        $self->{sock} = $socket;
34        $self->connect;
35    }
36}
37
38sub connect {
39    my $self = shift;
40
41    my $socket = $self->sock;
42
43    # read protocol version
44    my $proto_v;
45    $socket->read($proto_v, 12);
46    $proto_v ||= '';
47    chomp $proto_v;
48
49    my ($maj_v, $min_v) = $proto_v =~ /RFB (\d+)\.(\d+)/;
50    $self->{maj_v} = $maj_v;
51    $self->{min_v} = $min_v;
52
53    $self->log("Found RFB server ($maj_v.$min_v)");
54
55    if ($maj_v == 3) {
56        $self->auth;
57    } elsif ($maj_v) {
58        $self->log("Unknown RFB version $maj_v");
59    } else {
60        $self->log("Unknown RFB version response: $proto_v");
61    }
62}
63
64sub auth {
65    my $self = shift;
66    my $sock = $self->sock;
67
68    if ($self->{min_v} >= 7) {
69        # do v. 7 auth
70        $sock->print("RFB 003.007\n");
71
72        # should receive 1 byte count of auth types
73        my $sec_t_cnt;
74        $sock->read($sec_t_cnt, 1);
75
76        if ($sec_t_cnt) {
77            # read array of auth types
78            my $sec_t_array;
79            $sock->read($sec_t_array, int($sec_t_cnt));
80
81            # try auth bypass
82            $sock->print(pack('C', 0x01)); # auth type none
83            $self->check_auth_resp;
84        } else {
85            my $err_str_len;
86            $sock->read($err_str_len, 4);
87            $err_str_len = unpack('N', $err_str_len) + 0;
88
89            my $err_str;
90            $sock->read($err_str, $err_str_len);
91            $self->log("Got authentication error: $err_str");
92        }
93    } else {
94        # request version 3.3 auth
95        $sock->print("RFB 003.003\n");
96
97        # should get a type back
98        my $sec_t;
99        $sock->read($sec_t, 4);
100        $sec_t = unpack('N', $sec_t);
101
102        unless ($sec_t) {
103            $self->log("Auth rejected");
104            return;
105        }
106
107        if ($sec_t == 1) {
108            # no auth, yay
109            $self->log("No auth required!");
110        } else {
111            $self->log("Auth type $sec_t requested. Giving up.");
112        }
113    }
114}
115
116sub check_auth_resp {
117    my $self = shift;
118    my $sock = $self->sock;
119
120    # read securityresult
121    my $sec_res;
122    $sock->read($sec_res, 4);
123    $sec_res = unpack('N', $sec_res);
124
125    if ($sec_res == 0) {
126        # we're in!
127        $self->log("Connected successfully!");
128    } else {
129        # read reason
130        my $err_str_len;
131        $sock->read($err_str_len, 4);
132        $err_str_len = unpack('N*', $err_str_len) + 0;
133
134        my $err_str;
135        $sock->read($err_str, $err_str_len);
136        $self->log("Error in authentication: $err_str");
137
138        # server will disconnect
139        $sock->close;
140    }
141}
142
143sub log {
144    my ($self, ,$msg) = @_;
145    my $sock = $self->sock;
146    my $addr = $sock ? $sock->peerhost : '';
147    print "[$addr] $msg\n";
148}
Note: See TracBrowser for help on using the repository browser.