diff options
Diffstat (limited to 'scripts/hnap-info.nse')
-rw-r--r-- | scripts/hnap-info.nse | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/scripts/hnap-info.nse b/scripts/hnap-info.nse new file mode 100644 index 0000000..0cc53fc --- /dev/null +++ b/scripts/hnap-info.nse @@ -0,0 +1,130 @@ +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 https://nmap.org/book/man-legal.html" +categories = { + "safe", + "discovery", + "default", + "version" +} + + +portrule = function(host, port) + return (shortport.http(host,port) and nmap.version_intensity() >= 7) +end + +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) + + -- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests + local status_404, result_404, _ = http.identify_404(host,port) + if ( status_404 and result_404 == 200 ) then + stdnse.debug1("Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", host.ip, port.number) + return nil + end + + 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}) + + -- exit if the parser does not return output + if not next(output) then return nil end + + -- 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") + + return output + end +end + |