-
Notifications
You must be signed in to change notification settings - Fork 146
/
codesys-v2-discover.nse
128 lines (116 loc) · 3.72 KB
/
codesys-v2-discover.nse
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
local nmap = require "nmap"
local comm = require "comm"
local stdnse = require "stdnse"
local strbuf = require "strbuf"
local nsedebug = require "nsedebug"
description = [[
http://digitalbond.com
]]
author = "Stephen Hilt (Digital Bond)"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}
---
-- Script is executed for any TCP port.
portrule = function( host, port )
return port.protocol == "tcp"
end
---
-- Function to set the nmap output for the host, if a valid CoDeSyS packet
-- is received then the output will show that the port as CoDeSyS
--
-- @param host Host that was passed in via nmap
-- @param port port that CoDeSyS may be running on TCP/1200 or TCP/2455
function set_nmap(host, port)
--set port Open
port.state = "open"
-- set version name to CoDeSyS
port.version.name = "CoDeSyS"
nmap.set_port_version(host, port)
nmap.set_port_state(host, port, "open")
end
---
-- Remove extra whitespace from the beginning and end the string
--
-- @param s string to remove extra white space
function trim(s)
-- remove white spaces from beginning and ending of the string
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
---
-- Action Function that is used to run the NSE. This function will send the initial query to the
-- host and port that were passed in via nmap. The initial response is parsed to determine if host
-- is a CoDeSys device. If it is then more actions are taken to gather extra information.
--
-- @param host Host that was scanned via nmap
-- @param port port that was scanned via nmap
action = function( host, port )
-- little endian query
lile_query = bin.pack("H", "bbbb0100000001")
-- big endian query
bige_query = bin.pack("H", "bbbb0100000101")
-- set up table for output
local output = stdnse.output_table()
-- create socket
local sock = nmap.new_socket()
-- connect to remote host
local constatus, conerr = sock:connect(host, port)
-- if not successful debug error message and return nil
if not constatus then
stdnse.print_debug(1,
'Error establishing a TCP connection for %s - %s', host, conerr
)
return nil
end
-- send little endian query
local sendstatus, senderr = sock:send(lile_query)
if not sendstatus then
stdnse.print_debug(1,
'Error sending CoDeSyS request to %s:%d - %s',
host.ip, port.number, senderr
)
return nil
end
-- recieve response
local rcvstatus, response = sock:receive()
if(rcvstatus == false) then
stdnse.print_debug(1, "Receive error: %s", response)
return nil
end
-- if there was no response, try big endian
if(response == "EOF" or response == "TIMEOUT") then
-- try sending big endian query
local sendstatus, senderr = sock:send(bige_query)
if not sendstatus then
stdnse.print_debug(1,
'Error sending CoDeSyS request to %s:%d - %s',
host.ip, port.number, senderr
)
return nil
end
-- receive response
local rcvstatus, response = sock:receive()
if(rcvstatus == false) then
stdnse.print_debug(1, "Receive error: %s", response)
return nil
end
end
-- unpack first byte to see if it is 0xbb
local pos, codesys_check = bin.unpack("C", response, 1)
-- is first byte 0xbb?
if (codesys_check ~= 0xbb) then
sock:close()
return nil
end
local pos, os_name = bin.unpack("z", response, 65)
local pos , os_type = bin.unpack("z", response, 97)
local pos, product_type = bin.unpack("z", response, 129)
-- close socket
sock:close()
-- set nmap port
set_nmap(host, port)
-- set output table (for future growth of information)
output["OS Name"] = os_name .. " " .. os_type
output["Product Type"] = product_type
-- return output table to nmap
return output
end