Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/js/libs/vnc/vnc.go
2858 views
1
package vnc
2
3
import (
4
"context"
5
"fmt"
6
"net"
7
"strconv"
8
"time"
9
10
vnclib "github.com/alexsnet/go-vnc"
11
"github.com/praetorian-inc/fingerprintx/pkg/plugins"
12
vncplugin "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/vnc"
13
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
14
stringsutil "github.com/projectdiscovery/utils/strings"
15
)
16
17
type (
18
// IsVNCResponse is the response from the IsVNC function.
19
// @example
20
// ```javascript
21
// const vnc = require('nuclei/vnc');
22
// const isVNC = vnc.IsVNC('acme.com', 5900);
23
// log(toJSON(isVNC));
24
// ```
25
IsVNCResponse struct {
26
IsVNC bool
27
Banner string
28
}
29
30
// VNCClient is a client for VNC servers.
31
// @example
32
// ```javascript
33
// const vnc = require('nuclei/vnc');
34
// const client = new vnc.VNCClient();
35
// const connected = client.Connect('acme.com', 5900, 'password');
36
// log(toJSON(connected));
37
// ```
38
VNCClient struct{}
39
)
40
41
// Connect connects to VNC server using given password.
42
// If connection and authentication is successful, it returns true.
43
// If connection or authentication is unsuccessful, it returns false and error.
44
// The connection is closed after the function returns.
45
// @example
46
// ```javascript
47
// const vnc = require('nuclei/vnc');
48
// const client = new vnc.VNCClient();
49
// const connected = client.Connect('acme.com', 5900, 'password');
50
// ```
51
func (c *VNCClient) Connect(ctx context.Context, host string, port int, password string) (bool, error) {
52
executionId := ctx.Value("executionId").(string)
53
return connect(executionId, host, port, password)
54
}
55
56
// connect attempts to authenticate with a VNC server using the given password
57
func connect(executionId string, host string, port int, password string) (bool, error) {
58
if host == "" || port <= 0 {
59
return false, fmt.Errorf("invalid host or port")
60
}
61
if !protocolstate.IsHostAllowed(executionId, host) {
62
// host is not valid according to network policy
63
return false, protocolstate.ErrHostDenied.Msgf(host)
64
}
65
66
dialer := protocolstate.GetDialersWithId(executionId)
67
if dialer == nil {
68
return false, fmt.Errorf("dialers not initialized for %s", executionId)
69
}
70
71
conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
72
if err != nil {
73
return false, err
74
}
75
defer func() {
76
_ = conn.Close()
77
}()
78
79
// Set connection timeout
80
_ = conn.SetDeadline(time.Now().Add(10 * time.Second))
81
82
// Create VNC client config with password
83
vncConfig := vnclib.NewClientConfig(password)
84
85
// Attempt to connect and authenticate
86
c, err := vnclib.Connect(context.TODO(), conn, vncConfig)
87
if err != nil {
88
// Check for specific authentication errors
89
if isAuthError(err) {
90
return false, nil // Authentication failed, but connection succeeded
91
}
92
return false, err // Connection or other error
93
}
94
if c != nil {
95
_ = c.Close()
96
}
97
98
return true, nil
99
}
100
101
// isAuthError checks if the error is an authentication failure
102
func isAuthError(err error) bool {
103
if err == nil {
104
return false
105
}
106
107
// Check for common VNC authentication error messages
108
errStr := err.Error()
109
return stringsutil.ContainsAnyI(errStr, "authentication", "auth", "password", "invalid", "failed")
110
}
111
112
// IsVNC checks if a host is running a VNC server.
113
// It returns a boolean indicating if the host is running a VNC server
114
// and the banner of the VNC server.
115
// @example
116
// ```javascript
117
// const vnc = require('nuclei/vnc');
118
// const isVNC = vnc.IsVNC('acme.com', 5900);
119
// log(toJSON(isVNC));
120
// ```
121
func IsVNC(ctx context.Context, host string, port int) (IsVNCResponse, error) {
122
executionId := ctx.Value("executionId").(string)
123
return memoizedisVNC(executionId, host, port)
124
}
125
126
// @memo
127
func isVNC(executionId string, host string, port int) (IsVNCResponse, error) {
128
resp := IsVNCResponse{}
129
130
timeout := 5 * time.Second
131
dialer := protocolstate.GetDialersWithId(executionId)
132
if dialer == nil {
133
return IsVNCResponse{}, fmt.Errorf("dialers not initialized for %s", executionId)
134
}
135
conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
136
if err != nil {
137
return resp, err
138
}
139
defer func() {
140
_ = conn.Close()
141
}()
142
143
vncPlugin := vncplugin.VNCPlugin{}
144
service, err := vncPlugin.Run(conn, timeout, plugins.Target{Host: host})
145
if err != nil {
146
return resp, err
147
}
148
if service == nil {
149
return resp, nil
150
}
151
resp.Banner = service.Version
152
resp.IsVNC = true
153
return resp, nil
154
}
155
156