mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 22:21:29 +00:00
New script broadcast-ospf2-discover. Closes #743
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o [NSE][GH#743] New script broadcast-ospf2-discover discovers OSPF 2 routers
|
||||||
|
and neighbors. OSPFv2 authentication is supported. [Emiliano Ticci]
|
||||||
|
|
||||||
o [NSE][GH#740] New script http-vuln-cve2017-5638 checks for the RCE bug in
|
o [NSE][GH#740] New script http-vuln-cve2017-5638 checks for the RCE bug in
|
||||||
Apache Struts. [Seth Jackson]
|
Apache Struts. [Seth Jackson]
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
--
|
--
|
||||||
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
|
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
|
||||||
|
|
||||||
|
local math = require "math"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
local table = require "table"
|
local table = require "table"
|
||||||
@@ -674,6 +675,32 @@ hex_to_bin = function( hex )
|
|||||||
return status, result
|
return status, result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Convert a CIDR subnet mask to dotted decimal notation.
|
||||||
|
--
|
||||||
|
-- @param subnet CIDR string representing the subnet mask.
|
||||||
|
-- @usage
|
||||||
|
-- local netmask = ipOps.cidr_to_subnet( "/16" )
|
||||||
|
-- @return Dotted decimal representation of the suppliet subnet mask (e.g. "255.255.0.0")
|
||||||
|
cidr_to_subnet = function( subnet )
|
||||||
|
local bits = subnet:match("/(%d%d)$")
|
||||||
|
if not bits then return nil end
|
||||||
|
return fromdword((0xFFFFFFFF >> tonumber(bits)) ~ 0xFFFFFFFF)
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Convert a dotted decimal subnet mask to CIDR notation.
|
||||||
|
--
|
||||||
|
-- @param subnet Dotted decimal string representing the subnet mask.
|
||||||
|
-- @usage
|
||||||
|
-- local cidr = ipOps.subnet_to_cidr( "255.255.0.0" )
|
||||||
|
-- @return CIDR representation of the supplied subnet mask (e.g. "/16").
|
||||||
|
subnet_to_cidr = function( subnet )
|
||||||
|
local dword, err = todword(subnet)
|
||||||
|
if not dword then return nil, err end
|
||||||
|
return "/" .. tostring(32 - (math.tointeger(math.log((dword ~ 0xFFFFFFFF) + 1, 2))))
|
||||||
|
end
|
||||||
|
|
||||||
--Ignore the rest if we are not testing.
|
--Ignore the rest if we are not testing.
|
||||||
if not unittest.testing() then
|
if not unittest.testing() then
|
||||||
return _ENV
|
return _ENV
|
||||||
@@ -801,5 +828,7 @@ do
|
|||||||
test_suite:add_test(unittest.is_nil(expand_ip("2001:db8::1", "ipv4")),
|
test_suite:add_test(unittest.is_nil(expand_ip("2001:db8::1", "ipv4")),
|
||||||
"IPv6 to IPv4")
|
"IPv6 to IPv4")
|
||||||
end
|
end
|
||||||
|
test_suite:add_test(unittest.equal(cidr_to_subnet("/16"), "255.255.0.0"), "cidr_to_subnet")
|
||||||
|
test_suite:add_test(unittest.equal(subnet_to_cidr("255.255.0.0"), "/16"), "subnet_to_cidr")
|
||||||
|
|
||||||
return _ENV;
|
return _ENV;
|
||||||
|
|||||||
267
nselib/ospf.lua
267
nselib/ospf.lua
@@ -1,21 +1,25 @@
|
|||||||
---
|
---
|
||||||
-- A minimalistic OSPF (Open Shortest Path First routing protocol) library, currently supporting IPv4 and the following
|
-- A limited OSPF (Open Shortest Path First routing protocol) library, currently supporting IPv4 and the following
|
||||||
-- OSPF message types: HELLO
|
-- OSPF message types: HELLO, DB_DESCRIPTION, LS_REQUEST, LS_UPDATE
|
||||||
--
|
--
|
||||||
-- The library consists of an OSPF class that contains code to handle OSPFv2 packets.
|
-- The library consists of an OSPF class that contains code to handle OSPFv2 packets.
|
||||||
--
|
--
|
||||||
-- @author Patrik Karlsson <patrik@cqure.net>
|
-- @author Patrik Karlsson <patrik@cqure.net>
|
||||||
|
-- @author Emiliano Ticci <emiticci@gmail.com>
|
||||||
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
|
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
|
||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
local bit = require "bit"
|
local bit = require "bit"
|
||||||
local math = require "math"
|
local math = require "math"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
|
local string = require "string"
|
||||||
local table = require "table"
|
local table = require "table"
|
||||||
local ipOps = require "ipOps"
|
local ipOps = require "ipOps"
|
||||||
local packet = require "packet"
|
local packet = require "packet"
|
||||||
_ENV = stdnse.module("ospf", stdnse.seeall)
|
_ENV = stdnse.module("ospf", stdnse.seeall)
|
||||||
|
|
||||||
|
local have_ssl, openssl = pcall(require, "openssl")
|
||||||
|
|
||||||
-- The OSPF class.
|
-- The OSPF class.
|
||||||
OSPF = {
|
OSPF = {
|
||||||
|
|
||||||
@@ -23,13 +27,10 @@ OSPF = {
|
|||||||
Message = {
|
Message = {
|
||||||
HELLO = 1,
|
HELLO = 1,
|
||||||
DB_DESCRIPTION = 2,
|
DB_DESCRIPTION = 2,
|
||||||
|
LS_REQUEST = 3,
|
||||||
LS_UPDATE = 4,
|
LS_UPDATE = 4,
|
||||||
},
|
},
|
||||||
|
|
||||||
LSUpdate = {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
Header = {
|
Header = {
|
||||||
size = 24,
|
size = 24,
|
||||||
new = function(self, type, area_id, router_id, auth_type, auth_data)
|
new = function(self, type, area_id, router_id, auth_type, auth_data)
|
||||||
@@ -68,7 +69,7 @@ OSPF = {
|
|||||||
local _
|
local _
|
||||||
_, header.auth_data.keyid = bin.unpack(">C", data, pos+2)
|
_, header.auth_data.keyid = bin.unpack(">C", data, pos+2)
|
||||||
_, header.auth_data.length = bin.unpack(">C", data, pos+3)
|
_, header.auth_data.length = bin.unpack(">C", data, pos+3)
|
||||||
_, header.auth_data.seq = bin.unpack(">C", data, pos+4)
|
_, header.auth_data.seq = bin.unpack(">I", data, pos+4)
|
||||||
_, header.auth_data.hash = bin.unpack(">H"..header.auth_data.length, data, header.length+1)
|
_, header.auth_data.hash = bin.unpack(">H"..header.auth_data.length, data, header.length+1)
|
||||||
else
|
else
|
||||||
-- Shouldn't happen
|
-- Shouldn't happen
|
||||||
@@ -102,9 +103,9 @@ OSPF = {
|
|||||||
if self.auth_type == 0x00 then
|
if self.auth_type == 0x00 then
|
||||||
auth = bin.pack(">L", 0x00)
|
auth = bin.pack(">L", 0x00)
|
||||||
elseif self.auth_type == 0x01 then
|
elseif self.auth_type == 0x01 then
|
||||||
auth = bin.pack(">A8", self.auth_data.password)
|
auth = bin.pack(">A", self.auth_data.password)
|
||||||
elseif self.auth_type == 0x02 then
|
elseif self.auth_type == 0x02 then
|
||||||
auth = bin.pack(">A".. self.auth_data.length, self.auth_data.hash)
|
auth = bin.pack(">SCCI", 0, self.auth_data.keyid, self.auth_data.length, self.auth_data.seq)
|
||||||
end
|
end
|
||||||
local hdr = bin.pack(">CCS", self.ver, self.type, self.length )
|
local hdr = bin.pack(">CCS", self.ver, self.type, self.length )
|
||||||
.. bin.pack(">IISS", ipOps.todword(self.router_id), self.area_id, self.chksum, self.auth_type)
|
.. bin.pack(">IISS", ipOps.todword(self.router_id), self.area_id, self.chksum, self.auth_type)
|
||||||
@@ -169,10 +170,20 @@ OSPF = {
|
|||||||
data = data .. bin.pack(">I", ipOps.todword(n))
|
data = data .. bin.pack(">I", ipOps.todword(n))
|
||||||
end
|
end
|
||||||
self.header:setLength(#data)
|
self.header:setLength(#data)
|
||||||
|
if self.header.auth_data.hash then
|
||||||
|
data = data .. self.header.auth_data.hash
|
||||||
|
end
|
||||||
return tostring(self.header) .. data
|
return tostring(self.header) .. data
|
||||||
end
|
end
|
||||||
local data = tostr()
|
local data = tostr()
|
||||||
self.header.chksum = packet.in_cksum(data:sub(1,12) .. data:sub(25))
|
if have_ssl and self.header.auth_type == 0x02 then
|
||||||
|
while string.len(self.header.auth_data.key) < 16 do
|
||||||
|
self.header.auth_data.key = self.header.auth_data.key .. "\0"
|
||||||
|
end
|
||||||
|
self.header.auth_data.hash = openssl.md5(data .. bin.pack(">A", self.header.auth_data.key))
|
||||||
|
else
|
||||||
|
self.header.chksum = packet.in_cksum(data:sub(1,16) .. data:sub(25))
|
||||||
|
end
|
||||||
return tostr()
|
return tostr()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -208,10 +219,9 @@ OSPF = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
DBDescription = {
|
LSA = {
|
||||||
|
Header = {
|
||||||
LSAHeader = {
|
size = 20,
|
||||||
|
|
||||||
new = function(self)
|
new = function(self)
|
||||||
local o = {
|
local o = {
|
||||||
age = 0,
|
age = 0,
|
||||||
@@ -228,8 +238,113 @@ OSPF = {
|
|||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local lsa_h = OSPF.LSA.Header:new()
|
||||||
|
local pos = 1
|
||||||
|
pos, lsa_h.age, lsa_h.options, lsa_h.type, lsa_h.id, lsa_h.adv_router, lsa_h.sequence, lsa_h.checksum, lsa_h.length = bin.unpack(">SCCIIH4H2S", data, pos)
|
||||||
|
|
||||||
|
lsa_h.id = ipOps.fromdword(lsa_h.id)
|
||||||
|
lsa_h.adv_router = ipOps.fromdword(lsa_h.adv_router)
|
||||||
|
return lsa_h
|
||||||
|
end,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Link = {
|
||||||
|
new = function(self)
|
||||||
|
local o = {
|
||||||
|
id = 0,
|
||||||
|
data = 0,
|
||||||
|
type = 2,
|
||||||
|
num_metrics = 0,
|
||||||
|
metric = 10,
|
||||||
|
}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end,
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local lsa_link = OSPF.LSA.Link:new()
|
||||||
|
local pos = 1
|
||||||
|
pos, lsa_link.id, lsa_link.data, lsa_link.type, lsa_link.num_metrics, lsa_link.metric = bin.unpack(">IICCS", data, pos)
|
||||||
|
lsa_link.id = ipOps.fromdword(lsa_link.id)
|
||||||
|
lsa_link.data = ipOps.fromdword(lsa_link.data)
|
||||||
|
return lsa_link
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
Router = {
|
||||||
|
new = function(self)
|
||||||
|
local o = {
|
||||||
|
header = OSPF.LSA.Header:new(),
|
||||||
|
flags = 0,
|
||||||
|
num_links = 0,
|
||||||
|
links = {},
|
||||||
|
}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end,
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local router = OSPF.LSA.Router:new()
|
||||||
|
local pos = OSPF.LSA.Header.size + 1
|
||||||
|
router.header = OSPF.LSA.Header.parse(data)
|
||||||
|
pos, router.flags, router.num_links = bin.unpack(">CxS", data, pos)
|
||||||
|
|
||||||
|
while ( pos < router.header.length ) do
|
||||||
|
table.insert(router.links, OSPF.LSA.Link.parse(data:sub(pos, pos + 12)))
|
||||||
|
pos = pos + 12
|
||||||
|
end
|
||||||
|
|
||||||
|
return router
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
ASExternal = {
|
||||||
|
new = function(self)
|
||||||
|
local o = {
|
||||||
|
header = OSPF.LSA.Header:new(),
|
||||||
|
netmask = 0,
|
||||||
|
ext_type = 1,
|
||||||
|
metric = 1,
|
||||||
|
fw_address = 0,
|
||||||
|
ext_tag = 0,
|
||||||
|
}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end,
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local as_ext = OSPF.LSA.ASExternal:new()
|
||||||
|
local pos = OSPF.LSA.Header.size + 1
|
||||||
|
as_ext.header = OSPF.LSA.Header.parse(data)
|
||||||
|
|
||||||
|
pos, as_ext.netmask, as_ext.metric, as_ext.fw_address, as_ext.ext_tag = bin.unpack(">IIII", data, pos)
|
||||||
|
as_ext.netmask = ipOps.fromdword(as_ext.netmask)
|
||||||
|
as_ext.ext_type = 1 + bit.rshift(bit.band(as_ext.metric, 0xFF000000), 31)
|
||||||
|
as_ext.metric = bit.band(as_ext.metric, 0x00FFFFFF)
|
||||||
|
as_ext.fw_address = ipOps.fromdword(as_ext.fw_address)
|
||||||
|
|
||||||
|
return as_ext
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local header = OSPF.LSA.Header.parse(data)
|
||||||
|
if header.type == 1 then
|
||||||
|
return OSPF.LSA.Router.parse(data)
|
||||||
|
elseif header.type == 5 then
|
||||||
|
return OSPF.LSA.ASExternal.parse(data)
|
||||||
|
end
|
||||||
|
return header.length
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
DBDescription = {
|
||||||
|
|
||||||
new = function(self)
|
new = function(self)
|
||||||
local o = {
|
local o = {
|
||||||
header = OSPF.Header:new(OSPF.Message.DB_DESCRIPTION),
|
header = OSPF.Header:new(OSPF.Message.DB_DESCRIPTION),
|
||||||
@@ -238,7 +353,8 @@ OSPF = {
|
|||||||
init = true,
|
init = true,
|
||||||
more = true,
|
more = true,
|
||||||
master = true,
|
master = true,
|
||||||
sequence = math.random(123456789)
|
sequence = math.random(123456789),
|
||||||
|
lsa_headers = {}
|
||||||
}
|
}
|
||||||
setmetatable(o, self)
|
setmetatable(o, self)
|
||||||
self.__index = self
|
self.__index = self
|
||||||
@@ -254,10 +370,20 @@ OSPF = {
|
|||||||
|
|
||||||
local data = bin.pack(">SCCI", self.mtu, self.options, flags, self.sequence)
|
local data = bin.pack(">SCCI", self.mtu, self.options, flags, self.sequence)
|
||||||
self.header:setLength(#data)
|
self.header:setLength(#data)
|
||||||
|
if self.header.auth_data.hash then
|
||||||
|
data = data .. self.header.auth_data.hash
|
||||||
|
end
|
||||||
return tostring(self.header) .. data
|
return tostring(self.header) .. data
|
||||||
end
|
end
|
||||||
local data = tostr()
|
local data = tostr()
|
||||||
self.header.chksum = packet.in_cksum(data:sub(1,12) .. data:sub(25))
|
if have_ssl and self.header.auth_type == 0x02 then
|
||||||
|
while string.len(self.header.auth_data.key) < 16 do
|
||||||
|
self.header.auth_data.key = self.header.auth_data.key .. "\0"
|
||||||
|
end
|
||||||
|
self.header.auth_data.hash = openssl.md5(data .. bin.pack(">A", self.header.auth_data.key))
|
||||||
|
else
|
||||||
|
self.header.chksum = packet.in_cksum(data:sub(1,16) .. data:sub(25))
|
||||||
|
end
|
||||||
return tostr()
|
return tostr()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -265,7 +391,7 @@ OSPF = {
|
|||||||
local desc = OSPF.DBDescription:new()
|
local desc = OSPF.DBDescription:new()
|
||||||
local pos = OSPF.Header.size + 1
|
local pos = OSPF.Header.size + 1
|
||||||
desc.header = OSPF.Header.parse(data)
|
desc.header = OSPF.Header.parse(data)
|
||||||
assert( #data == desc.header.length, "OSPF packet too short")
|
assert( #data >= desc.header.length, "OSPF packet too short")
|
||||||
|
|
||||||
local flags = 0
|
local flags = 0
|
||||||
pos, desc.mtu, desc.options, flags, desc.sequence = bin.unpack(">SCCI", data, pos)
|
pos, desc.mtu, desc.options, flags, desc.sequence = bin.unpack(">SCCI", data, pos)
|
||||||
@@ -274,6 +400,11 @@ OSPF = {
|
|||||||
desc.more = ( bit.band(flags, 2) == 2 )
|
desc.more = ( bit.band(flags, 2) == 2 )
|
||||||
desc.master = ( bit.band(flags, 1) == 1 )
|
desc.master = ( bit.band(flags, 1) == 1 )
|
||||||
|
|
||||||
|
while ( pos < desc.header.length ) do
|
||||||
|
table.insert(desc.lsa_headers, OSPF.LSA.Header.parse(data:sub(pos, pos + 20)))
|
||||||
|
pos = pos + 20
|
||||||
|
end
|
||||||
|
|
||||||
if ( desc.init or not(desc.more) ) then
|
if ( desc.init or not(desc.more) ) then
|
||||||
return desc
|
return desc
|
||||||
end
|
end
|
||||||
@@ -283,6 +414,104 @@ OSPF = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
LSRequest = {
|
||||||
|
new = function(self)
|
||||||
|
local o = {
|
||||||
|
header = OSPF.Header:new(OSPF.Message.LS_REQUEST),
|
||||||
|
ls_requests = {},
|
||||||
|
}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end,
|
||||||
|
|
||||||
|
--- Adds a request to the list of requests.
|
||||||
|
-- @param type LS Type.
|
||||||
|
-- @param id Link State ID
|
||||||
|
-- @param adv_router Advertising Router
|
||||||
|
addRequest = function(self, type, id, adv_router)
|
||||||
|
local request = {
|
||||||
|
type = type,
|
||||||
|
id = id,
|
||||||
|
adv_router = adv_router
|
||||||
|
}
|
||||||
|
table.insert(self.ls_requests, request)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__tostring = function(self)
|
||||||
|
local function tostr()
|
||||||
|
local data = ""
|
||||||
|
for _, req in ipairs(self.ls_requests) do
|
||||||
|
data = data .. bin.pack(">III", req.type, ipOps.todword(req.id), ipOps.todword(req.adv_router))
|
||||||
|
end
|
||||||
|
self.header:setLength(#data)
|
||||||
|
if self.header.auth_data.hash then
|
||||||
|
data = data .. self.header.auth_data.hash
|
||||||
|
end
|
||||||
|
return tostring(self.header) .. data
|
||||||
|
end
|
||||||
|
local data = tostr()
|
||||||
|
if have_ssl and self.header.auth_type == 0x02 then
|
||||||
|
while string.len(self.header.auth_data.key) < 16 do
|
||||||
|
self.header.auth_data.key = self.header.auth_data.key .. "\0"
|
||||||
|
end
|
||||||
|
self.header.auth_data.hash = openssl.md5(data .. bin.pack(">A", self.header.auth_data.key))
|
||||||
|
else
|
||||||
|
self.header.chksum = packet.in_cksum(data:sub(1,16) .. data:sub(25))
|
||||||
|
end
|
||||||
|
return tostr()
|
||||||
|
end,
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local ls_req = OSPF.LSRequest:new()
|
||||||
|
local pos = OSPF.Header.size + 1
|
||||||
|
ls_req.header = OSPF.Header.parse(data)
|
||||||
|
assert( #data >= ls_req.header.length, "OSPF packet too short")
|
||||||
|
|
||||||
|
while ( pos < #data ) do
|
||||||
|
local req = {}
|
||||||
|
pos, req.type, req.id, req.adv_router = bin.unpack(">III", data, pos)
|
||||||
|
table.insert(ls_req.ls_requests, req)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ls_req
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
LSUpdate = {
|
||||||
|
new = function(self)
|
||||||
|
local o = {
|
||||||
|
header = OSPF.Header:new(OSPF.Message.LS_UPDATE),
|
||||||
|
num_lsas = 0,
|
||||||
|
lsas = {},
|
||||||
|
}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end,
|
||||||
|
|
||||||
|
parse = function(data)
|
||||||
|
local lsu = OSPF.LSUpdate:new()
|
||||||
|
local pos = OSPF.Header.size + 1
|
||||||
|
lsu.header = OSPF.Header.parse(data)
|
||||||
|
assert( #data >= lsu.header.length, "OSPF packet too short")
|
||||||
|
|
||||||
|
pos, lsu.num_lsas = bin.unpack(">I", data, pos)
|
||||||
|
|
||||||
|
while ( pos < lsu.header.length ) do
|
||||||
|
local lsa = OSPF.LSA.parse(data:sub(pos))
|
||||||
|
if ( type(lsa) == "table" ) then
|
||||||
|
table.insert(lsu.lsas, lsa)
|
||||||
|
pos = pos + lsa.header.length
|
||||||
|
else
|
||||||
|
pos = pos + lsa
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return lsu
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
Response = {
|
Response = {
|
||||||
|
|
||||||
parse = function(data)
|
parse = function(data)
|
||||||
@@ -291,6 +520,10 @@ OSPF = {
|
|||||||
return OSPF.Hello.parse( data )
|
return OSPF.Hello.parse( data )
|
||||||
elseif( ospf_type == OSPF.Message.DB_DESCRIPTION ) then
|
elseif( ospf_type == OSPF.Message.DB_DESCRIPTION ) then
|
||||||
return OSPF.DBDescription.parse(data)
|
return OSPF.DBDescription.parse(data)
|
||||||
|
elseif( ospf_type == OSPF.Message.LS_REQUEST ) then
|
||||||
|
return OSPF.LSRequest.parse(data)
|
||||||
|
elseif( ospf_type == OSPF.Message.LS_UPDATE ) then
|
||||||
|
return OSPF.LSUpdate.parse(data)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end,
|
end,
|
||||||
|
|||||||
431
scripts/broadcast-ospf2-discover.nse
Normal file
431
scripts/broadcast-ospf2-discover.nse
Normal file
@@ -0,0 +1,431 @@
|
|||||||
|
local ipOps = require "ipOps"
|
||||||
|
local nmap = require "nmap"
|
||||||
|
local ospf = require "ospf"
|
||||||
|
local packet = require "packet"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local target = require "target"
|
||||||
|
local os = require "os"
|
||||||
|
local string = require "string"
|
||||||
|
local table = require "table"
|
||||||
|
|
||||||
|
local have_ssl, openssl = pcall(require,'openssl')
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Discover IPv4 networks using Open Shortest Path First version 2(OSPFv2) protocol.
|
||||||
|
|
||||||
|
The script works by listening for OSPF Hello packets from the 224.0.0.5
|
||||||
|
multicast address. The script then replies and attempts to create a neighbor
|
||||||
|
relationship, in order to discover network database.
|
||||||
|
|
||||||
|
If no interface was provided as a script argument or through the -e option,
|
||||||
|
the script will fail unless a single interface is present on the system.
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage
|
||||||
|
-- nmap --script=broadcast-ospf2-discover
|
||||||
|
-- nmap --script=broadcast-ospf2-discover -e wlan0
|
||||||
|
--
|
||||||
|
-- @args broadcast-ospf2-discover.md5_key MD5 digest key to use if message digest
|
||||||
|
-- authentication is disclosed.
|
||||||
|
--
|
||||||
|
-- @args broadcast-ospf2-discover.router_id Router ID to use. Defaults to 0.0.0.1
|
||||||
|
--
|
||||||
|
-- @args broadcast-ospf2-discover.timeout Time in seconds that the script waits for
|
||||||
|
-- hello from other routers. Defaults to 10 seconds, matching OSPFv2 default
|
||||||
|
-- value for hello interval.
|
||||||
|
--
|
||||||
|
-- @args broadcast-ospf2-discover.interface Interface to send on (overrides -e). Mandatory
|
||||||
|
-- if not using -e and multiple interfaces are present.
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- Pre-scan script results:
|
||||||
|
-- | broadcast-ospf2-discover:
|
||||||
|
-- | Area ID: 0.0.0.0
|
||||||
|
-- | External Routes
|
||||||
|
-- | 192.168.24.0/24
|
||||||
|
-- |_ Use the newtargets script-arg to add the results as targets
|
||||||
|
--
|
||||||
|
|
||||||
|
author = "Emiliano Ticci"
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
categories = {"broadcast", "discovery", "safe"}
|
||||||
|
|
||||||
|
prerule = function()
|
||||||
|
if nmap.address_family() ~= "inet" then
|
||||||
|
stdnse.print_verbose("is IPv4 only.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if not nmap.is_privileged() then
|
||||||
|
stdnse.print_verbose("not running for lack of privileges.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Script constants
|
||||||
|
OSPF_ALL_ROUTERS = "224.0.0.5"
|
||||||
|
OSPF_MSG_HELLO = 0x01
|
||||||
|
OSPF_MSG_DBDESC = 0x02
|
||||||
|
OSPF_MSG_LSREQ = 0x03
|
||||||
|
OSPF_MSG_LSUPD = 0x04
|
||||||
|
local md5_key, router_id
|
||||||
|
|
||||||
|
-- Convenience functions
|
||||||
|
local function fail(err) return stdnse.format_output(false, err) end
|
||||||
|
|
||||||
|
-- Print OSPFv2 LSA Header packet details to debug output.
|
||||||
|
-- @param hello OSPFv2 LSA Header packet
|
||||||
|
local ospfDumpLSAHeader = function(lsa_h)
|
||||||
|
if 2 > nmap.debugging() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
stdnse.print_debug(2, "| LS Age: %s", lsa_h.age)
|
||||||
|
stdnse.print_debug(2, "| Options: %s", lsa_h.options)
|
||||||
|
stdnse.print_debug(2, "| LS Type: %s", lsa_h.type)
|
||||||
|
stdnse.print_debug(2, "| Link State ID: %s", lsa_h.id)
|
||||||
|
stdnse.print_debug(2, "| Advertising Router: %s", lsa_h.adv_router)
|
||||||
|
stdnse.print_debug(2, "| Sequence: 0x%s", lsa_h.sequence)
|
||||||
|
stdnse.print_debug(2, "| Checksum: 0x%s", lsa_h.checksum)
|
||||||
|
stdnse.print_debug(2, "| Length: %s", lsa_h.length)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Print OSPFv2 Database Description packet details to debug output.
|
||||||
|
-- @param hello OSPFv2 Database Description packet
|
||||||
|
local ospfDumpDBDesc = function(db_desc)
|
||||||
|
if 2 > nmap.debugging() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
stdnse.print_debug(2, "| MTU: %s", db_desc.mtu)
|
||||||
|
stdnse.print_debug(2, "| Options: %s", db_desc.options)
|
||||||
|
stdnse.print_debug(2, "| Init: %s", db_desc.init)
|
||||||
|
stdnse.print_debug(2, "| More: %s", db_desc.more)
|
||||||
|
stdnse.print_debug(2, "| Master: %s", db_desc.master)
|
||||||
|
stdnse.print_debug(2, "| Sequence: %s", db_desc.sequence)
|
||||||
|
if #db_desc.lsa_headers > 0 then
|
||||||
|
stdnse.print_debug(2, "| LSA Headers:")
|
||||||
|
for i, lsa_h in ipairs(db_desc.lsa_headers) do
|
||||||
|
ospfDumpLSAHeader(lsa_h)
|
||||||
|
if i < #db_desc.lsa_headers then
|
||||||
|
stdnse.print_debug(2, "|")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Print OSPFv2 Hello packet details to debug output.
|
||||||
|
-- @param hello OSPFv2 Hello packet
|
||||||
|
local ospfDumpHello = function(hello)
|
||||||
|
if 2 > nmap.debugging() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
stdnse.print_debug(2, "| Router ID: %s", hello.header.router_id)
|
||||||
|
stdnse.print_debug(2, "| Area ID: %s", ipOps.fromdword(hello.header.area_id))
|
||||||
|
stdnse.print_debug(2, "| Checksum: %s", hello.header.chksum)
|
||||||
|
stdnse.print_debug(2, "| Auth Type: %s", hello.header.auth_type)
|
||||||
|
if hello.header.auth_type == 0x01 then
|
||||||
|
stdnse.print_debug(2, "| Auth Password: %s", hello.header.auth_data.password)
|
||||||
|
elseif hello.header.auth_type == 0x02 then
|
||||||
|
stdnse.print_debug(2, "| Auth Crypt Key ID: %s", hello.header.auth_data.keyid)
|
||||||
|
stdnse.print_debug(2, "| Auth Data Length: %s", hello.header.auth_data.length)
|
||||||
|
stdnse.print_debug(2, "| Auth Crypt Seq: %s", hello.header.auth_data.seq)
|
||||||
|
end
|
||||||
|
stdnse.print_debug(2, "| Netmask: %s", hello.netmask)
|
||||||
|
stdnse.print_debug(2, "| Hello interval: %s", hello.interval)
|
||||||
|
stdnse.print_debug(2, "| Options: %s", hello.options)
|
||||||
|
stdnse.print_debug(2, "| Priority: %s", hello.prio)
|
||||||
|
stdnse.print_debug(2, "| Dead interval: %s", hello.router_dead_interval)
|
||||||
|
stdnse.print_debug(2, "| Designated Router: %s", hello.DR)
|
||||||
|
stdnse.print_debug(2, "| Backup Router: %s", hello.BDR)
|
||||||
|
stdnse.print_debug(2, "| Neighbors: %s", table.concat(hello.neighbors, ","))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Print OSPFv2 LS Request packet details to debug output.
|
||||||
|
-- @param ls_req OSPFv2 LS Request packet
|
||||||
|
local ospfDumpLSRequest = function(ls_req)
|
||||||
|
if 2 > nmap.debugging() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for i, req in ipairs(ls_req.ls_requests) do
|
||||||
|
stdnse.print_debug(2, "| LS Type: %s", req.type)
|
||||||
|
stdnse.print_debug(2, "| Link State ID: %s", req.id)
|
||||||
|
stdnse.print_debug(2, "| Avertising Router: %s", req.adv_router)
|
||||||
|
if i < #ls_req.ls_requests then
|
||||||
|
stdnse.print_debug(2, "|")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Print OSPFv2 LS Update packet details to debug output.
|
||||||
|
-- @param ls_upd OSPFv2 LS Update packet
|
||||||
|
local ospfDumpLSUpdate = function(ls_upd)
|
||||||
|
stdnse.print_debug(2, "| Number of LSAs: %s", ls_upd.num_lsas)
|
||||||
|
for i, lsa in ipairs(ls_upd.lsas) do
|
||||||
|
-- Only Type 1 (Router-LSA) and Type 5 (AS-External-LSA) are supported at the moment
|
||||||
|
ospfDumpLSAHeader(lsa.header)
|
||||||
|
if lsa.header.type == 1 then
|
||||||
|
stdnse.print_debug(2, "| Flags: %s", lsa.flags)
|
||||||
|
stdnse.print_debug(2, "| Number of links: %s", lsa.num_links)
|
||||||
|
for j, link in ipairs(lsa.links) do
|
||||||
|
stdnse.print_debug(2, "| Link ID: %s", link.id)
|
||||||
|
stdnse.print_debug(2, "| Link Data: %s", link.data)
|
||||||
|
stdnse.print_debug(2, "| Link Type: %s", link.type)
|
||||||
|
stdnse.print_debug(2, "| Number of Metrics: %s", link.num_metrics)
|
||||||
|
stdnse.print_debug(2, "| 0 Metric: %s", link.metric)
|
||||||
|
if j < #lsa.links then
|
||||||
|
stdnse.print_debug(2, "|")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if i < #ls_upd.lsas then
|
||||||
|
stdnse.print_debug(2, "|")
|
||||||
|
end
|
||||||
|
elseif lsa.header.type == 5 then
|
||||||
|
stdnse.print_debug(2, "| Netmask: %s", lsa.netmask)
|
||||||
|
stdnse.print_debug(2, "| External Type: %s", lsa.ext_type)
|
||||||
|
stdnse.print_debug(2, "| Metric: %s", lsa.metric)
|
||||||
|
stdnse.print_debug(2, "| Forwarding Address: %s", lsa.fw_address)
|
||||||
|
stdnse.print_debug(2, "| External Route Tag: %s", lsa.ext_tag)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Send OSPFv2 packet to specified destination.
|
||||||
|
-- @param interface Source interface to use
|
||||||
|
-- @param ip_dst Destination IP address
|
||||||
|
-- @param mac_dst Destination MAC address
|
||||||
|
-- @param ospf_packet Raw OSPF packet
|
||||||
|
local ospfSend = function(interface, ip_dst, mac_dst, ospf_packet)
|
||||||
|
local dnet = nmap.new_dnet()
|
||||||
|
local probe = packet.Frame:new()
|
||||||
|
|
||||||
|
probe.mac_src = interface.mac
|
||||||
|
probe.mac_dst = mac_dst
|
||||||
|
probe.ip_bin_src = ipOps.ip_to_str(interface.address)
|
||||||
|
probe.ip_bin_dst = ipOps.ip_to_str(ip_dst)
|
||||||
|
probe.l3_packet = ospf_packet
|
||||||
|
probe.ip_dsf = 0xc0
|
||||||
|
probe.ip_p = 89
|
||||||
|
probe.ip_ttl = 1
|
||||||
|
|
||||||
|
probe:build_ip_packet()
|
||||||
|
probe:build_ether_frame()
|
||||||
|
|
||||||
|
dnet:ethernet_open(interface.device)
|
||||||
|
dnet:ethernet_send(probe.frame_buf)
|
||||||
|
dnet:ethernet_close()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prepare OSPFv2 packet header for reply.
|
||||||
|
-- @param packet_in Source packet
|
||||||
|
-- @param packet_out Destination packet
|
||||||
|
local ospfSetHeader = function(packet_in, packet_out)
|
||||||
|
packet_out.header:setRouterId(router_id)
|
||||||
|
packet_out.header:setAreaID(packet_in.header.area_id)
|
||||||
|
if packet_in.header.auth_type == 0x01 then
|
||||||
|
packet_out.header.auth_type = 0x01
|
||||||
|
packet_out.header.auth_data.password = packet_in.header.auth_data.password
|
||||||
|
elseif packet_in.header.auth_type == 0x02 then
|
||||||
|
packet_out.header.auth_type = 0x02
|
||||||
|
packet_out.header.auth_data.key = md5_key
|
||||||
|
packet_out.header.auth_data.keyid = packet_in.header.auth_data.keyid
|
||||||
|
packet_out.header.auth_data.length = 16
|
||||||
|
packet_out.header.auth_data.seq = os.time()
|
||||||
|
end
|
||||||
|
|
||||||
|
return packet_out
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Reply to OSPFv2 Database Description with an LS Request.
|
||||||
|
-- @param interface Source interface
|
||||||
|
-- @param mac_dst Destination MAC address
|
||||||
|
-- @param db_desc_in OSPFv2 Database Description packet to reply for
|
||||||
|
local ospfSendLSRequest = function(interface, mac_dst, db_desc_in)
|
||||||
|
local ls_req_out = ospf.OSPF.LSRequest:new()
|
||||||
|
ls_req_out = ospfSetHeader(db_desc_in, ls_req_out)
|
||||||
|
|
||||||
|
for i, lsa_h in ipairs(db_desc_in.lsa_headers) do
|
||||||
|
ls_req_out:addRequest(lsa_h.type, lsa_h.id, lsa_h.adv_router)
|
||||||
|
end
|
||||||
|
|
||||||
|
stdnse.print_debug(2, "Crafted OSPFv2 LS Request packet with the following parameters:")
|
||||||
|
ospfDumpLSRequest(ls_req_out)
|
||||||
|
ospfSend(interface, db_desc_in.header.router_id, mac_dst, tostring(ls_req_out))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Reply to given OSPFv2 Database Description packet.
|
||||||
|
-- @param interface Source interface
|
||||||
|
-- @param mac_dst Destination MAC address
|
||||||
|
-- @param db_desc_in OSPFv2 Database Description packet to reply for
|
||||||
|
local ospfReplyDBDesc = function(interface, mac_dst, db_desc_in)
|
||||||
|
local reply = false
|
||||||
|
local db_desc_out = ospf.OSPF.DBDescription:new()
|
||||||
|
db_desc_out = ospfSetHeader(db_desc_in, db_desc_out)
|
||||||
|
|
||||||
|
if db_desc_in.init == true then
|
||||||
|
db_desc_out.init = false
|
||||||
|
db_desc_out.more = db_desc_in.more
|
||||||
|
db_desc_out.master = false
|
||||||
|
db_desc_out.sequence = db_desc_in.sequence
|
||||||
|
reply = true
|
||||||
|
elseif #db_desc_in.lsa_headers > 0 then
|
||||||
|
ospfSendLSRequest(interface, mac_dst, db_desc_in)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if reply then
|
||||||
|
stdnse.print_debug(2, "Crafted OSPFv2 Database Description packet with the following parameters:")
|
||||||
|
ospfDumpDBDesc(db_desc_out)
|
||||||
|
ospfSend(interface, db_desc_in.header.router_id, mac_dst, tostring(db_desc_out))
|
||||||
|
end
|
||||||
|
|
||||||
|
return reply
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Reply to given OSPFv2 Hello packet sending another Hello to
|
||||||
|
-- "All OSPF Routers" multicast address (224.0.0.5).
|
||||||
|
-- @param interface Source interface
|
||||||
|
-- @param hello_in OSPFv2 Hello packet to reply for
|
||||||
|
local ospfReplyHello = function(interface, hello_in)
|
||||||
|
local hello_out = ospf.OSPF.Hello:new()
|
||||||
|
hello_out = ospfSetHeader(hello_in, hello_out)
|
||||||
|
hello_out.interval = hello_in.interval
|
||||||
|
hello_out.router_dead_interval = hello_in.router_dead_interval
|
||||||
|
hello_out:setDesignatedRouter(hello_in.header.router_id)
|
||||||
|
hello_out:setNetmask(hello_in.netmask)
|
||||||
|
hello_out:addNeighbor(hello_in.header.router_id)
|
||||||
|
|
||||||
|
stdnse.print_debug(2, "Crafted OSPFv2 Hello packet with the following parameters:")
|
||||||
|
ospfDumpHello(hello_out)
|
||||||
|
|
||||||
|
ospfSend(interface, OSPF_ALL_ROUTERS, "\x01\x00\x5e\x00\x00\x05", tostring(hello_out))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Listen for OSPF packets on a specified interface.
|
||||||
|
-- @param interface Interface to use
|
||||||
|
-- @param timeout Amount of time to listen in seconds
|
||||||
|
local ospfListen = function(interface, timeout)
|
||||||
|
local status, l2_data, l3_data, ospf_raw, _
|
||||||
|
local start = nmap.clock_ms()
|
||||||
|
|
||||||
|
stdnse.print_debug("Start listening on interface %s...", interface.shortname)
|
||||||
|
local listener = nmap.new_socket()
|
||||||
|
listener:set_timeout(1000)
|
||||||
|
listener:pcap_open(interface.device, 1500, true, "ip proto 89 and not (ip src host " .. interface.address .. ")")
|
||||||
|
while (nmap.clock_ms() - start) < (timeout * 1000) do
|
||||||
|
status, _, l2_data, l3_data = listener:pcap_receive()
|
||||||
|
if status then
|
||||||
|
stdnse.print_debug(2, "Packet received on interface %s.", interface.shortname)
|
||||||
|
local p = packet.Packet:new(l3_data, #l3_data)
|
||||||
|
local ospf_raw = string.sub(l3_data, p.ip_hl * 4 + 1)
|
||||||
|
if ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_HELLO then
|
||||||
|
stdnse.print_debug(2, "OSPFv2 Hello packet detected.")
|
||||||
|
|
||||||
|
local ospf_hello = ospf.OSPF.Hello.parse(ospf_raw)
|
||||||
|
stdnse.print_debug(2, "Captured OSPFv2 Hello packet with the following parameters:")
|
||||||
|
ospfDumpHello(ospf_hello)
|
||||||
|
|
||||||
|
-- Additional checks required for message digest authentication
|
||||||
|
if ospf_hello.header.auth_type == 0x02 then
|
||||||
|
if not md5_key then
|
||||||
|
return fail("Argument md5_key must be present when message digest authentication is disclosed.")
|
||||||
|
elseif not have_ssl then
|
||||||
|
return fail("Cannot handle message digest authentication unless openssl is compiled in.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ospfReplyHello(interface, ospf_hello)
|
||||||
|
start = nmap.clock_ms()
|
||||||
|
elseif ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_DBDESC then
|
||||||
|
stdnse.print_debug(2, "OSPFv2 Database Description packet detected.")
|
||||||
|
|
||||||
|
local ospf_db_desc = ospf.OSPF.DBDescription.parse(ospf_raw)
|
||||||
|
stdnse.print_debug(2, "Captured OSPFv2 Database Description packet with the following parameters:")
|
||||||
|
ospfDumpDBDesc(ospf_db_desc)
|
||||||
|
|
||||||
|
if not ospfReplyDBDesc(interface, string.sub(l2_data, 7, 12), ospf_db_desc) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
elseif ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_LSUPD then
|
||||||
|
stdnse.print_debug(2, "OSPFv2 LS Update packet detected.")
|
||||||
|
|
||||||
|
local ospf_ls_upd = ospf.OSPF.LSUpdate.parse(ospf_raw)
|
||||||
|
stdnse.print_debug(2, "Captured OSPFv2 LS Update packet with the following parameters:")
|
||||||
|
ospfDumpLSUpdate(ospf_ls_upd)
|
||||||
|
|
||||||
|
local targets = {}
|
||||||
|
for i, lsa in ipairs(ospf_ls_upd.lsas) do
|
||||||
|
-- Only Type 1 (Router-LSA) and Type 5 (AS-External-LSA) are supported at the moment
|
||||||
|
if lsa.header.type == 1 then
|
||||||
|
for j, link in ipairs(lsa.links) do
|
||||||
|
if link.type == 3 then
|
||||||
|
local target = link.id .. ipOps.subnet_to_cidr(link.data)
|
||||||
|
targets[target] = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif lsa.header.type == 5 then
|
||||||
|
local target = lsa.header.id .. ipOps.subnet_to_cidr(lsa.netmask)
|
||||||
|
targets[target] = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local output = stdnse.output_table()
|
||||||
|
if next(targets) then
|
||||||
|
local out_links = {}
|
||||||
|
output["Area ID"] = ipOps.fromdword(ospf_ls_upd.header.area_id)
|
||||||
|
output["External Routes"] = out_links
|
||||||
|
for t, _ in pairs(targets) do
|
||||||
|
table.insert(out_links, t)
|
||||||
|
if target.ALLOW_NEW_TARGETS then
|
||||||
|
target.add(t)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not target.ALLOW_NEW_TARGETS then
|
||||||
|
stdnse.verbose("Use the newtargets script-arg to add the results as targets")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
listener:pcap_close()
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function()
|
||||||
|
-- Get script arguments
|
||||||
|
md5_key = stdnse.get_script_args(SCRIPT_NAME .. ".md5_key") or false
|
||||||
|
router_id = stdnse.get_script_args(SCRIPT_NAME .. ".router_id") or "0.0.0.1"
|
||||||
|
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) or 10
|
||||||
|
local interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
|
||||||
|
stdnse.print_debug("Value for router ID argument: %s.", router_id)
|
||||||
|
stdnse.print_debug("Value for timeout argument: %s.", timeout)
|
||||||
|
|
||||||
|
-- Determine interface to use
|
||||||
|
interface = interface or nmap.get_interface()
|
||||||
|
if interface then
|
||||||
|
interface = nmap.get_interface_info(interface)
|
||||||
|
if not interface then
|
||||||
|
return fail(("Failed to retrieve %s interface information."):format(interface))
|
||||||
|
end
|
||||||
|
stdnse.print_debug("Will use %s interface.", interface.shortname)
|
||||||
|
else
|
||||||
|
local interface_list = nmap.list_interfaces()
|
||||||
|
local interface_good = {}
|
||||||
|
for _, os_interface in ipairs(interface_list) do
|
||||||
|
if os_interface.address and os_interface.link == "ethernet" and
|
||||||
|
os_interface.address:match("%d+%.%d+%.%d+%.%d+") then
|
||||||
|
|
||||||
|
stdnse.print_debug(2, "Found usable interface: %s.", os_interface.shortname)
|
||||||
|
table.insert(interface_good, os_interface)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #interface_good == 1 then
|
||||||
|
interface = interface_good[1]
|
||||||
|
stdnse.print_debug("Will use %s interface.", interface.shortname)
|
||||||
|
elseif #interface_good == 0 then
|
||||||
|
return fail("Source interface not found.")
|
||||||
|
else
|
||||||
|
return fail("Ambiguous source interface, please specify it with -e or interface parameter.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ospfListen(interface, timeout)
|
||||||
|
end
|
||||||
@@ -39,6 +39,7 @@ Entry { filename = "broadcast-ms-sql-discover.nse", categories = { "broadcast",
|
|||||||
Entry { filename = "broadcast-netbios-master-browser.nse", categories = { "broadcast", "safe", } }
|
Entry { filename = "broadcast-netbios-master-browser.nse", categories = { "broadcast", "safe", } }
|
||||||
Entry { filename = "broadcast-networker-discover.nse", categories = { "broadcast", "safe", } }
|
Entry { filename = "broadcast-networker-discover.nse", categories = { "broadcast", "safe", } }
|
||||||
Entry { filename = "broadcast-novell-locate.nse", categories = { "broadcast", "safe", } }
|
Entry { filename = "broadcast-novell-locate.nse", categories = { "broadcast", "safe", } }
|
||||||
|
Entry { filename = "broadcast-ospf2-discover.nse", categories = { "broadcast", "discovery", "safe", } }
|
||||||
Entry { filename = "broadcast-pc-anywhere.nse", categories = { "broadcast", "safe", } }
|
Entry { filename = "broadcast-pc-anywhere.nse", categories = { "broadcast", "safe", } }
|
||||||
Entry { filename = "broadcast-pc-duo.nse", categories = { "broadcast", "safe", } }
|
Entry { filename = "broadcast-pc-duo.nse", categories = { "broadcast", "safe", } }
|
||||||
Entry { filename = "broadcast-pim-discovery.nse", categories = { "broadcast", "discovery", "safe", } }
|
Entry { filename = "broadcast-pim-discovery.nse", categories = { "broadcast", "discovery", "safe", } }
|
||||||
|
|||||||
Reference in New Issue
Block a user