mirror of
https://github.com/nmap/nmap.git
synced 2025-12-23 07:59:03 +00:00
Added slaxml, hnap-info and modified script.db to show the same
This commit is contained in:
387
nselib/slaxml.lua
Normal file
387
nselib/slaxml.lua
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
---
|
||||||
|
-- This is the NSE implementation of SLAXML.
|
||||||
|
-- SLAXML is a pure-Lua SAX-like streaming XML parser. It is more robust
|
||||||
|
-- than many (simpler) pattern-based parsers that exist, properly supporting
|
||||||
|
-- code like <code><expr test="5 > 7" /></code>, CDATA nodes, comments,
|
||||||
|
-- namespaces, and processing instructions.
|
||||||
|
-- It is currently not a truly valid XML parser, however, as it allows certain XML that is
|
||||||
|
-- syntactically-invalid (not well-formed) to be parsed without reporting an error.
|
||||||
|
-- The streaming parser does a simple pass through the input and reports what it sees along the way.
|
||||||
|
-- You can optionally ignore white-space only text nodes using the <code>stripWhitespace</code> option.
|
||||||
|
-- The library contains the parser class and the parseDOM function.
|
||||||
|
-- Basic Usage of the library:
|
||||||
|
-- <code>
|
||||||
|
-- local parser = parser:new()
|
||||||
|
-- parser:parseSAX(xmlbody, {stripWhitespace=true})
|
||||||
|
-- </code>
|
||||||
|
-- To specify custom call backs use :
|
||||||
|
-- <code>
|
||||||
|
-- local call_backs = {
|
||||||
|
-- startElement = function(name,nsURI,nsPrefix) end, -- When "<foo" or <x:foo is seen
|
||||||
|
-- attribute = function(name,value,nsURI,nsPrefix) end, -- attribute found on current element
|
||||||
|
-- closeElement = function(name,nsURI) end, -- When "</foo>" or </x:foo> or "/>" is seen
|
||||||
|
-- text = function(text) end, -- text and CDATA nodes
|
||||||
|
-- comment = function(content) end, -- comments
|
||||||
|
-- pi = function(target,content) end, -- processing instructions e.g. "<?yes mon?>"
|
||||||
|
-- }
|
||||||
|
-- local parser = parser:new(call_backs)
|
||||||
|
-- parser:parseSAX(xmlbody)
|
||||||
|
-- </code>
|
||||||
|
-- The code also contains the <code>parseDOM</code> function.
|
||||||
|
-- To get the dom table use the <code>parseDOM</code> method as follows.
|
||||||
|
-- <code>
|
||||||
|
-- parseDOM(xmlbody, options)
|
||||||
|
-- </code>
|
||||||
|
-- @author "Gavin Kistner<original pure lua implemetation>, Gyanendra Mishra<nse specific implementation>"
|
||||||
|
|
||||||
|
--[=====================================================================[
|
||||||
|
v0.7 Copyright © 2013-2014 Gavin Kistner <!@phrogz.net>; MIT Licensed
|
||||||
|
See http://github.com/Phrogz/SLAXML for details.
|
||||||
|
--]=====================================================================]
|
||||||
|
|
||||||
|
local string = require "string"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local table = require "table"
|
||||||
|
local unicode = require "unicode"
|
||||||
|
_ENV = stdnse.module("slaxml", stdnse.seeall)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- A table containing the default call backs to be used
|
||||||
|
-- This really floods the script output, you will mostly be
|
||||||
|
-- using custom call backs.
|
||||||
|
-- Set the debugging level required for the default call backs. Defaults to 3.
|
||||||
|
local debugging_level = tonumber(stdnse.get_script_args('slaxml.debug')) or 3
|
||||||
|
local DEFAULT_CALLBACKS = {
|
||||||
|
--- A call back for processing instructions.
|
||||||
|
-- To use define pi = function(<target>, <content>) <function body> end in parser._call table.
|
||||||
|
-- Executes whenever a comment is found.
|
||||||
|
-- @param target the PI target
|
||||||
|
-- @param content any value not containing the sequence '?>'
|
||||||
|
pi = function(target,content)
|
||||||
|
stdnse.debug(debugging_level, string.format("<?%s %s?>",target,content))
|
||||||
|
end,
|
||||||
|
--- A call back for comments.
|
||||||
|
-- To use define comment = function(<content>) <function body> end in parser._call table.
|
||||||
|
-- Executes whenever a comment is encountered.
|
||||||
|
-- @param content The comment body itself.
|
||||||
|
comment = function(content)
|
||||||
|
stdnse.debug(debugging_level, debugging_level, string.format("<!-- %s -->",content))
|
||||||
|
end,
|
||||||
|
--- A call back for the start of elements.
|
||||||
|
-- To use define startElement = function(<name>, <nsURI>, <nsPrefix>) <function body> end in parser._call table.
|
||||||
|
-- Executes whenever an element starts.
|
||||||
|
-- @param name The name of the element.
|
||||||
|
-- @param nsURI The name space URI.
|
||||||
|
-- @param nsPrefix The name space prefix.
|
||||||
|
startElement = function(name,nsURI,nsPrefix)
|
||||||
|
local output = "<"
|
||||||
|
if nsPrefix then output = output .. nsPrefix .. ":" end
|
||||||
|
output = output .. name
|
||||||
|
if nsURI then output = output .. " (ns='" .. nsURI .. "')" end
|
||||||
|
output = output .. ">"
|
||||||
|
stdnse.debug(debugging_level, output)
|
||||||
|
end,
|
||||||
|
--- A call back for attributes.
|
||||||
|
-- To use define attribute = function(<name>, <attribtute>, <nsURI>, <nsPrefix>) <function body> end in parser._call table.
|
||||||
|
-- Executes whenever an attribute is found.
|
||||||
|
-- @param name The name of the attribute.
|
||||||
|
-- @param value The value of the attribute.
|
||||||
|
-- @param nsURI The name space URI.
|
||||||
|
-- @param nsPrefix The name space prefix.
|
||||||
|
attribute = function(name,value,nsURI,nsPrefix)
|
||||||
|
local output = ' '
|
||||||
|
if nsPrefix then output = output .. nsPrefix .. ":" end
|
||||||
|
output = output .. name .. '=' .. string.format('%q',value)
|
||||||
|
if nsURI then output = output .. (" (ns='" .. nsURI .. "')") end
|
||||||
|
stdnse.debug(debugging_level, output)
|
||||||
|
end,
|
||||||
|
--- A call back for text content.
|
||||||
|
-- To use define text = function(<text>) <function body> end in parser._call table.
|
||||||
|
-- Executes whenever pure text is found.
|
||||||
|
-- @param text The actual text.
|
||||||
|
text = function(text)
|
||||||
|
stdnse.debug(debugging_level, string.format(" text: %q",text))
|
||||||
|
end,
|
||||||
|
--- A call back for the end of elements.
|
||||||
|
-- To use define closeElement = function(<name>, <nsURI>, <nsPrefix>) <function body> end in parser._call table.
|
||||||
|
-- Executes whenever an element closes.
|
||||||
|
-- @param name The name of the element.
|
||||||
|
-- @param nsURI The name space URI.
|
||||||
|
-- @param nsPrefix The name space prefix.
|
||||||
|
closeElement = function(name,nsURI,nsPrefix)
|
||||||
|
stdnse.debug(debugging_level, string.format("</%s>",name))
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
parser = {
|
||||||
|
|
||||||
|
new = function(self, callbacks)
|
||||||
|
local o = {
|
||||||
|
_call = callbacks or DEFAULT_CALLBACKS
|
||||||
|
}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end,
|
||||||
|
--- Parses the xml in sax like manner.
|
||||||
|
-- @param xml The xml body to be parsed.
|
||||||
|
-- @param options Options if any specified.
|
||||||
|
parseSAX = function(self, xml, options)
|
||||||
|
if not options then options = { stripWhitespace=false } end
|
||||||
|
|
||||||
|
-- Cache references for maximum speed
|
||||||
|
local find, sub, gsub, char, push, pop, concat = string.find, string.sub, string.gsub, string.char, table.insert, table.remove, table.concat
|
||||||
|
local first, last, match1, match2, match3, pos2, nsURI
|
||||||
|
local unpack = unpack or table.unpack
|
||||||
|
local pos = 1
|
||||||
|
local state = "text"
|
||||||
|
local textStart = 1
|
||||||
|
local currentElement={}
|
||||||
|
local currentAttributes={}
|
||||||
|
local currentAttributeCt -- manually track length since the table is re-used
|
||||||
|
local nsStack = {}
|
||||||
|
local anyElement = false
|
||||||
|
|
||||||
|
|
||||||
|
local entityMap = { ["lt"]="<", ["gt"]=">", ["amp"]="&", ["quot"]='"', ["apos"]="'" }
|
||||||
|
local entitySwap = function(orig,n,s) return entityMap[s] or n=="#" and utf8_enc(tonumber('0'..s)) or orig end
|
||||||
|
local function unescape(str) return gsub( str, '(&(#?)([%d%a]+);)', entitySwap ) end
|
||||||
|
|
||||||
|
local function finishText()
|
||||||
|
if first>textStart and self._call.text then
|
||||||
|
local text = sub(xml,textStart,first-1)
|
||||||
|
if options.stripWhitespace then
|
||||||
|
text = gsub(text,'^%s+','')
|
||||||
|
text = gsub(text,'%s+$','')
|
||||||
|
if #text==0 then text=nil end
|
||||||
|
end
|
||||||
|
if text then self._call.text(unescape(text)) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findPI()
|
||||||
|
first, last, match1, match2 = find( xml, '^<%?([:%a_][:%w_.-]*) ?(.-)%?>', pos )
|
||||||
|
if first then
|
||||||
|
finishText()
|
||||||
|
if self._call.pi then self._call.pi(match1,match2) end
|
||||||
|
pos = last+1
|
||||||
|
textStart = pos
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findComment()
|
||||||
|
first, last, match1 = find( xml, '^<!%-%-(.-)%-%->', pos )
|
||||||
|
if first then
|
||||||
|
finishText()
|
||||||
|
if self._call.comment then self._call.comment(match1) end
|
||||||
|
pos = last+1
|
||||||
|
textStart = pos
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function nsForPrefix(prefix)
|
||||||
|
if prefix=='xml' then return 'http://www.w3.org/XML/1998/namespace' end -- http://www.w3.org/TR/xml-names/#ns-decl
|
||||||
|
for i=#nsStack,1,-1 do if nsStack[i][prefix] then return nsStack[i][prefix] end end
|
||||||
|
stdnse.debug1(("Cannot find namespace for prefix %s"):format(prefix))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local function startElement()
|
||||||
|
anyElement = true
|
||||||
|
first, last, match1 = find( xml, '^<([%a_][%w_.-]*)', pos )
|
||||||
|
if first then
|
||||||
|
currentElement[2] = nil -- reset the nsURI, since this table is re-used
|
||||||
|
currentElement[3] = nil -- reset the nsPrefix, since this table is re-used
|
||||||
|
finishText()
|
||||||
|
pos = last+1
|
||||||
|
first,last,match2 = find(xml, '^:([%a_][%w_.-]*)', pos )
|
||||||
|
if first then
|
||||||
|
currentElement[1] = match2
|
||||||
|
currentElement[3] = match1 -- Save the prefix for later resolution
|
||||||
|
match1 = match2
|
||||||
|
pos = last+1
|
||||||
|
else
|
||||||
|
currentElement[1] = match1
|
||||||
|
for i=#nsStack,1,-1 do if nsStack[i]['!'] then currentElement[2] = nsStack[i]['!']; break end end
|
||||||
|
end
|
||||||
|
currentAttributeCt = 0
|
||||||
|
push(nsStack,{})
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findAttribute()
|
||||||
|
first, last, match1 = find( xml, '^%s+([:%a_][:%w_.-]*)%s*=%s*', pos )
|
||||||
|
if first then
|
||||||
|
pos2 = last+1
|
||||||
|
first, last, match2 = find( xml, '^"([^<"]*)"', pos2 ) -- FIXME: disallow non-entity ampersands
|
||||||
|
if first then
|
||||||
|
pos = last+1
|
||||||
|
match2 = unescape(match2)
|
||||||
|
else
|
||||||
|
first, last, match2 = find( xml, "^'([^<']*)'", pos2 ) -- FIXME: disallow non-entity ampersands
|
||||||
|
if first then
|
||||||
|
pos = last+1
|
||||||
|
match2 = unescape(match2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if match1 and match2 then
|
||||||
|
local currentAttribute = {match1,match2}
|
||||||
|
local prefix,name = string.match(match1,'^([^:]+):([^:]+)$')
|
||||||
|
if prefix then
|
||||||
|
if prefix=='xmlns' then
|
||||||
|
nsStack[#nsStack][name] = match2
|
||||||
|
else
|
||||||
|
currentAttribute[1] = name
|
||||||
|
currentAttribute[4] = prefix
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if match1=='xmlns' then
|
||||||
|
nsStack[#nsStack]['!'] = match2
|
||||||
|
currentElement[2] = match2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
currentAttributeCt = currentAttributeCt + 1
|
||||||
|
currentAttributes[currentAttributeCt] = currentAttribute
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findCDATA()
|
||||||
|
first, last, match1 = find( xml, '^<!%[CDATA%[(.-)%]%]>', pos )
|
||||||
|
if first then
|
||||||
|
finishText()
|
||||||
|
if self._call.text then self._call.text(match1) end
|
||||||
|
pos = last+1
|
||||||
|
textStart = pos
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function closeElement()
|
||||||
|
first, last, match1 = find( xml, '^%s*(/?)>', pos )
|
||||||
|
if first then
|
||||||
|
state = "text"
|
||||||
|
pos = last+1
|
||||||
|
textStart = pos
|
||||||
|
|
||||||
|
-- Resolve namespace prefixes AFTER all new/redefined prefixes have been parsed
|
||||||
|
if currentElement[3] then currentElement[2] = nsForPrefix(currentElement[3]) end
|
||||||
|
if self._call.startElement then self._call.startElement(unpack(currentElement)) end
|
||||||
|
if self._call.attribute then
|
||||||
|
for i=1,currentAttributeCt do
|
||||||
|
if currentAttributes[i][4] then currentAttributes[i][3] = nsForPrefix(currentAttributes[i][4]) end
|
||||||
|
self._call.attribute(unpack(currentAttributes[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if match1=="/" then
|
||||||
|
pop(nsStack)
|
||||||
|
if self._call.closeElement then self._call.closeElement(unpack(currentElement)) end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findElementClose()
|
||||||
|
first, last, match1, match2 = find( xml, '^</([%a_][%w_.-]*)%s*>', pos )
|
||||||
|
if first then
|
||||||
|
nsURI = nil
|
||||||
|
for i=#nsStack,1,-1 do if nsStack[i]['!'] then nsURI = nsStack[i]['!']; break end end
|
||||||
|
else
|
||||||
|
first, last, match2, match1 = find( xml, '^</([%a_][%w_.-]*):([%a_][%w_.-]*)%s*>', pos )
|
||||||
|
if first then nsURI = nsForPrefix(match2) end
|
||||||
|
end
|
||||||
|
if first then
|
||||||
|
finishText()
|
||||||
|
if self._call.closeElement then self._call.closeElement(match1,nsURI) end
|
||||||
|
pos = last+1
|
||||||
|
textStart = pos
|
||||||
|
pop(nsStack)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while pos<#xml do
|
||||||
|
if state=="text" then
|
||||||
|
if not (findPI() or findComment() or findCDATA() or findElementClose()) then
|
||||||
|
if startElement() then
|
||||||
|
state = "attributes"
|
||||||
|
else
|
||||||
|
first, last = find( xml, '^[^<]+', pos )
|
||||||
|
pos = (first and last or pos) + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif state=="attributes" then
|
||||||
|
if not findAttribute() then
|
||||||
|
if not closeElement() then
|
||||||
|
stdnse.debug1("Was in an element and couldn't find attributes or the close.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not anyElement then stdnse.debug1("Parsing did not discover any elements") end
|
||||||
|
if #nsStack > 0 then stdnse.debug1("Parsing ended with unclosed elements") end
|
||||||
|
end,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Parses xml and spits out dom
|
||||||
|
-- @param xml, the xml body to be parsed.
|
||||||
|
-- @param options if any to use. Supporst stripWhitespaces currently.
|
||||||
|
function parseDOM (xml, options)
|
||||||
|
if not options then options={} end
|
||||||
|
local rich = not options.simple
|
||||||
|
local push, pop = table.insert, table.remove
|
||||||
|
local stack = {}
|
||||||
|
local doc = { type="document", name="#doc", kids={} }
|
||||||
|
local current = doc
|
||||||
|
local builder = parser:new{
|
||||||
|
startElement = function(name,nsURI)
|
||||||
|
local el = { type="element", name=name, kids={}, el=rich and {} or nil, attr={}, nsURI=nsURI, parent=rich and current or nil }
|
||||||
|
if current==doc then
|
||||||
|
if doc.root then stdnse.debug2(("Encountered element '%s' when the document already has a root '%s' element"):format(name,doc.root.name)) return end
|
||||||
|
doc.root = el
|
||||||
|
end
|
||||||
|
push(current.kids,el)
|
||||||
|
if current.el then push(current.el,el) end
|
||||||
|
current = el
|
||||||
|
push(stack,el)
|
||||||
|
end,
|
||||||
|
attribute = function(name,value,nsURI)
|
||||||
|
if not current or current.type~="element" then stdnse.debug2(("Encountered an attribute %s=%s but I wasn't inside an element"):format(name,value)) return end
|
||||||
|
local attr = {type='attribute',name=name,nsURI=nsURI,value=value,parent=rich and current or nil}
|
||||||
|
if rich then current.attr[name] = value end
|
||||||
|
push(current.attr,attr)
|
||||||
|
end,
|
||||||
|
closeElement = function(name)
|
||||||
|
if current.name~=name or current.type~="element" then stdnse.debug2(("Received a close element notification for '%s' but was inside a '%s' %s"):format(name,current.name,current.type)) return end
|
||||||
|
pop(stack)
|
||||||
|
current = stack[#stack]
|
||||||
|
end,
|
||||||
|
text = function(value)
|
||||||
|
if current.type~='document' then
|
||||||
|
if current.type~="element" then stdnse.debug2(("Received a text notification '%s' but was inside a %s"):format(value,current.type)) return end
|
||||||
|
push(current.kids,{type='text',name='#text',value=value,parent=rich and current or nil})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
comment = function(value)
|
||||||
|
push(current.kids,{type='comment',name='#comment',value=value,parent=rich and current or nil})
|
||||||
|
end,
|
||||||
|
pi = function(name,value)
|
||||||
|
push(current.kids,{type='pi',name=name,value=value,parent=rich and current or nil})
|
||||||
|
end
|
||||||
|
}
|
||||||
|
builder:parseSAX (xml,options)
|
||||||
|
return doc
|
||||||
|
end
|
||||||
|
|
||||||
|
return _ENV;
|
||||||
|
|
||||||
116
scripts/hnap-info.nse
Normal file
116
scripts/hnap-info.nse
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
local http = require "http"
|
||||||
|
local table = require "table"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local slaxml = require "slaxml"
|
||||||
|
local nmap = require "nmap"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Retrieve hardwares details and configuration information utilizing HNAP, the "Home Network Administration Protocol".
|
||||||
|
It is an HTTP-Simple Object Access Protocol (SOAP)-based protocol which allows for remote topology discovery,
|
||||||
|
configuration, and management of devices (routers, cameras, PCs, NAS, etc.)]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage
|
||||||
|
-- nmap --script hnap-info -p80,8080 <target>
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- PORT STATE SERVICE REASON
|
||||||
|
-- 8080/tcp open http-proxy syn-ack
|
||||||
|
-- | hnap-info:
|
||||||
|
-- | Type: GatewayWithWiFi
|
||||||
|
-- | Device: Ingraham
|
||||||
|
-- | Vendor: Linksys
|
||||||
|
-- | Description: Linksys E1200
|
||||||
|
-- | Model: E1200
|
||||||
|
-- | Firmware: 1.0.00 build 11
|
||||||
|
-- | Presentation URL: http://192.168.1.1/
|
||||||
|
-- | SOAPACTIONS:
|
||||||
|
-- | http://purenetworks.com/HNAP1/IsDeviceReady
|
||||||
|
-- | http://purenetworks.com/HNAP1/GetDeviceSettings
|
||||||
|
-- | http://purenetworks.com/HNAP1/SetDeviceSettings
|
||||||
|
-- | http://purenetworks.com/HNAP1/GetDeviceSettings2
|
||||||
|
-- | http://purenetworks.com/HNAP1/SetDeviceSettings2
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- @xmloutput
|
||||||
|
-- <elem key="Type">GatewayWithWiFi</elem>
|
||||||
|
-- <elem key="Device">Ingraham</elem>
|
||||||
|
-- <elem key="Vendor">Linksys</elem>
|
||||||
|
-- <elem key="Description">Linksys E1200</elem>
|
||||||
|
-- <elem key="Model">E1200</elem>
|
||||||
|
-- <elem key="Firmware">1.0.00 build 11</elem>
|
||||||
|
-- <elem key="Presentation URL">http://192.168.1.1/</elem>
|
||||||
|
-- <table key="SOAPACTIONS">
|
||||||
|
-- <elem>http://purenetworks.com/HNAP1/IsDeviceReady</elem>
|
||||||
|
-- <elem>http://purenetworks.com/HNAP1/GetDeviceSettings</elem>
|
||||||
|
-- <elem>http://purenetworks.com/HNAP1/SetDeviceSettings</elem>
|
||||||
|
-- <elem>http://purenetworks.com/HNAP1/GetDeviceSettings2</elem>
|
||||||
|
-- <elem>http://purenetworks.com/HNAP1/SetDeviceSettings2</elem>
|
||||||
|
-- </table>
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
author = "Gyanendra Mishra"
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
categories = {
|
||||||
|
"safe",
|
||||||
|
"discovery",
|
||||||
|
"default",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
portrule = shortport.http
|
||||||
|
|
||||||
|
local ELEMENTS = {["Type"] = "Type",
|
||||||
|
["DeviceName"] = "Device",
|
||||||
|
["VendorName"] = "Vendor",
|
||||||
|
["ModelDescription"] = "Description",
|
||||||
|
["ModelName"] = "Model",
|
||||||
|
["FirmwareVersion"] = "Firmware",
|
||||||
|
["PresentationURL"] = "Presentation URL",
|
||||||
|
["string"] = "SOAPACTIONS",
|
||||||
|
["SubDeviceURLs"] = "Sub Device URLs"}
|
||||||
|
|
||||||
|
function get_text_callback(store, name)
|
||||||
|
if ELEMENTS[name] == nil then return end
|
||||||
|
name = ELEMENTS[name]
|
||||||
|
if name == 'SOAPACTIONS' or name == 'Sub Device URLs' or name == 'Type' then
|
||||||
|
return function(content)
|
||||||
|
store[name] = store[name] or {}
|
||||||
|
table.insert(store[name], content)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return function(content)
|
||||||
|
store[name] = content
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function action (host, port)
|
||||||
|
local output = stdnse.output_table()
|
||||||
|
local response = http.get(host, port, '/HNAP1')
|
||||||
|
if response.status and response.status == 200 then
|
||||||
|
local parser = slaxml.parser:new()
|
||||||
|
parser._call = {startElement = function(name)
|
||||||
|
parser._call.text = get_text_callback(output, name) end,
|
||||||
|
closeElement = function(name) parser._call.text = function() return nil end end
|
||||||
|
}
|
||||||
|
parser:parseSAX(response.body, {stripWhitespace=true})
|
||||||
|
|
||||||
|
-- set the port verson
|
||||||
|
port.version.name = "hnap"
|
||||||
|
port.version.name_confidence = 10
|
||||||
|
port.version.product = output["Description"] or nil
|
||||||
|
port.version.version = output["Model"] or nil
|
||||||
|
port.version.devicetype = output["Type"] and output["Type"][1] or nil
|
||||||
|
port.version.cpe = port.version.cpe or {}
|
||||||
|
|
||||||
|
if output["Vendor"] and output["Model"] then
|
||||||
|
table.insert(port.version.cpe, "cpe:/h:".. output["Vendor"]:lower() .. ":" .. output["Model"]:lower())
|
||||||
|
end
|
||||||
|
nmap.set_port_version(host, port, "hardmatched")
|
||||||
|
|
||||||
|
if #output >0 then return output end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@@ -131,6 +131,7 @@ Entry { filename = "hadoop-tasktracker-info.nse", categories = { "default", "dis
|
|||||||
Entry { filename = "hbase-master-info.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "hbase-master-info.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "hbase-region-info.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "hbase-region-info.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "hddtemp-info.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "hddtemp-info.nse", categories = { "default", "discovery", "safe", } }
|
||||||
|
Entry { filename = "hnap-info.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "hostmap-bfk.nse", categories = { "discovery", "external", "intrusive", } }
|
Entry { filename = "hostmap-bfk.nse", categories = { "discovery", "external", "intrusive", } }
|
||||||
Entry { filename = "hostmap-ip2hosts.nse", categories = { "discovery", "external", } }
|
Entry { filename = "hostmap-ip2hosts.nse", categories = { "discovery", "external", } }
|
||||||
Entry { filename = "hostmap-robtex.nse", categories = { "discovery", "external", "safe", } }
|
Entry { filename = "hostmap-robtex.nse", categories = { "discovery", "external", "safe", } }
|
||||||
|
|||||||
Reference in New Issue
Block a user