1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-23 16:09:02 +00:00

Add dns-service-discovery.nse from Patrik Karlsson. See

http://seclists.org/nmap-dev/2010/q1/87 for more information.
This commit is contained in:
david
2010-01-21 01:53:46 +00:00
parent d390452e36
commit ad0a63deef
2 changed files with 188 additions and 0 deletions

View File

@@ -1,5 +1,11 @@
# Nmap Changelog ($Id$); -*-text-*-
o [NSE] Added the new dns-service-discovery protocol which uses DNS-SD
to identify services. DNS-SD is one part of automatic configuration
technologies known by names such as Bonjour, Rendezvous, and
Zeroconf. This one script can provide as much information as a full
port scan in some cases. [Patrik Karlsson]
o [NSE] Added a new library, afp.lua, and a script that uses it,
afp-showmount. The library is for the Apple Filing Protocol and the
script shows shares and their permissions. [Patrik Karlsson]

View File

@@ -0,0 +1,182 @@
description=[[
Attempts to discover a hosts services using the DNS Service Discovery protocol.
The script first sends a query for _services._dns-sd._udp.local to get a
list of services. It then sends a followup query for each one to try to
get more information.
]]
---
-- @usage
-- nmap --script=dns-service-discovery -p 5353 <host>
--
-- @output
-- PORT STATE SERVICE REASON
-- 5353/udp open zeroconf udp-response
-- | dns-service-discovery:
-- | 548/tcp afpovertcp
-- | model=MacBook5,1
-- | Address=192.168.0.2 fe80:0:0:0:223:6cff:1234:5678
-- | 3689/tcp daap
-- | txtvers=1
-- | iTSh Version=196609
-- | MID=0xFB5338C04123456
-- | Database ID=6FA9761FE123456
-- | dmv=131078
-- | Version=196616
-- | OSsi=0x1F6
-- | Machine Name=Patrik Karlsson\xE2\x80\x99s Library
-- | Media Kinds Shared=1
-- | Machine ID=8945A7123456
-- | Password=0
-- |_ Address=192.168.0.2 fe80:0:0:0:223:6cff:1234:5678
-- Version 0.2
-- Created 01/06/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
-- Revised 01/13/2010 - v0.2 - modified to use existing dns library instead of mdns, changed output to be less DNS like
author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "safe"}
require 'shortport'
require 'dns'
portrule = shortport.portnumber(5353, "udp")
--- Gets a record from both the Answer and Additional section
--
-- @param dtype DNS resource record type.
-- @param dec Decoded DNS response.
-- @param retAll If true, return all entries, not just the first.
-- @return True if one or more answers of the required type were found - otherwise false.
-- @return Answer according to the answer fetcher for <code>dtype</code> or an Error message.
function getRecordType( dtype, dec, retAll )
local result = {}
local status1, answers = dns.findNiceAnswer( dtype, response, retAll )
if status1 then
if retAll then
for _, v in ipairs(answers) do
table.insert(result, string.format("%s", v) )
end
else
return true, answers
end
end
local status2, answers = dns.findNiceAdditional( dtype, response, retAll )
if status2 then
if retAll then
for _, v in ipairs(answers) do
table.insert(result, v)
end
else
return true, answers
end
end
if not status1 and not status2 then
return false, answers
end
return true, result
end
action = function(host, port)
-- do some exception handling / cleanup
local catch = function()
socket:close()
end
local try = nmap.new_try(catch)
local result = {}
local deviceinfo = {}
response = try( dns.query( "_services._dns-sd._udp.local", { port = 5353, host = host.ip, dtype="PTR", retAll=true} ) )
-- for each service response in answers, send a service query
for _, v in ipairs( response ) do
stdnse.print_debug( string.format("-> Sending MDNS query for: %s", v ) )
local service = {}
local txt = {}
local status, ip, ipv6, srv, address, port, proto
response = try( dns.query( v, { port = 5353, host = host.ip, dtype="PTR", retPkt=true} ) )
status, ip = getRecordType( dns.types.A, response, false )
if status then
address = ip
end
status, ipv6 = getRecordType( dns.types.AAAA, response, false )
if status then
address = address .. " " .. ipv6
end
status, txt = getRecordType( dns.types.TXT, response, true )
if status then
for _, v in ipairs(txt) do
if v:len() > 0 then
table.insert(service, v)
end
end
end
status, srv = getRecordType( dns.types.SRV, response, false )
if status then
local srvparams = stdnse.strsplit( ":", srv )
if #srvparams > 3 then
port = srvparams[3]
end
end
if address then
table.insert( service, ("Address=%s"):format( address ) )
end
if v == "_device-info._tcp.local" then
service.name = "Device Information"
deviceinfo = service
else
local serviceparams = stdnse.strsplit("[.]", v)
if #serviceparams > 2 then
local servicename = serviceparams[1]:sub(2)
local proto = serviceparams[2]:sub(2)
if port == nil or proto == nil or servicename == nil then
service.name = v
else
service.name = string.format( "%s/%s %s", port, proto, servicename)
end
end
table.insert( result, service )
end
end
-- we want the device information at the end
table.insert( result, deviceinfo )
-- set port to open
nmap.set_port_state(host, port, "open")
return stdnse.format_output(true, result )
end