diff --git a/nselib/data/http-default-accounts-fingerprints.lua b/nselib/data/http-default-accounts-fingerprints.lua
index 6fa336792..fb574b5d3 100644
--- a/nselib/data/http-default-accounts-fingerprints.lua
+++ b/nselib/data/http-default-accounts-fingerprints.lua
@@ -1,6 +1,7 @@
local base64 = require "base64"
local bin = require "bin"
local http = require "http"
+local stdnse = require "stdnse"
local table = require "table"
local url = require "url"
@@ -86,6 +87,7 @@ table.insert(fingerprints, {
name = "Cacti",
category = "web",
paths = {
+ {path = "/"},
{path = "/cacti/"}
},
target_check = function (host, port, path, response)
@@ -101,7 +103,10 @@ table.insert(fingerprints, {
{username = "admin", password = "admin"}
},
login_check = function (host, port, path, user, pass)
- return try_http_post_login(host, port, path, "index.php", "Invalid User Name/Password", {action="login", login_username=user, login_password=pass}, false)
+ return try_http_post_login(host, port, path, "index.php",
+ "Invalid User Name/Password",
+ {action="login", login_username=user, login_password=pass},
+ false)
end
})
@@ -242,9 +247,11 @@ table.insert(fingerprints, {
})
table.insert(fingerprints, {
+ -- Version 12.2SE on Catalyst 3750
name = "Cisco IOS",
category = "routers",
paths = {
+ {path = "/"},
{path = "/exec/show/log/CR"},
{path = "/level/15/exec/-/configure/http"},
{path = "/level/15/exec/-"},
@@ -253,7 +260,7 @@ table.insert(fingerprints, {
target_check = function (host, port, path, response)
local realm = http_auth_realm(response) or ""
-- Exact PCRE: "^level 15?( or view)? access$"
- return realm:gsub("_"," "):find("^level 15? .*access$")
+ return realm:gsub("_"," "):find("^level 15? .*%f[^%s]access$")
end,
login_combos = {
{username = "", password = ""},
@@ -265,10 +272,11 @@ table.insert(fingerprints, {
})
table.insert(fingerprints, {
+ -- Version 1.0.22
name = "Cisco WAP200",
category = "routers",
paths = {
- {path = "/StatusLan.htm"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
return http_auth_realm(response) == "Linksys WAP200"
@@ -282,10 +290,11 @@ table.insert(fingerprints, {
})
table.insert(fingerprints, {
+ -- Version 1.07.01
name = "Cisco WAP55AG",
category = "routers",
paths = {
- {path = "/WPA_Preshared.asp"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
return http_auth_realm(response) == "Linksys WAP55AG"
@@ -299,10 +308,11 @@ table.insert(fingerprints, {
})
table.insert(fingerprints, {
+ -- Version 1.0.1.3
name = "ASUS RT-N10U",
category = "routers",
paths = {
- {path = "/as.asp"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
return http_auth_realm(response) == "RT-N10U"
@@ -316,71 +326,76 @@ table.insert(fingerprints, {
})
table.insert(fingerprints, {
+ -- Version 3.3.2, 4.3.1, 4.4.0, 4.4.1 on RFS6000
name = "Motorola RF Switch",
category = "routers",
paths = {
- {path = "/getfwversion.cgi"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
- -- true if the response is HTTP/200 and returns a firmware version
return response.status == 200
- and not response.header["server"]
- and response.header["content-type"] == "text/plain"
+ and response.header["server"]
+ and response.header["server"]:find("^thttpd/%d+%.")
and response.body
- and response.body:find("\n%d+%.%d+%.%d+%.%d+%-%w+\n")
+ and response.body:lower():find("
motorola wireless network management", 1, true)
end,
login_combos = {
{username = "admin", password = "superuser"}
},
login_check = function (host, port, path, user, pass)
- local tohex = function (str)
- local _, hex = bin.unpack("H" .. str:len(), str)
- return hex:lower()
- end
- local login = ("J20K34NMMT89XPIJ34S login %s %s"):format(tohex(user), tohex(pass))
- local lpath = url.absolute(path, "usmCgi.cgi/?" .. url.escape(login))
- local req = http.get(host, port, lpath, {no_cache=true, redirect_ok = false})
- return req
- and req.status == 200
+ local login = ("J20K34NMMT89XPIJ34S login %s %s"):format(stdnse.tohex(user), stdnse.tohex(pass))
+ local lurl = url.absolute(path, "usmCgi.cgi/?" .. url.escape(login))
+ local req = http.get(host, port, lurl, {no_cache=true, redirect_ok=false})
+ return req.status == 200
and req.body
- and req.body:match("^login 0 ")
+ and req.body:find("^login 0 ")
end
})
table.insert(fingerprints, {
+ -- Version 08.05.100 on NVR 1750D
name = "Nortel VPN Router",
category = "routers",
paths = {
- {path = "/manage/bdy_sys.htm"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
- return http_auth_realm(response) == "Management(1)"
+ return response.status == 200
+ and response.header["server"] == "HTTP Server"
+ and response.body
+ and response.body:lower():find("nortel vpn router", 1, true)
end,
login_combos = {
{username = "admin", password = "setup"}
},
login_check = function (host, port, path, user, pass)
- return try_http_basic_login(host, port, path, user, pass, false)
+ return try_http_basic_login(host, port,
+ url.absolute(path, "manage/bdy_sys.htm"),
+ user, pass, false)
end
})
table.insert(fingerprints, {
+ -- Version 11.4.1, 11.5.3
name = "F5 BIG-IP",
category = "routers",
paths = {
- {path = "/tmui/login.jsp"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
return response.status == 200
- and response.header["f5-login-page"] == "true"
and response.body
- and response.body:find("logmein.html",1,true)
+ and response.body:find("F5 Networks", 1, true)
+ and response.body:find("BIG-IP", 1, true)
+ and response.body:find("/tmui/tmui/system/settings/redirect.jsp", 1, true)
end,
login_combos = {
{username = "admin", password = "admin"}
},
login_check = function (host, port, path, user, pass)
- return try_http_post_login(host, port, path, "logmein.html", "login%.jsp%?msgcode=1", {username=user, passwd=pass})
+ return try_http_post_login(host, port, path, "tmui/logmein.html",
+ "login%.jsp%?msgcode=1",
+ {username=user, passwd=pass})
end
})
@@ -408,22 +423,24 @@ table.insert(fingerprints, {
--Printers
---
table.insert(fingerprints, {
+ -- Version 61.17.5Z on ZTC GK420d
name = "Zebra Printer",
category = "printer",
paths = {
- {path = "/setgen"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
- return response.body
- and response.body:lower():find("zebra technologies
", 1, true)
+ return response.status == 200
+ and response.body
+ and response.body:find("Zebra Technologies", 1, true)
+ and response.body:lower():find('view printer configuration', 1, true)
end,
login_combos = {
{username = "", password = "1234"}
},
login_check = function (host, port, path, user, pass)
- local form = {}
- form["0"] = pass
- return try_http_post_login(host, port, path, "authorize", "incorrect password", form)
+ return try_http_post_login(host, port, path, "authorize",
+ "incorrect password", {["0"]=pass})
end
})
@@ -447,24 +464,32 @@ table.insert(fingerprints, {
})
table.insert(fingerprints, {
+ -- Version 1.04.9 on RICOH MP C4503, 1.05 on MP 5054, 1.12 pn MP C5000
name = "RICOH Web Image Monitor",
category = "printer",
paths = {
- {path = "/web/guest/en/websys/webArch/header.cgi"}
+ {path = "/"}
},
target_check = function (host, port, path, response)
- return response.header["server"]
- and response.header["server"]:find("^Web%-Server/%d+%.%d+$")
+ return response.status == 200
+ and response.header["server"]
+ and response.header["server"]:find("^Web%-Server/%d+%.")
and response.body
- and response.body:find("RICOH", 1, true)
+ and response.body:find("/websys/webArch/mainFrame.cgi", 1, true)
end,
login_combos = {
{username = "admin", password = ""},
{username = "supervisor", password = ""}
},
login_check = function (host, port, path, user, pass)
+ -- determine proper login path by locale
+ local req0 = http.get(host, port, path)
+ if req0.status ~= 200 then return false end
+ local lpath = req0.body and req0.body:match('location%.href="(/[^"]+/)mainFrame%.cgi"')
+ if not lpath then return false end
-- harvest the login form token
- local req1 = http.get(host, port, url.absolute(path, "authForm.cgi"), {no_cache=true, redirect_ok = false, cookies = "cookieOnOffChecker=on"})
+ local req1 = http.get(host, port, url.absolute(lpath, "authForm.cgi"),
+ {cookies="cookieOnOffChecker=on", no_cache=true, redirect_ok=false})
if req1.status ~= 200 then return false end
local token = req1.body and req1.body:match('Lantronix SLC",1,true)
+ and response.body:lower():find("lantronix slc", 1, true)
end,
login_combos = {
{username = "sysadmin", password = "PASS"}
},
login_check = function (host, port, path, user, pass)
- return try_http_post_login(host, port, path, "./", "%sname%s*=%s*(['\"]?)slcpassword%1[%s>]", {slclogin=user, slcpassword=pass})
+ return try_http_post_login(host, port, path, "./",
+ "%sname%s*=%s*(['\"]?)slcpassword%1[%s>]",
+ {slclogin=user, slcpassword=pass})
end
})