-
Notifications
You must be signed in to change notification settings - Fork 28
/
melsecq-discover.nse
90 lines (76 loc) · 2.25 KB
/
melsecq-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
-- Nmap Scripting Engine
-- required packages for this script
--
-- ICS Security Workspace(plcscan.org)
-- ICS Discovery Tools Releases
---
local bin = require "bin"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
--Usage:
--Identify MELSEC-Q Series PLC CPUINFO
--nmap -script melsecq-discover -sT -p 5007 <host>
--Output Example:
--PORT STATE SERVICE REASON
--5007/tcp open MelsoftTCP syn-ack
--| melsecq-discover:
--|_ CPUINFO: Q03UDECPU
description = [[
discovery Mitsubishi Electric Q Series PLC
GET CPUINFO
]]
author = "ICS Security Workspace(plcscan.org)"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery","intrusive"}
function set_nmap(host, port)
port.state = "open"
port.version.name = "MelsoftTCP"
port.version.product = "Mitsubishi Q PLC"
nmap.set_port_version(host, port)
nmap.set_port_state(host, port, "open")
end
function send_receive(socket, query)
local sendstatus, senderr = socket:send(query)
if(sendstatus == false) then
return "Error Sending getcpuinfopack"
end
local rcvstatus,response = socket:receive()
if(rcvstatus == false) then
return "Error Reading getcpuinfopack"
end
return response
end
portrule = shortport.port_or_service(5007, "MelsoftTCP", "tcp")
action = function(host,port)
local getcpuinfopack = bin.pack("H","57000000001111070000ffff030000fe03000014001c080a080000000000000004" .. "0101" .. "010000000001")
local response
local output = stdnse.output_table()
local sock = nmap.new_socket()
local constatus,conerr = sock:connect(host,port)
if not constatus then
stdnse.print_debug(1,
'Error establishing connection for %s - %s', host,conerr
)
return nil
end
response = send_receive(sock, getcpuinfopack)
local mel, pack_head = bin.unpack("C", response, 1)
-- local mel, space_id = bin.unpack("C", response, 55)
local offset = 0
if ( pack_head == 0xd7) then
-- if ( space_id == 0x20) then
local mel
local mel, cpuinfo = bin.unpack("z", response, 42 + offset)
output["CPUINFO"] = string.sub(cpuinfo, 1, 16)
set_nmap(host, port)
sock:close()
return output
-- end
else
sock:close()
return nil
end
end