122 lines
3.1 KiB
Lua
122 lines
3.1 KiB
Lua
local coroutine = require "coroutine"
|
|
local dhcp6 = require "dhcp6"
|
|
local nmap = require "nmap"
|
|
local stdnse = require "stdnse"
|
|
local table = require "table"
|
|
|
|
description = [[
|
|
Sends a DHCPv6 request (Solicit) to the DHCPv6 multicast address,
|
|
parses the response, then extracts and prints the address along with
|
|
any options returned by the server.
|
|
|
|
The script requires Nmap to be run in privileged mode as it binds the socket
|
|
to a privileged port (udp/546).
|
|
]]
|
|
|
|
---
|
|
-- @see broadcast-dhcp-discover.nse
|
|
-- @see dhcp-discover.nse
|
|
--
|
|
-- @usage
|
|
-- nmap -6 --script broadcast-dhcp6-discover
|
|
--
|
|
-- @output
|
|
-- | broadcast-dhcp6-discover:
|
|
-- | Interface: en0
|
|
-- | Message type: Advertise
|
|
-- | Transaction id: 74401
|
|
-- | Options
|
|
-- | Client identifier: MAC: 68:AB:CD:EF:AB:CD; Time: 2012-01-24 20:36:48
|
|
-- | Server identifier: MAC: 08:FE:DC:BA:98:76; Time: 2012-01-20 11:44:58
|
|
-- | Non-temporary Address: 2001:db8:1:2:0:0:0:1000
|
|
-- | DNS Servers: 2001:db8:0:0:0:0:0:35
|
|
-- | Domain Search: example.com, sub.example.com
|
|
-- |_ NTP Servers: 2001:db8:1111:0:0:0:0:123, 2001:db8:1111:0:0:0:0:124
|
|
--
|
|
|
|
author = "Patrik Karlsson"
|
|
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
|
|
categories = {"broadcast", "safe"}
|
|
|
|
|
|
prerule = function()
|
|
if not nmap.is_privileged() then
|
|
stdnse.verbose1("not running for lack of privileges.")
|
|
return false
|
|
end
|
|
|
|
if nmap.address_family() ~= 'inet6' then
|
|
stdnse.debug1("is IPv6 compatible only.")
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Gets a list of available interfaces based on link and up filters
|
|
--
|
|
-- @param link string containing the link type to filter
|
|
-- @param up string containing the interface status to filter
|
|
-- @return result table containing the matching interfaces
|
|
local function getInterfaces(link, up)
|
|
if( not(nmap.list_interfaces) ) then return end
|
|
local interfaces, err = nmap.list_interfaces()
|
|
local result
|
|
if ( not(err) ) then
|
|
for _, iface in ipairs(interfaces) do
|
|
if ( iface.link == link and iface.up == up ) then
|
|
result = result or {}
|
|
result[iface.device] = true
|
|
end
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
local function solicit(iface, result)
|
|
local condvar = nmap.condvar(result)
|
|
local helper = dhcp6.Helper:new(iface)
|
|
if ( not(helper) ) then
|
|
condvar "signal"
|
|
return
|
|
end
|
|
|
|
local status, response = helper:solicit()
|
|
if ( status ) then
|
|
response.name=("Interface: %s"):format(iface)
|
|
table.insert(result, response )
|
|
end
|
|
condvar "signal"
|
|
end
|
|
|
|
action = function(host, port)
|
|
|
|
local iface = nmap.get_interface()
|
|
local ifs, result, threads = {}, {}, {}
|
|
local condvar = nmap.condvar(result)
|
|
|
|
if ( iface ) then
|
|
ifs[iface] = true
|
|
else
|
|
ifs = getInterfaces("ethernet", "up")
|
|
end
|
|
|
|
for iface in pairs(ifs) do
|
|
local co = stdnse.new_thread( solicit, iface, result )
|
|
threads[co] = true
|
|
end
|
|
|
|
-- wait until the probes are all done
|
|
repeat
|
|
for thread in pairs(threads) do
|
|
if coroutine.status(thread) == "dead" then
|
|
threads[thread] = nil
|
|
end
|
|
end
|
|
if ( next(threads) ) then
|
|
condvar "wait"
|
|
end
|
|
until next(threads) == nil
|
|
|
|
return stdnse.format_output(true, result)
|
|
end
|