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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
local nmap = require "nmap"
local rpc = require "rpc"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
description = [[
Detects vulnerabilities and gathers information (such as version
numbers and hardware support) from VxWorks Wind DeBug agents.
Wind DeBug is a SunRPC-type service that is enabled by default on many devices
that use the popular VxWorks real-time embedded operating system. H.D. Moore
of Metasploit has identified several security vulnerabilities and design flaws
with the service, including weakly-hashed passwords and raw memory dumping.
See also:
http://www.kb.cert.org/vuls/id/362332
]]
---
-- @usage
-- nmap -sU -p 17185 --script wdb-version <target>
-- @output
-- 17185/udp open wdb Wind DeBug Agent 2.0
-- | wdb-version:
-- | VULNERABLE: Wind River Systems VxWorks debug service enabled. See http://www.kb.cert.org/vuls/id/362332
-- | Agent version: 2.0
-- | VxWorks version: VxWorks5.4.2
-- | Board Support Package: PCD ARM940T REV 1
-- | Boot line: host:vxWorks.z
--@xmloutput
-- <elem>VULNERABLE: Wind River Systems VxWorks debug service enabled. See http://www.kb.cert.org/vuls/id/362332</elem>
-- <elem key="Agent version">2.0</elem>
-- <elem key="VxWorks version">5.4</elem>
-- <elem key="Board Support Package">Alcatel CMM MPC8245/100</elem>
-- <elem key="Boot line">lanswitchCmm:</elem>
author = "Daniel Miller"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "safe", "version", "discovery", "vuln"}
-- WDB protocol information
-- http://www.vxdev.com/docs/vx55man/tornado-api/wdbpcl/wdb.html
-- http://www.verysource.com/code/2817990_1/wdb.h.html
-- Metasploit scanner module
-- https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/wdbrpc.rb
portrule = shortport.version_port_or_service(17185, "wdbrpc", {"udp"} )
rpc.RPC_version["wdb"] = { min=1, max=1 }
local WDB_Procedure = {
["WDB_TARGET_PING"] = 0,
["WDB_TARGET_CONNECT"] = 1,
["WDB_TARGET_DISCONNECT"] = 2,
["WDB_TARGET_MODE_SET"] = 3,
["WDB_TARGET_MODE_GET"] = 4,
}
local function checksum(data)
local sum = 0
local p = 5 -- skip first 4 bytes
while p < #data do
local c
c, p = (">I2"):unpack(data, p)
sum = sum + c
end
sum = (sum & 0xffff) + (sum >> 16)
return ~sum & 0xffff
end
local seqnum = 0
local function seqno()
seqnum = seqnum + 1
return seqnum
end
local function request(comm, procedure, data)
local packet = comm:EncodePacket( nil, procedure, {type = rpc.Portmap.AuthType.NULL}, nil )
local wdbwrapper = (">I4I4"):pack(#data + #packet + 8, seqno())
local sum = checksum(packet .. "\0\0\0\0" .. wdbwrapper .. data)
return packet .. (">I2I2"):pack(0xffff, sum) .. wdbwrapper .. data
end
local function stripnull(str)
return (str:gsub("\0*$",""))
end
local function decode_reply(data, pos)
local wdberr, len
local done = data:len()
local info = {}
local _
pos, _ = rpc.Util.unmarshall_uint32(data, pos)
pos, _ = rpc.Util.unmarshall_uint32(data, pos)
pos, wdberr = rpc.Util.unmarshall_uint32(data, pos)
info["error"] = wdberr & 0xc0000000
if info["error"] ~= 0x00000000 then
stdnse.debug1("Error from decode_reply: %x", info["error"])
return nil, info
end
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if len ~= 0 then
pos, info["agent_ver"] = rpc.Util.unmarshall_vopaque(len, data, pos)
end
pos, info["agent_mtu"] = rpc.Util.unmarshall_uint32(data, pos)
pos, info["agent_mod"] = rpc.Util.unmarshall_uint32(data, pos)
pos, info["rt_type"] = rpc.Util.unmarshall_uint32(data, pos)
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if pos == done then return pos, info end
if len ~= 0 then
pos, info["rt_vers"] = rpc.Util.unmarshall_vopaque(len, data, pos)
end
pos, info["rt_cpu_type"] = rpc.Util.unmarshall_uint32(data, pos)
pos, len = rpc.Util.unmarshall_uint32(data, pos)
info["rt_has_fpp"] = ( len ~= 0 )
pos, len = rpc.Util.unmarshall_uint32(data, pos)
info["rt_has_wp"] = ( len ~= 0 )
pos, info["rt_page_size"] = rpc.Util.unmarshall_uint32(data, pos)
pos, info["rt_endian"] = rpc.Util.unmarshall_uint32(data, pos)
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if len ~= 0 then
pos, info["rt_bsp_name"] = rpc.Util.unmarshall_vopaque(len, data, pos)
end
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if len ~= 0 then
pos, info["rt_bootline"] = rpc.Util.unmarshall_vopaque(len, data, pos)
end
if pos == done then return pos, info end
pos, info["rt_membase"] = rpc.Util.unmarshall_uint32(data, pos)
if pos == done then return pos, info end
pos, info["rt_memsize"] = rpc.Util.unmarshall_uint32(data, pos)
if pos == done then return pos, info end
pos, info["rt_region_count"] = rpc.Util.unmarshall_uint32(data, pos)
if pos == done then return pos, info end
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if len ~= 0 then
info["rt_regions"] = {}
for i = 1, len do
pos, info["rt_regions"][i] = rpc.Util.unmarshall_uint32(data, pos)
end
end
if pos == done then return pos, info end
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if len == nil then return pos, info end
if len ~= 0 then
pos, info["rt_hostpool_base"] = rpc.Util.unmarshall_vopaque(len, data, pos)
end
if pos == done then return pos, info end
pos, len = rpc.Util.unmarshall_uint32(data, pos)
if len ~= 0 then
pos, info["rt_hostpool_size"] = rpc.Util.unmarshall_vopaque(len, data, pos)
end
return pos, info
end
action = function(host, port)
local comm = rpc.Comm:new("wdb", 1)
local status, err = comm:Connect(host, port)
if not status then
return stdnse.format_output(false, err)
end
local packet = request(comm, WDB_Procedure["WDB_TARGET_CONNECT"], (">I4I4I4"):pack(2, 0, 0))
if not comm:SendPacket(packet) then
return stdnse.format_output(false, "Failed to send request")
end
local status, data = comm:ReceivePacket()
if not status then
--return stdnse.format_output(false, "Failed to read data")
return nil
end
nmap.set_port_state(host, port, "open")
local pos, header = comm:DecodeHeader(data, 1)
if not header then
return stdnse.format_output(false, "Failed to decode header")
end
if pos == #data then
return stdnse.format_output(false, "No WDB data in reply")
end
local pos, info = decode_reply(data, pos)
if not pos then
return stdnse.format_output(false, "WDB error: "..info.error)
end
port.version.name = "wdb"
port.version.name_confidence = 10
port.version.product = "Wind DeBug Agent"
port.version.version = stripnull(info["agent_ver"])
if port.version.ostype ~= nil then
port.version.ostype = "VxWorks " .. stripnull(info["rt_vers"])
end
nmap.set_port_version(host, port)
-- Clean up (some agents will continue to send data until we disconnect)
packet = request(comm, WDB_Procedure["WDB_TARGET_DISCONNECT"], (">I4I4I4"):pack(2, 0, 0))
if not comm:SendPacket(packet) then
return stdnse.format_output(false, "Failed to send request")
end
local o = stdnse.output_table()
table.insert(o, "VULNERABLE: Wind River Systems VxWorks debug service enabled. See http://www.kb.cert.org/vuls/id/362332")
if info.agent_ver then
o["Agent version"] = stripnull(info.agent_ver)
end
--table.insert(o, "Agent MTU: " .. info.agent_mtu)
if info.rt_vers then
o["VxWorks version"] = stripnull(info.rt_vers)
end
-- rt_cpu_type is an enum type, but I don't have access to
-- cputypes.h, where it is defined
--table.insert(o, "CPU Type: " .. info.rt_cpu_type)
if info.rt_bsp_name then
o["Board Support Package"] = stripnull(info.rt_bsp_name)
end
if info.rt_bootline then
o["Boot line"] = stripnull(info.rt_bootline)
end
return o
end
|