1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local vnc = require "vnc"
description = [[
Queries a VNC server for its protocol version and supported security types.
]]
author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "safe"}
---
-- @output
-- PORT STATE SERVICE
-- 5900/tcp open vnc
-- | vnc-info:
-- | Protocol version: 3.889
-- | Security types:
-- | Mac OS X security type (30)
-- |_ Mac OS X security type (35)
--
-- @xmloutput
-- <elem key="Protocol version">3.8</elem>
-- <table key="Security types">
-- <table>
-- <elem key="name">Ultra</elem>
-- <elem key="type">17</elem>
-- </table>
-- <table>
-- <elem key="name">VNC Authentication</elem>
-- <elem key="type">2</elem>
-- </table>
-- </table>
-- Version 0.2
-- Created 07/07/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
-- Revised 08/14/2010 - v0.2 - changed so that errors are reported even without debugging
portrule = shortport.port_or_service( {5900, 5901, 5902} , "vnc", "tcp", "open")
local function fail(err) return stdnse.format_output(false, err) end
action = function(host, port)
local v = vnc.VNC:new( host, port )
local status, data
local result = stdnse.output_table()
status, data = v:connect()
if ( not(status) ) then return fail(data) end
status, data = v:handshake()
if ( not(status) ) then return fail(data) end
data = v:getSecTypesAsTable()
result["Protocol version"] = v:getProtocolVersion()
if ( data and #data ~= 0 ) then
result["Security types"] = data
end
local none_auth = false
if ( v:supportsSecType(v.sectypes.NONE) ) then
none_auth = true
end
if v:supportsSecType(v.sectypes.VENCRYPT) then
v:sendSecType(v.sectypes.VENCRYPT)
status, data = v:handshake_vencrypt()
if not status then
stdnse.debug1("Failed to handshake VeNCrypt: %s", data)
else
result["VeNCrypt auth subtypes"] = v:getVencryptTypesAsTable()
if not none_auth then
for i=1, v.vencrypt.count do
if v.vencrypt.types[i] == vnc.VENCRYPT_SUBTYPES.TLSNONE or
v.vencrypt.types[i] == vnc.VENCRYPT_SUBTYPES.TLSNONE then
none_auth = true
break
end
end
end
end
-- Reset the connection for further tests
v:disconnect()
end
if v:supportsSecType(v.sectypes.TIGHT) then
if not v.socket:get_info() then
-- reconnect if necessary
v:connect()
v:handshake()
end
v:sendSecType(v.sectypes.TIGHT)
status, data = v:handshake_tight()
if not status then
stdnse.debug1("Failed to handshake Tight: %s", data)
else
if v.aten then
result["Tight auth"] = "ATEN KVM VNC"
else
local mt = {
__tostring = function(t)
return string.format("%s %s (%d)", t.vendor, t.signature, t.code)
end
}
local tunnels = {}
for _, t in ipairs(v.tight.tunnels) do
setmetatable(t, mt)
tunnels[#tunnels+1] = t
end
if #tunnels > 0 then
result["Tight auth tunnels"] = tunnels
end
if #v.tight.types == 0 then
none_auth = true
result["Tight auth subtypes"] = {"None"}
else
local subtypes = {}
for _, t in ipairs(v.tight.types) do
if t.code == 1 then
none_auth = true
end
setmetatable(t, mt)
subtypes[#subtypes+1] = t
end
result["Tight auth subtypes"] = subtypes
end
end
end
-- Reset the connection for further tests
v:disconnect()
end
if v:supportsSecType(v.sectypes.TLS) then
if not v.socket:get_info() then
-- reconnect if necessary
v:connect()
v:handshake()
end
v:sendSecType(v.sectypes.TLS)
status, data = v:handshake_tls()
if not status then
stdnse.debug1("Failed to handshake TLS: %s", data)
else
result["TLS auth subtypes"] = v:getSecTypesAsTable()
if v:supportsSecType(v.sectypes.NONE) then
none_auth = true
end
end
end
if none_auth then
result["WARNING"] = "Server does not require authentication"
end
return result
end
|