mirror of
https://github.com/nmap/nmap.git
synced 2025-12-29 19:09:01 +00:00
Remove trailing whitespace in lua files
Whitespace is not significant, so this should not be a problem. https://secwiki.org/w/Nmap/Code_Standards
This commit is contained in:
@@ -23,7 +23,7 @@ For more information about acarsd, see:
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 2202/tcp open unknown
|
||||
-- | acarsd-info:
|
||||
-- | acarsd-info:
|
||||
-- | Version: 1.65
|
||||
-- | API Version: API-2005-Oct-18
|
||||
-- | Authorization Required: 0
|
||||
@@ -107,7 +107,7 @@ action = function(host, port)
|
||||
end
|
||||
port.version.name = "acarsd"
|
||||
port.version.product = "ACARS Decoder"
|
||||
nmap.set_port_version(host, port)
|
||||
nmap.set_port_version(host, port)
|
||||
|
||||
-- Return results
|
||||
return stdnse.format_output(true, result)
|
||||
|
||||
@@ -28,48 +28,48 @@ definitions of some terms.
|
||||
-- @output
|
||||
-- Nmap scan report for ::1.2.3.4
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | IPv4-compatible:
|
||||
-- | address-info:
|
||||
-- | IPv4-compatible:
|
||||
-- |_ IPv4 address: 1.2.3.4
|
||||
--
|
||||
--
|
||||
-- Nmap scan report for ::ffff:1.2.3.4
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | IPv4-mapped:
|
||||
-- | address-info:
|
||||
-- | IPv4-mapped:
|
||||
-- |_ IPv4 address: 1.2.3.4
|
||||
--
|
||||
--
|
||||
-- Nmap scan report for 2001:0:506:708:282a:3d75:fefd:fcfb
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | Teredo:
|
||||
-- | address-info:
|
||||
-- | Teredo:
|
||||
-- | Server IPv4 address: 5.6.7.8
|
||||
-- | Client IPv4 address: 1.2.3.4
|
||||
-- |_ UDP port: 49802
|
||||
--
|
||||
--
|
||||
-- Nmap scan report for 2002:102:304::1
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | 6to4:
|
||||
-- | address-info:
|
||||
-- | 6to4:
|
||||
-- |_ IPv4 address: 1.2.3.4
|
||||
--
|
||||
--
|
||||
-- Nmap scan report for fe80::a8bb:ccff:fedd:eeff
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | IPv6 EUI-64:
|
||||
-- | MAC address:
|
||||
-- | address-info:
|
||||
-- | IPv6 EUI-64:
|
||||
-- | MAC address:
|
||||
-- | address: aa:bb:cc:dd:ee:ff
|
||||
-- |_ manuf: Unknown
|
||||
--
|
||||
--
|
||||
-- Nmap scan report for 64:ff9b::c000:221
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | IPv4-embedded IPv6 address:
|
||||
-- | address-info:
|
||||
-- | IPv4-embedded IPv6 address:
|
||||
-- |_ IPv4 address: 192.0.2.33
|
||||
--
|
||||
--
|
||||
-- Nmap scan report for ::ffff:0:c0a8:101
|
||||
-- Host script results:
|
||||
-- | address-info:
|
||||
-- | IPv4-translated IPv6 address:
|
||||
-- | address-info:
|
||||
-- | IPv4-translated IPv6 address:
|
||||
-- |_ IPv4 address: 192.168.1.1
|
||||
|
||||
-- * ISATAP. RFC 5214.
|
||||
@@ -249,8 +249,8 @@ local function do_ipv6(addr)
|
||||
return {["IPv4-embedded IPv6 address"]= {["IPv4 address"] = format_ipv4(ipv4)}}
|
||||
end
|
||||
elseif matches(addr, "0000:0000:0000:0000:ffff:0000:XXXX:XXXX") then
|
||||
-- IPv4-translated IPv6 addresses. RFC 2765, Section 2.1
|
||||
return {["IPv4-translated IPv6 address"]=
|
||||
-- IPv4-translated IPv6 addresses. RFC 2765, Section 2.1
|
||||
return {["IPv4-translated IPv6 address"]=
|
||||
{["IPv4 address"] = format_ipv4( {addr[13], addr[14], addr[15], addr[16]})}}
|
||||
elseif matches(addr, "XXXX:XXXX:XXXX:XX00:0000:5efe:XXXX:XXXX") then
|
||||
-- ISATAP. RFC 5214, Appendix A
|
||||
|
||||
@@ -15,13 +15,13 @@ Performs password guessing against Apple Filing Protocol (AFP).
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- @usage
|
||||
-- nmap -p 548 --script afp-brute <host>
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 548/tcp open afp
|
||||
-- | afp-brute:
|
||||
-- | afp-brute:
|
||||
-- |_ admin:KenSentMe => Valid credentials
|
||||
|
||||
-- Information on AFP implementations
|
||||
@@ -55,13 +55,13 @@ action = function( host, port )
|
||||
local valid_accounts, found_users = {}, {}
|
||||
local helper
|
||||
local usernames, passwords
|
||||
|
||||
|
||||
status, usernames = unpwdb.usernames()
|
||||
if not status then return end
|
||||
|
||||
status, passwords = unpwdb.passwords()
|
||||
status, passwords = unpwdb.passwords()
|
||||
if not status then return end
|
||||
|
||||
|
||||
for password in passwords do
|
||||
for username in usernames do
|
||||
if ( not(found_users[username]) ) then
|
||||
@@ -87,11 +87,11 @@ action = function( host, port )
|
||||
found_users[username] = true
|
||||
end
|
||||
|
||||
if status then
|
||||
if status then
|
||||
-- Add credentials for other afp scripts to use
|
||||
if nmap.registry.afp == nil then
|
||||
nmap.registry.afp = {}
|
||||
end
|
||||
end
|
||||
nmap.registry.afp[username]=password
|
||||
found_users[username] = true
|
||||
|
||||
@@ -100,12 +100,12 @@ action = function( host, port )
|
||||
end
|
||||
helper:CloseSession()
|
||||
end
|
||||
end
|
||||
end
|
||||
usernames("reset")
|
||||
end
|
||||
|
||||
|
||||
local output = stdnse.format_output(true, valid_accounts)
|
||||
|
||||
|
||||
return output
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ The output is intended to resemble the output of <code>ls</code>.
|
||||
--@output
|
||||
-- PORT STATE SERVICE
|
||||
-- 548/tcp open afp syn-ack
|
||||
-- | afp-ls:
|
||||
-- | afp-ls:
|
||||
-- | Macintosh HD
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw-r--r-- 501 80 15364 2010-06-13 17:52 .DS_Store
|
||||
@@ -45,7 +45,7 @@ The output is intended to resemble the output of <code>ls</code>.
|
||||
-- | -rw------- 501 20 102 2010-06-14 01:46 .lesshst
|
||||
-- | -rw-r--r-- 501 20 241 2010-06-14 01:45 .profile
|
||||
-- | -rw------- 501 20 218 2010-09-12 16:35 .recently-used.xbel
|
||||
-- |
|
||||
-- |
|
||||
-- | Information retrieved as: patrik
|
||||
-- |_ Output restricted to 10 entries per volume. (See afp-ls.maxfiles)
|
||||
--
|
||||
@@ -75,7 +75,7 @@ local function createFileTable()
|
||||
tab.add(filetab, 5, "TIME")
|
||||
tab.add(filetab, 6, "FILENAME")
|
||||
tab.nextrow(filetab)
|
||||
|
||||
|
||||
return filetab
|
||||
end
|
||||
|
||||
@@ -87,12 +87,12 @@ action = function(host, port)
|
||||
local users = nmap.registry.afp or { ['nil'] = 'nil' }
|
||||
local maxfiles = tonumber(stdnse.get_script_args("afp-ls.maxfiles") or 10)
|
||||
local output = {}
|
||||
|
||||
|
||||
if ( args['afp.username'] ) then
|
||||
users = {}
|
||||
users[args['afp.username']] = args['afp.password']
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for username, password in pairs(users) do
|
||||
|
||||
local status, response = afpHelper:OpenSession(host, port)
|
||||
@@ -124,7 +124,7 @@ action = function(host, port)
|
||||
if ( not(status) ) then
|
||||
return ("\n\nERROR: Failed to list the contents of %s"):format(vol)
|
||||
end
|
||||
|
||||
|
||||
local file_tab = createFileTable()
|
||||
local counter = maxfiles or 10
|
||||
for _, item in ipairs(tbl[1]) do
|
||||
@@ -139,7 +139,7 @@ action = function(host, port)
|
||||
if ( not(status) ) then
|
||||
return ("\n\nERROR: Failed to retreive file dates for %/%s"):format(vol, item.name)
|
||||
end
|
||||
|
||||
|
||||
tab.addrow(file_tab, result.privs, result.uid, result.gid, fsize, date.create, item.name)
|
||||
|
||||
counter = counter - 1
|
||||
@@ -152,10 +152,10 @@ action = function(host, port)
|
||||
table.insert(output, result_part)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
status, response = afpHelper:Logout()
|
||||
status, response = afpHelper:CloseSession()
|
||||
|
||||
|
||||
-- stop after first succesfull attempt
|
||||
if ( output and #output > 0 ) then
|
||||
table.insert(output, "")
|
||||
|
||||
@@ -5,7 +5,7 @@ local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
local vulns = require "vulns"
|
||||
|
||||
description = [[
|
||||
description = [[
|
||||
Detects the Mac OS X AFP directory traversal vulnerability, CVE-2010-0533.
|
||||
|
||||
This script attempts to iterate over all AFP shares on the remote
|
||||
@@ -32,7 +32,7 @@ For additional information:
|
||||
--@output
|
||||
-- PORT STATE SERVICE
|
||||
-- 548/tcp open afp
|
||||
-- | afp-path-vuln:
|
||||
-- | afp-path-vuln:
|
||||
-- | VULNERABLE:
|
||||
-- | Apple Mac OS X AFP server directory traversal
|
||||
-- | State: VULNERABLE (Exploitable)
|
||||
@@ -59,7 +59,7 @@ For additional information:
|
||||
-- Version 0.3
|
||||
--
|
||||
-- Created 02/09/2010 - v0.1 - created by Patrik Karlsson as PoC for Apple
|
||||
-- Revised 05/03/2010 - v0.2 - cleaned up and added dependency to afp-brute and added support
|
||||
-- Revised 05/03/2010 - v0.2 - cleaned up and added dependency to afp-brute and added support
|
||||
-- for credentials by argument or registry
|
||||
-- Revised 10/03/2010 - v0.3 - combined afp-path-exploit and afp-path-vuln into this script
|
||||
-- Revised 21/10/2011 - v0.4 - Use the vulnerability library vulns.lua
|
||||
@@ -96,10 +96,10 @@ local function processResponse( tbl, max_count, out, count )
|
||||
elseif( type(v) == 'table' ) then
|
||||
local tmp = {}
|
||||
table.insert( out, tmp )
|
||||
processResponse( v, max_count, tmp, count )
|
||||
processResponse( v, max_count, tmp, count )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- strip the outer table
|
||||
return out[1]
|
||||
end
|
||||
@@ -184,7 +184,7 @@ Directory traversal vulnerability in AFP Server in Apple Mac OS X before
|
||||
status, shares = afp_helper:ListShares()
|
||||
|
||||
for _, share in ipairs(shares) do
|
||||
|
||||
|
||||
local status, response = afp_helper:Dir( share .. "/../", { max_depth = 2 } )
|
||||
|
||||
if ( not(status) ) then
|
||||
@@ -209,7 +209,7 @@ Directory traversal vulnerability in AFP Server in Apple Mac OS X before
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ( vulnerable ) then
|
||||
afp_vuln.state = vulns.STATE.EXPLOIT
|
||||
else
|
||||
|
||||
@@ -57,15 +57,15 @@ action = function(host, port)
|
||||
local status
|
||||
local result = {}
|
||||
local temp
|
||||
|
||||
|
||||
-- set a reasonable timeout value
|
||||
socket:set_timeout(5000)
|
||||
|
||||
|
||||
-- do some exception handling / cleanup
|
||||
local catch = function()
|
||||
socket:close()
|
||||
end
|
||||
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
try( socket:connect(host, port) )
|
||||
@@ -75,10 +75,10 @@ action = function(host, port)
|
||||
|
||||
local response = afp_proto:fp_get_server_info( socket )
|
||||
response = response.result
|
||||
|
||||
|
||||
-- all the server information is output in the order it occurs in the server
|
||||
-- response. It might be better rearranged?
|
||||
|
||||
|
||||
-- output the server flags nicely
|
||||
table.insert(result, string.format("| Server Flags: 0x%04x", response.flags.raw))
|
||||
table.insert(result, string.format("| Super Client: %s", response.flags.SuperClient and "Yes" or "No"))
|
||||
@@ -92,12 +92,12 @@ action = function(host, port)
|
||||
table.insert(result, string.format("| ServerMessages: %s", response.flags.ServerMessages and "Yes" or "No"))
|
||||
table.insert(result, string.format("| Password Saving Prohibited: %s", response.flags.NoPasswordSaving and "Yes" or "No"))
|
||||
table.insert(result, string.format("| Password Changing: %s", response.flags.ChangeablePasswords and "Yes" or "No"))
|
||||
table.insert(result, string.format("|_ Copy File: %s", response.flags.CopyFile and "Yes" or "No"))
|
||||
table.insert(result, string.format("|_ Copy File: %s", response.flags.CopyFile and "Yes" or "No"))
|
||||
|
||||
-- other info
|
||||
table.insert(result, string.format("Server Name: %s", response.server_name))
|
||||
table.insert(result, string.format("Machine Type: %s", response.machine_type))
|
||||
|
||||
|
||||
-- list the supported AFP versions
|
||||
temp = "AFP Versions: "
|
||||
for i = 1, response.afp_version_count-1 do
|
||||
@@ -105,7 +105,7 @@ action = function(host, port)
|
||||
end
|
||||
temp = temp .. response.afp_versions[response.afp_version_count]
|
||||
table.insert(result, temp)
|
||||
|
||||
|
||||
-- list the supported UAMs (User Authentication Modules)
|
||||
temp = "UAMs: "
|
||||
for i = 1, response.uam_count-1 do
|
||||
@@ -113,28 +113,28 @@ action = function(host, port)
|
||||
end
|
||||
temp = temp .. response.uams[response.uam_count]
|
||||
table.insert(result, temp)
|
||||
|
||||
|
||||
-- server signature, not sure of the format here so just showing a hex string
|
||||
if response.flags.ServerSignature then
|
||||
table.insert(result, string.format("Server Signature: %s", stdnse.tohex(response.server_signature)))
|
||||
end
|
||||
|
||||
|
||||
-- listing the network addresses one line each
|
||||
-- the default for Mac OS X AFP server is to bind everywhere, so this will
|
||||
-- list all network interfaces that the machine has
|
||||
for i = 1, response.network_addresses_count do
|
||||
table.insert(result, string.format("Network Address %d: %s", i, response.network_addresses[i]))
|
||||
end
|
||||
|
||||
|
||||
-- similar to above
|
||||
for i = 1, response.directory_names_count do
|
||||
table.insert(result, string.format("Directory Name %d: %s", i, response.directory_names[i]))
|
||||
end
|
||||
|
||||
|
||||
-- and finally the utf8 server name
|
||||
if response.flags.UTF8ServerName then
|
||||
table.insert(result, string.format("UTF8 Server Name: %s", response.utf8_server_name))
|
||||
end
|
||||
|
||||
|
||||
return stdnse.format_output(true, result)
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ Shows AFP shares and ACLs.
|
||||
--@output
|
||||
-- PORT STATE SERVICE
|
||||
-- 548/tcp open afp
|
||||
-- | afp-showmount:
|
||||
-- | afp-showmount:
|
||||
-- | Yoda's Public Folder
|
||||
-- | Owner: Search,Read,Write
|
||||
-- | Group: Search,Read
|
||||
@@ -54,7 +54,7 @@ action = function(host, port)
|
||||
if ( args['afp.username'] ) then
|
||||
users = {}
|
||||
users[args['afp.username']] = args['afp.password']
|
||||
end
|
||||
end
|
||||
|
||||
for username, password in pairs(users) do
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Retrieves the authentication scheme and realm of an AJP service (Apache JServ Pr
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8009/tcp open ajp13
|
||||
-- | ajp-auth:
|
||||
-- | ajp-auth:
|
||||
-- |_ Digest opaque=GPui3SvCGBoHrRMMzSsgaYBV qop=auth nonce=1336063830612:935b5b389696b0f67b9193e19f47e037 realm=example.org
|
||||
--
|
||||
-- @args ajp-auth.path Define the request path
|
||||
@@ -34,11 +34,11 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
|
||||
|
||||
action = function(host, port)
|
||||
local helper = ajp.Helper:new(host, port)
|
||||
|
||||
|
||||
if ( not(helper:connect()) ) then
|
||||
return fail("Failed to connect to AJP server")
|
||||
end
|
||||
|
||||
|
||||
local status, answer = helper:get(arg_path or "/")
|
||||
|
||||
--- check for 401 response code
|
||||
|
||||
@@ -14,12 +14,12 @@ back-end Java application server containers.
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 8009 <ip> --script ajp-brute
|
||||
-- nmap -p 8009 <ip> --script ajp-brute
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8009/tcp open ajp13
|
||||
-- | ajp-brute:
|
||||
-- | ajp-brute:
|
||||
-- | Accounts
|
||||
-- | root:secret - Valid credentials
|
||||
-- | Statistics
|
||||
@@ -38,32 +38,32 @@ local arg_url = stdnse.get_script_args(SCRIPT_NAME .. ".path") or "/"
|
||||
local function fail(err) return ("\n ERROR: %s"):format(err or "") end
|
||||
|
||||
Driver = {
|
||||
|
||||
|
||||
new = function(self, host, port, options)
|
||||
local o = { host = host,
|
||||
port = port,
|
||||
options = options,
|
||||
local o = { host = host,
|
||||
port = port,
|
||||
options = options,
|
||||
helper = ajp.Helper:new(host, port)
|
||||
}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect = function(self)
|
||||
return self.helper:connect()
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function(self)
|
||||
return self.helper:close()
|
||||
end,
|
||||
|
||||
|
||||
login = function(self, user, pass)
|
||||
local headers = {
|
||||
["Authorization"] = ("Basic %s"):format(base64.enc(user .. ":" .. pass))
|
||||
}
|
||||
local status, response = self.helper:get(arg_url, headers)
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
local err = brute.Error:new( response )
|
||||
err:setRetry( true )
|
||||
@@ -83,7 +83,7 @@ action = function(host, port)
|
||||
if ( not(helper:connect()) ) then
|
||||
return fail("Failed to connect to server")
|
||||
end
|
||||
|
||||
|
||||
local status, response = helper:get(arg_url)
|
||||
if ( not(response.headers['www-authenticate']) ) then
|
||||
return "\n URL does not require authentication"
|
||||
@@ -97,14 +97,14 @@ action = function(host, port)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ( not(options.scheme) ) then
|
||||
return fail("Could not find a supported authentication scheme")
|
||||
end
|
||||
|
||||
|
||||
local engine = brute.Engine:new(Driver, host, port )
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
|
||||
local status, result = engine:start()
|
||||
if ( status ) then
|
||||
return result
|
||||
|
||||
@@ -14,13 +14,13 @@ optional directory of an Apache JServ Protocol server and returns the server res
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8009/tcp open ajp13
|
||||
-- | ajp-headers:
|
||||
-- | ajp-headers:
|
||||
-- | X-Powered-By: JSP/2.2
|
||||
-- | Set-Cookie: JSESSIONID=goTHax+8ktEcZsBldANHBAuf.undefined; Path=/helloworld
|
||||
-- | Content-Type: text/html;charset=ISO-8859-1
|
||||
-- |_ Content-Length: 149
|
||||
--
|
||||
-- @args ajp-headers.path The path to request, such as <code>/index.php</code>. Default <code>/</code>.
|
||||
-- @args ajp-headers.path The path to request, such as <code>/index.php</code>. Default <code>/</code>.
|
||||
|
||||
|
||||
portrule = shortport.port_or_service(8009, 'ajp13', 'tcp')
|
||||
@@ -40,7 +40,7 @@ action = function(host, port)
|
||||
|
||||
local status, response = helper:get(arg_path)
|
||||
helper:close()
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return fail("Failed to retrieve server headers")
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ http://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8009/tcp open ajp13
|
||||
-- | ajp-methods:
|
||||
-- | ajp-methods:
|
||||
-- | Supported methods: GET HEAD POST PUT DELETE TRACE OPTIONS
|
||||
-- | Potentially risky methods: PUT DELETE TRACE
|
||||
-- |_ See http://nmap.org/nsedoc/scripts/ajp-methods.html
|
||||
@@ -59,19 +59,19 @@ action = function(host, port)
|
||||
if ( not(helper:connect()) ) then
|
||||
return fail("Failed to connect to server")
|
||||
end
|
||||
|
||||
|
||||
local status, response = helper:options(arg_url)
|
||||
helper:close()
|
||||
if ( not(status) or response.status ~= 200 or
|
||||
if ( not(status) or response.status ~= 200 or
|
||||
not(response.headers) or not(response.headers['allow']) ) then
|
||||
return "Failed to get a valid response for the OPTION request"
|
||||
end
|
||||
|
||||
|
||||
local methods = stdnse.strsplit(",%s", response.headers['allow'])
|
||||
|
||||
local output = {}
|
||||
table.insert(output, ("Supported methods: %s"):format(stdnse.strjoin(" ", methods)))
|
||||
|
||||
|
||||
local interesting = filter_out(methods, UNINTERESTING_METHODS)
|
||||
if ( #interesting > 0 ) then
|
||||
table.insert(output, "Potentially risky methods: " .. stdnse.strjoin(" ", interesting))
|
||||
|
||||
@@ -19,12 +19,12 @@ back-end Java application server containers.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8009/tcp open ajp13
|
||||
-- | ajp-request:
|
||||
-- | ajp-request:
|
||||
-- | <!DOCTYPE HTML>
|
||||
-- | <html>
|
||||
-- | <head>
|
||||
-- | <title>JSP Test</title>
|
||||
-- |
|
||||
-- |
|
||||
-- | </head>
|
||||
-- | <body>
|
||||
-- | <h2>Hello, World.</h2>
|
||||
@@ -60,21 +60,21 @@ action = function(host, port)
|
||||
if ( not(helper:connect()) ) then
|
||||
return fail("Failed to connect to AJP server")
|
||||
end
|
||||
|
||||
|
||||
local valid_methods = {
|
||||
["GET"] = true,
|
||||
["HEAD"] = true,
|
||||
["HEAD"] = true,
|
||||
["TRACE"] = true,
|
||||
["PUT"] = true,
|
||||
["DELETE"] = true,
|
||||
["OPTIONS"]= true,
|
||||
}
|
||||
|
||||
|
||||
local method = arg_method:upper()
|
||||
if ( not(valid_methods[method]) ) then
|
||||
return fail(("Method not supported: %s"):format(arg_method))
|
||||
end
|
||||
|
||||
|
||||
local options = { auth = { username = arg_username, password = arg_password } }
|
||||
local status, response = helper:request(arg_method, arg_path, nil, nil, options)
|
||||
if ( not(status) ) then
|
||||
@@ -83,8 +83,8 @@ action = function(host, port)
|
||||
helper:close()
|
||||
|
||||
if ( response ) then
|
||||
local output = response['status-line'] .. "\n" ..
|
||||
stdnse.strjoin("\n", response.rawheaders) ..
|
||||
local output = response['status-line'] .. "\n" ..
|
||||
stdnse.strjoin("\n", response.rawheaders) ..
|
||||
(response.body and "\n\n" .. response.body or "")
|
||||
if ( arg_file ) then
|
||||
local f = io.open(arg_file, "w")
|
||||
|
||||
@@ -66,7 +66,7 @@ action = function(host, port)
|
||||
|
||||
owner = try(client_ident:receive_lines(1))
|
||||
|
||||
if string.match(owner, "ERROR") then
|
||||
if string.match(owner, "ERROR") then
|
||||
owner = nil
|
||||
else
|
||||
owner = string.match(owner,
|
||||
|
||||
@@ -20,15 +20,15 @@ the script against).
|
||||
--
|
||||
-- @arg backorifice-brute.ports (mandatory) List of UDP ports to run the script against separated with "," ex. "U:31337,25252,151-222", "U:1024-1512"
|
||||
--
|
||||
-- This script uses the brute library to perform password guessing. A
|
||||
-- successful password guess is stored in the nmap registry, under the
|
||||
-- <code>nmap.registry.credentials.backorifice</code> table for other BackOrifice
|
||||
-- This script uses the brute library to perform password guessing. A
|
||||
-- successful password guess is stored in the nmap registry, under the
|
||||
-- <code>nmap.registry.credentials.backorifice</code> table for other BackOrifice
|
||||
-- scripts to use.
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 31337/udp open BackOrifice
|
||||
-- | backorifice-brute:
|
||||
-- | backorifice-brute:
|
||||
-- | Accounts:
|
||||
-- | michael => Valid credentials
|
||||
-- | Statistics
|
||||
@@ -62,12 +62,12 @@ portrule = function(host, port)
|
||||
stdnse.print_debug("Port 31337/udp is open. Possibility of version detection and password bruteforcing using the backorifice-brute script")
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
return port.protocol == "udp" and stdnse.in_port_range(port, ports:gsub(",",",") ) and
|
||||
not(shortport.port_is_excluded(port.number,port.protocol))
|
||||
end
|
||||
|
||||
local backorifice =
|
||||
local backorifice =
|
||||
{
|
||||
new = function(self, host, port)
|
||||
local o = {}
|
||||
@@ -77,7 +77,7 @@ local backorifice =
|
||||
o.port = port
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
--- Initializes the backorifice object
|
||||
--
|
||||
initialize = function(self)
|
||||
@@ -86,8 +86,8 @@ local backorifice =
|
||||
self.socket:set_timeout(self.host.times.timeout * 1000)
|
||||
return true
|
||||
end,
|
||||
|
||||
--- Attempts to send an encrypted PING packet to BackOrifice service
|
||||
|
||||
--- Attempts to send an encrypted PING packet to BackOrifice service
|
||||
--
|
||||
-- @param password string containing password for encryption
|
||||
-- @param initial_seed number containing initial encryption seed
|
||||
@@ -97,26 +97,26 @@ local backorifice =
|
||||
--initialize BackOrifice PING packet: |MAGICSTRING|size|packetID|TYPE_PING|arg1|arg_separat|arg2|CRC/disregarded|
|
||||
local PING_PACKET = bin.pack("A<IICACAC", "*!*QWTY?", 19, 0, 0x01, "", 0x00, "", 0x00)
|
||||
local seed, status, response, encrypted_ping
|
||||
|
||||
if not(initial_seed) then
|
||||
|
||||
if not(initial_seed) then
|
||||
seed = self:gen_initial_seed(password)
|
||||
else
|
||||
seed = initial_seed
|
||||
end
|
||||
|
||||
|
||||
encrypted_ping = self:BOcrypt(PING_PACKET,seed)
|
||||
|
||||
|
||||
status, response = self.socket:sendto(self.host.ip, self.port.number, encrypted_ping)
|
||||
if not(status) then
|
||||
return false, response
|
||||
end
|
||||
status, response = self.socket:receive()
|
||||
|
||||
-- The first 8 bytes of both response and sent data are
|
||||
|
||||
-- The first 8 bytes of both response and sent data are
|
||||
-- magicstring = "*!*QWTY?", without the quotes, and since
|
||||
-- both are encrypted with the same initial seed, this is
|
||||
-- both are encrypted with the same initial seed, this is
|
||||
-- how we verify we are talking to a BackOrifice service.
|
||||
-- The statement is optimized so as not to decrypt unless
|
||||
-- The statement is optimized so as not to decrypt unless
|
||||
-- comparison of encrypted magicstrings succeds
|
||||
if status and response:sub(1,8) == encrypted_ping:sub(1,8)
|
||||
and self:BOcrypt(response,seed):match("!PONG!(1%.20)!.*!") then
|
||||
@@ -131,14 +131,14 @@ local backorifice =
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
--- Close the socket
|
||||
--
|
||||
-- @return status true on success, false on failure
|
||||
close = function(self)
|
||||
return self.socket:close()
|
||||
end,
|
||||
|
||||
|
||||
--- Generates the initial encryption seed from a password
|
||||
--
|
||||
-- @param password string containing password
|
||||
@@ -168,7 +168,7 @@ local backorifice =
|
||||
return z
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
--- Generates next encryption seed from given seed
|
||||
--
|
||||
-- @param seed number containing current seed
|
||||
@@ -178,7 +178,7 @@ local backorifice =
|
||||
seed = bit.band(seed,0xffffff)
|
||||
return seed
|
||||
end,
|
||||
|
||||
|
||||
--- Encrypts/decrypts data using BackOrifice algorithm
|
||||
--
|
||||
-- @param data binary string containing data to be encrypted/decrypted
|
||||
@@ -187,7 +187,7 @@ local backorifice =
|
||||
BOcrypt = function(self, data, initial_seed )
|
||||
if data==nil then return end
|
||||
|
||||
local output =""
|
||||
local output =""
|
||||
local seed = initial_seed
|
||||
local data_byte
|
||||
local crypto_byte
|
||||
@@ -203,20 +203,20 @@ local backorifice =
|
||||
crypto_byte = bit.bxor(data_byte,key)
|
||||
output = bin.pack("AC",output,crypto_byte)
|
||||
--ARGSIZE limitation from BackOrifice server
|
||||
if i == 256 then break end
|
||||
if i == 256 then break end
|
||||
end
|
||||
return output
|
||||
end,
|
||||
|
||||
|
||||
insert_version_info = function(self,BOversion,BOhostname,initial_seed,password)
|
||||
if not self.port.version then self.port.version={} end
|
||||
if not self.port.version.name then
|
||||
if not self.port.version.name then
|
||||
self.port.version.name ="BackOrifice"
|
||||
self.port.version.name_confidence = 10
|
||||
end
|
||||
if not self.port.version.product then self.port.version.product ="BackOrifice trojan" end
|
||||
if not self.port.version.version then self.port.version.version = BOversion end
|
||||
if not self.port.version.extrainfo then
|
||||
if not self.port.version.extrainfo then
|
||||
if not password then
|
||||
if not initial_seed then
|
||||
self.port.version.extrainfo = "no password"
|
||||
@@ -235,7 +235,7 @@ local backorifice =
|
||||
}
|
||||
|
||||
local Driver =
|
||||
{
|
||||
{
|
||||
new = function(self, host, port)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
@@ -244,18 +244,18 @@ local Driver =
|
||||
o.port = port
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect=function(self)
|
||||
--only initialize since BackOrifice service knows no connect()
|
||||
self.bo = backorifice:new(self.host,self.port)
|
||||
self.bo:initialize()
|
||||
return true
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function( self )
|
||||
self.bo:close()
|
||||
end,
|
||||
|
||||
|
||||
--- Attempts to send encrypted PING packet to BackOrifice service
|
||||
--
|
||||
-- @param username string containing username which is disregarded
|
||||
@@ -273,26 +273,26 @@ local Driver =
|
||||
end
|
||||
table.insert( nmap.registry.credentials.backorifice, { password = password } )
|
||||
return true, brute.Account:new("", password, creds.State.VALID)
|
||||
else
|
||||
else
|
||||
-- The only indication that the password is incorrect is a timeout
|
||||
local err = brute.Error:new( "Incorrect password" )
|
||||
err:setRetry(false)
|
||||
return false, err
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
action = function( host, port )
|
||||
|
||||
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver,host,port)
|
||||
|
||||
|
||||
engine.options.firstonly = true
|
||||
engine.options.passonly = true
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
|
||||
status, result = engine:start()
|
||||
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -234,13 +234,13 @@ end
|
||||
|
||||
local function insert_version_info(host,port,BOversion,BOhostname,initial_seed,password)
|
||||
if(port.version==nil) then port.version={} end
|
||||
if(port.version.name==nil) then
|
||||
if(port.version.name==nil) then
|
||||
port.version.name ="BackOrifice"
|
||||
port.version.name_confidence = 10
|
||||
end
|
||||
if(port.version.product==nil) then port.version.product ="BackOrifice trojan" end
|
||||
if(port.version.version == nil) then port.version.version = BOversion end
|
||||
if(port.version.extrainfo == nil) then
|
||||
if(port.version.extrainfo == nil) then
|
||||
if password == nil then
|
||||
if initial_seed == nil then
|
||||
port.version.extrainfo = "no password"
|
||||
@@ -286,18 +286,18 @@ action = function( host, port )
|
||||
if p_type ~= TYPE.ERROR then
|
||||
local tmp_str = cmds[i].filter(response)
|
||||
if tmp_str ~= nil then
|
||||
if cmds[i].p_code==TYPE.PING then
|
||||
if cmds[i].p_code==TYPE.PING then
|
||||
--invalid chars for hostname are allowed on old windows boxes
|
||||
local BOversion, BOhostname = string.match(tmp_str,"!PONG!(1%.20)!(.*)!")
|
||||
if BOversion==nil then
|
||||
if BOversion==nil then
|
||||
--in case of bad PING reply return ""
|
||||
return
|
||||
return
|
||||
else
|
||||
--fill up version information
|
||||
insert_version_info(host,port,BOversion,BOhostname,initial_seed,password)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
table.insert(output,tmp_str)
|
||||
end
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Queries a Bitcoin server for a list of known Bitcoin nodes
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8333/tcp open unknown
|
||||
-- | bitcoin-getaddr:
|
||||
-- | bitcoin-getaddr:
|
||||
-- | ip timestamp
|
||||
-- | 10.10.10.10:8333 11/09/11 17:38:00
|
||||
-- | 10.10.10.11:8333 11/09/11 17:42:39
|
||||
@@ -32,26 +32,26 @@ categories = {"discovery", "safe"}
|
||||
|
||||
--
|
||||
-- Version 0.1
|
||||
--
|
||||
--
|
||||
-- Created 11/09/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
--
|
||||
|
||||
portrule = shortport.port_or_service(8333, "bitcoin", "tcp" )
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
|
||||
local bcoin = bitcoin.Helper:new(host, port, { timeout = 20000 })
|
||||
local status = bcoin:connect()
|
||||
|
||||
if ( not(status) ) then
|
||||
return "\n ERROR: Failed to connect to server"
|
||||
end
|
||||
|
||||
|
||||
local status, ver = bcoin:exchVersion()
|
||||
if ( not(status) ) then
|
||||
return "\n ERROR: Failed to extract version information"
|
||||
end
|
||||
|
||||
|
||||
local status, nodes = bcoin:getNodes()
|
||||
if ( not(status) ) then
|
||||
return "\n ERROR: Failed to extract address information"
|
||||
|
||||
@@ -14,7 +14,7 @@ Extracts version and node information from a Bitcoin server
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8333/tcp open unknown
|
||||
-- | bitcoin-info:
|
||||
-- | bitcoin-info:
|
||||
-- | Timestamp: Wed Nov 9 19:47:23 2011
|
||||
-- | Network: main
|
||||
-- | Version: 0.4.0
|
||||
@@ -28,7 +28,7 @@ categories = {"discovery", "safe"}
|
||||
|
||||
--
|
||||
-- Version 0.1
|
||||
--
|
||||
--
|
||||
-- Created 11/09/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
--
|
||||
|
||||
@@ -37,18 +37,18 @@ portrule = shortport.port_or_service(8333, "bitcoin", "tcp" )
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local NETWORK = {
|
||||
local NETWORK = {
|
||||
[3652501241] = "main",
|
||||
[3669344250] = "testnet"
|
||||
}
|
||||
|
||||
|
||||
local bcoin = bitcoin.Helper:new(host, port, { timeout = 10000 })
|
||||
local status = bcoin:connect()
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return "\n ERROR: Failed to connect to server"
|
||||
end
|
||||
|
||||
|
||||
local status, ver = bcoin:exchVersion()
|
||||
if ( not(status) ) then
|
||||
return "\n ERROR: Failed to extract version information"
|
||||
@@ -61,6 +61,6 @@ action = function(host, port)
|
||||
table.insert(result, ("Version: %s"):format(ver.ver))
|
||||
table.insert(result, ("Node Id: %s"):format(ver.nodeid))
|
||||
table.insert(result, ("Lastblock: %s"):format(ver.lastblock))
|
||||
|
||||
|
||||
return stdnse.format_output(true, result)
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ Obtains information from a Bitcoin server by calling <code>getinfo</code> on its
|
||||
-- @args creds.global http credentials used for the query (user:pass)
|
||||
-- @output
|
||||
-- 8332/tcp open unknown
|
||||
-- | bitcoinrpc-info.nse:
|
||||
-- | bitcoinrpc-info.nse:
|
||||
-- | USER: root
|
||||
-- | connections: 36
|
||||
-- | hashespersec: 0
|
||||
|
||||
@@ -13,12 +13,12 @@ include-nodes NSE argument is given) implement the DHT protocol and
|
||||
are used to track the peers. The sets of peers and nodes are not the
|
||||
same, but they usually intersect.
|
||||
|
||||
If the <code>newtargets</code> script-arg is supplied it adds the discovered
|
||||
If the <code>newtargets</code> script-arg is supplied it adds the discovered
|
||||
peers as targets.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- @usage
|
||||
-- nmap --script bittorrent-discovery --script-args newtargets,bittorrent-discovery.torrent=<torrent_file>
|
||||
--
|
||||
-- @args bittorrent-discovery.torrent a string containing the filename of the torrent file
|
||||
@@ -63,7 +63,7 @@ action = function()
|
||||
local filename = stdnse.get_script_args(SCRIPT_NAME..".torrent")
|
||||
local magnet = stdnse.get_script_args(SCRIPT_NAME..".magnet")
|
||||
local include_nodes = stdnse.get_script_args(SCRIPT_NAME..".include-nodes")
|
||||
|
||||
|
||||
local t = bittorrent.Torrent:new()
|
||||
if filename then
|
||||
t:load_from_file(filename)
|
||||
@@ -72,13 +72,13 @@ action = function()
|
||||
end
|
||||
t:trackers_peers()
|
||||
t:dht_peers(timeout)
|
||||
|
||||
|
||||
local output = {}
|
||||
local peers = {}
|
||||
peers.name = "Peers:"
|
||||
local nodes = {}
|
||||
nodes.name = "Nodes:"
|
||||
|
||||
|
||||
-- add peers
|
||||
if target.ALLOW_NEW_TARGETS then
|
||||
for peer_ip in pairs(t.peers) do
|
||||
@@ -90,13 +90,13 @@ action = function()
|
||||
end
|
||||
else
|
||||
for peer_ip in pairs(t.peers) do
|
||||
table.insert(peers, peer_ip)
|
||||
table.insert(peers, peer_ip)
|
||||
end
|
||||
if #peers>0 then
|
||||
table.insert(peers, "Total of "..#peers.." peers discovered")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- add nodes
|
||||
if target.ALLOW_NEW_TARGETS and include_nodes then
|
||||
for node_ip in pairs(t.nodes) do
|
||||
@@ -114,10 +114,10 @@ action = function()
|
||||
table.insert(nodes, "Total of "..#nodes.." nodes discovered")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local print_out = false
|
||||
|
||||
if #peers > 0 then
|
||||
if #peers > 0 then
|
||||
table.insert(output, peers)
|
||||
print_out = true
|
||||
end
|
||||
@@ -126,7 +126,7 @@ action = function()
|
||||
table.insert(output, nodes)
|
||||
print_out = true
|
||||
end
|
||||
|
||||
|
||||
if print_out and not target.ALLOW_NEW_TARGETS then
|
||||
table.insert(output,"Use the newtargets script-arg to add the results as targets")
|
||||
end
|
||||
|
||||
@@ -11,14 +11,14 @@ devices.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8611/udp open canon-bjnp1
|
||||
-- | bjnp-discover:
|
||||
-- | bjnp-discover:
|
||||
-- | Manufacturer: Canon
|
||||
-- | Model: MG5200 series
|
||||
-- | Description: Canon MG5200 series
|
||||
-- | Firmware version: 1.050
|
||||
-- |_ Command: BJL,BJRaster3,BSCCe,NCCe,IVEC,IVECPLI
|
||||
-- 8612/udp open canon-bjnp2
|
||||
-- | bjnp-discover:
|
||||
-- | bjnp-discover:
|
||||
-- | Manufacturer: Canon
|
||||
-- | Model: MG5200 series
|
||||
-- | Description: Canon MG5200 series
|
||||
|
||||
@@ -14,7 +14,7 @@ simple, high-performance access to SATA drives over Ethernet.
|
||||
|
||||
Discovery is performed by sending a Query Config Request to the Ethernet
|
||||
broadcast address with all bits set in the major and minor fields of the
|
||||
header.
|
||||
header.
|
||||
]]
|
||||
|
||||
---
|
||||
@@ -23,7 +23,7 @@ header.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-ataoe-discover:
|
||||
-- | broadcast-ataoe-discover:
|
||||
-- |_ Server: 08:00:27:12:34:56; Version: 1; Major: 0; Minor: 1
|
||||
--
|
||||
|
||||
@@ -36,13 +36,13 @@ prerule = function() return true end
|
||||
|
||||
-- The minimalistic ATAoE interface
|
||||
ATAoE = {
|
||||
|
||||
|
||||
-- Supported commands
|
||||
Cmd = {
|
||||
QUERY_CONFIG_INFORMATION = 1,
|
||||
},
|
||||
|
||||
Header = {
|
||||
|
||||
Header = {
|
||||
-- creates a new Header instance
|
||||
new = function(self, cmd, tag)
|
||||
local o = {
|
||||
@@ -52,48 +52,48 @@ ATAoE = {
|
||||
minor = 0xff,
|
||||
error = 0,
|
||||
cmd = ATAoE.Cmd.QUERY_CONFIG_INFORMATION,
|
||||
tag = tag or createRandomTag(),
|
||||
tag = tag or createRandomTag(),
|
||||
}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
-- parses a raw string of data and creates a new Header instance
|
||||
-- @return header new instance of header
|
||||
parse = function(data)
|
||||
local header = ATAoE.Header:new()
|
||||
local pos, verflags
|
||||
|
||||
pos, verflags, header.error,
|
||||
|
||||
pos, verflags, header.error,
|
||||
header.major, header.minor,
|
||||
header.cmd, header.tag = bin.unpack(">CCSCCI", data)
|
||||
header.cmd, header.tag = bin.unpack(">CCSCCI", data)
|
||||
header.version = bit.rshift(verflags, 4)
|
||||
header.flags = bit.band(verflags, 0x0F)
|
||||
return header
|
||||
end,
|
||||
|
||||
|
||||
-- return configuration info request as string
|
||||
__tostring = function(self)
|
||||
assert(self.tag, "No tag was specified in Config Info Request")
|
||||
local verflags = bit.lshift(self.version, 4)
|
||||
return bin.pack(">CCSCCI", verflags, self.error, self.major, self.minor, self.cmd, self.tag)
|
||||
end,
|
||||
end,
|
||||
},
|
||||
|
||||
|
||||
-- The Configuration Info Request
|
||||
ConfigInfoRequest = {
|
||||
new = function(self, tag)
|
||||
local o = {
|
||||
local o = {
|
||||
header = ATAoE.Header:new(ATAoE.Cmd.QUERY_CONFIG_INFORMATION, tag)
|
||||
}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
__tostring = function(self)
|
||||
return tostring(self.header)
|
||||
return tostring(self.header)
|
||||
end,
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ local function sendConfigInfoRequest(iface)
|
||||
p.ether_type = bin.pack(">S", P_ATAOE)
|
||||
p.buf = tostring(req)
|
||||
p:build_ether_frame()
|
||||
|
||||
|
||||
local dnet = nmap.new_dnet()
|
||||
dnet:ethernet_open(iface.device)
|
||||
dnet:ethernet_send(p.frame_buf)
|
||||
@@ -134,13 +134,13 @@ action = function()
|
||||
stdnse.print_debug("%s: No interface supplied, use -e", SCRIPT_NAME)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if ( not(nmap.is_privileged()) ) then
|
||||
stdnse.print_debug("%s: not running for lack of privileges", SCRIPT_NAME)
|
||||
return
|
||||
end
|
||||
|
||||
local iface = nmap.get_interface_info(iname)
|
||||
|
||||
local iface = nmap.get_interface_info(iname)
|
||||
if ( not(iface) ) then
|
||||
return fail("Failed to retrieve interface information")
|
||||
end
|
||||
@@ -148,13 +148,13 @@ action = function()
|
||||
local pcap = nmap.new_socket()
|
||||
pcap:set_timeout(5000)
|
||||
pcap:pcap_open(iface.device, 1500, true, "ether proto 0x88a2 && !ether src " .. stdnse.format_mac(iface.mac))
|
||||
|
||||
|
||||
sendConfigInfoRequest(iface)
|
||||
|
||||
local result = {}
|
||||
repeat
|
||||
local status, len, l2_data, l3_data = pcap:pcap_receive()
|
||||
|
||||
|
||||
if ( status ) then
|
||||
local header = ATAoE.Header.parse(l3_data)
|
||||
local f = packet.Frame:new(l2_data)
|
||||
|
||||
@@ -16,7 +16,7 @@ vulnerable.
|
||||
|
||||
Reference:
|
||||
* http://avahi.org/ticket/325
|
||||
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1002
|
||||
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1002
|
||||
]]
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Reference:
|
||||
-- nmap --script=broadcast-avahi-dos
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-avahi-dos:
|
||||
-- | broadcast-avahi-dos:
|
||||
-- | Discovered hosts:
|
||||
-- | 10.0.1.150
|
||||
-- | 10.0.1.151
|
||||
@@ -55,7 +55,7 @@ action = function()
|
||||
local wtime = stdnse.get_script_args("broadcast-avahi-dos.wait") or 20
|
||||
local helper = dnssd.Helper:new()
|
||||
helper:setMulticast(true)
|
||||
|
||||
|
||||
local status, result = helper:queryServices()
|
||||
if (status) then
|
||||
local output, hosts, tmp = {}, {}, {}
|
||||
@@ -88,7 +88,7 @@ action = function()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vulns = {}
|
||||
for ip, _ in pairs(tmp) do
|
||||
@@ -101,7 +101,7 @@ action = function()
|
||||
else
|
||||
table.insert(output, "Hosts are all up (not vulnerable).")
|
||||
end
|
||||
|
||||
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ information for all discovered devices.
|
||||
-- nmap --script broadcast-bjnp-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-bjnp-discover:
|
||||
-- | broadcast-bjnp-discover:
|
||||
-- | 192.168.0.10
|
||||
-- | Printer
|
||||
-- | Manufacturer: Canon
|
||||
@@ -75,7 +75,7 @@ local function identifyDevices(devices, devtype)
|
||||
end
|
||||
|
||||
local function identifyScanners(scanners)
|
||||
return identifyDevices(scanners, "scanners")
|
||||
return identifyDevices(scanners, "scanners")
|
||||
end
|
||||
|
||||
local function identifyPrinters(printers)
|
||||
@@ -136,10 +136,10 @@ action = function()
|
||||
|
||||
local co = stdnse.new_thread(getPrinters, devices)
|
||||
threads[co] = true
|
||||
|
||||
|
||||
co = stdnse.new_thread(getScanners, devices)
|
||||
threads[co] = true
|
||||
|
||||
|
||||
while(next(threads)) do
|
||||
for t in pairs(threads) do
|
||||
threads[t] = ( coroutine.status(t) ~= "dead" ) and true or nil
|
||||
@@ -148,12 +148,12 @@ action = function()
|
||||
condvar "wait"
|
||||
end
|
||||
end
|
||||
|
||||
for ip in getKeys(devices) do
|
||||
|
||||
for ip in getKeys(devices) do
|
||||
local result_part = {}
|
||||
local printer = ( devices["printers"] and devices["printers"][ip] )
|
||||
local scanner = ( devices["scanners"] and devices["scanners"][ip] )
|
||||
|
||||
|
||||
if ( printer ) then
|
||||
printer.name = "Printer"
|
||||
table.insert(result_part, printer)
|
||||
@@ -167,7 +167,7 @@ action = function()
|
||||
table.insert(result, result_part)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ( result ) then
|
||||
return stdnse.format_output(true, result)
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ Attempts to discover DB2 servers on the network by sending a broadcast request t
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-db2-discover:
|
||||
-- | broadcast-db2-discover:
|
||||
-- | 10.0.200.132 (UBU804-DB2E) - IBM DB2 v9.07.0
|
||||
-- |_ 10.0.200.119 (EDUSRV011) - IBM DB2 v9.07.0
|
||||
|
||||
@@ -38,7 +38,7 @@ local function parseVersion( server_version )
|
||||
if pfx == "SQL" then
|
||||
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
|
||||
if string.sub(major_version,1,1) == "0" then
|
||||
major_version = string.sub(major_version,2)
|
||||
@@ -49,7 +49,7 @@ local function parseVersion( server_version )
|
||||
else
|
||||
return "Unknown version"
|
||||
end
|
||||
|
||||
|
||||
return ("IBM DB2 v%s"):format(server_version)
|
||||
end
|
||||
|
||||
@@ -68,19 +68,19 @@ action = function()
|
||||
local data
|
||||
status, data = socket:receive()
|
||||
if( not(status) ) then break end
|
||||
|
||||
|
||||
local version, srvname = data:match("DB2RETADDR.(SQL%d+).(.-)\0")
|
||||
local _, ip
|
||||
status, _, _, ip, _ = socket:get_info()
|
||||
if ( not(status) ) then return end
|
||||
|
||||
|
||||
if target.ALLOW_NEW_TARGETS then target.add(ip) end
|
||||
|
||||
if ( status ) then
|
||||
table.insert( result, ("%s - Host: %s; Version: %s"):format(ip, srvname, parseVersion( version ) ) )
|
||||
end
|
||||
end
|
||||
socket:close()
|
||||
socket:close()
|
||||
|
||||
return stdnse.format_output( true, result )
|
||||
end
|
||||
|
||||
@@ -25,9 +25,9 @@ The script needs to be run as a privileged user, typically root.
|
||||
---
|
||||
-- @usage
|
||||
-- sudo nmap --script broadcast-dhcp-discover
|
||||
--
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-dhcp-discover:
|
||||
-- | broadcast-dhcp-discover:
|
||||
-- | IP Offered: 192.168.1.114
|
||||
-- | DHCP Message Type: DHCPOFFER
|
||||
-- | Server Identifier: 192.168.1.1
|
||||
@@ -70,7 +70,7 @@ local function randomizeMAC()
|
||||
local mac_addr = ""
|
||||
for j=1, 6 do
|
||||
mac_addr = mac_addr .. string.char(math.random(1, 255))
|
||||
end
|
||||
end
|
||||
return mac_addr
|
||||
end
|
||||
|
||||
@@ -92,7 +92,7 @@ local function getInterfaces(link, up)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
-- Listens for an incoming dhcp response
|
||||
--
|
||||
@@ -102,9 +102,9 @@ end
|
||||
-- @param result a table to which the result is written
|
||||
local function dhcp_listener(sock, timeout, xid, result)
|
||||
local condvar = nmap.condvar(result)
|
||||
|
||||
|
||||
sock:set_timeout(100)
|
||||
|
||||
|
||||
local start_time = nmap.clock_ms()
|
||||
while( nmap.clock_ms() - start_time < timeout ) do
|
||||
local status, _, _, data = sock:pcap_receive()
|
||||
@@ -114,7 +114,7 @@ local function dhcp_listener(sock, timeout, xid, result)
|
||||
condvar "signal"
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if ( status ) then
|
||||
local p = packet.Packet:new( data, #data )
|
||||
if ( p and p.udp_dport ) then
|
||||
@@ -144,9 +144,9 @@ action = function()
|
||||
-- if ran multiple times, so we should probably refrain from doing
|
||||
-- this?
|
||||
local mac = string.char(0xDE,0xAD,0xC0,0xDE,0xCA,0xFE)--randomizeMAC()
|
||||
|
||||
|
||||
local interfaces
|
||||
|
||||
|
||||
-- first check if the user supplied an interface
|
||||
if ( nmap.get_interface() ) then
|
||||
interfaces = { [nmap.get_interface()] = true }
|
||||
@@ -159,7 +159,7 @@ action = function()
|
||||
end
|
||||
|
||||
if( not(interfaces) ) then return "\n ERROR: Failed to retrieve interfaces (try setting one explicitly using -e)" end
|
||||
|
||||
|
||||
local transaction_id = bin.pack("<I", math.random(0, 0x7FFFFFFF))
|
||||
local request_type = dhcp.request_types["DHCPDISCOVER"]
|
||||
local ip_address = bin.pack(">I", ipOps.todword("0.0.0.0"))
|
||||
@@ -172,7 +172,7 @@ action = function()
|
||||
local threads = {}
|
||||
local result = {}
|
||||
local condvar = nmap.condvar(result)
|
||||
|
||||
|
||||
-- start a listening thread for each interface
|
||||
for iface, _ in pairs(interfaces) do
|
||||
local sock, co
|
||||
@@ -186,9 +186,9 @@ action = function()
|
||||
socket:bind(nil, 68)
|
||||
socket:sendto( host, port, packet )
|
||||
socket:close()
|
||||
|
||||
|
||||
-- wait until all threads are done
|
||||
repeat
|
||||
repeat
|
||||
for thread in pairs(threads) do
|
||||
if coroutine.status(thread) == "dead" then threads[thread] = nil end
|
||||
end
|
||||
@@ -196,7 +196,7 @@ action = function()
|
||||
condvar "wait"
|
||||
end
|
||||
until next(threads) == nil
|
||||
|
||||
|
||||
local response = {}
|
||||
-- Display the results
|
||||
for i, r in ipairs(result) do
|
||||
@@ -209,5 +209,5 @@ action = function()
|
||||
end
|
||||
end
|
||||
end
|
||||
return stdnse.format_output(true, response)
|
||||
return stdnse.format_output(true, response)
|
||||
end
|
||||
|
||||
@@ -18,7 +18,7 @@ to a privileged port (udp/546).
|
||||
-- nmap -6 --script broadcast-dhcp6-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-dhcp6-discover:
|
||||
-- | broadcast-dhcp6-discover:
|
||||
-- | Interface: en0
|
||||
-- | Message type: Advertise
|
||||
-- | Transaction id: 74401
|
||||
@@ -76,7 +76,7 @@ local function solicit(iface, result)
|
||||
condvar "signal"
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local status, response = helper:solicit()
|
||||
if ( status ) then
|
||||
response.name=("Interface: %s"):format(iface)
|
||||
@@ -101,7 +101,7 @@ action = function(host, port)
|
||||
local co = stdnse.new_thread( solicit, iface, result )
|
||||
threads[co] = true
|
||||
end
|
||||
|
||||
|
||||
-- wait until the probes are all done
|
||||
repeat
|
||||
for thread in pairs(threads) do
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local dnssd = require "dnssd"
|
||||
local stdnse = require "stdnse"
|
||||
|
||||
description=[[
|
||||
description=[[
|
||||
Attempts to discover hosts' services using the DNS Service Discovery protocol. It sends a multicast DNS-SD query and collects all the responses.
|
||||
|
||||
The script first sends a query for _services._dns-sd._udp.local to get a
|
||||
@@ -15,7 +15,7 @@ get more information.
|
||||
-- nmap --script=broadcast-dns-service-discovery
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-dns-service-discovery:
|
||||
-- | broadcast-dns-service-discovery:
|
||||
-- | 1.2.3.1
|
||||
-- | _ssh._tcp.local
|
||||
-- | _http._tcp.local
|
||||
@@ -49,9 +49,9 @@ prerule = function() return true end
|
||||
action = function()
|
||||
local helper = dnssd.Helper:new( )
|
||||
helper:setMulticast(true)
|
||||
|
||||
|
||||
local status, result = helper:queryServices()
|
||||
if ( status ) then
|
||||
if ( status ) then
|
||||
return stdnse.format_output(true, result)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,12 +16,12 @@ If the <code>newtargets</code> script argument is given, all discovered Dropbox
|
||||
-- nmap --script=broadcast-dropbox-listener --script-args=newtargets -Pn
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-dropbox-listener:
|
||||
-- | broadcast-dropbox-listener:
|
||||
-- | displayname ip port version host_int namespaces
|
||||
-- |_noob 192.168.0.110 17500 1.8 34176083 26135075
|
||||
--
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-dropbox-listener:
|
||||
-- | broadcast-dropbox-listener:
|
||||
-- | displayname ip port version host_int namespaces
|
||||
-- |_noob 192.168.0.110 17500 1.8 34176083 26135075
|
||||
-- Nmap scan report for 192.168.0.110
|
||||
|
||||
@@ -37,7 +37,7 @@ through all valid ethernet interfaces simultaneously.
|
||||
-- @args broadcast-eigrp-discovery.timeout Max amount of time to listen for A.S
|
||||
-- announcements and updates. Defaults to <code>10</code> seconds.
|
||||
--
|
||||
-- @args broadcast-eigrp-discovery.kparams the K metrics.
|
||||
-- @args broadcast-eigrp-discovery.kparams the K metrics.
|
||||
-- Defaults to <code>101000</code>.
|
||||
-- @args broadcast-eigrp-discovery.interface Interface to send on (overrides -e)
|
||||
--
|
||||
@@ -45,7 +45,7 @@ through all valid ethernet interfaces simultaneously.
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-eigrp-discovery:
|
||||
-- | 192.168.2.2
|
||||
-- | Interface: eth0
|
||||
-- | Interface: eth0
|
||||
-- | A.S: 1
|
||||
-- | Virtual Router ID: 0
|
||||
-- | Internal Route
|
||||
@@ -134,7 +134,7 @@ local eigrpListener = function(interface, timeout, responses)
|
||||
if status then
|
||||
p = packet.Packet:new(l3data, #l3data)
|
||||
eigrp_raw = string.sub(l3data, p.ip_hl*4 + 1)
|
||||
-- Check if it is an EIGRPv2 Update
|
||||
-- Check if it is an EIGRPv2 Update
|
||||
if eigrp_raw:byte(1) == 0x02 and eigrp_raw:byte(2) == 0x01 then
|
||||
-- Skip if did get the info from this router before
|
||||
if not routers[p.ip_src] then
|
||||
@@ -230,7 +230,7 @@ action = function()
|
||||
local ifacelist = nmap.list_interfaces()
|
||||
for _, iface in ipairs(ifacelist) do
|
||||
-- Match all ethernet interfaces
|
||||
if iface.address and iface.link=="ethernet" and
|
||||
if iface.address and iface.link=="ethernet" and
|
||||
iface.address:match("%d+%.%d+%.%d+%.%d+") then
|
||||
|
||||
stdnse.print_debug("%s: Will use %s interface.", SCRIPT_NAME, iface.shortname)
|
||||
|
||||
@@ -15,7 +15,7 @@ Discovers targets that have IGMP Multicast memberships and grabs interesting inf
|
||||
The scripts works by sending IGMP Membership Query message to the 224.0.0.1 All
|
||||
Hosts multicast address and listening for IGMP Membership Report messages. The
|
||||
script then extracts all the interesting information from the report messages
|
||||
such as the version, group, mode, source addresses (depending on the version).
|
||||
such as the version, group, mode, source addresses (depending on the version).
|
||||
|
||||
The script defaults to sending an IGMPv2 Query but this could be changed to
|
||||
another version (version 1 or 3) or to sending queries of all three version. If
|
||||
@@ -43,7 +43,7 @@ interfaces.
|
||||
--
|
||||
--@output
|
||||
--Pre-scan script results:
|
||||
-- | broadcast-igmp-discovery:
|
||||
-- | broadcast-igmp-discovery:
|
||||
-- | 192.168.2.2
|
||||
-- | Interface: tap0
|
||||
-- | Version: 3
|
||||
@@ -71,9 +71,9 @@ interfaces.
|
||||
-- |_ Use the newtargets script-arg to add the results as targets
|
||||
--
|
||||
|
||||
--
|
||||
--
|
||||
-- The Multicast Group names DB can be created by the following script:
|
||||
--
|
||||
--
|
||||
-- #!/usr/bin/awk -f
|
||||
-- BEGIN { FS="<|>"; }
|
||||
-- /<record/ { r=1; addr1=""; addr2=""; rfc=""; }
|
||||
@@ -226,7 +226,7 @@ local igmpRaw = function(interface, version)
|
||||
|
||||
if version == 3 then
|
||||
-- Reserved = 4 bits (Should be zeroed)
|
||||
-- Supress Flag = 1 bit
|
||||
-- Supress Flag = 1 bit
|
||||
-- QRV (Querier's Robustness Variable) = 3 bits
|
||||
-- all are set to 0
|
||||
igmp_raw = igmp_raw .. bin.pack(">C", 0x00)
|
||||
@@ -270,7 +270,7 @@ igmpQuery = function(interface, version)
|
||||
|
||||
local sock = nmap.new_dnet()
|
||||
sock:ethernet_open(interface.device)
|
||||
|
||||
|
||||
-- Ethernet IPv4 multicast, our ethernet address and type IP
|
||||
local eth_hdr = bin.pack("HAH", "01 00 5e 00 00 01", interface.mac, "08 00")
|
||||
sock:ethernet_send(eth_hdr .. igmp_packet.buf)
|
||||
@@ -346,7 +346,7 @@ action = function(host, port)
|
||||
local ifacelist = nmap.list_interfaces()
|
||||
for _, iface in ipairs(ifacelist) do
|
||||
-- Match all ethernet interfaces
|
||||
if iface.address and iface.link=="ethernet" and
|
||||
if iface.address and iface.link=="ethernet" and
|
||||
iface.address:match("%d+%.%d+%.%d+%.%d+") then
|
||||
|
||||
stdnse.print_debug("%s: Will use %s interface.", SCRIPT_NAME, iface.shortname)
|
||||
@@ -414,7 +414,7 @@ action = function(host, port)
|
||||
sourcetable = {}
|
||||
sourcetable.name = "Sources:"
|
||||
table.insert(sourcetable, group.src)
|
||||
table.insert(grouptable, sourcetable)
|
||||
table.insert(grouptable, sourcetable)
|
||||
end
|
||||
table.insert(result, grouptable)
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ local packet = require "packet"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
|
||||
description = [[
|
||||
description = [[
|
||||
Sniffs the network for incoming broadcast communication and
|
||||
attempts to decode the received packets. It supports protocols like CDP, HSRP,
|
||||
Spotify, DropBox, DHCP, ARP and a few more. See packetdecoders.lua for more
|
||||
@@ -22,7 +22,7 @@ unless a specific interface was given using the -e argument to Nmap.
|
||||
-- nmap --script broadcast-listener -e eth0
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-listener:
|
||||
-- | broadcast-listener:
|
||||
-- | udp
|
||||
-- | Netbios
|
||||
-- | ip query
|
||||
@@ -63,13 +63,13 @@ unless a specific interface was given using the -e argument to Nmap.
|
||||
-- ether decoders are triggered by a pattern match. The port or pattern is used
|
||||
-- as an index in a table containing functions to process packets and fetch
|
||||
-- the decoded results.
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- Version 0.1
|
||||
-- Created 07/02/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 07/25/2011 - v0.2 -
|
||||
-- Revised 07/25/2011 - v0.2 -
|
||||
-- * added more documentation
|
||||
-- * added getInterfaces code to detect available
|
||||
-- interfaces.
|
||||
@@ -114,7 +114,7 @@ loadDecoders = function(fname)
|
||||
stdnse.print_debug("%s: Couldn't load decoder file: %s", SCRIPT_NAME, fname)
|
||||
return false, "ERROR: Couldn't load decoder file: " .. fname
|
||||
end
|
||||
|
||||
|
||||
file()
|
||||
|
||||
local d = env.Decoders
|
||||
@@ -126,7 +126,7 @@ end
|
||||
---
|
||||
-- Starts sniffing the selected interface for packets with a destination that
|
||||
-- is not explicitly ours (broadcast, multicast etc.)
|
||||
--
|
||||
--
|
||||
-- @param iface table containing <code>name</code> and <code>address</code>
|
||||
-- @param Decoders the decoders class loaded externally
|
||||
-- @param decodertab the "result" table to which all discovered items are
|
||||
@@ -148,7 +148,7 @@ sniffInterface = function(iface, Decoders, decodertab)
|
||||
local start_time = nmap.clock_ms()
|
||||
while( nmap.clock_ms() - start_time < timeout ) do
|
||||
local status, _, _, data = sock:pcap_receive()
|
||||
|
||||
|
||||
if ( status ) then
|
||||
local p = packet.Packet:new( data, #data )
|
||||
|
||||
@@ -194,7 +194,7 @@ end
|
||||
|
||||
---
|
||||
-- Gets a list of available interfaces based on link and up filters
|
||||
-- Interfaces are only added if they've got an ipv4 address
|
||||
-- Interfaces are only added if they've got an ipv4 address
|
||||
--
|
||||
-- @param link string containing the link type to filter
|
||||
-- @param up string containing the interface status to filter
|
||||
@@ -208,13 +208,13 @@ getInterfaces = function(link, up)
|
||||
local result = {}
|
||||
if ( not(err) ) then
|
||||
for _, iface in ipairs(interfaces) do
|
||||
if ( iface.link == link and
|
||||
if ( iface.link == link and
|
||||
iface.up == up and
|
||||
iface.address ) then
|
||||
|
||||
iface.address ) then
|
||||
|
||||
-- exclude ipv6 addresses for now
|
||||
if ( not(iface.address:match(":")) ) then
|
||||
table.insert(result, { name = iface.device,
|
||||
table.insert(result, { name = iface.device,
|
||||
address = iface.address } )
|
||||
end
|
||||
end
|
||||
@@ -228,21 +228,21 @@ action = function()
|
||||
local DECODERFILE = "nselib/data/packetdecoders.lua"
|
||||
local iface = nmap.get_interface()
|
||||
local interfaces = {}
|
||||
|
||||
|
||||
-- was an interface supplied using the -e argument?
|
||||
if ( iface ) then
|
||||
if ( iface ) then
|
||||
local iinfo, err = nmap.get_interface_info(iface)
|
||||
|
||||
|
||||
if ( not(iinfo.address) ) then
|
||||
return "\n ERROR: The IP address of the interface could not be determined ..."
|
||||
end
|
||||
|
||||
|
||||
interfaces = { { name = iface, address = iinfo.address } }
|
||||
else
|
||||
-- no interface was supplied, attempt autodiscovery
|
||||
interfaces = getInterfaces("ethernet", "up")
|
||||
end
|
||||
|
||||
|
||||
-- make sure we have at least one interface to start sniffing
|
||||
if ( #interfaces == 0 ) then
|
||||
return "\n ERROR: Could not determine any valid interfaces"
|
||||
@@ -251,18 +251,18 @@ action = function()
|
||||
-- load the decoders from file
|
||||
local status, Decoders = loadDecoders(DECODERFILE)
|
||||
if ( not(status) ) then return "\n " .. Decoders end
|
||||
|
||||
|
||||
-- create a local table to handle instantiated decoders
|
||||
local decodertab = { udp = {}, ether = {} }
|
||||
local condvar = nmap.condvar(decodertab)
|
||||
local threads = {}
|
||||
|
||||
|
||||
-- start a thread for each interface to sniff
|
||||
for _, iface in ipairs(interfaces) do
|
||||
local co = stdnse.new_thread(sniffInterface, iface, Decoders, decodertab)
|
||||
threads[co] = true
|
||||
end
|
||||
|
||||
|
||||
-- wait for all threads to finish sniffing
|
||||
repeat
|
||||
for thread in pairs(threads) do
|
||||
@@ -276,7 +276,7 @@ action = function()
|
||||
until next(threads) == nil
|
||||
|
||||
local out_outer = {}
|
||||
|
||||
|
||||
-- create the results table
|
||||
for proto, _ in pairs(decodertab) do
|
||||
local out_inner = {}
|
||||
|
||||
@@ -10,7 +10,7 @@ local target = require "target"
|
||||
description = [[
|
||||
Discovers Microsoft SQL servers in the same broadcast domain.
|
||||
|
||||
SQL Server credentials required: No (will not benefit from
|
||||
SQL Server credentials required: No (will not benefit from
|
||||
<code>mssql.username</code> & <code>mssql.password</code>).
|
||||
|
||||
The script attempts to discover SQL Server instances in the same broadcast
|
||||
@@ -23,7 +23,7 @@ broadcast version will only use the SQL Server Browser service discovery method.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- @usage
|
||||
-- nmap --script broadcast-ms-sql-discover
|
||||
-- nmap --script broadcast-ms-sql-discover,ms-sql-info --script-args=newtargets
|
||||
--
|
||||
@@ -58,7 +58,7 @@ prerule = function() return true end
|
||||
|
||||
|
||||
--- Adds a label and value to an output table. If the value is a boolean, it is
|
||||
-- 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 )
|
||||
|
||||
if outputData ~= nil then
|
||||
@@ -67,7 +67,7 @@ local function add_to_output_table( outputTable, outputLabel, outputData )
|
||||
elseif outputData == false then
|
||||
outputData = "No"
|
||||
end
|
||||
|
||||
|
||||
table.insert(outputTable, string.format( "%s: %s", outputLabel, outputData ) )
|
||||
end
|
||||
|
||||
@@ -89,10 +89,10 @@ local function create_instance_output_table( instance )
|
||||
end
|
||||
|
||||
action = function()
|
||||
|
||||
|
||||
local host = { ip = "255.255.255.255" }
|
||||
local port = { number = 1434, protocol = "udp" }
|
||||
|
||||
|
||||
local status, result = mssql.Helper.DiscoverBySsrp(host, port, true)
|
||||
if ( not(status) ) then return end
|
||||
|
||||
@@ -108,7 +108,7 @@ action = function()
|
||||
serverOutput.name = string.format( "%s (%s)", ip, serverName )
|
||||
table.insert( scriptOutput, serverOutput )
|
||||
end
|
||||
|
||||
|
||||
return stdnse.format_output( true, scriptOutput )
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ Attempts to discover master browsers and the domains they manage.
|
||||
-- nmap --script=broadcast-netbios-master-browser
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-netbios-master-browser:
|
||||
-- | broadcast-netbios-master-browser:
|
||||
-- | ip server domain
|
||||
-- |_10.0.200.156 WIN2K3-EPI-1 WORKGROUP
|
||||
--
|
||||
@@ -42,10 +42,10 @@ action = function()
|
||||
|
||||
local status, result = netbios.nbquery( { ip = BROADCAST_ADDR }, NBNAME, { multiple = true })
|
||||
if ( not(status) ) then return end
|
||||
|
||||
|
||||
local outtab = tab.new(3)
|
||||
tab.addrow(outtab, 'ip', 'server', 'domain')
|
||||
|
||||
|
||||
for _, v in ipairs(result) do
|
||||
local status, names, _ = netbios.do_nbstat(v.peer)
|
||||
local srv_name, domain_name
|
||||
|
||||
@@ -12,7 +12,7 @@ Discovers EMC Networker backup software servers on a LAN by sending a network br
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-networker-discover:
|
||||
-- | broadcast-networker-discover:
|
||||
-- |_ 10.20.30.40
|
||||
--
|
||||
--
|
||||
@@ -25,7 +25,7 @@ categories = {"broadcast", "safe"}
|
||||
prerule = function() return true end
|
||||
|
||||
local function Callit( host, port, program, protocol )
|
||||
|
||||
|
||||
local results = {}
|
||||
local portmap, comm = rpc.Portmap:new(), rpc.Comm:new('rpcbind', 2)
|
||||
|
||||
@@ -46,14 +46,14 @@ local function Callit( host, port, program, protocol )
|
||||
if (not(status)) then
|
||||
return false, "Failed to get socket information"
|
||||
end
|
||||
|
||||
|
||||
if ( status ) then
|
||||
table.insert(results, rhost)
|
||||
end
|
||||
|
||||
|
||||
status, result = comm:ReceivePacket()
|
||||
end
|
||||
|
||||
|
||||
comm:Disconnect()
|
||||
return true, results
|
||||
end
|
||||
@@ -65,29 +65,29 @@ action = function()
|
||||
local results = {}
|
||||
local ip = ( nmap.address_family() == "inet" ) and "255.255.255.255" or "ff02::202"
|
||||
local iface = nmap.get_interface()
|
||||
|
||||
|
||||
-- handle problematic sends on OS X requiring the interface to be
|
||||
-- supplied as part of IPv6
|
||||
if ( iface and nmap.address_family() == "inet6" ) then
|
||||
ip = ip .. "%" .. iface
|
||||
end
|
||||
|
||||
|
||||
for _, port in ipairs({7938,111}) do
|
||||
local host, port = { ip = ip }, { number = port, protocol = "udp" }
|
||||
local status
|
||||
status, results = Callit( host, port, "nsrstat", "udp" )
|
||||
|
||||
|
||||
-- warn about problematic sends on OS X requiring the interface to be
|
||||
-- supplied as part of IPv6
|
||||
if ( not(status) and results == "Portmap.Callit: Failed to send data" ) then
|
||||
return fail("Failed sending data, try supplying the correct interface using -e")
|
||||
end
|
||||
|
||||
|
||||
if ( status ) then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ( "table" == type(results) and 0 < #results ) then
|
||||
return stdnse.format_output(true, results)
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ Attempts to use the Service Location Protocol to discover Novell NetWare Core Pr
|
||||
--
|
||||
--@output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-novell-locate:
|
||||
-- | broadcast-novell-locate:
|
||||
-- | Tree name: CQURE-LABTREE
|
||||
-- | Server name: linux-l84t
|
||||
-- | Addresses
|
||||
@@ -33,7 +33,7 @@ prerule = function() return true end
|
||||
function action()
|
||||
|
||||
local helper = srvloc.Helper:new()
|
||||
|
||||
|
||||
local status, bindery = helper:ServiceRequest("bindery.novell", "DEFAULT")
|
||||
if ( not(status) or not(bindery) ) then
|
||||
helper:close()
|
||||
@@ -41,7 +41,7 @@ function action()
|
||||
end
|
||||
bindery = bindery[1]
|
||||
local srvname = bindery:match("%/%/%/(.*)$")
|
||||
|
||||
|
||||
local status, attrib = helper:AttributeRequest(bindery, "DEFAULT", "svcaddr-ws")
|
||||
helper:close()
|
||||
attrib = attrib:match("^%(svcaddr%-ws=(.*)%)$")
|
||||
@@ -57,7 +57,7 @@ function action()
|
||||
if ( addr ) then
|
||||
local pos, dw_addr = bin.unpack( "<I", bin.pack("H", addr) )
|
||||
local ip = ipOps.fromdword(dw_addr)
|
||||
|
||||
|
||||
if ( not(ips[ip]) ) then
|
||||
table.insert(addrs, ip)
|
||||
ips[ip] = ip
|
||||
@@ -67,13 +67,13 @@ function action()
|
||||
|
||||
local output = {}
|
||||
local status, treename = helper:ServiceRequest("ndap.novell", "DEFAULT")
|
||||
if ( status ) then
|
||||
if ( status ) then
|
||||
treename = treename[1]
|
||||
treename = treename:match("%/%/%/(.*)%.$")
|
||||
table.insert(output, ("Tree name: %s"):format(treename))
|
||||
end
|
||||
table.insert(output, ("Server name: %s"):format(srvname))
|
||||
table.insert(output, addrs)
|
||||
|
||||
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ Sends a special broadcast probe to discover PC-Anywhere hosts running on a LAN.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-pc-anywhere:
|
||||
-- | broadcast-pc-anywhere:
|
||||
-- |_ 10.0.200.113 - WIN2K3SRV-1
|
||||
--
|
||||
-- @args broadcast-pc-anywhere.timeout specifies the amount of seconds to sniff
|
||||
@@ -32,7 +32,7 @@ action = function()
|
||||
|
||||
local host = { ip = "255.255.255.255" }
|
||||
local port = { number = 5632, protocol = "udp" }
|
||||
|
||||
|
||||
local socket = nmap.new_socket("udp")
|
||||
socket:set_timeout(500)
|
||||
|
||||
@@ -42,11 +42,11 @@ action = function()
|
||||
return "\n ERROR: Failed to send broadcast request"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local timeout = TIMEOUT or ( 20 / ( nmap.timing_level() + 1 ) )
|
||||
local responses = {}
|
||||
local stime = os.time()
|
||||
|
||||
|
||||
repeat
|
||||
local status, data = socket:receive()
|
||||
if ( status ) then
|
||||
@@ -63,7 +63,7 @@ action = function()
|
||||
end
|
||||
until( os.time() - stime > timeout )
|
||||
socket:close()
|
||||
|
||||
|
||||
local result = {}
|
||||
for ip, name in pairs(responses) do
|
||||
table.insert(result, ("%s - %s"):format(ip,name))
|
||||
|
||||
@@ -15,7 +15,7 @@ Discovers PC-DUO remote control hosts and gateways running on a LAN by sending a
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-pc-duo:
|
||||
-- | broadcast-pc-duo:
|
||||
-- | PC-Duo Gateway Server
|
||||
-- | 10.0.200.113 - WIN2K3SRV-1
|
||||
-- | PC-Duo Hosts
|
||||
@@ -36,7 +36,7 @@ prerule = function() return ( nmap.address_family() == "inet") end
|
||||
-- @param probe table contaning a pc-duo probe
|
||||
-- @param responses table containing the responses
|
||||
local function udpProbe(probe, responses)
|
||||
|
||||
|
||||
local condvar = nmap.condvar(responses)
|
||||
local socket = nmap.new_socket("udp")
|
||||
socket:set_timeout(500)
|
||||
@@ -47,11 +47,11 @@ local function udpProbe(probe, responses)
|
||||
return "\n ERROR: Failed to send broadcast request"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local timeout = TIMEOUT or ( 20 / ( nmap.timing_level() + 1 ) )
|
||||
local stime = os.time()
|
||||
local hosts = {}
|
||||
|
||||
|
||||
repeat
|
||||
local status, data = socket:receive()
|
||||
if ( status ) then
|
||||
@@ -68,26 +68,26 @@ local function udpProbe(probe, responses)
|
||||
end
|
||||
until( os.time() - stime > timeout )
|
||||
socket:close()
|
||||
|
||||
|
||||
local result = {}
|
||||
for ip, name in pairs(hosts) do
|
||||
table.insert(result, ("%s - %s"):format(ip,name))
|
||||
end
|
||||
|
||||
|
||||
if ( #result > 0 ) then
|
||||
result.name = probe.topic
|
||||
table.insert(responses, result)
|
||||
end
|
||||
|
||||
|
||||
condvar "signal"
|
||||
end
|
||||
|
||||
action = function()
|
||||
|
||||
|
||||
-- PC-Duo UDP probes
|
||||
local probes = {
|
||||
-- PC-Duo Host probe
|
||||
{
|
||||
{
|
||||
host = { ip = "255.255.255.255" },
|
||||
port = { number = 1505, protocol = "udp" },
|
||||
data = bin.pack("H", "00808008ff00"),
|
||||
@@ -95,18 +95,18 @@ action = function()
|
||||
topic= "PC-Duo Hosts"
|
||||
},
|
||||
-- PC-Duo Gateway Server probe
|
||||
{
|
||||
{
|
||||
host = { ip = "255.255.255.255" },
|
||||
port = { number = 2303, protocol = "udp" },
|
||||
data = bin.pack("H", "20908008ff00"),
|
||||
match= "^.........(%w*)\0",
|
||||
topic= "PC-Duo Gateway Server"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
local threads, responses = {}, {}
|
||||
local condvar = nmap.condvar(responses)
|
||||
|
||||
|
||||
-- start a thread for each probe
|
||||
for _, p in ipairs(probes) do
|
||||
local th = stdnse.new_thread( udpProbe, p, responses )
|
||||
@@ -124,7 +124,7 @@ action = function()
|
||||
condvar "wait"
|
||||
end
|
||||
until next(threads) == nil
|
||||
|
||||
|
||||
table.sort(responses, function(a,b) return a.name < b.name end)
|
||||
-- did we get any responses
|
||||
if ( #responses > 0 ) then
|
||||
|
||||
@@ -22,12 +22,12 @@ This works by sending a PIM Hello message to the PIM multicast address
|
||||
--@usage
|
||||
-- nmap --script broadcast-pim-discovery
|
||||
--
|
||||
-- nmap --script broadcast-pim-discovery -e eth1
|
||||
-- nmap --script broadcast-pim-discovery -e eth1
|
||||
-- --script-args 'broadcast-pim-discovery.timeout=10'
|
||||
--
|
||||
--@output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-pim-discovery:
|
||||
-- | broadcast-pim-discovery:
|
||||
-- | 172.16.0.12
|
||||
-- | 172.16.0.31
|
||||
-- | 172.16.0.44
|
||||
@@ -40,7 +40,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
|
||||
categories = {"discovery", "safe", "broadcast"}
|
||||
|
||||
prerule = function()
|
||||
prerule = function()
|
||||
if nmap.address_family() ~= 'inet' then
|
||||
stdnse.print_verbose("%s is IPv4 only.", SCRIPT_NAME)
|
||||
return false
|
||||
@@ -53,7 +53,7 @@ prerule = function()
|
||||
end
|
||||
|
||||
-- Generates a raw PIM Hello message.
|
||||
--@return hello Raw PIM Hello message
|
||||
--@return hello Raw PIM Hello message
|
||||
local helloRaw = function()
|
||||
-- Version: 2, Type: Hello (0)
|
||||
local hello_raw = bin.pack(">C", 0x20)
|
||||
@@ -73,7 +73,7 @@ local helloRaw = function()
|
||||
-- Calculate checksum
|
||||
hello_raw = hello_raw:sub(1,2) .. bin.pack(">S", packet.in_cksum(hello_raw)) .. hello_raw:sub(5)
|
||||
|
||||
return hello_raw
|
||||
return hello_raw
|
||||
end
|
||||
|
||||
-- Sends a PIM Hello message.
|
||||
@@ -84,7 +84,7 @@ local helloQuery = function(interface, dstip)
|
||||
local srcip = interface.address
|
||||
|
||||
local hello_raw = helloRaw()
|
||||
local ip_raw = bin.pack("H", "45c00040ed780000016718bc0a00c8750a00c86b") .. hello_raw
|
||||
local ip_raw = bin.pack("H", "45c00040ed780000016718bc0a00c8750a00c86b") .. hello_raw
|
||||
hello_packet = packet.Packet:new(ip_raw, ip_raw:len())
|
||||
hello_packet:ip_set_bin_src(ipOps.ip_to_str(srcip))
|
||||
hello_packet:ip_set_bin_dst(ipOps.ip_to_str(dstip))
|
||||
@@ -157,9 +157,9 @@ action = function()
|
||||
local mcast = "224.0.0.13"
|
||||
|
||||
-- Get the network interface to use
|
||||
local interface = nmap.get_interface()
|
||||
local interface = nmap.get_interface()
|
||||
if interface then
|
||||
interface = nmap.get_interface_info(interface)
|
||||
interface = nmap.get_interface_info(interface)
|
||||
else
|
||||
interface = getInterface(mcast)
|
||||
end
|
||||
@@ -180,7 +180,7 @@ action = function()
|
||||
|
||||
if #responses > 0 then
|
||||
table.sort(responses)
|
||||
if target.ALLOW_NEW_TARGETS then
|
||||
if target.ALLOW_NEW_TARGETS then
|
||||
for _, response in pairs(responses) do
|
||||
target.add(response)
|
||||
end
|
||||
|
||||
@@ -11,29 +11,29 @@ local target = require "target"
|
||||
local openssl = stdnse.silent_require "openssl"
|
||||
|
||||
description = [[
|
||||
Sends broadcast pings on a selected interface using raw ethernet packets and
|
||||
outputs the responding hosts' IP and MAC addresses or (if requested) adds them as targets. Root privileges on UNIX are required to run this script since it uses raw sockets. Most operating systems don't respond to broadcast-ping probes,
|
||||
Sends broadcast pings on a selected interface using raw ethernet packets and
|
||||
outputs the responding hosts' IP and MAC addresses or (if requested) adds them as targets. Root privileges on UNIX are required to run this script since it uses raw sockets. Most operating systems don't respond to broadcast-ping probes,
|
||||
but they can be configured to do so.
|
||||
|
||||
The interface on which is broadcasted can be specified using the -e Nmap option
|
||||
or the <code>broadcast-ping.interface</code> script-arg. If no interface is
|
||||
or the <code>broadcast-ping.interface</code> script-arg. If no interface is
|
||||
specified this script broadcasts on all ethernet interfaces which have an IPv4
|
||||
address defined.
|
||||
|
||||
The <code>newtarget</code> script-arg can be used so the script adds the
|
||||
The <code>newtarget</code> script-arg can be used so the script adds the
|
||||
discovered IPs as targets.
|
||||
|
||||
The timeout of the ICMP probes can be specified using the <code>timeout</code>
|
||||
script-arg. The default timeout is 3000 ms. A higher number might be necesary
|
||||
script-arg. The default timeout is 3000 ms. A higher number might be necesary
|
||||
when scanning across larger networks.
|
||||
|
||||
The number of sent probes can be specified using the <code>num-probes</code>
|
||||
script-arg. The default number is 1. A higher value might get more results on
|
||||
script-arg. The default number is 1. A higher value might get more results on
|
||||
larger networks.
|
||||
|
||||
The ICMP probes sent comply with the --ttl and --data-length Nmap options, so
|
||||
you can use those to control the TTL(time to live) and ICMP payload length
|
||||
respectively. The default value for TTL is 64, and the length of the payload
|
||||
The ICMP probes sent comply with the --ttl and --data-length Nmap options, so
|
||||
you can use those to control the TTL(time to live) and ICMP payload length
|
||||
respectively. The default value for TTL is 64, and the length of the payload
|
||||
is 0. The payload is consisted of random bytes.
|
||||
]]
|
||||
|
||||
@@ -47,8 +47,8 @@ is 0. The payload is consisted of random bytes.
|
||||
-- @args broadcast-ping.timeout timespec specifying how long to wait for response (default 3s)
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-ping:
|
||||
-- | IP: 192.168.1.1 MAC: 00:23:69:2a:b1:25
|
||||
-- | broadcast-ping:
|
||||
-- | IP: 192.168.1.1 MAC: 00:23:69:2a:b1:25
|
||||
-- | IP: 192.168.1.106 MAC: 1c:65:9d:88:d8:36
|
||||
-- |_ Use --script-args=newtargets to add the results as targets
|
||||
--
|
||||
@@ -68,12 +68,12 @@ prerule = function()
|
||||
nmap.registry[SCRIPT_NAME].rootfail = true
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
if nmap.address_family() ~= 'inet' then
|
||||
stdnse.print_debug("%s is IPv4 compatible only.", SCRIPT_NAME)
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -83,14 +83,14 @@ end
|
||||
-- @param srcIP string containing the source IP, IPv4 format
|
||||
-- @param dstIP string containing the destination IP, IPv4 format
|
||||
-- @param ttl number containing value for the TTL (time to live) field in IP header
|
||||
-- @param data_length number value of ICMP payload length
|
||||
-- @param data_length number value of ICMP payload length
|
||||
local icmp_packet = function(srcIP, dstIP, ttl, data_length, mtu, seqNo, icmp_id)
|
||||
-- A couple of checks first
|
||||
assert((seqNo and seqNo>0 and seqNo<=0xffff),"ICMP Sequence number: Value out of range(1-65535).")
|
||||
assert((ttl and ttl>0 and ttl<0xff),"TTL(time-to-live): Value out of range(1-256).")
|
||||
-- MTU values should be considered here!
|
||||
assert((data_length and data_length>=0 and data_length<mtu),"ICMP Payload length: Value out of range(0-mtu).")
|
||||
|
||||
|
||||
-- ICMP Message
|
||||
local icmp_payload = nil
|
||||
if data_length and data_length>0 then
|
||||
@@ -98,99 +98,99 @@ local icmp_packet = function(srcIP, dstIP, ttl, data_length, mtu, seqNo, icmp_id
|
||||
else
|
||||
icmp_payload = ""
|
||||
end
|
||||
|
||||
|
||||
local seqNo_hex = stdnse.tohex(seqNo)
|
||||
local icmp_seqNo = bin.pack(">H", string.rep("0",(4-seqNo_hex))..seqNo_hex)
|
||||
|
||||
-- Type=08; Code=00; Chksum=0000; ID=icmp_id; SeqNo=icmp_seqNo; Payload=icmp_payload(hex string);
|
||||
local icmp_tmp = bin.pack(">HAAA", "0800 0000", icmp_id, icmp_seqNo, icmp_payload)
|
||||
|
||||
|
||||
local icmp_checksum = packet.in_cksum(icmp_tmp)
|
||||
|
||||
|
||||
local icmp_msg = bin.pack(">HHAAA", "0800", stdnse.tohex(icmp_checksum), icmp_id, icmp_seqNo, icmp_payload)
|
||||
|
||||
|
||||
|
||||
|
||||
--IP Total Length
|
||||
local length_hex = stdnse.tohex(20 + #icmp_msg)
|
||||
local ip_length = bin.pack(">H", string.rep("0",(4-#length_hex))..length_hex)
|
||||
|
||||
|
||||
--TTL
|
||||
local ttl_hex = stdnse.tohex(ttl)
|
||||
local ip_ttl = bin.pack(">H", string.rep("0",(2-ttl_hex))..ttl_hex)
|
||||
|
||||
|
||||
--IP header
|
||||
local ip_bin = bin.pack(">HAHAH","4500",ip_length, "0000 4000", ip_ttl,
|
||||
"01 0000 0000 0000 0000 0000")
|
||||
|
||||
|
||||
-- IP+ICMP; Addresses and checksum need to be filled
|
||||
local icmp_bin = bin.pack(">AA",ip_bin, icmp_msg)
|
||||
|
||||
|
||||
--Packet
|
||||
local icmp = packet.Packet:new(icmp_bin,#icmp_bin)
|
||||
assert(icmp,"Mistake during ICMP packet parsing")
|
||||
|
||||
|
||||
icmp:ip_set_bin_src(packet.iptobin(srcIP))
|
||||
icmp:ip_set_bin_dst(packet.iptobin(dstIP))
|
||||
icmp:ip_count_checksum()
|
||||
|
||||
|
||||
return icmp
|
||||
end
|
||||
|
||||
local broadcast_if = function(if_table,icmp_responders)
|
||||
local condvar = nmap.condvar(icmp_responders)
|
||||
|
||||
|
||||
local num_probes = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".num-probes")) or 1
|
||||
|
||||
|
||||
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
|
||||
timeout = (timeout or 3) * 1000
|
||||
|
||||
|
||||
local ttl = nmap.get_ttl()
|
||||
|
||||
|
||||
local data_length = nmap.get_payload_length()
|
||||
local sequence_number = 1
|
||||
local destination_IP = "255.255.255.255"
|
||||
|
||||
-- raw IPv4 socket
|
||||
-- raw IPv4 socket
|
||||
local dnet = nmap.new_dnet()
|
||||
local try = nmap.new_try()
|
||||
try = nmap.new_try(function() dnet:ethernet_close() end)
|
||||
|
||||
|
||||
-- raw sniffing socket (icmp echoreply style)
|
||||
local pcap = nmap.new_socket()
|
||||
pcap:set_timeout(timeout)
|
||||
|
||||
local mtu = if_table.mtu or 256 -- 256 is minimal mtu
|
||||
|
||||
|
||||
pcap:pcap_open(if_table.device, 104, false, "dst host ".. if_table.address ..
|
||||
" and icmp[icmptype]==icmp-echoreply")
|
||||
try(dnet:ethernet_open(if_table.device))
|
||||
|
||||
local source_IP = if_table.address
|
||||
|
||||
|
||||
local source_IP = if_table.address
|
||||
|
||||
local icmp_ids = {}
|
||||
|
||||
for i = 1, num_probes do
|
||||
-- ICMP packet
|
||||
local icmp_id = openssl.rand_bytes(2)
|
||||
icmp_ids[icmp_id]=true
|
||||
local icmp = icmp_packet( source_IP, destination_IP, ttl,
|
||||
local icmp = icmp_packet( source_IP, destination_IP, ttl,
|
||||
data_length, mtu, sequence_number, icmp_id)
|
||||
|
||||
|
||||
local ethernet_icmp = bin.pack("HAHA", "FF FF FF FF FF FF", if_table.mac, "08 00", icmp.buf)
|
||||
|
||||
try( dnet:ethernet_send(ethernet_icmp) )
|
||||
end
|
||||
|
||||
while true do
|
||||
local status, plen, l2, l3data, _ = pcap:pcap_receive()
|
||||
local status, plen, l2, l3data, _ = pcap:pcap_receive()
|
||||
if not status then break end
|
||||
|
||||
|
||||
-- Do stuff with packet
|
||||
local icmpreply = packet.Packet:new(l3data,plen,false)
|
||||
-- We check whether the packet is parsed ok, and whether the ICMP ID of the sent packet
|
||||
-- is the same with the ICMP ID of the received packet. We don't want ping probes interfering
|
||||
local icmp_id = icmpreply:raw(icmpreply.icmp_offset+4,2)
|
||||
if icmpreply:ip_parse() and icmp_ids[icmp_id] then
|
||||
local icmp_id = icmpreply:raw(icmpreply.icmp_offset+4,2)
|
||||
if icmpreply:ip_parse() and icmp_ids[icmp_id] then
|
||||
if not icmp_responders[icmpreply.ip_src] then
|
||||
-- [key = IP]=MAC
|
||||
local mac_pretty = stdnse.format_mac(l2:sub(7,12))
|
||||
@@ -203,17 +203,17 @@ local broadcast_if = function(if_table,icmp_responders)
|
||||
|
||||
pcap:close()
|
||||
dnet:ethernet_close()
|
||||
|
||||
|
||||
condvar "signal"
|
||||
end
|
||||
|
||||
|
||||
action = function()
|
||||
|
||||
action = function()
|
||||
|
||||
--get interface script-args, if any
|
||||
local interface_arg = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
|
||||
local interface_opt = nmap.get_interface()
|
||||
|
||||
|
||||
-- interfaces list (decide which interfaces to broadcast on)
|
||||
local interfaces ={}
|
||||
if interface_opt or interface_arg then
|
||||
@@ -228,24 +228,24 @@ action = function()
|
||||
else
|
||||
local tmp_ifaces = nmap.list_interfaces()
|
||||
for _, if_table in ipairs(tmp_ifaces) do
|
||||
if if_table.address and
|
||||
if_table.link=="ethernet" and
|
||||
if if_table.address and
|
||||
if_table.link=="ethernet" and
|
||||
if_table.address:match("%d+%.%d+%.%d+%.%d+") then
|
||||
table.insert(interfaces, if_table)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #interfaces == 0 then
|
||||
|
||||
if #interfaces == 0 then
|
||||
stdnse.print_debug("No interfaces found.")
|
||||
return
|
||||
return
|
||||
end
|
||||
|
||||
local icmp_responders={}
|
||||
local threads ={}
|
||||
local condvar = nmap.condvar(icmp_responders)
|
||||
|
||||
-- party time
|
||||
-- party time
|
||||
for _, if_table in ipairs(interfaces) do
|
||||
-- create a thread for each interface
|
||||
local co = stdnse.new_thread(broadcast_if, if_table, icmp_responders)
|
||||
@@ -260,7 +260,7 @@ action = function()
|
||||
condvar "wait"
|
||||
end
|
||||
until next(threads) == nil
|
||||
|
||||
|
||||
-- generate output
|
||||
local output = tab.new()
|
||||
for ip_addr, mac_addr in pairs(icmp_responders) do
|
||||
|
||||
@@ -20,7 +20,7 @@ mode to operate.
|
||||
-- nmap --script broadcast-pppoe-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-pppoe-discover:
|
||||
-- | broadcast-pppoe-discover:
|
||||
-- | Server: 08:00:27:AB:CD:EF
|
||||
-- | Version: 1
|
||||
-- | Type: 1
|
||||
@@ -55,17 +55,17 @@ local function discoverPPPoE(helper)
|
||||
if ( not(status) ) then
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
local status, pado = helper:discoverInit()
|
||||
if ( not(status) ) then
|
||||
return false, pado
|
||||
end
|
||||
|
||||
|
||||
status, err = helper:discoverRequest()
|
||||
if ( not(status) ) then
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
return true, pado
|
||||
end
|
||||
|
||||
@@ -87,19 +87,19 @@ local function getInterfaces(link, up)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
action = function()
|
||||
|
||||
local interfaces
|
||||
|
||||
|
||||
-- first check if the user supplied an interface
|
||||
if ( nmap.get_interface() ) then
|
||||
interfaces = { [nmap.get_interface()] = true }
|
||||
else
|
||||
interfaces = getInterfaces("ethernet", "up")
|
||||
end
|
||||
|
||||
|
||||
for iface in pairs(interfaces) do
|
||||
local helper, err = pppoe.Helper:new(iface)
|
||||
if ( not(helper) ) then
|
||||
@@ -110,11 +110,11 @@ action = function()
|
||||
return fail(pado)
|
||||
end
|
||||
helper:close()
|
||||
|
||||
|
||||
local output = { name = ("Server: %s"):format(stdnse.format_mac(pado.mac_srv)) }
|
||||
table.insert(output, ("Version: %d"):format(pado.header.version))
|
||||
table.insert(output, ("Type: %d"):format(pado.header.type))
|
||||
|
||||
|
||||
local tags = { name = "TAGs" }
|
||||
for _, tag in ipairs(pado.tags) do
|
||||
local name, val = pppoe.PPPoE.TagName[tag.tag], tag.decoded
|
||||
|
||||
@@ -17,7 +17,7 @@ from all devices responding to the request.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-rip-discover:
|
||||
-- | broadcast-rip-discover:
|
||||
-- | Discovered RIPv2 devices
|
||||
-- | 10.0.200.107
|
||||
-- | ip netmask nexthop metric
|
||||
@@ -30,7 +30,7 @@ from all devices responding to the request.
|
||||
-- | 10.0.200.101
|
||||
-- | ip netmask nexthop metric
|
||||
-- |_ 0.0.0.0 0.0.0.0 10.0.200.1 1
|
||||
--
|
||||
--
|
||||
-- @args broadcast-rip-discover.timeout timespec defining how long to wait for
|
||||
-- a response. (default 5s)
|
||||
|
||||
@@ -47,25 +47,25 @@ categories = {"broadcast", "safe"}
|
||||
prerule = function() return not( nmap.address_family() == "inet6") end
|
||||
|
||||
RIPv2 = {
|
||||
|
||||
|
||||
Command = {
|
||||
Request = 1,
|
||||
Response = 2,
|
||||
},
|
||||
|
||||
|
||||
AddressFamily = {
|
||||
IP = 2,
|
||||
},
|
||||
|
||||
|
||||
-- The Request class contains functions to build a RIPv2 Request
|
||||
Request = {
|
||||
|
||||
|
||||
-- Creates a new Request instance
|
||||
--
|
||||
-- @param command number containing the RIPv2 Command to use
|
||||
-- @return o instance of request
|
||||
new = function(self, command)
|
||||
local o = {
|
||||
local o = {
|
||||
version = 2,
|
||||
command = command,
|
||||
domain = 0,
|
||||
@@ -80,7 +80,7 @@ RIPv2 = {
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
-- Converts the whole request to a string
|
||||
__tostring = function(self)
|
||||
assert(self.command, "No command was supplied")
|
||||
@@ -89,26 +89,26 @@ RIPv2 = {
|
||||
local RESERVED = 0
|
||||
-- RIPv2 stuff, should be 0 for RIPv1
|
||||
local tag, subnet, nexthop = 0, 0, 0
|
||||
|
||||
|
||||
local data = bin.pack(">CCSSSIIII",
|
||||
self.command, self.version, self.domain, self.family, self.tag,
|
||||
self.address, self.subnet, self.nexthop, self.metric)
|
||||
|
||||
|
||||
return data
|
||||
end,
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
-- The Response class contains code needed to parse a RIPv2 response
|
||||
Response = {
|
||||
|
||||
|
||||
-- Creates a new Response instance based on raw socket data
|
||||
--
|
||||
-- @param data string containing the raw socket response
|
||||
-- @return o Response instance
|
||||
new = function(self, data)
|
||||
local o = { data = data }
|
||||
|
||||
|
||||
if ( not(data) or #data < 3 ) then
|
||||
return
|
||||
end
|
||||
@@ -117,15 +117,15 @@ RIPv2 = {
|
||||
if ( o.command ~= RIPv2 and o.version ~= 2 ) then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local routes = tab.new(2)
|
||||
tab.addrow(routes, "ip", "netmask", "nexthop", "metric")
|
||||
|
||||
|
||||
while( #data - pos >= 20 ) do
|
||||
local family, address, metric, _, netmask, nexthop
|
||||
pos, family, _, address, netmask, nexthop,
|
||||
metric = bin.unpack(">SS<III>I", data, pos)
|
||||
|
||||
|
||||
if ( family == RIPv2.AddressFamily.IP ) then
|
||||
local ip = ipOps.fromdword(address)
|
||||
netmask = ipOps.fromdword(netmask)
|
||||
@@ -133,16 +133,16 @@ RIPv2 = {
|
||||
tab.addrow(routes, ip, netmask, nexthop, metric)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ( #routes > 1 ) then o.routes = routes end
|
||||
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -152,9 +152,9 @@ action = function()
|
||||
|
||||
local socket = nmap.new_socket("udp")
|
||||
socket:set_timeout(timeout)
|
||||
|
||||
|
||||
local rip = RIPv2.Request:new(RIPv2.Command.Request)
|
||||
local status, err = socket:sendto("224.0.0.9",
|
||||
local status, err = socket:sendto("224.0.0.9",
|
||||
{ number = 520, protocol = "udp" },
|
||||
tostring(rip))
|
||||
local result = {}
|
||||
@@ -165,12 +165,12 @@ action = function()
|
||||
local status, _, _, rhost, _ = socket:get_info()
|
||||
local response = RIPv2.Response:new(data)
|
||||
table.insert(result, rhost)
|
||||
|
||||
|
||||
if ( response and response.routes and #response.routes > 0 ) then
|
||||
--response.routes.name = "Routes"
|
||||
table.insert(result, { tab.dump(response.routes) } )
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
until( not(status) )
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ LAN by sending a broadcast RIPng Request command and collecting any responses.
|
||||
-- nmap --script broadcast-ripng-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-ripng-discover:
|
||||
-- | broadcast-ripng-discover:
|
||||
-- | fe80::a00:27ff:fe9a:880c
|
||||
-- | route metric next hop
|
||||
-- | fe80:470:0:0:0:0:0:0/64 1
|
||||
-- | fe80:471:0:0:0:0:0:0/64 1
|
||||
-- |_ fe80:472:0:0:0:0:0:0/64 1
|
||||
-- | fe80:470:0:0:0:0:0:0/64 1
|
||||
-- | fe80:471:0:0:0:0:0:0/64 1
|
||||
-- |_ fe80:472:0:0:0:0:0:0/64 1
|
||||
--
|
||||
-- @args broadcast-ripng-discover.timeout sets the connection timeout
|
||||
-- (default: 5s)
|
||||
@@ -39,10 +39,10 @@ RIPng = {
|
||||
Request = 1,
|
||||
Response = 2,
|
||||
},
|
||||
|
||||
|
||||
-- Route table entry
|
||||
RTE = {
|
||||
|
||||
|
||||
-- Creates a new Route Table Entry
|
||||
-- @param prefix string containing the ipv6 route prefix
|
||||
-- @param tag number containing the route tag
|
||||
@@ -61,20 +61,20 @@ RIPng = {
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
-- Parses a byte string and creates an instance of RTE
|
||||
-- @param data string of bytes
|
||||
-- @return rte instance of RTE
|
||||
parse = function(data)
|
||||
local rte = RIPng.RTE:new()
|
||||
local pos, ip
|
||||
|
||||
|
||||
pos, ip, rte.tag, rte.prefix_len, rte.metric = bin.unpack(">A16SCC", data)
|
||||
ip = select(2, bin.unpack("B" .. #ip, ip))
|
||||
rte.prefix = ipOps.bin_to_ip(ip)
|
||||
return rte
|
||||
end,
|
||||
|
||||
|
||||
-- Converts a RTE instance to string
|
||||
-- @return string of bytes to send to the server
|
||||
__tostring = function(self)
|
||||
@@ -82,19 +82,19 @@ RIPng = {
|
||||
assert(16 == #ipstr, "Invalid IPv6 address encountered")
|
||||
return bin.pack(">ASCC", ipstr, self.tag, self.prefix_len, self.metric)
|
||||
end,
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
-- The Request class contains functions to build a RIPv2 Request
|
||||
Request = {
|
||||
|
||||
|
||||
-- Creates a new Request instance
|
||||
--
|
||||
-- @param command number containing the RIPv2 Command to use
|
||||
-- @return o instance of request
|
||||
new = function(self, entries)
|
||||
local o = {
|
||||
local o = {
|
||||
command = 1,
|
||||
version = 1,
|
||||
entries = entries,
|
||||
@@ -103,7 +103,7 @@ RIPng = {
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
-- Converts the whole request to a string
|
||||
__tostring = function(self)
|
||||
local RESERVED = 0
|
||||
@@ -115,10 +115,10 @@ RIPng = {
|
||||
end,
|
||||
|
||||
},
|
||||
|
||||
|
||||
-- A RIPng Response
|
||||
Response = {
|
||||
|
||||
|
||||
-- Creates a new Response instance
|
||||
-- @return o new instance of Response
|
||||
new = function(self)
|
||||
@@ -127,13 +127,13 @@ RIPng = {
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
-- Creates a new Response instance based on a string of bytes
|
||||
-- @return resp new instance of Response
|
||||
parse = function(data)
|
||||
local resp = RIPng.Response:new()
|
||||
local pos, _
|
||||
|
||||
|
||||
pos, resp.command, resp.version, _ = bin.unpack(">CCS", data)
|
||||
resp.entries = {}
|
||||
while( pos < #data ) do
|
||||
@@ -141,9 +141,9 @@ RIPng = {
|
||||
table.insert(resp.entries, e)
|
||||
pos = pos + 20
|
||||
end
|
||||
|
||||
|
||||
return resp
|
||||
end,
|
||||
end,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ end
|
||||
|
||||
action = function()
|
||||
|
||||
local req = RIPng.Request:new( { RIPng.RTE:new("0::", 0, 0, 16) } )
|
||||
local req = RIPng.Request:new( { RIPng.RTE:new("0::", 0, 0, 16) } )
|
||||
local host, port = "FF02::9", { number = 521, protocol = "udp" }
|
||||
local iface = nmap.get_interface()
|
||||
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout"))
|
||||
@@ -180,7 +180,7 @@ action = function()
|
||||
sock:set_timeout(timeout)
|
||||
|
||||
local status = sock:sendto(host, port, tostring(req))
|
||||
|
||||
|
||||
-- do we need to add the interface name to the address?
|
||||
if ( not(status) ) then
|
||||
if ( not(iface) ) then
|
||||
@@ -188,7 +188,7 @@ action = function()
|
||||
end
|
||||
status = sock:sendto(host .. "%" .. iface, port, tostring(req))
|
||||
end
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return fail("Failed to send request to server")
|
||||
end
|
||||
@@ -206,7 +206,7 @@ action = function()
|
||||
responses[rhost] = RIPng.Response.parse(data)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local result = {}
|
||||
for ip, resp in pairs(responses) do
|
||||
stdnse.print_debug(ip, resp)
|
||||
|
||||
@@ -15,7 +15,7 @@ Discovers Sybase Anywhere servers on the LAN by sending broadcast discovery mess
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-sybase-asa-discover:
|
||||
-- | broadcast-sybase-asa-discover:
|
||||
-- | ip=192.168.0.1; name=mysqlanywhere1; port=2638
|
||||
-- |_ ip=192.168.0.2; name=mysqlanywhere2; port=49152
|
||||
--
|
||||
@@ -31,7 +31,7 @@ prerule = function() return ( nmap.address_family() == "inet") end
|
||||
-- more scripts that make use of it are developed.
|
||||
--
|
||||
Ping = {
|
||||
|
||||
|
||||
-- The PING request class
|
||||
Request = {
|
||||
|
||||
@@ -49,7 +49,7 @@ Ping = {
|
||||
"000000010000040005000500000102000003010104080000000000000000070204b1")
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
-- The Ping Response class
|
||||
Response = {
|
||||
-- Creates a new response
|
||||
@@ -95,7 +95,7 @@ Ping = {
|
||||
|
||||
-- Main script interface
|
||||
Helper = {
|
||||
|
||||
|
||||
-- Creates a new helper instance
|
||||
-- @param host table as received by the action method
|
||||
-- @param port table as received by the action method
|
||||
@@ -112,7 +112,7 @@ Helper = {
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
-- Sends a ping request to the service and processes the response
|
||||
-- @return status true on success, false on failure
|
||||
-- @return instances table of instance tables containing
|
||||
@@ -123,7 +123,7 @@ Helper = {
|
||||
ping = function(self)
|
||||
local socket = nmap.new_socket("udp")
|
||||
socket:set_timeout(1000)
|
||||
|
||||
|
||||
-- send 2 packets just in case
|
||||
for i=1, 2 do
|
||||
local ping_req = Ping.Request:new()
|
||||
@@ -154,26 +154,26 @@ Helper = {
|
||||
end
|
||||
until( os.time() - stime > timeout )
|
||||
socket:close()
|
||||
|
||||
|
||||
return true, instances
|
||||
end,
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
action = function()
|
||||
|
||||
|
||||
local timeout = ( 20 / ( nmap.timing_level() + 1 ) )
|
||||
local host = { ip = "255.255.255.255" }
|
||||
local port = { number = 2638, protocol = "udp" }
|
||||
|
||||
|
||||
local helper = Helper:new(host, port)
|
||||
local status, instances = helper:ping()
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return ("\n ERROR: %s"):format(instances)
|
||||
end
|
||||
|
||||
|
||||
-- if we don't have any instances, silently abort
|
||||
if ( next(instances) == nil ) then
|
||||
return
|
||||
|
||||
@@ -13,7 +13,7 @@ dimmers and electric outlets. For more information: http://www.telldus.com/
|
||||
-- nmap --script broadcast-tellstick-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-tellstick-discover:
|
||||
-- | broadcast-tellstick-discover:
|
||||
-- | 192.168.0.100
|
||||
-- | Product: TellStickNet
|
||||
-- | MAC: ACCA12345678
|
||||
@@ -32,7 +32,7 @@ local function fail(err) return ("\n ERROR: %s"):format(err or "") end
|
||||
action = function()
|
||||
local socket = nmap.new_socket("udp")
|
||||
local host, port = { ip = "255.255.255.255" }, { number = 30303, protocol = "udp" }
|
||||
|
||||
|
||||
socket:set_timeout(5000)
|
||||
if ( not(socket:sendto(host, port, "D")) ) then
|
||||
return fail("Failed to send discovery request to server")
|
||||
@@ -64,7 +64,7 @@ action = function()
|
||||
table.insert(output, output_part)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ( 0 < #output ) then
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ Attempts to extract system information from the UPnP service by sending a multic
|
||||
|
||||
---
|
||||
-- @output
|
||||
-- | broadcast-upnp-info:
|
||||
-- | broadcast-upnp-info:
|
||||
-- | 1.2.3.50
|
||||
-- | Debian/4.0 DLNADOC/1.50 UPnP/1.0 MiniDLNA/1.0
|
||||
-- | Location: http://1.2.3.50:8200/rootDesc.xml
|
||||
@@ -37,13 +37,13 @@ categories = {"broadcast", "safe"}
|
||||
prerule = function() return true end
|
||||
|
||||
---
|
||||
-- Sends UPnP discovery packet to host,
|
||||
-- Sends UPnP discovery packet to host,
|
||||
-- and extracts service information from results
|
||||
action = function()
|
||||
local helper = upnp.Helper:new()
|
||||
helper:setMulticast(true)
|
||||
local status, result = helper:queryServices()
|
||||
|
||||
|
||||
if ( status ) then
|
||||
return stdnse.format_output(true, result)
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ Discovers Versant object databases using the broadcast srvloc protocol.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-versant-locate:
|
||||
-- | broadcast-versant-locate:
|
||||
-- |_ vod://192.168.200.222:5019
|
||||
--
|
||||
|
||||
@@ -28,10 +28,10 @@ action = function()
|
||||
local helper = srvloc.Helper:new()
|
||||
local status, result = helper:ServiceRequest("service:odbms.versant:vod", "default")
|
||||
helper:close()
|
||||
|
||||
|
||||
if ( not(status) ) then return end
|
||||
local output = {}
|
||||
for _, v in ipairs(result) do
|
||||
for _, v in ipairs(result) do
|
||||
table.insert(output, v:match("^service:odbms.versant:vod://(.*)$"))
|
||||
end
|
||||
return stdnse.format_output(true, output)
|
||||
|
||||
@@ -12,7 +12,7 @@ Wakes a remote system up from sleep by sending a Wake-On-Lan packet.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-wake-on-lan:
|
||||
-- | broadcast-wake-on-lan:
|
||||
-- |_ Sent WOL packet to: 10:9a:dd:a8:40:24
|
||||
--
|
||||
-- @args broadcast-wake-on-lan.MAC The MAC address of the remote system to wake up
|
||||
@@ -53,7 +53,7 @@ action = function()
|
||||
else
|
||||
return "\n ERROR: Failed to process MAC address"
|
||||
end
|
||||
|
||||
|
||||
local host = { ip = address or "255.255.255.255" }
|
||||
local port = { number = 9, protocol = "udp" }
|
||||
local socket = nmap.new_socket("udp")
|
||||
@@ -68,4 +68,4 @@ action = function()
|
||||
end
|
||||
return stdnse.format_output(true, ("Sent WOL packet to: %s"):format(MAC))
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ argument or by attempting to reverse resolve the local IP.
|
||||
-- nmap --script broadcast-wpad-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-wpad-discover:
|
||||
-- | broadcast-wpad-discover:
|
||||
-- | 1.2.3.4:8080
|
||||
-- |_ 4.5.6.7:3128
|
||||
--
|
||||
--
|
||||
-- @args broadcast-wpad-discover.domain the domain in which the WPAD host should be discovered
|
||||
-- @args broadcast-wpad-discover.nodns instructs the script to skip discovery using DNS
|
||||
-- @args broadcast-wpad-discover.nodhcp instructs the script to skip discovery using dhcp
|
||||
@@ -70,7 +70,7 @@ local function getInterfaces(link, up)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function parseDHCPResponse(response)
|
||||
@@ -83,16 +83,16 @@ end
|
||||
|
||||
local function getWPAD(u)
|
||||
local u_parsed = url.parse(u)
|
||||
|
||||
|
||||
if ( not(u_parsed) ) then
|
||||
return false, ("Failed to parse url: %s"):format(u)
|
||||
end
|
||||
|
||||
|
||||
local response = http.get(u_parsed.host, u_parsed.port or 80, u_parsed.path)
|
||||
if ( response and response.status == 200 ) then
|
||||
return true, response.body
|
||||
end
|
||||
|
||||
|
||||
return false, ("Failed to retrieve wpad.dat (%s) from server"):format(u)
|
||||
end
|
||||
|
||||
@@ -125,9 +125,9 @@ local function dnsDiscover()
|
||||
return true, { name = name, ip = response[1] }
|
||||
end
|
||||
until( not(d) or not(d:match("%.")) )
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- first try a domain if it was supplied
|
||||
if ( arg_domain ) then
|
||||
local status, response = enumWPADNames(arg_domain)
|
||||
@@ -135,8 +135,8 @@ local function dnsDiscover()
|
||||
return status, response
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- if no domain was supplied, attempt to reverse lookup every ip on each
|
||||
-- interface to find our FQDN hostname, once we do, try to query for WPAD
|
||||
for i in pairs(getInterfaces("ethernet", "up") or {}) do
|
||||
@@ -154,7 +154,7 @@ local function dnsDiscover()
|
||||
domains[domain] = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- attempt to discover the ip for WPAD in all domains
|
||||
-- each domain is processed and reduced and ones the first
|
||||
-- match is received it returns an IP
|
||||
@@ -164,12 +164,12 @@ local function dnsDiscover()
|
||||
return true, response
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return false, "Failed to find WPAD using DNS"
|
||||
|
||||
end
|
||||
@@ -182,7 +182,7 @@ local function dhcpDiscover()
|
||||
if ( iface ) then
|
||||
local req_list = createRequestList( { 1, 15, 3, 6, 44, 46, 47, 31, 33, 249, 43, 252 } )
|
||||
local status, response = dhcp.make_request("255.255.255.255", dhcp.request_types["DHCPDISCOVER"], "0.0.0.0", iface.mac, nil, req_list, { flags = 0x8000 } )
|
||||
|
||||
|
||||
-- if we got a response, we're happy and don't need to continue
|
||||
if (status) then
|
||||
return status, response
|
||||
@@ -196,18 +196,18 @@ end
|
||||
action = function()
|
||||
|
||||
local status, response, wpad
|
||||
|
||||
|
||||
if ( arg_nodhcp and arg_nodns ) then
|
||||
return "\n ERROR: Both nodns and nodhcp arguments were supplied"
|
||||
end
|
||||
|
||||
|
||||
if ( nmap.is_privileged() and not(arg_nodhcp) ) then
|
||||
status, response = dhcpDiscover()
|
||||
if ( status ) then
|
||||
status, wpad = parseDHCPResponse(response)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- if the DHCP did not get a result, fallback to DNS
|
||||
if (not(status) and not(arg_nodns) ) then
|
||||
status, response = dnsDiscover()
|
||||
@@ -217,16 +217,16 @@ action = function()
|
||||
end
|
||||
wpad = ("http://%s/wpad.dat"):format( response.name )
|
||||
end
|
||||
|
||||
|
||||
if ( status ) then
|
||||
status, response = getWPAD(wpad)
|
||||
end
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return status, response
|
||||
end
|
||||
|
||||
|
||||
local output = ( arg_getwpad and response or parseWPAD(response) )
|
||||
|
||||
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
local wsdd = require "wsdd"
|
||||
|
||||
description = [[
|
||||
description = [[
|
||||
Uses a multicast query to discover devices supporting the Web Services
|
||||
Dynamic Discovery (WS-Discovery) protocol. It also attempts to locate
|
||||
any published Windows Communication Framework (WCF) web services (.NET
|
||||
@@ -13,10 +13,10 @@ any published Windows Communication Framework (WCF) web services (.NET
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- sudo ./nmap --script broadcast-wsdd-discover
|
||||
-- sudo ./nmap --script broadcast-wsdd-discover
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-wsdd-discover:
|
||||
-- | broadcast-wsdd-discover:
|
||||
-- | Devices
|
||||
-- | 1.2.3.116
|
||||
-- | Message id: 9ea97e41-e874-faa7-fe28-deadbeefceb3
|
||||
@@ -35,7 +35,7 @@ any published Windows Communication Framework (WCF) web services (.NET
|
||||
-- | Message id: c1767df8-43e5-4440-9e26--deadbeefceb3
|
||||
-- |_ Address: http://win-7:8090/discovery/scenarios/service2/deadbeef-3382-4668-86e7-deadbeefb935/
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
--
|
||||
-- Version 0.1
|
||||
@@ -60,7 +60,7 @@ discoverThread = function( funcname, results )
|
||||
local helper = wsdd.Helper:new()
|
||||
helper:setMulticast(true)
|
||||
helper:setTimeout(timeout)
|
||||
|
||||
|
||||
local status, result = helper[funcname](helper)
|
||||
if ( status ) then table.insert(results, result) end
|
||||
condvar("broadcast")
|
||||
@@ -77,12 +77,12 @@ action = function()
|
||||
|
||||
local threads, results = {}, {}
|
||||
local condvar = nmap.condvar( results )
|
||||
|
||||
|
||||
-- Attempt to discover both devices and WCF web services
|
||||
for _, f in ipairs( {"discoverDevices", "discoverWCFServices"} ) do
|
||||
threads[stdnse.new_thread( discoverThread, f, results )] = true
|
||||
end
|
||||
|
||||
|
||||
local done
|
||||
-- wait for all threads to finish
|
||||
while( not(done) ) do
|
||||
|
||||
@@ -15,7 +15,7 @@ are marked using the keyword Willing in the result.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | broadcast-xdmcp-discover:
|
||||
-- | broadcast-xdmcp-discover:
|
||||
-- |_ 192.168.2.162 - Willing
|
||||
--
|
||||
-- @args broadcast-xdmcp-discover.timeout socket timeout (default: 5s)
|
||||
@@ -32,16 +32,16 @@ local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME ..
|
||||
action = function()
|
||||
|
||||
local host, port = { ip = "255.255.255.255" }, { number = 177, protocol = "udp" }
|
||||
local options = { timeout = 1 }
|
||||
local options = { timeout = 1 }
|
||||
local helper = xdmcp.Helper:new(host, port, options)
|
||||
local status = helper:connect()
|
||||
|
||||
|
||||
local req = xdmcp.Packet[xdmcp.OpCode.BCAST_QUERY]:new(nil)
|
||||
local status, err = helper:send(req)
|
||||
if ( not(status) ) then
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
local timeout = arg_timeout or 5
|
||||
local start = os.time()
|
||||
local result = {}
|
||||
@@ -58,7 +58,7 @@ action = function()
|
||||
result[rhost] = false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
until( os.time() - start > timeout )
|
||||
|
||||
local output = {}
|
||||
|
||||
@@ -21,7 +21,7 @@ http://cassandra.apache.org/
|
||||
-- @output
|
||||
-- PORT STATE SERVICE VERSION
|
||||
-- 9160/tcp open apani1?
|
||||
-- | cassandra-brute:
|
||||
-- | cassandra-brute:
|
||||
-- | Accounts
|
||||
-- | admin:lover - Valid credentials
|
||||
-- | Statistics
|
||||
@@ -35,14 +35,14 @@ categories = {"intrusive", "brute"}
|
||||
portrule = shortport.port_or_service({9160}, {"cassandra"})
|
||||
|
||||
Driver = {
|
||||
|
||||
|
||||
new = function(self, host, port, options)
|
||||
local o = { host = host, port = port, socket = nmap.new_socket() }
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect = function(self)
|
||||
return self.socket:connect(self.host, self.port)
|
||||
end,
|
||||
@@ -73,7 +73,7 @@ Driver = {
|
||||
err:setAbort( true )
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
_, size = bin.unpack(">I", response, 1)
|
||||
|
||||
magic = string.sub(response,18,22)
|
||||
@@ -83,10 +83,10 @@ Driver = {
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
elseif (magic == cassandra.LOGINFAIL) then
|
||||
stdnse.print_debug(3,"Account FAIL: "..combo)
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
elseif (magic == cassandra.LOGINACC) then
|
||||
stdnse.print_debug(3, "Account VALID, but wrong password: "..combo)
|
||||
return false, brute.Error:new( "Good user, bad password" )
|
||||
return false, brute.Error:new( "Good user, bad password" )
|
||||
else
|
||||
stdnse.print_debug(3, "Unrecognized packet for "..combo)
|
||||
stdnse.print_debug(3, "packet hex: %s", stdnse.tohex(response) )
|
||||
@@ -95,13 +95,13 @@ Driver = {
|
||||
local err = brute.Error:new( response )
|
||||
err:setRetry( true )
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function(self)
|
||||
return self.socket:close()
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
local function noAuth(host, port)
|
||||
@@ -124,7 +124,7 @@ action = function(host, port)
|
||||
end
|
||||
|
||||
local engine = brute.Engine:new(Driver, host, port )
|
||||
|
||||
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
engine.options.firstonly = true
|
||||
local status, result = engine:start()
|
||||
|
||||
@@ -18,14 +18,14 @@ http://cassandra.apache.org/
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 9160 <ip> --script=cassandra-info
|
||||
--
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 9160/tcp open cassandra syn-ack
|
||||
-- | cassandra-info:
|
||||
-- | cassandra-info:
|
||||
-- | Cluster name: Test Cluster
|
||||
-- |_ Version: 19.10.0
|
||||
--
|
||||
--
|
||||
|
||||
-- version 0.1
|
||||
-- Created 14/09/2012 - v0.1 - created by Vlatko Kosturjak <kost@linux.hr>
|
||||
@@ -42,18 +42,18 @@ function action(host,port)
|
||||
|
||||
local socket = nmap.new_socket()
|
||||
local cassinc = 2 -- cmd/resp starts at 2
|
||||
|
||||
|
||||
-- set a reasonable timeout value
|
||||
socket:set_timeout(10000)
|
||||
-- do some exception / cleanup
|
||||
local catch = function()
|
||||
socket:close()
|
||||
end
|
||||
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
try( socket:connect(host, port) )
|
||||
|
||||
|
||||
local results = {}
|
||||
|
||||
-- uglyness to allow creds.cassandra to work, as the port is not recognized
|
||||
|
||||
@@ -22,7 +22,7 @@ accounts will be locked.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 8080/tcp open http-proxy syn-ack
|
||||
-- | citrix-brute-xml:
|
||||
-- | citrix-brute-xml:
|
||||
-- | Joe:password => Must change password at next logon
|
||||
-- | Luke:summer => Login was successful
|
||||
-- |_ Jane:secret => Account is disabled
|
||||
@@ -49,18 +49,18 @@ portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
-- @param domain string, the Windows domain to authenticate against
|
||||
--
|
||||
-- @return success, message
|
||||
--
|
||||
--
|
||||
function verify_password( host, port, username, password, domain )
|
||||
|
||||
local response = citrixxml.request_validate_credentials(host, port, {Credentials={Domain=domain, Password=password, UserName=username}})
|
||||
local cred_status = citrixxml.parse_validate_credentials_response(response)
|
||||
|
||||
|
||||
local account = {}
|
||||
|
||||
account.username = username
|
||||
account.password = password
|
||||
account.domain = domain
|
||||
|
||||
|
||||
if cred_status.ErrorId then
|
||||
if cred_status.ErrorId == "must-change-credentials" then
|
||||
account.valid = true
|
||||
@@ -88,7 +88,7 @@ function verify_password( host, port, username, password, domain )
|
||||
end
|
||||
|
||||
return account
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Formats the result from the table of valid accounts
|
||||
@@ -99,10 +99,10 @@ function create_result_from_table(accounts)
|
||||
|
||||
local result = ""
|
||||
|
||||
for _, account in ipairs(accounts) do
|
||||
for _, account in ipairs(accounts) do
|
||||
result = result .. " " .. account.username .. ":" .. account.password .. " => " .. account.message .. "\n"
|
||||
end
|
||||
|
||||
|
||||
return "\n" .. result
|
||||
end
|
||||
|
||||
@@ -113,13 +113,13 @@ action = function(host, port)
|
||||
local args = nmap.registry.args
|
||||
local ntdomain = args.ntdomain
|
||||
local valid_accounts = {}
|
||||
|
||||
|
||||
if not ntdomain then
|
||||
return "FAILED: No domain specified (use ntdomain argument)"
|
||||
end
|
||||
|
||||
|
||||
status, nextUser = unpwdb.usernames()
|
||||
|
||||
|
||||
if not status then
|
||||
return
|
||||
end
|
||||
@@ -129,36 +129,36 @@ action = function(host, port)
|
||||
if not status then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
username = nextUser()
|
||||
|
||||
|
||||
-- iterate over userlist
|
||||
while username do
|
||||
password = nextPass()
|
||||
|
||||
|
||||
-- iterate over passwordlist
|
||||
while password do
|
||||
local result = "Trying " .. username .. "/" .. password .. " "
|
||||
local account = verify_password(host.ip, port.number, username, password, ntdomain)
|
||||
|
||||
|
||||
if account.valid then
|
||||
|
||||
|
||||
table.insert(valid_accounts, account)
|
||||
|
||||
|
||||
if account.valid then
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Correct, Info: %s", username, password, account.message)
|
||||
else
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Correct", username, password)
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Correct", username, password)
|
||||
end
|
||||
else
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Failed, Reason: %s", username, password, account.message)
|
||||
end
|
||||
password = nextPass()
|
||||
end
|
||||
|
||||
|
||||
nextPass("reset")
|
||||
username = nextUser()
|
||||
end
|
||||
|
||||
|
||||
return create_result_from_table(valid_accounts)
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ local shortport = require "shortport"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
|
||||
description = [[
|
||||
description = [[
|
||||
Extracts a list of applications, ACLs, and settings from the Citrix XML
|
||||
service.
|
||||
|
||||
@@ -18,14 +18,14 @@ The script returns more output with higher verbosity.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8080/tcp open http-proxy
|
||||
-- | citrix-enum-apps-xml:
|
||||
-- | citrix-enum-apps-xml:
|
||||
-- | Application: Notepad; Users: Anonymous
|
||||
-- | Application: iexplorer; Users: Anonymous
|
||||
-- |_ Application: registry editor; Users: WIN-B4RL0SUCJ29\Joe; Groups: WIN-B4RL0SUCJ29\HR, *CITRIX_BUILTIN*\*CITRIX_ADMINISTRATORS*
|
||||
--
|
||||
-- PORT STATE SERVICE
|
||||
-- 8080/tcp open http-proxy
|
||||
-- | citrix-enum-apps-xml:
|
||||
-- | citrix-enum-apps-xml:
|
||||
-- | Application: Notepad
|
||||
-- | Disabled: false
|
||||
-- | Desktop: false
|
||||
@@ -77,7 +77,7 @@ portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
function format_output(appdata, mode)
|
||||
|
||||
local result = {}
|
||||
local setting_titles = { {appisdisabled="Disabled"}, {appisdesktop="Desktop"}, {AppOnDesktop="On Desktop"},
|
||||
local setting_titles = { {appisdisabled="Disabled"}, {appisdesktop="Desktop"}, {AppOnDesktop="On Desktop"},
|
||||
{Encryption="Encryption"}, {AppInStartmenu="In start menu"},
|
||||
{PublisherName="Publisher"}, {SSLEnabled="SSL"}, {RemoteAccessEnabled="Remote Access"} }
|
||||
|
||||
@@ -88,7 +88,7 @@ function format_output(appdata, mode)
|
||||
|
||||
if AppData.AccessList then
|
||||
|
||||
if AppData.AccessList.User then
|
||||
if AppData.AccessList.User then
|
||||
line = line .. "; Users: " .. stdnse.strjoin(", ", AppData.AccessList.User)
|
||||
end
|
||||
|
||||
@@ -104,9 +104,9 @@ function format_output(appdata, mode)
|
||||
|
||||
for app_name, AppData in ipairs(appdata) do
|
||||
local result_part = {}
|
||||
|
||||
|
||||
result_part.name = "Application: " .. AppData.FName
|
||||
|
||||
|
||||
local settings = AppData.Settings
|
||||
|
||||
for _, setting_pairs in ipairs(setting_titles) do
|
||||
@@ -120,15 +120,15 @@ function format_output(appdata, mode)
|
||||
if AppData.AccessList then
|
||||
if AppData.AccessList.User then
|
||||
table.insert(result_part, "Users: " .. stdnse.strjoin(", ", AppData.AccessList.User) )
|
||||
end
|
||||
|
||||
if AppData.AccessList.Group then
|
||||
end
|
||||
|
||||
if AppData.AccessList.Group then
|
||||
table.insert(result_part, "Groups: " .. stdnse.strjoin(", ", AppData.AccessList.Group) )
|
||||
end
|
||||
|
||||
|
||||
table.insert(result, result_part)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -136,15 +136,15 @@ function format_output(appdata, mode)
|
||||
return result
|
||||
|
||||
end
|
||||
|
||||
|
||||
action = function(host,port)
|
||||
|
||||
local response = citrixxml.request_appdata(host.ip, port.number, {ServerAddress="",attr={addresstype="dot"},DesiredDetails={"all","access-list"} })
|
||||
|
||||
action = function(host,port)
|
||||
|
||||
local response = citrixxml.request_appdata(host.ip, port.number, {ServerAddress="",attr={addresstype="dot"},DesiredDetails={"all","access-list"} })
|
||||
local appdata = citrixxml.parse_appdata_response(response)
|
||||
|
||||
|
||||
local response = format_output(appdata, (nmap.verbosity() > 1 and "long" or "short"))
|
||||
|
||||
|
||||
return stdnse.format_output(true, response)
|
||||
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ local stdnse = require "stdnse"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
|
||||
description = [[
|
||||
description = [[
|
||||
Extracts a list of published applications from the ICA Browser service.
|
||||
]]
|
||||
|
||||
@@ -16,7 +16,7 @@ Extracts a list of published applications from the ICA Browser service.
|
||||
-- PORT STATE SERVICE
|
||||
-- 1604/udp open unknown
|
||||
-- 1604/udp open unknown
|
||||
-- | citrix-enum-apps:
|
||||
-- | citrix-enum-apps:
|
||||
-- | Notepad
|
||||
-- | iexplorer
|
||||
-- |_ registry editor
|
||||
@@ -41,7 +41,7 @@ portrule = shortport.portnumber(1604, "udp")
|
||||
-- @param response string, complete server response
|
||||
-- @return string row delimited with \n containing all published applications
|
||||
function process_pa_response(response)
|
||||
|
||||
|
||||
local pos, packet_len = bin.unpack("SS", response)
|
||||
local app_name
|
||||
local pa_list = {}
|
||||
@@ -56,7 +56,7 @@ function process_pa_response(response)
|
||||
while offset < packet_len do
|
||||
pos, app_name = bin.unpack("z", response:sub(offset))
|
||||
offset = offset + pos - 1
|
||||
|
||||
|
||||
table.insert(pa_list, app_name)
|
||||
end
|
||||
|
||||
@@ -73,7 +73,7 @@ action = function(host, port)
|
||||
|
||||
--
|
||||
-- Packets were intercepted from the Citrix Program Neighborhood client
|
||||
-- They are used to query a server for it's list of servers
|
||||
-- They are used to query a server for it's list of servers
|
||||
--
|
||||
-- We're really not interested in the responses to the first two packets
|
||||
-- The third response contains the list of published applications
|
||||
@@ -81,12 +81,12 @@ action = function(host, port)
|
||||
-- some brief information for the bits and bytes this script uses.
|
||||
--
|
||||
-- Spec. of response to query[2] that contains a list of published apps
|
||||
--
|
||||
--
|
||||
-- offset size content
|
||||
-- -------------------------
|
||||
-- 0 16-bit Length
|
||||
-- 12 32-bit Server IP (not used here)
|
||||
-- 30 8-bit Last packet (1), More packets(0)
|
||||
-- 30 8-bit Last packet (1), More packets(0)
|
||||
-- 40 - null-separated list of applications
|
||||
--
|
||||
query[0] = string.char(
|
||||
@@ -99,19 +99,19 @@ action = function(host, port)
|
||||
|
||||
query[1] = string.char(
|
||||
0x20, 0x00, -- Length: 32
|
||||
0x01, 0x36, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x36, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
|
||||
query[2] = string.char(
|
||||
0x2a, 0x00, -- Length: 42
|
||||
0x01, 0x32, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
counter = 0
|
||||
@@ -141,18 +141,18 @@ action = function(host, port)
|
||||
while packet:sub(31,31) ~= string.char(0x01) do
|
||||
packet = try( socket:receive() )
|
||||
local tmp_table = process_pa_response( packet )
|
||||
|
||||
|
||||
for _,v in pairs(tmp_table) do
|
||||
table.insert(pa_list, v)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
-- set port to open
|
||||
if #pa_list>0 then
|
||||
nmap.set_port_state(host, port, "open")
|
||||
end
|
||||
|
||||
|
||||
socket:close()
|
||||
|
||||
return stdnse.format_output(true, pa_list)
|
||||
|
||||
@@ -15,7 +15,7 @@ service.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 8080/tcp open http-proxy syn-ack
|
||||
-- | citrix-enum-servers-xml:
|
||||
-- | citrix-enum-servers-xml:
|
||||
-- | CITRIX-SRV01
|
||||
-- |_ CITRIX-SRV01
|
||||
|
||||
@@ -29,7 +29,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
|
||||
portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
@@ -37,11 +37,11 @@ action = function(host, port)
|
||||
local xmldata = citrixxml.request_server_data(host.ip, port.number)
|
||||
local servers = citrixxml.parse_server_data_response(xmldata)
|
||||
local response = {}
|
||||
|
||||
|
||||
for _, srv in ipairs(servers) do
|
||||
table.insert(response, srv)
|
||||
end
|
||||
|
||||
|
||||
return stdnse.format_output(true, response)
|
||||
|
||||
end
|
||||
|
||||
@@ -5,18 +5,18 @@ local stdnse = require "stdnse"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
|
||||
description = [[
|
||||
description = [[
|
||||
Extracts a list of Citrix servers from the ICA Browser service.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage sudo ./nmap -sU --script=citrix-enum-servers -p 1604
|
||||
-- @usage sudo ./nmap -sU --script=citrix-enum-servers -p 1604
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 1604/udp open unknown
|
||||
-- | citrix-enum-servers:
|
||||
-- | CITRIXSRV01
|
||||
-- | citrix-enum-servers:
|
||||
-- | CITRIXSRV01
|
||||
-- |_ CITRIXSRV02
|
||||
--
|
||||
|
||||
@@ -39,7 +39,7 @@ portrule = shortport.portnumber(1604, "udp")
|
||||
-- @return string row delimited with \n containing all published applications
|
||||
--
|
||||
function process_server_response(response)
|
||||
|
||||
|
||||
local pos, packet_len = bin.unpack("SS", response)
|
||||
local server_name
|
||||
local server_list = {}
|
||||
@@ -78,31 +78,31 @@ action = function(host, port)
|
||||
-- some brief information for the bits and bytes this script uses.
|
||||
--
|
||||
-- Spec. of response to query[2] that contains a list of published apps
|
||||
--
|
||||
--
|
||||
-- offset size content
|
||||
-- -------------------------
|
||||
-- 0 16-bit Length
|
||||
-- 12 32-bit Server IP (not used here)
|
||||
-- 30 8-bit Last packet (1), More packets(0)
|
||||
-- 30 8-bit Last packet (1), More packets(0)
|
||||
-- 40 - null-separated list of applications
|
||||
--
|
||||
query[0] = string.char(
|
||||
0x1e, 0x00, -- Length: 30
|
||||
0x01, 0x30, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
query[1] = string.char(
|
||||
0x2a, 0x00, -- Length: 42
|
||||
0x01, 0x32, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x01, 0x32, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
|
||||
counter = 0
|
||||
|
||||
socket = nmap.new_socket()
|
||||
@@ -128,8 +128,8 @@ action = function(host, port)
|
||||
--
|
||||
while packet:sub(31,31) ~= string.char(0x01) do
|
||||
packet = try( socket:receive() )
|
||||
local tmp_table = process_server_response( packet )
|
||||
|
||||
local tmp_table = process_server_response( packet )
|
||||
|
||||
for _, v in ipairs(tmp_table) do
|
||||
table.insert(server_list, v)
|
||||
end
|
||||
@@ -138,7 +138,7 @@ action = function(host, port)
|
||||
if #server_list>0 then
|
||||
nmap.set_port_state(host, port, "open")
|
||||
end
|
||||
|
||||
|
||||
socket:close()
|
||||
|
||||
return stdnse.format_output(true, server_list)
|
||||
|
||||
@@ -8,7 +8,7 @@ local table = require "table"
|
||||
description = [[
|
||||
Gets database tables from a CouchDB database.
|
||||
|
||||
For more info about the CouchDB HTTP API, see
|
||||
For more info about the CouchDB HTTP API, see
|
||||
http://wiki.apache.org/couchdb/HTTP_database_API.
|
||||
]]
|
||||
|
||||
@@ -18,7 +18,7 @@ http://wiki.apache.org/couchdb/HTTP_database_API.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 5984/tcp open unknown syn-ack
|
||||
-- | couchdb-databases:
|
||||
-- | couchdb-databases:
|
||||
-- | 1 = test_suite_db
|
||||
-- | 2 = test_suite_db_a
|
||||
-- | 3 = test_suite_db/with_slashes
|
||||
@@ -68,32 +68,32 @@ action = function(host, port)
|
||||
local data, result, err
|
||||
dbg("Requesting all databases")
|
||||
data = http.get( host, port, '/_all_dbs' )
|
||||
|
||||
|
||||
-- check that body was received
|
||||
if not data.body or data.body == "" then
|
||||
local msg = ("%s did not respond with any data."):format(host.targetname or host.ip )
|
||||
dbg( msg )
|
||||
dbg( msg )
|
||||
return msg
|
||||
end
|
||||
|
||||
-- The html body should look like this :
|
||||
|
||||
-- The html body should look like this :
|
||||
-- ["somedatabase", "anotherdatabase"]
|
||||
|
||||
|
||||
local status, result = json.parse(data.body)
|
||||
if not status then
|
||||
dbg(result)
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
-- Here we know it is a couchdb
|
||||
port.version.name ='httpd'
|
||||
port.version.product='Apache CouchDB'
|
||||
nmap.set_port_version(host,port)
|
||||
|
||||
|
||||
-- We have a valid table in result containing the parsed json
|
||||
-- now, get all the interesting bits
|
||||
|
||||
-- now, get all the interesting bits
|
||||
|
||||
result = queryResultToTable(result)
|
||||
|
||||
|
||||
return stdnse.format_output(true, result )
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ local table = require "table"
|
||||
description = [[
|
||||
Gets database statistics from a CouchDB database.
|
||||
|
||||
For more info about the CouchDB HTTP API and the statistics, see
|
||||
For more info about the CouchDB HTTP API and the statistics, see
|
||||
http://wiki.apache.org/couchdb/Runtime_Statistics
|
||||
and
|
||||
http://wiki.apache.org/couchdb/HTTP_database_API.
|
||||
@@ -21,7 +21,7 @@ http://wiki.apache.org/couchdb/HTTP_database_API.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 5984/tcp open httpd syn-ack
|
||||
-- | couchdb-stats:
|
||||
-- | couchdb-stats:
|
||||
-- | httpd_request_methods
|
||||
-- | GET (number of HTTP GET requests)
|
||||
-- | current = 5
|
||||
@@ -84,17 +84,17 @@ end
|
||||
|
||||
action = function(host, port)
|
||||
local data, result, err
|
||||
|
||||
|
||||
data = http.get( host, port, '/_stats' )
|
||||
|
||||
|
||||
-- check that body was received
|
||||
if not data.body or data.body == "" then
|
||||
local msg = ("%s did not respond with any data."):format(host.targetname or host.ip )
|
||||
dbg( msg )
|
||||
dbg( msg )
|
||||
return msg
|
||||
end
|
||||
|
||||
-- The html body should look like this :
|
||||
|
||||
-- The html body should look like this :
|
||||
--
|
||||
--{"httpd_status_codes":{"200":{"current":10,"count":29894,"mean":0.0003345152873486337,"min":0,"max":1,"stddev":0.01828669972606202,"description":"number of HTTP 200 OK responses"},"500":{"current":1,"count":28429,"mean":0.00003517534911534013,"min":0,"max":1,"stddev":0.005930776661631644,"description":"number of HTTP 500 Internal Server Error responses"}},"httpd_request_methods":{"GET":{"current":12,"count":29894,"mean":0.00040141834481835866,"min":0,"max":2,"stddev":0.02163701147572207,"description":"number of HTTP GET requests"}},"httpd":{"requests":{"current":12,"count":29894,"mean":0.00040141834481835866,"min":0,"max":2,"stddev":0.02163701147572207,"description":"number of HTTP requests"}},"couchdb":{"request_time":{"current":23,"count":12,"mean":32.58333333333333,"min":1,"max":287,"stddev":77.76723638882608,"description":"length of a request inside CouchDB without MochiWeb"}}}
|
||||
|
||||
@@ -103,19 +103,19 @@ action = function(host, port)
|
||||
dbg(result)
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
-- Here we know it is a couchdb
|
||||
port.version.name ='httpd'
|
||||
port.version.product='Apache CouchDB'
|
||||
nmap.set_port_version(host,port)
|
||||
|
||||
|
||||
-- We have a valid table in result containing the parsed json
|
||||
-- now, get all the interesting bits
|
||||
|
||||
-- now, get all the interesting bits
|
||||
|
||||
result = queryResultToTable(result)
|
||||
|
||||
|
||||
-- Additionally, we can check if authentication is used :
|
||||
-- The following actions are restricted if auth is used
|
||||
-- The following actions are restricted if auth is used
|
||||
-- create db (PUT /database)
|
||||
-- delete db (DELETE /database)
|
||||
-- Creating a design document (PUT /database/_design/app)
|
||||
@@ -126,13 +126,13 @@ action = function(host, port)
|
||||
-- Restart the server (POST /_restart)
|
||||
-- Read the active configuration (GET /_config)
|
||||
-- Update the active configuration (PUT /_config)
|
||||
|
||||
data = http.get( host, port, '/_config' )
|
||||
|
||||
data = http.get( host, port, '/_config' )
|
||||
local status, authresult = json.parse(data.body)
|
||||
|
||||
-- If authorization is used, we should get back something like
|
||||
-- {"error":"unauthorized","reason":"You are not a server admin."}
|
||||
-- Otherwise, a *lot* of data, :
|
||||
-- Otherwise, a *lot* of data, :
|
||||
-- {"httpd_design_handlers":{"_info":"{couch_httpd_db, handle_design_info_req}",
|
||||
-- "_list":"{couch_httpd_show, handle_view_list_req}","_show":"{couch_httpd_show, handle_doc_show_req}",
|
||||
-- "_update":"{couch_httpd_show, handle_doc_update_req}","_view":"{couch_httpd_view, handle_view_req}"},
|
||||
@@ -163,9 +163,9 @@ action = function(host, port)
|
||||
local auth = "Authentication : %s"
|
||||
local authEnabled = "unknown"
|
||||
|
||||
if(status) then
|
||||
if(status) then
|
||||
if(authresult["error"] == "unauthorized") then authEnabled = "enabled"
|
||||
elseif (authresult["httpd_design_handlers"] ~= nil) then authEnabled = "NOT enabled ('admin party')"
|
||||
elseif (authresult["httpd_design_handlers"] ~= nil) then authEnabled = "NOT enabled ('admin party')"
|
||||
end
|
||||
end
|
||||
table.insert(result, auth:format(authEnabled))
|
||||
|
||||
@@ -6,7 +6,7 @@ Lists all discovered credentials (e.g. from brute force and default password che
|
||||
|
||||
---
|
||||
--@output
|
||||
-- | creds-summary:
|
||||
-- | creds-summary:
|
||||
-- | 10.10.10.10
|
||||
-- | 22/ssh
|
||||
-- | lisbon:jane - Account is valid
|
||||
@@ -29,7 +29,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"auth", "default", "safe"}
|
||||
|
||||
|
||||
postrule = function()
|
||||
postrule = function()
|
||||
local all = creds.Credentials:new(creds.ALL_DATA)
|
||||
local tab = all:getTable()
|
||||
if ( tab and #tab > 0 ) then return true end
|
||||
|
||||
@@ -15,22 +15,22 @@ Lists printers managed by the CUPS printing service.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 631/tcp open ipp
|
||||
-- | cups-info:
|
||||
-- | cups-info:
|
||||
-- | Generic-PostScript-Printer
|
||||
-- | DNS-SD Name: Lexmark S300-S400 Series @ ubu1110
|
||||
-- | Location:
|
||||
-- | Location:
|
||||
-- | Model: Local Raw Printer
|
||||
-- | State: Processing
|
||||
-- | Queue: 0 print jobs
|
||||
-- | Lexmark-S300-S400-Series
|
||||
-- | DNS-SD Name: Lexmark S300-S400 Series @ ubu1110
|
||||
-- | Location:
|
||||
-- | Location:
|
||||
-- | Model: Local Raw Printer
|
||||
-- | State: Stopped
|
||||
-- | Queue: 0 print jobs
|
||||
-- | PDF
|
||||
-- | DNS-SD Name: PDF @ ubu1110
|
||||
-- | Location:
|
||||
-- | Location:
|
||||
-- | Model: Generic CUPS-PDF Printer
|
||||
-- | State: Idle
|
||||
-- |_ Queue: 0 print jobs
|
||||
@@ -51,12 +51,12 @@ action = function(host, port)
|
||||
if ( not(helper:connect()) ) then
|
||||
return fail("Failed to connect to server")
|
||||
end
|
||||
|
||||
|
||||
local status, printers = helper:getPrinters()
|
||||
if ( not(status) ) then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local output = {}
|
||||
for _, printer in ipairs(printers) do
|
||||
local states = {
|
||||
@@ -65,7 +65,7 @@ action = function(host, port)
|
||||
[ipp.IPP.PrinterState.IPP_PRINTER_STOPPED] = "Stopped",
|
||||
}
|
||||
local pos, state = bin.unpack(">I", printer.state)
|
||||
table.insert(output, {
|
||||
table.insert(output, {
|
||||
name = printer.name,
|
||||
("DNS-SD Name: %s"):format(printer.dns_sd_name or ""),
|
||||
("Location: %s"):format(printer.location or ""),
|
||||
@@ -74,7 +74,7 @@ action = function(host, port)
|
||||
("Queue: %s print jobs"):format(tonumber(printer.queue_count) or 0),
|
||||
} )
|
||||
end
|
||||
|
||||
|
||||
if ( 0 ~= #output ) then
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
|
||||
@@ -9,12 +9,12 @@ printer.
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 631 <ip> --script cups-queue-info
|
||||
-- nmap -p 631 <ip> --script cups-queue-info
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 631/tcp open ipp
|
||||
-- | cups-queue-info:
|
||||
-- | cups-queue-info:
|
||||
-- | HP Laserjet
|
||||
-- | id time state size (kb) owner jobname
|
||||
-- | 14 2012-04-26 22:01:19 Held 2071k Patrik Karlsson Print - CUPS Implementation of IPP - Documentation - CUPS
|
||||
@@ -41,7 +41,7 @@ action = function(host, port)
|
||||
if ( not(helper:connect()) ) then
|
||||
return fail("Failed to connect to server")
|
||||
end
|
||||
|
||||
|
||||
local output = helper:getQueueInfo()
|
||||
if ( output ) then
|
||||
return stdnse.format_output(true, output)
|
||||
|
||||
@@ -14,13 +14,13 @@ With knowledge of the correct repository name, usernames and passwords can be gu
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- @usage
|
||||
-- nmap -p 2401 --script cvs-brute-repository <host>
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 2401/tcp open cvspserver syn-ack
|
||||
-- | cvs-brute-repository:
|
||||
-- | cvs-brute-repository:
|
||||
-- | Repositories
|
||||
-- | /myrepos
|
||||
-- | /demo
|
||||
@@ -44,7 +44,7 @@ categories = {"intrusive", "brute"}
|
||||
|
||||
portrule = shortport.port_or_service(2401, "cvspserver")
|
||||
|
||||
Driver =
|
||||
Driver =
|
||||
{
|
||||
|
||||
new = function(self, host, port )
|
||||
@@ -53,7 +53,7 @@ Driver =
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect = function( self )
|
||||
self.helper:connect()
|
||||
return true
|
||||
@@ -72,30 +72,30 @@ Driver =
|
||||
end
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function( self )
|
||||
self.helper:close()
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local status, result
|
||||
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
|
||||
|
||||
-- a list of "common" repository names:
|
||||
-- the first two are Debian/Ubuntu default names
|
||||
-- the rest were found during tests or in google searches
|
||||
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",
|
||||
"/usr/local/cvs"}
|
||||
|
||||
|
||||
local repofile = stdnse.get_script_args("cvs-brute-repository.repofile")
|
||||
local f
|
||||
|
||||
|
||||
if ( repofile ) then
|
||||
f = io.open( repofile, "r" )
|
||||
if ( not(f) ) then
|
||||
@@ -114,7 +114,7 @@ action = function(host, port)
|
||||
end
|
||||
return coroutine.wrap(next_repo)
|
||||
end
|
||||
|
||||
|
||||
engine.options:setTitle("Repositories")
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
engine.options.passonly = true
|
||||
|
||||
@@ -10,12 +10,12 @@ Performs brute force password auditing against CVS pserver authentication.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- @usage
|
||||
-- nmap -p 2401 --script cvs-brute <host>
|
||||
--
|
||||
-- @output
|
||||
-- 2401/tcp open cvspserver syn-ack
|
||||
-- | cvs-brute:
|
||||
-- | cvs-brute:
|
||||
-- | Accounts
|
||||
-- | hotchner:francisco - Account is valid
|
||||
-- | reid:secret - Account is valid
|
||||
@@ -40,7 +40,7 @@ dependencies = {"cvs-brute-repository"}
|
||||
|
||||
portrule = shortport.port_or_service(2401, "cvspserver")
|
||||
|
||||
Driver =
|
||||
Driver =
|
||||
{
|
||||
|
||||
new = function(self, host, port, repo)
|
||||
@@ -49,7 +49,7 @@ Driver =
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect = function( self )
|
||||
self.helper:connect()
|
||||
return true
|
||||
@@ -57,10 +57,10 @@ Driver =
|
||||
|
||||
login = function( self, username, password )
|
||||
local status, err = self.helper:login( self.repo, username, password )
|
||||
if ( status ) then
|
||||
if ( status ) then
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
|
||||
-- This error seems to indicate tha the user does not exist
|
||||
if ( err:match("E PAM start error%: Critical error %- immediate abort\0$") ) then
|
||||
stdnse.print_debug(2, "%s: The user %s does not exist", SCRIPT_NAME, username)
|
||||
@@ -70,36 +70,36 @@ Driver =
|
||||
end
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function( self )
|
||||
self.helper:close()
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
local function getDiscoveredRepos(host)
|
||||
|
||||
if ( not(host.registry.cvs_repos)) then
|
||||
if ( not(host.registry.cvs_repos)) then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
return host.registry.cvs_repos
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local repo = stdnse.get_script_args("cvs-brute.repo") and
|
||||
{ stdnse.get_script_args("cvs-brute.repo") } or
|
||||
|
||||
local repo = stdnse.get_script_args("cvs-brute.repo") and
|
||||
{ stdnse.get_script_args("cvs-brute.repo") } or
|
||||
getDiscoveredRepos(host)
|
||||
if ( not(repo) ) then return "\n ERROR: No CVS repository specified (see cvs-brute.repo)" end
|
||||
|
||||
local status, result
|
||||
|
||||
|
||||
-- If repositories were discovered and not overridden by argument
|
||||
-- only attempt to brute force the first one.
|
||||
local engine = brute.Engine:new(Driver, host, port, repo[1])
|
||||
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
status, result = engine:start()
|
||||
|
||||
return result
|
||||
|
||||
@@ -23,7 +23,7 @@ http://www.tapjam.net/daap/.
|
||||
-- @args daap_item_limit Changes the output limit from 100 songs. If set to a negative value, no limit is enforced.
|
||||
--
|
||||
-- @output
|
||||
-- | daap-get-library:
|
||||
-- | daap-get-library:
|
||||
-- | BUBBA|TWO
|
||||
-- | Fever Ray
|
||||
-- | Fever Ray (Deluxe Edition)
|
||||
@@ -53,8 +53,8 @@ portrule = shortport.port_or_service(3689, "daap")
|
||||
|
||||
--- Gets the name of the library from the server
|
||||
--
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @return string containing the name of the library
|
||||
function getLibraryName( host, port )
|
||||
local _, libname, pos
|
||||
@@ -64,7 +64,7 @@ function getLibraryName( host, port )
|
||||
if response == nil or response.body == nil or response.body=="" then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
pos = string.find(response.body, "minm")
|
||||
|
||||
if pos > 0 then
|
||||
@@ -73,88 +73,88 @@ function getLibraryName( host, port )
|
||||
pos, len = bin.unpack( ">I", response.body, pos )
|
||||
pos, libname = bin.unpack( "A" .. len, response.body, pos )
|
||||
end
|
||||
|
||||
|
||||
return libname
|
||||
end
|
||||
|
||||
--- Reads the first item value specified by name
|
||||
--- Reads the first item value specified by name
|
||||
--
|
||||
-- @param data string containing the unparsed item
|
||||
-- @param name string containing the name of the value to read
|
||||
-- @return number
|
||||
-- @return number
|
||||
local function getAttributeAsInt( data, name )
|
||||
|
||||
local pos = string.find(data, name)
|
||||
local attrib
|
||||
|
||||
|
||||
if pos and pos > 0 then
|
||||
pos = pos + 4
|
||||
local len
|
||||
pos, len = bin.unpack( ">I", data, pos )
|
||||
|
||||
|
||||
if ( len ~= 4 ) then
|
||||
stdnse.print_debug( string.format("Unexpected length returned: %d", len ) )
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
pos, attrib = bin.unpack( ">I", data, pos )
|
||||
end
|
||||
|
||||
|
||||
return attrib
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Gets the revision number for the library
|
||||
--
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @return number containing the session identity received from the server
|
||||
function getSessionId( host, port )
|
||||
|
||||
local _, sessionid
|
||||
local response = http.get( host, port, "/login", nil, nil, nil )
|
||||
|
||||
|
||||
if response ~= nil then
|
||||
sessionid = getAttributeAsInt( response.body, "mlid")
|
||||
sessionid = getAttributeAsInt( response.body, "mlid")
|
||||
end
|
||||
|
||||
|
||||
return sessionid
|
||||
end
|
||||
|
||||
--- Gets the revision number for the library
|
||||
--
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param sessionid number containing session identifier from <code>getSessionId</code>
|
||||
-- @return number containing the revision number for the library
|
||||
function getRevisionNumber( host, port, sessionid )
|
||||
local url = "/update?session-id=" .. sessionid .. "&revision-number=1"
|
||||
local _, revision
|
||||
local response = http.get( host, port, url, nil, nil, nil )
|
||||
|
||||
|
||||
if response ~= nil then
|
||||
revision = getAttributeAsInt( response.body, "musr")
|
||||
end
|
||||
|
||||
return revision
|
||||
|
||||
return revision
|
||||
end
|
||||
|
||||
--- Gets the database identitity for the library
|
||||
--
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param sessionid number containing session identifier from <code>getSessionId</code>
|
||||
-- @param revid number containing the revision id as retrieved from <code>getRevisionNumber</code>
|
||||
function getDatabaseId( host, port, sessionid, revid )
|
||||
local url = "/databases?session-id=" .. sessionid .. "&revision-number=" .. revid
|
||||
local response = http.get( host, port, url, nil, nil, nil )
|
||||
local miid
|
||||
|
||||
|
||||
if response ~= nil then
|
||||
miid = getAttributeAsInt( response.body, "miid")
|
||||
end
|
||||
|
||||
return miid
|
||||
|
||||
return miid
|
||||
end
|
||||
|
||||
--- Gets a string item type from data
|
||||
@@ -165,13 +165,13 @@ end
|
||||
-- @return value string containing the string item that was read
|
||||
local function getStringItem( data, pos )
|
||||
local len
|
||||
|
||||
|
||||
pos, len = bin.unpack(">I", data, pos)
|
||||
|
||||
|
||||
if ( len > 0 ) then
|
||||
return bin.unpack( "A"..len, data, pos )
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
local itemFetcher = {}
|
||||
@@ -186,16 +186,16 @@ itemFetcher["asar"] = itemFetcher["mikd"]
|
||||
--
|
||||
-- @param data string containing the unparsed item starting at the first available tag
|
||||
-- @param len number containing the length of the item
|
||||
-- @return item table containing <code>mikd</code>, <code>miid</code>, <code>minm</code>,
|
||||
-- @return item table containing <code>mikd</code>, <code>miid</code>, <code>minm</code>,
|
||||
-- <code>asal</code> and <code>asar</code> when available
|
||||
parseItem = function( data, len )
|
||||
|
||||
local pos, name, value = 1, nil, nil
|
||||
local item = {}
|
||||
|
||||
|
||||
while( len - pos > 0 ) do
|
||||
pos, name = bin.unpack( "A4", data, pos )
|
||||
|
||||
|
||||
if itemFetcher[name] then
|
||||
pos, item[name] = itemFetcher[name](data, pos )
|
||||
else
|
||||
@@ -204,15 +204,15 @@ parseItem = function( data, len )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
return item
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Request and process all music items
|
||||
--
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param host table containing an ip field.
|
||||
-- @param port table containing number and protocol fields.
|
||||
-- @param sessionid number containing session identifier from <code>getSessionId</code>
|
||||
-- @param dbid number containing database id from <code>getDatabaseId</code>
|
||||
-- @param limit number containing the maximum amount of songs to return
|
||||
@@ -228,19 +228,19 @@ function getItems( host, port, sessionid, revid, dbid, limit )
|
||||
if response == nil then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- get our position to the list of items
|
||||
pos = string.find(response.body, "mlcl")
|
||||
pos = pos + 4
|
||||
|
||||
|
||||
while ( pos > 0 and pos + 8 < response.body:len() ) do
|
||||
|
||||
-- find the next single item
|
||||
pos = string.find(response.body, "mlit", pos)
|
||||
pos = string.find(response.body, "mlit", pos)
|
||||
pos = pos + 4
|
||||
|
||||
|
||||
pos, len = bin.unpack( ">I", response.body, pos )
|
||||
|
||||
|
||||
if ( pos < response.body:len() and pos + len < response.body:len() ) then
|
||||
pos, data = bin.unpack( "A" .. len, response.body, pos )
|
||||
else
|
||||
@@ -249,45 +249,45 @@ function getItems( host, port, sessionid, revid, dbid, limit )
|
||||
|
||||
-- parse a single item
|
||||
item = parseItem( data, len )
|
||||
|
||||
|
||||
local album = item.asal or "unknown"
|
||||
local artist= item.asar or "unknown"
|
||||
local song = item.minm or ""
|
||||
|
||||
|
||||
if items[artist] == nil then
|
||||
items[artist] = {}
|
||||
end
|
||||
|
||||
|
||||
if items[artist][album] == nil then
|
||||
items[artist][album] = {}
|
||||
end
|
||||
|
||||
|
||||
if limit == 0 then
|
||||
break
|
||||
elseif limit > 0 then
|
||||
limit = limit - 1
|
||||
end
|
||||
|
||||
|
||||
table.insert( items[artist][album], song )
|
||||
|
||||
end
|
||||
|
||||
|
||||
return items
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
|
||||
local limit = tonumber(nmap.registry.args.daap_item_limit) or 100
|
||||
local libname = getLibraryName( host, port )
|
||||
|
||||
local libname = getLibraryName( host, port )
|
||||
|
||||
if libname == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local sessionid = getSessionId( host, port )
|
||||
|
||||
local sessionid = getSessionId( host, port )
|
||||
|
||||
if sessionid == nil then
|
||||
return stdnse.format_output(true, "Libname: " .. libname)
|
||||
@@ -324,18 +324,18 @@ action = function(host, port)
|
||||
end
|
||||
table.insert( albums, album )
|
||||
table.insert( albums, songs )
|
||||
end
|
||||
end
|
||||
table.insert( artists, artist )
|
||||
table.insert( artists, albums )
|
||||
end
|
||||
|
||||
|
||||
table.insert( results, artists )
|
||||
local output = stdnse.format_output( true, results )
|
||||
|
||||
|
||||
if limit > 0 then
|
||||
output = output .. string.format("\n\nOutput limited to %d items", limit )
|
||||
end
|
||||
|
||||
|
||||
return output
|
||||
|
||||
end
|
||||
|
||||
@@ -70,9 +70,9 @@ categories = {"safe", "discovery", "version"}
|
||||
|
||||
--- Research Notes:
|
||||
--
|
||||
-- Little documentation on the protocol used to communicate with the IBM DB2 Admin Server
|
||||
-- Little documentation on the protocol used to communicate with the IBM DB2 Admin Server
|
||||
-- service exists. The packets and methods here were developed based on data captured
|
||||
-- in the wild. Interviews with knowledgeable individuals indicates that the following
|
||||
-- in the wild. Interviews with knowledgeable individuals indicates that the following
|
||||
-- information can be used to recreate the traffic.
|
||||
--
|
||||
-- Requirements:
|
||||
@@ -102,22 +102,22 @@ portrule = shortport.version_port_or_service({523}, nil,
|
||||
-- @param data string containing the "info" section as parsed by parse_db2_packet
|
||||
-- @return string containing the complete server profile
|
||||
function extract_server_profile(data)
|
||||
|
||||
|
||||
local server_profile_offset = 37
|
||||
|
||||
|
||||
if server_profile_offset > data:len() then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
return data:sub(server_profile_offset)
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Does *very* basic parsing of a DB2 packet
|
||||
--
|
||||
-- Due to the limited documentation of the protocol this function is guesswork
|
||||
-- The section called info is essentialy the data part of the db2das data response
|
||||
-- The length of this section is found at offset 158 in the db2das.data section
|
||||
-- The length of this section is found at offset 158 in the db2das.data section
|
||||
--
|
||||
--
|
||||
-- @param packet table as returned from read_db2_packet
|
||||
@@ -133,20 +133,20 @@ function parse_db2_packet(packet)
|
||||
stdnse.print_debug( "db2-das-info: packet too short to be DB2 response...")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local _, len = bin.unpack(">S", packet.data:sub(info_length_offset, info_length_offset + 1))
|
||||
_, response.version = bin.unpack("z", packet.data:sub(version_offset) )
|
||||
response.info_length = len - 4
|
||||
response.info = packet.data:sub(info_offset, info_offset + response.info_length - (info_offset-info_length_offset))
|
||||
|
||||
|
||||
if(nmap.debugging() > 3) then
|
||||
stdnse.print_debug( string.format("db2-das-info: version: %s", response.version) )
|
||||
stdnse.print_debug( string.format("db2-das-info: info_length: %d", response.info_length) )
|
||||
stdnse.print_debug( string.format("db2-das-info: response.info:len(): %d", response.info:len()))
|
||||
end
|
||||
|
||||
|
||||
return response
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Reads a DB2 packet from the socket
|
||||
@@ -157,12 +157,12 @@ end
|
||||
--
|
||||
-- Offset 38 of the header contains an integer with the length of the data section
|
||||
-- The length of the data section can unfortunately be of either endianess
|
||||
-- There's
|
||||
-- There's
|
||||
--
|
||||
-- @param socket connected to the server
|
||||
-- @return table with header and data
|
||||
function read_db2_packet(socket)
|
||||
|
||||
|
||||
local packet = {}
|
||||
local header_len = 41
|
||||
local total_len = 0
|
||||
@@ -175,34 +175,34 @@ function read_db2_packet(socket)
|
||||
stdnse.print_debug("%s", "db2-das-info: ERROR communicating with DB2 server")
|
||||
socket:close()
|
||||
end
|
||||
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
packet.header = {}
|
||||
|
||||
buf = try( socket:receive_bytes(header_len) )
|
||||
|
||||
|
||||
packet.header.raw = buf:sub(1, header_len)
|
||||
|
||||
|
||||
if packet.header.raw:sub(1, 10) == string.char(0x00, 0x00, 0x00, 0x00, 0x44, 0x42, 0x32, 0x44, 0x41, 0x53) then
|
||||
|
||||
|
||||
stdnse.print_debug("db2-das-info: Got DB2DAS packet")
|
||||
|
||||
local _, endian = bin.unpack( "A2", packet.header.raw, ENDIANESS_OFFSET )
|
||||
local _, endian = bin.unpack( "A2", packet.header.raw, ENDIANESS_OFFSET )
|
||||
|
||||
if endian == "9z" then
|
||||
_, packet.header.data_len = bin.unpack("I", packet.header.raw, DATA_LENGTH_OFFSET )
|
||||
else
|
||||
_, packet.header.data_len = bin.unpack(">I", packet.header.raw, DATA_LENGTH_OFFSET )
|
||||
_, packet.header.data_len = bin.unpack(">I", packet.header.raw, DATA_LENGTH_OFFSET )
|
||||
end
|
||||
|
||||
|
||||
total_len = header_len + packet.header.data_len
|
||||
|
||||
|
||||
if(nmap.debugging() > 3) then
|
||||
stdnse.print_debug( string.format("db2-das-info: data_len: %d", packet.header.data_len) )
|
||||
stdnse.print_debug( string.format("db2-das-info: buf_len: %d", buf:len()))
|
||||
stdnse.print_debug( string.format("db2-das-info: total_len: %d", total_len))
|
||||
end
|
||||
|
||||
|
||||
-- do we have all data as specified by data_len?
|
||||
while total_len > buf:len() do
|
||||
-- if not read additional bytes
|
||||
@@ -215,16 +215,16 @@ function read_db2_packet(socket)
|
||||
end
|
||||
buf = buf .. tmp
|
||||
end
|
||||
|
||||
|
||||
packet.data = buf:sub(header_len + 1)
|
||||
|
||||
|
||||
else
|
||||
stdnse.print_debug("db2-das-info: Unknown packet, aborting ...")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
return packet
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Sends a db2 packet table over the wire
|
||||
@@ -240,7 +240,7 @@ function send_db2_packet( socket, packet )
|
||||
end
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
|
||||
local buf = packet.header.raw .. packet.data
|
||||
|
||||
try( socket:send(buf) )
|
||||
@@ -260,47 +260,47 @@ end
|
||||
-- @return table as described above
|
||||
--
|
||||
function create_das_packet( magic, data )
|
||||
|
||||
|
||||
local packet = {}
|
||||
local data_len = data:len()
|
||||
|
||||
|
||||
packet.header = {}
|
||||
|
||||
|
||||
packet.header.raw = string.char(0x00, 0x00, 0x00, 0x00, 0x44, 0x42, 0x32, 0x44, 0x41, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20)
|
||||
packet.header.raw = packet.header.raw .. string.char(0x01, 0x04, 0x00, 0x00, 0x00, 0x10, 0x39, 0x7a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
|
||||
packet.header.raw = packet.header.raw .. string.char(0x00, 0x00, 0x00, 0x00 )
|
||||
packet.header.raw = packet.header.raw .. string.char(0x00, 0x00, 0x00, 0x00 )
|
||||
packet.header.raw = packet.header.raw .. bin.pack("C", magic)
|
||||
packet.header.raw = packet.header.raw .. bin.pack("S", data_len)
|
||||
packet.header.raw = packet.header.raw .. string.char(0x00, 0x00)
|
||||
|
||||
|
||||
packet.header.data_len = data_len
|
||||
packet.data = data
|
||||
|
||||
|
||||
return packet
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
|
||||
|
||||
|
||||
-- create the socket used for our connection
|
||||
local socket = nmap.new_socket()
|
||||
|
||||
|
||||
-- set a reasonable timeout value
|
||||
socket:set_timeout(10000)
|
||||
|
||||
|
||||
-- do some exception handling / cleanup
|
||||
local catch = function()
|
||||
stdnse.print_debug("%s", "db2-das-info: ERROR communicating with " .. host.ip .. " on port " .. port.number)
|
||||
socket:close()
|
||||
end
|
||||
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
|
||||
try(socket:connect(host, port))
|
||||
|
||||
|
||||
local query
|
||||
|
||||
|
||||
-- ************************************************************************************
|
||||
-- Transaction block 1
|
||||
-- ************************************************************************************
|
||||
@@ -308,23 +308,23 @@ action = function(host, port)
|
||||
|
||||
--try(socket:send(query))
|
||||
local db2packet = create_das_packet(0x02, data)
|
||||
|
||||
|
||||
send_db2_packet( socket, db2packet )
|
||||
read_db2_packet( socket )
|
||||
|
||||
|
||||
-- ************************************************************************************
|
||||
-- Transaction block 2
|
||||
-- ************************************************************************************
|
||||
-- ************************************************************************************
|
||||
data = string.char(0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00)
|
||||
data = data .. string.char(0x0c, 0x00, 0x00, 0x00, 0x08, 0x59, 0xe7, 0x1f, 0x4b, 0x79, 0xf0, 0x90, 0x72, 0x85, 0xe0, 0x8f)
|
||||
data = data .. string.char(0x3e, 0x38, 0x45, 0x38, 0xe3, 0xe5, 0x12, 0xc4, 0x3b, 0xe9, 0x7d, 0xe2, 0xf5, 0xf0, 0x78, 0xcc)
|
||||
data = data .. string.char(0x81, 0x6f, 0x87, 0x5f, 0x91)
|
||||
|
||||
|
||||
db2packet = create_das_packet(0x05, data)
|
||||
|
||||
|
||||
send_db2_packet( socket, db2packet )
|
||||
read_db2_packet( socket )
|
||||
|
||||
|
||||
-- ************************************************************************************
|
||||
-- Transaction block 3
|
||||
-- ************************************************************************************
|
||||
@@ -338,7 +338,7 @@ action = function(host, port)
|
||||
db2packet = create_das_packet(0x0a, data)
|
||||
send_db2_packet( socket, db2packet )
|
||||
read_db2_packet( socket )
|
||||
|
||||
|
||||
-- ************************************************************************************
|
||||
-- Transaction block 4
|
||||
-- ************************************************************************************
|
||||
@@ -355,10 +355,10 @@ action = function(host, port)
|
||||
data = data .. string.char(0x0c, 0x00, 0x00, 0x00, 0x4c, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00)
|
||||
data = data .. string.char(0x0c, 0x00, 0x00, 0x00, 0x4c, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00)
|
||||
data = data .. string.char(0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0xb8, 0x00)
|
||||
|
||||
|
||||
db2packet = create_das_packet(0x06, data)
|
||||
send_db2_packet( socket, db2packet )
|
||||
|
||||
|
||||
data = string.char( 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00)
|
||||
data = data .. string.char(0x00, 0x04, 0xb8, 0x64, 0x62, 0x32, 0x64, 0x61, 0x73, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x44, 0x73)
|
||||
data = data .. string.char(0x63, 0x76, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00)
|
||||
@@ -376,15 +376,15 @@ action = function(host, port)
|
||||
|
||||
local packet = read_db2_packet( socket )
|
||||
local db2response = parse_db2_packet(packet)
|
||||
|
||||
|
||||
socket:close()
|
||||
|
||||
|
||||
-- The next block of code is essentially the version extraction code from db2-info.nse
|
||||
local server_version
|
||||
if string.sub(db2response.version,1,3) == "SQL" then
|
||||
local major_version = string.sub(db2response.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
|
||||
if string.sub(major_version,1,1) == "0" then
|
||||
major_version = string.sub(major_version,2)
|
||||
@@ -393,32 +393,32 @@ action = function(host, port)
|
||||
local hotfix = string.sub(db2response.version,8)
|
||||
server_version = major_version .. "." .. minor_version .. "." .. hotfix
|
||||
end
|
||||
|
||||
-- Try to determine which of the two values (probe version vs script) has more
|
||||
|
||||
-- Try to determine which of the two values (probe version vs script) has more
|
||||
-- precision. A couple DB2 versions send DB2 UDB 7.1 vs SQL090204 (9.02.04)
|
||||
local _
|
||||
local current_count = 0
|
||||
if port.version.version ~= nil then
|
||||
_, current_count = string.gsub(port.version.version, "%.", ".")
|
||||
end
|
||||
end
|
||||
|
||||
local new_count = 0
|
||||
if server_version ~= nil then
|
||||
_, new_count = string.gsub(server_version, "%.", ".")
|
||||
end
|
||||
|
||||
|
||||
if current_count < new_count then
|
||||
port.version.version = server_version
|
||||
end
|
||||
|
||||
local result = false
|
||||
|
||||
local db2profile = extract_server_profile( db2response.info )
|
||||
local result = false
|
||||
|
||||
if (db2profile ~= nil ) then
|
||||
local db2profile = extract_server_profile( db2response.info )
|
||||
|
||||
if (db2profile ~= nil ) then
|
||||
result = "DB2 Administration Server Settings\r\n"
|
||||
result = result .. extract_server_profile( db2response.info )
|
||||
|
||||
result = result .. extract_server_profile( db2response.info )
|
||||
|
||||
-- Set port information
|
||||
port.version.name = "ibm-db2"
|
||||
port.version.product = "IBM DB2 Database Server"
|
||||
@@ -426,7 +426,7 @@ action = function(host, port)
|
||||
nmap.set_port_version(host, port)
|
||||
nmap.set_port_state(host, port, "open")
|
||||
end
|
||||
|
||||
|
||||
return result
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -15,13 +15,13 @@ Attempts to discover DB2 servers on the network by querying open ibm-db2 UDP por
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 523/udp open ibm-db2
|
||||
-- | db2-discover:
|
||||
-- | db2-discover:
|
||||
-- | Host: EDUSRV011
|
||||
-- |_ Version: IBM DB2 v9.07.0
|
||||
|
||||
-- Version 0.1
|
||||
-- Created 08/27/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 10/10/2010 - v0.2 - add prerule, newtargets <patrik@cqure.net>
|
||||
-- Revised 10/10/2010 - v0.2 - add prerule, newtargets <patrik@cqure.net>
|
||||
-- Revised 10/07/2011 - v0.3 - moved broadcast support to
|
||||
-- broadcast-db2-discover.nse <patrik@cqure.net>
|
||||
|
||||
@@ -43,7 +43,7 @@ local function parseVersion( server_version )
|
||||
if pfx == "SQL" then
|
||||
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
|
||||
if string.sub(major_version,1,1) == "0" then
|
||||
major_version = string.sub(major_version,2)
|
||||
@@ -54,16 +54,16 @@ local function parseVersion( server_version )
|
||||
else
|
||||
return "Unknown version"
|
||||
end
|
||||
|
||||
|
||||
return ("IBM DB2 v%s"):format(server_version)
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
|
||||
local DB2GETADDR = "DB2GETADDR\0SQL09010\0"
|
||||
local socket = nmap.new_socket()
|
||||
local result = {}
|
||||
|
||||
|
||||
socket:set_timeout(5000)
|
||||
|
||||
local status, err = socket:connect( host, port, "udp")
|
||||
@@ -78,7 +78,7 @@ action = function(host, port)
|
||||
socket:close()
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local version, srvname = data:match("DB2RETADDR.(SQL%d+).(.-)\0")
|
||||
|
||||
if ( status ) then
|
||||
@@ -86,9 +86,9 @@ action = function(host, port)
|
||||
table.insert( result, ("Version: %s"):format(parseVersion(version)) )
|
||||
end
|
||||
|
||||
socket:close()
|
||||
socket:close()
|
||||
-- set port to open
|
||||
nmap.set_port_state(host, port, "open")
|
||||
|
||||
return stdnse.format_output( true, result )
|
||||
return stdnse.format_output( true, result )
|
||||
end
|
||||
|
||||
@@ -15,11 +15,11 @@ address. The request sends a list of which fields it wants to know (a handful by
|
||||
verbosity is turned on), and the server responds with the fields that were requested. It should be noted
|
||||
that the server doesn't have to return every field, nor does it have to return them in the same order,
|
||||
or honour the request at all. A Linksys WRT54g, for example, completely ignores the list of requested
|
||||
fields and returns a few standard ones. This script displays every field it receives.
|
||||
fields and returns a few standard ones. This script displays every field it receives.
|
||||
|
||||
With script arguments, the type of DHCP request can be changed, which can lead to interesting results.
|
||||
With script arguments, the type of DHCP request can be changed, which can lead to interesting results.
|
||||
Additionally, the MAC address can be randomized, which in should override the cache on the DHCP server and
|
||||
assign a new IP address. Extra requests can also be sent to exhaust the IP address range more quickly.
|
||||
assign a new IP address. Extra requests can also be sent to exhaust the IP address range more quickly.
|
||||
|
||||
Some of the more useful fields:
|
||||
* DHCP Server (the address of the server that responded)
|
||||
@@ -31,13 +31,13 @@ Some of the more useful fields:
|
||||
|
||||
---
|
||||
-- @args dhcptype The type of DHCP request to make. By default, DHCPINFORM is sent, but this
|
||||
-- argument can change it to DHCPOFFER, DHCPREQUEST, DHCPDECLINE, DHCPACK, DHCPNAK,
|
||||
-- argument can change it to DHCPOFFER, DHCPREQUEST, DHCPDECLINE, DHCPACK, DHCPNAK,
|
||||
-- DHCPRELEASE or DHCPINFORM. Not all types will evoke a response from all servers,
|
||||
-- and many require different fields to contain specific values.
|
||||
-- and many require different fields to contain specific values.
|
||||
-- @args randomize_mac Set to <code>true</code> or <code>1</code> to send a random MAC address with
|
||||
-- the request (keep in mind that you may not see the response). This should
|
||||
-- the request (keep in mind that you may not see the response). This should
|
||||
-- cause the router to reserve a new IP address each time.
|
||||
-- @args requests Set to an integer to make up to that many requests (and display the results).
|
||||
-- @args requests Set to an integer to make up to that many requests (and display the results).
|
||||
--
|
||||
-- @output
|
||||
-- Interesting ports on 192.168.1.1:
|
||||
@@ -50,7 +50,7 @@ Some of the more useful fields:
|
||||
-- | | Subnet Mask: 255.255.255.0
|
||||
-- | | Router: 192.168.1.1
|
||||
-- |_ |_ Domain Name Server: 208.81.7.10, 208.81.7.14
|
||||
--
|
||||
--
|
||||
|
||||
--
|
||||
-- 2011-12-28 - Revised by Patrik Karlsson <patrik@cqure.net>
|
||||
@@ -89,7 +89,7 @@ local function go(host, port)
|
||||
if(request_type == nil) then
|
||||
return false, "Valid request types: " .. stdnse.strjoin(", ", dhcp.request_types_str)
|
||||
end
|
||||
|
||||
|
||||
-- Generate the MAC address, if it's random
|
||||
local mac_addr = host.mac_addr_src
|
||||
if(nmap.registry.args.randomize_mac == 'true' or nmap.registry.args.randomize_mac == '1') then
|
||||
@@ -99,12 +99,12 @@ local function go(host, port)
|
||||
mac_addr = mac_addr .. string.char(math.random(1, 255))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local iface, err = nmap.get_interface_info(host.interface)
|
||||
if ( not(iface) or not(iface.address) ) then
|
||||
return false, "Couldn't determine local ip for interface: " .. host.interface
|
||||
end
|
||||
|
||||
|
||||
local status, result = dhcp.make_request(host.ip, request_type, iface.address, mac_addr)
|
||||
if( not(status) ) then
|
||||
stdnse.print_debug(1, "dhcp-discover: Couldn't send DHCP request: %s", result)
|
||||
@@ -141,7 +141,7 @@ action = function(host, port)
|
||||
for i, result in ipairs(results) do
|
||||
local result_table = {}
|
||||
|
||||
if ( nmap.registry.args.dhcptype and
|
||||
if ( nmap.registry.args.dhcptype and
|
||||
"DHCPINFORM" ~= nmap.registry.args.dhcptype ) then
|
||||
table.insert(result_table, string.format("IP Offered: %s", result.yiaddr_str))
|
||||
end
|
||||
|
||||
@@ -21,10 +21,10 @@ list of databases will not be shown.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 2628/tcp open dict
|
||||
-- | dict-info:
|
||||
-- | dict-info:
|
||||
-- | dictd 1.12.0/rf on Linux 3.0.0-12-generic
|
||||
-- | On ubu1110: up 15.000, 4 forks (960.0/hour)
|
||||
-- |
|
||||
-- |
|
||||
-- | Database Headwords Index Data Uncompressed
|
||||
-- | bouvier 6797 128 kB 2338 kB 6185 kB
|
||||
-- |_ fd-eng-swe 5489 76 kB 77 kB 204 kB
|
||||
@@ -44,19 +44,19 @@ action = function(host, port)
|
||||
if ( not(socket:connect(host, port)) ) then
|
||||
return fail("Failed to connect to dictd server")
|
||||
end
|
||||
|
||||
|
||||
local probes = {
|
||||
'client "dict 1.12.0/rf on Linux 3.0.0-12-generic"',
|
||||
'show server',
|
||||
'quit',
|
||||
}
|
||||
|
||||
|
||||
if ( not(socket:send(stdnse.strjoin("\r\n", probes) .. "\r\n")) ) then
|
||||
return fail("Failed to send request to server")
|
||||
end
|
||||
|
||||
|
||||
local srvinfo
|
||||
|
||||
|
||||
repeat
|
||||
local status, data = socket:receive_buf("\r\n", false)
|
||||
if ( not(status) ) then
|
||||
@@ -70,7 +70,7 @@ action = function(host, port)
|
||||
end
|
||||
until(not(status) or data:match("^221") or data:match("^%.$"))
|
||||
socket:close()
|
||||
|
||||
|
||||
-- if last item is an empty string remove it, to avoid trailing line feed
|
||||
srvinfo[#srvinfo] = ( srvinfo[#srvinfo] ~= "" and srvinfo[#srvinfo] or nil )
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ present in modern implementation due to poor configuration of the service.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 3632/tcp open distccd
|
||||
-- | distcc-test:
|
||||
-- | distcc-test:
|
||||
-- | VULNERABLE:
|
||||
-- | distcc Daemon Command Execution
|
||||
-- | State: VULNERABLE (Exploitable)
|
||||
@@ -25,12 +25,12 @@ present in modern implementation due to poor configuration of the service.
|
||||
-- | Description:
|
||||
-- | Allows executing of arbitrary commands on systems running distccd 3.1 and
|
||||
-- | earlier. The vulnerability is the consequence of weak service configuration.
|
||||
-- |
|
||||
-- |
|
||||
-- | Disclosure date: 2002-02-01
|
||||
-- | Extra information:
|
||||
-- |
|
||||
-- |
|
||||
-- | uid=118(distccd) gid=65534(nogroup) groups=65534(nogroup)
|
||||
-- |
|
||||
-- |
|
||||
-- | References:
|
||||
-- | http://distcc.googlecode.com/svn/trunk/doc/web/security.html
|
||||
-- | http://http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2004-2687
|
||||
@@ -80,21 +80,21 @@ earlier. The vulnerability is the consequence of weak service configuration.
|
||||
if ( not(socket:connect(host, port)) ) then
|
||||
return fail("Failed to connect to distcc server")
|
||||
end
|
||||
|
||||
|
||||
local cmds = {
|
||||
"DIST00000001",
|
||||
("ARGC00000008ARGV00000002shARGV00000002-cARGV%08.8xsh -c " ..
|
||||
("ARGC00000008ARGV00000002shARGV00000002-cARGV%08.8xsh -c " ..
|
||||
"'(%s)'ARGV00000001#ARGV00000002-cARGV00000006main.cARGV00000002" ..
|
||||
"-oARGV00000006main.o"):format(10 + #arg_cmd, arg_cmd),
|
||||
"DOTI00000001A\n",
|
||||
}
|
||||
|
||||
|
||||
for _, cmd in ipairs(cmds) do
|
||||
if ( not(socket:send(cmd)) ) then
|
||||
return fail("Failed to send data to distcc server")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local status, data = socket:receive_buf("DOTO00000000", false)
|
||||
|
||||
if ( status ) then
|
||||
|
||||
@@ -12,11 +12,11 @@ PROXY) or to a specific service name. ]]
|
||||
-- @usage
|
||||
-- nmap --script dns-blacklist --script-args='dns-blacklist.ip=<ip>'
|
||||
-- or
|
||||
-- nmap -sn <ip> --script dns-blacklist
|
||||
-- nmap -sn <ip> --script dns-blacklist
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | dns-blacklist:
|
||||
-- | dns-blacklist:
|
||||
-- | 1.2.3.4
|
||||
-- | PROXY
|
||||
-- | dnsbl.ahbl.org - PROXY
|
||||
@@ -33,7 +33,7 @@ PROXY) or to a specific service name. ]]
|
||||
-- |_ spam.dnsbl.sorbs.net - SPAM
|
||||
--
|
||||
-- Supported blacklist list mode (--script-args dns-blacklist.list):
|
||||
-- | dns-blacklist:
|
||||
-- | dns-blacklist:
|
||||
-- | PROXY
|
||||
-- | dnsbl.ahbl.org
|
||||
-- | socks.dnsbl.sorbs.net
|
||||
@@ -113,7 +113,7 @@ local function formatResult(result)
|
||||
end
|
||||
|
||||
dnsblAction = function(host)
|
||||
|
||||
|
||||
local helper
|
||||
if ( arg_services and ( not(arg_category) or "all" == arg_category:lower() ) ) then
|
||||
return "\n ERROR: A service filter can't be used without a specific category"
|
||||
@@ -143,11 +143,11 @@ dnsblAction = function(host)
|
||||
end
|
||||
if ( #output == 0 ) then return end
|
||||
end
|
||||
|
||||
|
||||
if ( "prerule" == SCRIPT_TYPE ) then
|
||||
output.name = host.ip
|
||||
end
|
||||
|
||||
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
|
||||
@@ -158,16 +158,16 @@ action = function(...)
|
||||
if ( arg_mode ~= "short" and arg_mode ~= "long" ) then
|
||||
return "\n ERROR: Invalid argument supplied, mode should be either 'short' or 'long'"
|
||||
end
|
||||
|
||||
|
||||
if ( arg_IP and not(ipOps.todword(arg_IP)) ) then
|
||||
return "\n ERROR: Invalid IP address was supplied"
|
||||
end
|
||||
|
||||
|
||||
-- if the list argument was given, just list the services and abort
|
||||
if ( arg_list ) then
|
||||
return listServices()
|
||||
end
|
||||
|
||||
|
||||
if ( arg_IP and "prerule" == SCRIPT_TYPE ) then
|
||||
return dnsblAction( { ip = arg_IP } )
|
||||
elseif ( "hostrule" == SCRIPT_TYPE ) then
|
||||
|
||||
@@ -244,7 +244,7 @@ action = function(host)
|
||||
table.insert(srvlist, l)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
i = 1
|
||||
threads = {}
|
||||
howmany = math.floor(#srvlist/max_threads)+1
|
||||
|
||||
@@ -6,7 +6,7 @@ local ipOps = require "ipOps"
|
||||
description = [[
|
||||
Checks DNS zone configuration against best practices, including RFC 1912.
|
||||
The configuration checks are divided into categories which each have a number
|
||||
of different tests.
|
||||
of different tests.
|
||||
]]
|
||||
|
||||
---
|
||||
@@ -14,7 +14,7 @@ of different tests.
|
||||
-- nmap -sn -Pn ns1.example.com --script dns-check-zone --script-args='dns-check-zone.domain=example.com'
|
||||
--
|
||||
-- @output
|
||||
-- | dns-check-zone:
|
||||
-- | dns-check-zone:
|
||||
-- | DNS check results for domain: example.com
|
||||
-- | SOA
|
||||
-- | PASS - SOA REFRESH
|
||||
@@ -70,15 +70,15 @@ local function isValidSOA(res)
|
||||
return true
|
||||
end
|
||||
|
||||
local dns_checks = {
|
||||
|
||||
local dns_checks = {
|
||||
|
||||
["NS"] = {
|
||||
{
|
||||
{
|
||||
desc = "Recursive queries",
|
||||
func = function(domain, server)
|
||||
local status, res = dns.query(domain, { host = server, dtype='NS', retAll = true })
|
||||
local result = {}
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of DNS servers"
|
||||
end
|
||||
@@ -88,42 +88,42 @@ local dns_checks = {
|
||||
table.insert(result, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local output = "None of the servers allow recursive queries."
|
||||
if ( 0 < #result ) then
|
||||
output = ("The following servers allow recursive queries: %s"):format(stdnse.strjoin(", ", result))
|
||||
return true, { status = Status.FAIL, output = output }
|
||||
end
|
||||
return true, { status = Status.PASS, output = output }
|
||||
end
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "Multiple name servers",
|
||||
func = function(domain, server)
|
||||
local status, res = dns.query(domain, { host = server, dtype='NS', retAll = true })
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local status = Status.FAIL
|
||||
if ( 1 < #res ) then
|
||||
status = Status.PASS
|
||||
end
|
||||
return true, { status = status, output = ("Server has %d name servers"):format(#res) }
|
||||
end
|
||||
return true, { status = status, output = ("Server has %d name servers"):format(#res) }
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "DNS name server IPs are public",
|
||||
func = function(domain, server)
|
||||
|
||||
|
||||
local status, res = dns.query(domain, { host = server, dtype='NS', retAll = true })
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local result = {}
|
||||
for _, srv in ipairs(res or {}) do
|
||||
local status, res = dns.query(srv, { dtype='A', retAll = true })
|
||||
@@ -136,7 +136,7 @@ local dns_checks = {
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local output = "All DNS IPs were public"
|
||||
if ( 0 < #result ) then
|
||||
output = ("The following private IPs were detected: %s"):format(stdnse.strjoin(", ", result))
|
||||
@@ -148,7 +148,7 @@ local dns_checks = {
|
||||
return true, { status = status, output = output }
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "DNS server response",
|
||||
func = function(domain, server)
|
||||
@@ -156,7 +156,7 @@ local dns_checks = {
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local result = {}
|
||||
for _, srv in ipairs(res or {}) do
|
||||
local status, res = dns.query(domain, { host = srv, dtype='SOA', retPkt = true })
|
||||
@@ -164,7 +164,7 @@ local dns_checks = {
|
||||
table.insert(result, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local output = "All servers respond to DNS queries"
|
||||
if ( 0 < #result ) then
|
||||
output = ("The following servers did not respond to DNS queries: %s"):format(stdnse.strjoin(", ", result))
|
||||
@@ -173,7 +173,7 @@ local dns_checks = {
|
||||
return true, { status = Status.PASS, output = output }
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "Missing nameservers reported by parent",
|
||||
func = function(domain, server)
|
||||
@@ -182,21 +182,21 @@ local dns_checks = {
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of TLD DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local status, parent_res = dns.query(domain, { host = res, dtype = "NS", retAll = true, retPkt = true, noauth = true } )
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve a list of parent DNS servers"
|
||||
end
|
||||
|
||||
|
||||
if ( not(status) or not(parent_res) or type(parent_res.auth) ~= "table" ) then
|
||||
return false, "Failed to retrieve a list of parent DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local parent_dns = {}
|
||||
for _, auth in ipairs(parent_res.auth) do
|
||||
parent_dns[auth.domain] = true
|
||||
end
|
||||
|
||||
|
||||
status, res = dns.query(domain, { host = server, dtype = "NS", retAll = true } )
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve a list of DNS servers"
|
||||
@@ -216,12 +216,12 @@ local dns_checks = {
|
||||
local output = ("The following servers were found in the zone, but not in the parent: %s"):format(stdnse.strjoin(", ", result))
|
||||
return true, { status = Status.FAIL, output = output }
|
||||
end
|
||||
|
||||
|
||||
return true, { status = Status.PASS, output = "All DNS servers match" }
|
||||
end,
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
desc = "Missing nameservers reported by your nameservers",
|
||||
func = function(domain, server)
|
||||
@@ -230,21 +230,21 @@ local dns_checks = {
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of TLD DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local status, parent_res = dns.query(domain, { host = res, dtype = "NS", retAll = true, retPkt = true, noauth = true } )
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve a list of parent DNS servers"
|
||||
end
|
||||
|
||||
|
||||
if ( not(status) or not(parent_res) or type(parent_res.auth) ~= "table" ) then
|
||||
return false, "Failed to retrieve a list of parent DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local parent_dns = {}
|
||||
for _, auth in ipairs(parent_res.auth) do
|
||||
parent_dns[auth.domain] = true
|
||||
end
|
||||
|
||||
|
||||
status, res = dns.query(domain, { host = server, dtype = "NS", retAll = true } )
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve a list of DNS servers"
|
||||
@@ -264,28 +264,28 @@ local dns_checks = {
|
||||
local output = ("The following servers were found in the parent, but not in the zone: %s"):format(stdnse.strjoin(", ", result))
|
||||
return true, { status = Status.FAIL, output = output }
|
||||
end
|
||||
|
||||
|
||||
return true, { status = Status.PASS, output = "All DNS servers match" }
|
||||
end,
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
["SOA"] =
|
||||
|
||||
["SOA"] =
|
||||
{
|
||||
{
|
||||
desc = "SOA REFRESH",
|
||||
func = function(domain, server)
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
if ( not(status) or not(isValidSOA(res)) ) then
|
||||
return false, "Failed to retrieve SOA record"
|
||||
end
|
||||
|
||||
|
||||
local refresh = tonumber(res.answers[1].SOA.refresh)
|
||||
if ( not(refresh) ) then
|
||||
return false, "Failed to retrieve SOA REFRESH"
|
||||
end
|
||||
|
||||
|
||||
if ( refresh < 1200 or refresh > 43200 ) then
|
||||
return true, { status = Status.FAIL, output = ("SOA REFRESH was NOT within recommended range (%ss)"):format(refresh) }
|
||||
else
|
||||
@@ -297,16 +297,16 @@ local dns_checks = {
|
||||
{
|
||||
desc = "SOA RETRY",
|
||||
func = function(domain, server)
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
if ( not(status) or not(isValidSOA(res)) ) then
|
||||
return false, "Failed to retrieve SOA record"
|
||||
end
|
||||
|
||||
|
||||
local retry = tonumber(res.answers[1].SOA.retry)
|
||||
if ( not(retry) ) then
|
||||
return false, "Failed to retrieve SOA RETRY"
|
||||
end
|
||||
|
||||
|
||||
if ( retry < 180 ) then
|
||||
return true, { status = Status.FAIL, output = ("SOA RETRY was NOT within recommended range (%ss)"):format(retry) }
|
||||
else
|
||||
@@ -314,20 +314,20 @@ local dns_checks = {
|
||||
end
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "SOA EXPIRE",
|
||||
func = function(domain, server)
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
if ( not(status) or not(isValidSOA(res)) ) then
|
||||
return false, "Failed to retrieve SOA record"
|
||||
end
|
||||
|
||||
|
||||
local expire = tonumber(res.answers[1].SOA.expire)
|
||||
if ( not(expire) ) then
|
||||
return false, "Failed to retrieve SOA EXPIRE"
|
||||
end
|
||||
|
||||
|
||||
if ( expire < 1209600 or expire > 2419200 ) then
|
||||
return true, { status = Status.FAIL, output = ("SOA EXPIRE was NOT within recommended range (%ss)"):format(expire) }
|
||||
else
|
||||
@@ -335,30 +335,30 @@ local dns_checks = {
|
||||
end
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "SOA MNAME entry check",
|
||||
func = function(domain, server)
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
local status, res = dns.query(domain, { host = server, dtype='SOA', retPkt=true })
|
||||
if ( not(status) or not(isValidSOA(res)) ) then
|
||||
return false, "Failed to retrieve SOA record"
|
||||
end
|
||||
local mname = res.answers[1].SOA.mname
|
||||
|
||||
status, res = dns.query(domain, { host = server, dtype='NS', retAll = true })
|
||||
|
||||
status, res = dns.query(domain, { host = server, dtype='NS', retAll = true })
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of DNS servers"
|
||||
end
|
||||
|
||||
for _, srv in ipairs(res or {}) do
|
||||
if ( srv == mname ) then
|
||||
return true, { status = Status.PASS, output = "SOA MNAME record is listed as DNS server" }
|
||||
return true, { status = Status.PASS, output = "SOA MNAME record is listed as DNS server" }
|
||||
end
|
||||
end
|
||||
return true, { status = Status.FAIL, output = "SOA MNAME record is NOT listed as DNS server" }
|
||||
return true, { status = Status.FAIL, output = "SOA MNAME record is NOT listed as DNS server" }
|
||||
end
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
desc = "Zone serial numbers",
|
||||
func = function(domain, server)
|
||||
@@ -366,16 +366,16 @@ local dns_checks = {
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of DNS servers"
|
||||
end
|
||||
|
||||
|
||||
local result = {}
|
||||
local serial
|
||||
|
||||
|
||||
for _, srv in ipairs(res or {}) do
|
||||
local status, res = dns.query(domain, { host = srv, dtype='SOA', retPkt = true })
|
||||
if ( not(status) or not(isValidSOA(res)) ) then
|
||||
return false, "Failed to retrieve SOA record"
|
||||
end
|
||||
|
||||
|
||||
local s = res.answers[1].SOA.serial
|
||||
if ( not(serial) ) then
|
||||
serial = s
|
||||
@@ -383,14 +383,14 @@ local dns_checks = {
|
||||
return true, { status = Status.FAIL, output = "Different zone serials were detected" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return true, { status = Status.PASS, output = "Zone serials match" }
|
||||
end,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
["MX"] = {
|
||||
|
||||
|
||||
{
|
||||
desc = "Reverse MX A records",
|
||||
func = function(domain, server)
|
||||
@@ -398,7 +398,7 @@ local dns_checks = {
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve list of mail servers"
|
||||
end
|
||||
|
||||
|
||||
local result = {}
|
||||
for _, record in ipairs(res or {}) do
|
||||
local prio, mx = record:match("^(%d*):([^:]*)")
|
||||
@@ -407,15 +407,15 @@ local dns_checks = {
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to retrieve A records for MX"
|
||||
end
|
||||
|
||||
|
||||
for _, ip in ipairs(ips) do
|
||||
local status, res = dns.query(dns.reverse(ip), { dtype='PTR' })
|
||||
if ( not(status) ) then
|
||||
table.insert(result, ip)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local output = "All MX records have PTR records"
|
||||
if ( 0 < #result ) then
|
||||
output = ("The following IPs do not have PTR records: %s"):format(stdnse.strjoin(", ", result))
|
||||
@@ -428,10 +428,10 @@ local dns_checks = {
|
||||
}
|
||||
}
|
||||
|
||||
action = function(host, port)
|
||||
action = function(host, port)
|
||||
local server = host.ip
|
||||
local output = { name = ("DNS check results for domain: %s"):format(arg_domain) }
|
||||
|
||||
|
||||
for group in pairs(dns_checks) do
|
||||
local group_output = { name = group }
|
||||
for _, check in ipairs(dns_checks[group]) do
|
||||
@@ -445,6 +445,6 @@ action = function(host, port)
|
||||
end
|
||||
end
|
||||
table.insert(output, group_output)
|
||||
end
|
||||
end
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ requests using a given subnet.
|
||||
--
|
||||
-- @output
|
||||
-- 53/udp open domain udp-response
|
||||
-- | dns-client-subnet-scan:
|
||||
-- | dns-client-subnet-scan:
|
||||
-- | www.google.com
|
||||
-- | 1.2.3.4
|
||||
-- | 5.6.7.8
|
||||
@@ -304,7 +304,7 @@ local areaIPs = {
|
||||
Z4 = {ip=40321024, desc="GB,Z4,Wrexham"}
|
||||
}
|
||||
|
||||
local get_addresses = function(address, mask, domain, nameserver)
|
||||
local get_addresses = function(address, mask, domain, nameserver)
|
||||
|
||||
-- translate the IP's in the areaIPs to strings, as this is what the
|
||||
-- DNS library expects
|
||||
@@ -325,12 +325,12 @@ end
|
||||
|
||||
local function fail(err) return ("\n ERROR: %s"):format(err or "") end
|
||||
|
||||
action = function(host, port)
|
||||
action = function(host, port)
|
||||
|
||||
if ( not(argDomain) ) then
|
||||
return fail(SCRIPT_NAME .. ".domain was not specified")
|
||||
end
|
||||
|
||||
|
||||
local nameserver = argNS or (host and host.ip)
|
||||
-- as the nameserver argument overrides the host.ip, the prerule should
|
||||
-- already have done our work, so abort
|
||||
@@ -339,9 +339,9 @@ action = function(host, port)
|
||||
-- if we have no nameserver argument and no host, we dont have sufficient
|
||||
-- information to continue, abort
|
||||
elseif ( not(argNS) and not(host) ) then
|
||||
return
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local addrs = argAddr or areaIPs
|
||||
if ( "string" == type(addrs) ) then addrs = {{ ip = addrs }} end
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ local stdnse = require "stdnse"
|
||||
local string = require "string"
|
||||
|
||||
description = [[
|
||||
Launches a DNS fuzzing attack against DNS servers.
|
||||
Launches a DNS fuzzing attack against DNS servers.
|
||||
|
||||
The script induces errors into randomly generated but valid DNS packets.
|
||||
The packet template that we use includes one uncompressed and one
|
||||
@@ -67,19 +67,19 @@ function pingServer (host, port, attempts)
|
||||
local data
|
||||
local pkt = dns.newPacket()
|
||||
pkt.id = math.random(65535)
|
||||
|
||||
|
||||
pkt.flags.OC3 = true
|
||||
|
||||
|
||||
data = dns.encode(pkt)
|
||||
|
||||
for i = 1, attempts do
|
||||
|
||||
for i = 1, attempts do
|
||||
status, result = comm.exchange(host, port, data, {proto="udp", timeout=math.pow(DNStimeout,slowDown)})
|
||||
if status then
|
||||
return true
|
||||
end
|
||||
slowDown = slowDown + 0.25
|
||||
end
|
||||
|
||||
|
||||
return false
|
||||
else
|
||||
-- just do a vanilla recursive lookup of scanme.nmap.org
|
||||
@@ -159,7 +159,7 @@ end
|
||||
---
|
||||
-- Introduce bit errors into a packet at a rate of 1/50
|
||||
-- As Charlie Miller points out in "Fuzz by Number"
|
||||
-- -> cansecwest.com/csw08/csw08-miller.pdf
|
||||
-- -> cansecwest.com/csw08/csw08-miller.pdf
|
||||
-- It's difficult to tell how much random you should insert into packets
|
||||
-- "If data is too valid, might not cause problems, If data is too invalid,
|
||||
-- might be quickly rejected"
|
||||
@@ -211,7 +211,7 @@ function injectByte (dnsPacket)
|
||||
dnsPacket:gsub(".", function(c)
|
||||
i=i+1
|
||||
if i==byteToInject then
|
||||
newPacket = newPacket .. string.char(math.random(0,255))
|
||||
newPacket = newPacket .. string.char(math.random(0,255))
|
||||
end
|
||||
newPacket = newPacket .. c
|
||||
end)
|
||||
@@ -262,7 +262,7 @@ function corruptAndSend (host, port, query)
|
||||
elseif randCorr==4 then
|
||||
query = truncatePacket(query)
|
||||
end
|
||||
|
||||
|
||||
status, result = comm.exchange(host, port, query, {proto="udp", timeout=DNStimeout})
|
||||
if not status then
|
||||
if not pingServer(host,port,3) then
|
||||
@@ -288,7 +288,7 @@ action = function(host, port)
|
||||
local timelimit, err
|
||||
local retStr
|
||||
local query
|
||||
|
||||
|
||||
for _, k in ipairs({"dns-fuzz.timelimit", "timelimit"}) do
|
||||
if nmap.registry.args[k] then
|
||||
timelimit, err = stdnse.parse_timespec(nmap.registry.args[k])
|
||||
@@ -305,8 +305,8 @@ action = function(host, port)
|
||||
-- 10 minutes
|
||||
endT = 10*60*1000 + nmap.clock_ms()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Check if the server is a DNS server.
|
||||
if not pingServer(host,port,1) then
|
||||
-- David reported that his DNS server doesn't respond to
|
||||
|
||||
@@ -25,7 +25,7 @@ http://7bits.nl/blog/2012/03/26/finding-v6-hosts-by-efficiently-mapping-ip6-arpa
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | dns-ip6-arpa-scan:
|
||||
-- | dns-ip6-arpa-scan:
|
||||
-- | ip ptr
|
||||
-- | 2001:0DB8:0:0:0:0:0:2 resolver1.example.com
|
||||
-- |_2001:0DB8:0:0:0:0:0:3 resolver2.example.com
|
||||
@@ -95,7 +95,7 @@ action = function()
|
||||
threads[co] = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local condvar = nmap.condvar(result)
|
||||
repeat
|
||||
for t in pairs(threads) do
|
||||
@@ -105,11 +105,11 @@ action = function()
|
||||
condvar "wait"
|
||||
end
|
||||
until( next(threads) == nil )
|
||||
|
||||
|
||||
if ( 0 == #result ) then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
found = result
|
||||
i = i + 1
|
||||
until( 128 == i * 2 + mask )
|
||||
@@ -121,6 +121,6 @@ action = function()
|
||||
for _, item in ipairs(result) do
|
||||
tab.addrow(output, item.ip, item.ptr)
|
||||
end
|
||||
|
||||
|
||||
return "\n" .. tab.dump(output)
|
||||
end
|
||||
|
||||
@@ -52,7 +52,7 @@ References:
|
||||
]]
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -sU -p 53 <target> --script=dns-nsec3-enum --script-args dns-nsec3-enum.domains=example.com
|
||||
-- nmap -sU -p 53 <target> --script=dns-nsec3-enum --script-args dns-nsec3-enum.domains=example.com
|
||||
---
|
||||
-- @args dns-nsec3-enum.domains The domain or list of domains to
|
||||
-- enumerate. If not provided, the script will make a guess based on the
|
||||
@@ -85,7 +85,7 @@ local function get_end_time()
|
||||
local t = nmap.timing_level()
|
||||
local limit = stdnse.parse_timespec(stdnse.get_script_args('dns-nsec3-enum.timelimit') or "30m")
|
||||
local end_time = 1000 * limit + nmap.clock_ms()
|
||||
return end_time
|
||||
return end_time
|
||||
end
|
||||
|
||||
local function remove_empty(t)
|
||||
@@ -172,13 +172,13 @@ local function random_string()
|
||||
return msrpc.random_crap(8,"etaoinshrdlucmfw")
|
||||
end
|
||||
|
||||
-- generate a random hash with domains suffix
|
||||
-- generate a random hash with domains suffix
|
||||
-- return both domain and it's hash
|
||||
local function generate_hash(domain, iter, salt)
|
||||
local rand_str = random_string()
|
||||
local random_domain = rand_str .. "." .. domain
|
||||
local random_domain = rand_str .. "." .. domain
|
||||
local packed_domain = ""
|
||||
for word in string.gmatch(domain,"[^%.]+") do
|
||||
for word in string.gmatch(domain,"[^%.]+") do
|
||||
packed_domain = packed_domain .. bin.pack("c",string.len(word)) .. word
|
||||
end
|
||||
local to_hash = bin.pack("c",string.len(rand_str)) .. rand_str .. packed_domain .. bin.pack("c",0) .. bin.pack("H",salt)
|
||||
@@ -191,7 +191,7 @@ local function generate_hash(domain, iter, salt)
|
||||
return string.lower(base32.enc(hash,true)), random_domain
|
||||
end
|
||||
|
||||
-- convenience function , returns size of a table
|
||||
-- convenience function , returns size of a table
|
||||
local function table_size(tbl)
|
||||
local numItems = 0
|
||||
for k,v in pairs(tbl) do
|
||||
@@ -205,16 +205,16 @@ local function get_first(tbl)
|
||||
for k,v in pairs(tbl) do
|
||||
return k,v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- queries the domain and parses the results
|
||||
-- queries the domain and parses the results
|
||||
-- returns the list of new ranges
|
||||
local function query_for_hashes(host,subdomain,domain)
|
||||
local status
|
||||
local result
|
||||
local ranges = {}
|
||||
status, result = dns.query(subdomain, {host = host.ip, dtype='NSEC3', retAll=true, retPkt=true, dnssec=true})
|
||||
if status then
|
||||
if status then
|
||||
for _, nsec3 in ipairs(auth_filter(result, "NSEC3")) do
|
||||
local h1 = string.lower(remove_suffix(nsec3.dname,domain))
|
||||
local h2 = string.lower(nsec3.hash.base32)
|
||||
@@ -224,15 +224,15 @@ local function query_for_hashes(host,subdomain,domain)
|
||||
end
|
||||
ranges[h1] = h2
|
||||
end
|
||||
else
|
||||
else
|
||||
stdnse.print_debug(1, "DNS error: %s", result)
|
||||
end
|
||||
end
|
||||
return ranges
|
||||
end
|
||||
|
||||
-- does the actuall enumeration
|
||||
local function enum(host, port, domain)
|
||||
|
||||
|
||||
local seen, seen_subdomain = {}, {}
|
||||
local ALG ={}
|
||||
ALG[1] = "SHA-1"
|
||||
@@ -241,8 +241,8 @@ local function enum(host, port, domain)
|
||||
local result = {}
|
||||
local subdomain = msrpc.random_crap(8,"etaoinshrdlucmfw")
|
||||
local full_domain = join({subdomain, domain})
|
||||
local iter
|
||||
local salt
|
||||
local iter
|
||||
local salt
|
||||
local end_time = get_end_time()
|
||||
|
||||
-- do one query to determine the hash and if DNSSEC is actually used
|
||||
@@ -251,12 +251,12 @@ local function enum(host, port, domain)
|
||||
local is_nsec3 = false
|
||||
for _, nsec3 in ipairs(auth_filter(result, "NSEC3")) do -- parse the results and add initial ranges
|
||||
is_nsec3 = true
|
||||
dnssec = true
|
||||
dnssec = true
|
||||
iter = nsec3.iterations
|
||||
salt = nsec3.salt.hex
|
||||
local h1 = string.lower(remove_suffix(nsec3.dname,domain))
|
||||
local h2 = string.lower(nsec3.hash.base32)
|
||||
if table_size(todo) == 0 then
|
||||
if table_size(todo) == 0 then
|
||||
table.insert(all_results, "domain " .. domain)
|
||||
stdnse.print_debug("domain " .. domain)
|
||||
table.insert(all_results, "salt " .. salt)
|
||||
@@ -265,11 +265,11 @@ local function enum(host, port, domain)
|
||||
stdnse.print_debug("iterations " .. iter)
|
||||
if h1 < h2 then
|
||||
todo[h2] = h1
|
||||
else
|
||||
else
|
||||
todo[h1] = h2
|
||||
end
|
||||
else
|
||||
for b,a in pairs(todo) do
|
||||
else
|
||||
for b,a in pairs(todo) do
|
||||
if h1 == b and h2 == a then -- h2:a b:h1 case
|
||||
todo[b] = nil
|
||||
break
|
||||
@@ -284,7 +284,7 @@ local function enum(host, port, domain)
|
||||
todo[b] = h2
|
||||
break
|
||||
end
|
||||
if h1 > b then -- a b h1 h2
|
||||
if h1 > b then -- a b h1 h2
|
||||
todo[b] = nil
|
||||
todo[b] = h1
|
||||
todo[h2] = a
|
||||
@@ -299,7 +299,7 @@ local function enum(host, port, domain)
|
||||
end -- for
|
||||
end -- else
|
||||
table.insert(all_results, "nexthash " .. h1 .. " " .. h2)
|
||||
stdnse.print_debug("nexthash " .. h1 .. " " .. h2)
|
||||
stdnse.print_debug("nexthash " .. h1 .. " " .. h2)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -308,7 +308,7 @@ local function enum(host, port, domain)
|
||||
local hash
|
||||
hash, subdomain = generate_hash(domain,iter,salt)
|
||||
local queried = false
|
||||
for a,b in pairs(todo) do
|
||||
for a,b in pairs(todo) do
|
||||
if a == b then
|
||||
todo[a] = nil
|
||||
break
|
||||
@@ -358,7 +358,7 @@ local function enum(host, port, domain)
|
||||
end
|
||||
if h1 == a and h2 > h1 then -- b a:h1 h2 case
|
||||
todo[a] = nil
|
||||
todo[h1] = b
|
||||
todo[h1] = b
|
||||
changed = true
|
||||
end
|
||||
if h1 == a and h2 < b then -- h2 b a:h1 case
|
||||
@@ -393,7 +393,7 @@ local function enum(host, port, domain)
|
||||
if queried then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return dnssec, status, all_results
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ References:
|
||||
--
|
||||
-- @output
|
||||
-- 53/udp open domain udp-response
|
||||
-- | dns-nsid:
|
||||
-- | dns-nsid:
|
||||
-- | NSID dns.example.com (646E732E6578616D706C652E636F6D)
|
||||
-- | id.server: dns.example.com
|
||||
-- |_ bind.version: 9.7.3-P3
|
||||
@@ -60,7 +60,7 @@ local function rr_filter(pktRR, label)
|
||||
end
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
action = function(host, port)
|
||||
local result = stdnse.output_table()
|
||||
local flag = false
|
||||
local status, resp = dns.query("id.server", {host = host.ip, dtype='TXT', class=dns.CLASS.CH, retAll=true, retPkt=true, nsid=true, dnssec=true})
|
||||
@@ -80,13 +80,13 @@ action = function(host, port)
|
||||
local status, id_server = rr_filter(resp.answers,'TXT')
|
||||
if ( status ) then
|
||||
flag = true
|
||||
result["id.server"] = id_server
|
||||
result["id.server"] = id_server
|
||||
end
|
||||
end
|
||||
local status, bind_version = dns.query("version.bind", {host = host.ip, dtype='TXT', class=dns.CLASS.CH})
|
||||
if ( status ) then
|
||||
flag = true
|
||||
result["bind.version"] = bind_version
|
||||
result["bind.version"] = bind_version
|
||||
end
|
||||
if flag then
|
||||
return result
|
||||
|
||||
@@ -122,7 +122,7 @@ action = function(host, port)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Check for two Answer RRs and 1 Authority RR
|
||||
if (string.byte(result, 5) ~= 0x00
|
||||
or string.byte(result, 6) ~= 0x01
|
||||
@@ -148,7 +148,7 @@ action = function(host, port)
|
||||
-- in any way, this won't work and will fail.
|
||||
-- Jump to second answer and check to see that it is TXT, IN
|
||||
-- then grab the length and display that text...
|
||||
|
||||
|
||||
-- Check for TXT
|
||||
if (string.byte(result, 118) ~= 0x00
|
||||
or string.byte(result, 119) ~= 0x10)
|
||||
|
||||
@@ -122,7 +122,7 @@ action = function(host, port)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Check for two Answer RRs and 1 Authority RR
|
||||
if (string.byte(result, 5) ~= 0x00
|
||||
or string.byte(result, 6) ~= 0x01
|
||||
@@ -148,7 +148,7 @@ action = function(host, port)
|
||||
-- in any way, this won't work and will fail.
|
||||
-- Jump to second answer and check to see that it is TXT, IN
|
||||
-- then grab the length and display that text...
|
||||
|
||||
|
||||
-- Check for TXT
|
||||
if (string.byte(result, 118) ~= 0x00
|
||||
or string.byte(result, 119) ~= 0x10)
|
||||
|
||||
@@ -3,7 +3,7 @@ local nmap = require "nmap"
|
||||
local shortport = require "shortport"
|
||||
local stdnse = require "stdnse"
|
||||
|
||||
description=[[
|
||||
description=[[
|
||||
Attempts to discover target hosts' services using the DNS Service Discovery protocol.
|
||||
|
||||
The script first sends a query for _services._dns-sd._udp.local to get a
|
||||
@@ -19,7 +19,7 @@ get more information.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 5353/udp open zeroconf udp-response
|
||||
-- | dns-service-discovery:
|
||||
-- | dns-service-discovery:
|
||||
-- | 548/tcp afpovertcp
|
||||
-- | model=MacBook5,1
|
||||
-- | Address=192.168.0.2 fe80:0:0:0:223:6cff:1234:5678
|
||||
|
||||
@@ -25,7 +25,7 @@ The following services are enumerated by the script:
|
||||
-- nmap --script dns-srv-enum --script-args "dns-srv-enum.domain='example.com'"
|
||||
--
|
||||
-- @output
|
||||
-- | dns-srv-enum:
|
||||
-- | dns-srv-enum:
|
||||
-- | Active Directory Global Catalog
|
||||
-- | service prio weight host
|
||||
-- | 3268/tcp 0 100 stodc01.example.com
|
||||
@@ -72,7 +72,7 @@ local function parseSvcList(services)
|
||||
local i = 1
|
||||
return function()
|
||||
local svc = services[i]
|
||||
if ( svc ) then
|
||||
if ( svc ) then
|
||||
i=i + 1
|
||||
else
|
||||
return
|
||||
@@ -151,20 +151,20 @@ action = function(host)
|
||||
{ name = "XMPP server-to-server", query = {"_xmpp-server._tcp"} },
|
||||
{ name = "XMPP client-to-server", query = {"_xmpp-client._tcp"} },
|
||||
}
|
||||
|
||||
|
||||
if ( not(checkFilter(services)) ) then
|
||||
return fail(("Invalid filter (%s) was supplied"):format(arg_filter))
|
||||
end
|
||||
|
||||
local threads, result = {}, {}
|
||||
for name, queries in parseSvcList(services) do
|
||||
if ( not(arg_filter) or 0 == #arg_filter or
|
||||
if ( not(arg_filter) or 0 == #arg_filter or
|
||||
"all" == arg_filter or arg_filter == name ) then
|
||||
local co = stdnse.new_thread(doQuery, name, queries, result)
|
||||
threads[co] = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local condvar = nmap.condvar(result)
|
||||
repeat
|
||||
for t in pairs(threads) do
|
||||
@@ -174,8 +174,8 @@ action = function(host)
|
||||
condvar "wait"
|
||||
end
|
||||
until( next(threads) == nil )
|
||||
|
||||
|
||||
table.sort(result, function(a,b) return a.name < b.name end)
|
||||
|
||||
|
||||
return stdnse.format_output(true, result)
|
||||
end
|
||||
|
||||
@@ -16,7 +16,7 @@ categories = {"discovery", "safe"}
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 53/udp open domain
|
||||
-- | dns-update:
|
||||
-- | dns-update:
|
||||
-- | Successfully added the record "nmap-test.cqure.net"
|
||||
-- |_ Successfully deleted the record "nmap-test.cqure.net"
|
||||
--
|
||||
@@ -49,7 +49,7 @@ categories = {"discovery", "safe"}
|
||||
portrule = shortport.port_or_service( 53, "dns", "udp", {"open", "open|filtered"} )
|
||||
|
||||
local function test(host, port)
|
||||
|
||||
|
||||
local status, err = dns.update( "www.cqure.net", { host=host, port=port, dtype="A", data="10.10.10.10" } )
|
||||
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
|
||||
status, err = dns.update( "www2", { zone="cqure.net", host=host, port=port, dtype="A", data="10.10.10.10" } )
|
||||
@@ -60,7 +60,7 @@ local function test(host, port)
|
||||
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
|
||||
status, err = dns.update( "_ldap._tcp.cqure.net", { host=host, port=port, dtype="SRV", data={ prio=0, weight=100, port=389, target="ldap.cqure.net" } } )
|
||||
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
|
||||
|
||||
|
||||
status, err = dns.update( "www.cqure.net", { host=host, port=port, dtype="A", data="", ttl=0 } )
|
||||
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
|
||||
status, err = dns.update( "www2.cqure.net", { host=host, port=port, dtype="A", data="", ttl=0 } )
|
||||
@@ -71,11 +71,11 @@ local function test(host, port)
|
||||
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
|
||||
status, err = dns.update( "_ldap._tcp.cqure.net", { host=host, port=port, dtype="SRV", data="", ttl=0 } )
|
||||
if ( status ) then stdnse.print_debug("SUCCESS") else stdnse.print_debug("FAIL: " .. (err or "")) end
|
||||
|
||||
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
|
||||
local t = stdnse.get_script_args('dns-update.test')
|
||||
local name, ip = stdnse.get_script_args('dns-update.hostname', 'dns-update.ip')
|
||||
|
||||
@@ -98,7 +98,7 @@ action = function(host, port)
|
||||
nmap.set_port_state(host, port, "open")
|
||||
return stdnse.format_output(true, result)
|
||||
elseif ( err ) then
|
||||
return "\n ERROR: " .. err
|
||||
return "\n ERROR: " .. err
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -9,21 +9,21 @@ Checks if the target IP range is part of a Zeus botnet by querying ZTDNS @ abuse
|
||||
Please review the following information before you start to scan:
|
||||
* https://zeustracker.abuse.ch/ztdns.php
|
||||
]]
|
||||
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -sn -PN --script=dns-zeustracker <ip>
|
||||
-- @output
|
||||
-- Host script results:
|
||||
-- | dns-zeustracker:
|
||||
-- | dns-zeustracker:
|
||||
-- | Name IP SBL ASN Country Status Level Files Online Date added
|
||||
-- | foo.example.com 1.2.3.4 SBL123456 1234 CN online Bulletproof hosted 0 2011-06-17
|
||||
-- |_ bar.example.com 1.2.3.5 SBL123456 1234 CN online Bulletproof hosted 0 2011-06-15
|
||||
|
||||
|
||||
author = "Mikael Keri"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"safe", "discovery", "external", "malware"}
|
||||
|
||||
|
||||
|
||||
|
||||
hostrule = function(host) return not(ipOps.isPrivate(host.ip)) end
|
||||
@@ -31,7 +31,7 @@ hostrule = function(host) return not(ipOps.isPrivate(host.ip)) end
|
||||
action = function(host)
|
||||
|
||||
local levels = {
|
||||
"Bulletproof hosted",
|
||||
"Bulletproof hosted",
|
||||
"Hacked webserver",
|
||||
"Free hosting service",
|
||||
"Unknown",
|
||||
@@ -51,7 +51,7 @@ action = function(host)
|
||||
tab.addrow(output, "Name", "IP", "SBL", "ASN", "Country", "Status", "Level",
|
||||
"Files Online", "Date added")
|
||||
for _, record in ipairs(result) do
|
||||
local name, ip, sbl, asn, country, status, level, files_online,
|
||||
local name, ip, sbl, asn, country, status, level, files_online,
|
||||
dateadded = table.unpack(stdnse.strsplit("| ", record))
|
||||
level = levels[tonumber(level)] or "Unknown"
|
||||
tab.addrow(output, name, ip, sbl, asn, country, status, level, files_online, dateadded)
|
||||
|
||||
@@ -57,25 +57,25 @@ Useful resources
|
||||
-- 53/tcp open domain
|
||||
-- | dns-zone-transfer:
|
||||
-- | foo.com. SOA ns2.foo.com. piou.foo.com.
|
||||
-- | foo.com. TXT
|
||||
-- | foo.com. NS ns1.foo.com.
|
||||
-- | foo.com. NS ns2.foo.com.
|
||||
-- | foo.com. NS ns3.foo.com.
|
||||
-- | foo.com. A 127.0.0.1
|
||||
-- | foo.com. MX mail.foo.com.
|
||||
-- | anansie.foo.com. A 127.0.0.2
|
||||
-- | dhalgren.foo.com. A 127.0.0.3
|
||||
-- | foo.com. TXT
|
||||
-- | foo.com. NS ns1.foo.com.
|
||||
-- | foo.com. NS ns2.foo.com.
|
||||
-- | foo.com. NS ns3.foo.com.
|
||||
-- | foo.com. A 127.0.0.1
|
||||
-- | foo.com. MX mail.foo.com.
|
||||
-- | anansie.foo.com. A 127.0.0.2
|
||||
-- | dhalgren.foo.com. A 127.0.0.3
|
||||
-- | drupal.foo.com. CNAME
|
||||
-- | goodman.foo.com. A 127.0.0.4 i
|
||||
-- | goodman.foo.com. MX mail.foo.com.
|
||||
-- | isaac.foo.com. A 127.0.0.5
|
||||
-- | julie.foo.com. A 127.0.0.6
|
||||
-- | mail.foo.com. A 127.0.0.7
|
||||
-- | ns1.foo.com. A 127.0.0.7
|
||||
-- | ns2.foo.com. A 127.0.0.8
|
||||
-- | ns3.foo.com. A 127.0.0.9
|
||||
-- | stubing.foo.com. A 127.0.0.10
|
||||
-- | vicki.foo.com. A 127.0.0.11
|
||||
-- | goodman.foo.com. A 127.0.0.4 i
|
||||
-- | goodman.foo.com. MX mail.foo.com.
|
||||
-- | isaac.foo.com. A 127.0.0.5
|
||||
-- | julie.foo.com. A 127.0.0.6
|
||||
-- | mail.foo.com. A 127.0.0.7
|
||||
-- | ns1.foo.com. A 127.0.0.7
|
||||
-- | ns2.foo.com. A 127.0.0.8
|
||||
-- | ns3.foo.com. A 127.0.0.9
|
||||
-- | stubing.foo.com. A 127.0.0.10
|
||||
-- | vicki.foo.com. A 127.0.0.11
|
||||
-- | votetrust.foo.com. CNAME
|
||||
-- | www.foo.com. CNAME
|
||||
-- |_ foo.com. SOA ns2.foo.com. piou.foo.com.
|
||||
@@ -437,7 +437,7 @@ local RD = {
|
||||
offset, field = bin.unpack("A" .. (bto16(data, offset-2)-2), data, offset+2)
|
||||
return offset, string.format("%d %d %s", coding, subcoding, stdnse.tohex(field))
|
||||
end,
|
||||
--OPT APL DS
|
||||
--OPT APL DS
|
||||
SSHFP = function(data, offset)
|
||||
local algorithm, fptype, fplen, fingerprint
|
||||
algorithm = string.byte(data, offset)
|
||||
@@ -625,7 +625,7 @@ function add_zone_info(response)
|
||||
return false, ret and ret or "Error: failed to add DNS records."
|
||||
end
|
||||
tab.addrow(outtab, "Node Names", newhosts_count)
|
||||
nhosts = newhosts_count
|
||||
nhosts = newhosts_count
|
||||
|
||||
tab.nextrow(outtab)
|
||||
|
||||
@@ -636,7 +636,7 @@ function add_zone_info(response)
|
||||
if rectype == 'A' then
|
||||
for rdata in pairs(RR[rectype]) do
|
||||
if dns_opts.addall or not ipOps.isPrivate(rdata) then
|
||||
status, ret = target.add(rdata)
|
||||
status, ret = target.add(rdata)
|
||||
if not status then
|
||||
stdnse.print_debug(3,
|
||||
"Error: failed to add all 'A' records.")
|
||||
|
||||
@@ -16,7 +16,7 @@ Performs brute force password auditing against the Lotus Domino Console.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 2050/tcp open unknown syn-ack
|
||||
-- | domcon-brute:
|
||||
-- | domcon-brute:
|
||||
-- | Accounts
|
||||
-- |_ patrik karlsson:secret => Login correct
|
||||
--
|
||||
@@ -40,7 +40,7 @@ portrule = shortport.port_or_service(2050, "", "tcp", "open")
|
||||
local not_admins = {}
|
||||
|
||||
SocketPool = {
|
||||
|
||||
|
||||
new = function(self, max_sockets)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
@@ -49,7 +49,7 @@ SocketPool = {
|
||||
o.pool = {}
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
getSocket = function(self, host, port)
|
||||
while(true) do
|
||||
for i=1, #self.pool do
|
||||
@@ -61,11 +61,11 @@ SocketPool = {
|
||||
if ( #self.pool < self.max_sockets ) then
|
||||
local socket = nmap.new_socket()
|
||||
local status = socket:connect( host.ip, port.number, "tcp")
|
||||
|
||||
|
||||
if ( status ) then
|
||||
socket:reconnect_ssl()
|
||||
end
|
||||
|
||||
|
||||
if ( status and socket ) then
|
||||
table.insert( self.pool, {['socket'] = socket, ['inuse'] = false})
|
||||
end
|
||||
@@ -73,7 +73,7 @@ SocketPool = {
|
||||
stdnse.sleep(1)
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
releaseSocket = function( self, socket )
|
||||
for i=1, #self.pool do
|
||||
if( socket == self.pool[i].socket ) then
|
||||
@@ -82,16 +82,16 @@ SocketPool = {
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
shutdown = function( self )
|
||||
for i=1, #self.pool do
|
||||
self.pool[i].socket:close()
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
Driver =
|
||||
Driver =
|
||||
{
|
||||
|
||||
new = function(self, host, port, options)
|
||||
@@ -103,10 +103,10 @@ Driver =
|
||||
o.sockpool = options
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect = function( self )
|
||||
self.socket = self.sockpool:getSocket( self.host, self.port )
|
||||
|
||||
|
||||
if ( self.socket ) then
|
||||
return true
|
||||
else
|
||||
@@ -124,7 +124,7 @@ Driver =
|
||||
login = function( self, username, password )
|
||||
local data = ("#UI %s,%s\n"):format(username,password)
|
||||
local status
|
||||
|
||||
|
||||
if ( not_admins[username] ) then
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end
|
||||
@@ -135,7 +135,7 @@ Driver =
|
||||
err:setRetry(true)
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
status, data = self.socket:receive_bytes(5)
|
||||
|
||||
if ( status and data:match("NOT_REG_ADMIN") ) then
|
||||
@@ -147,22 +147,22 @@ Driver =
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function( self )
|
||||
self.sockpool:releaseSocket( self.socket )
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
local status, result
|
||||
local status, result
|
||||
local pool = SocketPool:new(10)
|
||||
local engine = brute.Engine:new(Driver, host, port, pool )
|
||||
|
||||
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
status, result = engine:start()
|
||||
pool:shutdown()
|
||||
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -15,25 +15,25 @@ Runs a console command on the Lotus Domino Console using the given authenticatio
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 2050/tcp open unknown syn-ack
|
||||
-- | domcon-cmd:
|
||||
-- | domcon-cmd:
|
||||
-- | show server
|
||||
-- |
|
||||
-- |
|
||||
-- | Lotus Domino (r) Server (Release 8.5 for Windows/32) 2010-07-30 00:52:58
|
||||
-- |
|
||||
-- |
|
||||
-- | Server name: server1/cqure - cqure testing server
|
||||
-- | Domain name: cqure
|
||||
-- | Server directory: C:\Program Files\IBM\Lotus\Domino\data
|
||||
-- | Partition: C.Program Files.IBM.Lotus.Domino.data
|
||||
-- | Elapsed time: 00:27:11
|
||||
-- | Transactions/minute: Last minute: 0; Last hour: 0; Peak: 0
|
||||
-- | Peak # of sessions: 0 at
|
||||
-- | Peak # of sessions: 0 at
|
||||
-- | Transactions: 0 Max. concurrent: 20
|
||||
-- | ThreadPool Threads: 20 (TCPIP Port)
|
||||
-- | Availability Index: 100 (state: AVAILABLE)
|
||||
-- | Mail Tracking: Not Enabled
|
||||
-- | Mail Journalling: Not Enabled
|
||||
-- | Number of Mailboxes: 1
|
||||
-- | Pending mail: 0 Dead mail: 0
|
||||
-- | Pending mail: 0 Dead mail: 0
|
||||
-- | Waiting Tasks: 0
|
||||
-- | DAOS: Not Enabled
|
||||
-- | Transactional Logging: Not Enabled
|
||||
@@ -69,7 +69,7 @@ portrule = shortport.port_or_service(2050, "dominoconsole", "tcp", "open")
|
||||
-- @return result table containing lines with server response
|
||||
-- or error message if status is false
|
||||
local function readAPIBlock( socket )
|
||||
|
||||
|
||||
local lines
|
||||
local result = {}
|
||||
local status, line = socket:receive_lines(1)
|
||||
@@ -82,7 +82,7 @@ local function readAPIBlock( socket )
|
||||
table.insert(result, line)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Clear trailing empty lines
|
||||
while( true ) do
|
||||
if ( result[#result] == "" ) then
|
||||
@@ -93,7 +93,7 @@ local function readAPIBlock( socket )
|
||||
end
|
||||
|
||||
return true, result
|
||||
|
||||
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
@@ -115,24 +115,24 @@ action = function(host, port)
|
||||
if ( status ) then
|
||||
socket:reconnect_ssl()
|
||||
end
|
||||
|
||||
|
||||
socket:send("#API\n")
|
||||
socket:send( ("#UI %s,%s\n"):format(user,pass) )
|
||||
socket:receive_lines(1)
|
||||
socket:send("#EXIT\n")
|
||||
|
||||
|
||||
for i=1, #cmds do
|
||||
socket:send(cmds[i] .. "\n")
|
||||
status, result_part = readAPIBlock( socket )
|
||||
if( status ) then
|
||||
result_part.name = cmds[i]
|
||||
table.insert( result, result_part )
|
||||
table.insert( result, result_part )
|
||||
else
|
||||
return " \n ERROR: " .. result_part
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
socket:close()
|
||||
|
||||
|
||||
return stdnse.format_output( true, result )
|
||||
end
|
||||
|
||||
@@ -50,7 +50,7 @@ portrule = shortport.port_or_service(1352, "lotusnotes", "tcp", "open")
|
||||
--- Saves the ID file to disk
|
||||
--
|
||||
-- @param filename string containing the name and full path to the file
|
||||
-- @param data contains the data
|
||||
-- @param data contains the data
|
||||
-- @return status true on success, false on failure
|
||||
-- @return err string containing error message if status is false
|
||||
local function saveIDFile( filename, data )
|
||||
@@ -76,14 +76,14 @@ action = function(host, port)
|
||||
local counter = 0
|
||||
local domino_username = stdnse.get_script_args("domino-enum-users.username")
|
||||
if ( domino_username ) then
|
||||
usernames = ( function()
|
||||
local b = true
|
||||
return function()
|
||||
if ( b ) then
|
||||
b=false;
|
||||
usernames = ( function()
|
||||
local b = true
|
||||
return function()
|
||||
if ( b ) then
|
||||
b=false;
|
||||
return domino_username
|
||||
end
|
||||
end
|
||||
end
|
||||
end )()
|
||||
else
|
||||
status, usernames = unpwdb.usernames()
|
||||
@@ -91,7 +91,7 @@ action = function(host, port)
|
||||
return false, "Failed to load usernames"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
for username in usernames do
|
||||
status = helper:connect()
|
||||
if ( not(status) ) then
|
||||
@@ -101,11 +101,11 @@ action = function(host, port)
|
||||
|
||||
status, data = helper:isValidUser( username )
|
||||
helper:disconnect()
|
||||
|
||||
|
||||
if ( status and data and path ) then
|
||||
local filename = path .. "/" .. stdnse.filename_escape(username .. ".id")
|
||||
local status, err = saveIDFile( filename, data )
|
||||
|
||||
|
||||
if ( status ) then
|
||||
table.insert(result, ("Succesfully stored \"%s\" in %s"):format(username, filename) )
|
||||
else
|
||||
@@ -113,22 +113,22 @@ action = function(host, port)
|
||||
table.insert(result, ("Failed to store \"%s\" to %s"):format(username, filename) )
|
||||
end
|
||||
elseif( status and data ) then
|
||||
table.insert(result, ("Succesfully retrieved ID for \"%s\" (to store set the domino-enum-users.path argument)"):format(username) )
|
||||
table.insert(result, ("Succesfully retrieved ID for \"%s\" (to store set the domino-enum-users.path argument)"):format(username) )
|
||||
elseif ( status ) then
|
||||
table.insert(result, ("User \"%s\" found, but no ID file could be downloaded"):format(username) )
|
||||
table.insert(result, ("User \"%s\" found, but no ID file could be downloaded"):format(username) )
|
||||
end
|
||||
|
||||
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
|
||||
if ( #result == 0 ) then
|
||||
table.insert(result, ("Guessed %d usernames, none were found"):format(counter) )
|
||||
end
|
||||
|
||||
|
||||
result = stdnse.format_output( true, result )
|
||||
if ( err ) then
|
||||
result = result .. (" \n %s"):format(err)
|
||||
end
|
||||
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ Performs brute force password auditing against an iPhoto Library.
|
||||
--
|
||||
-- @output
|
||||
-- 8770/tcp open apple-iphoto syn-ack
|
||||
-- | dpap-brute:
|
||||
-- | dpap-brute:
|
||||
-- | Accounts
|
||||
-- | secret => Login correct
|
||||
-- | Statistics
|
||||
@@ -34,7 +34,7 @@ categories = {"intrusive", "brute"}
|
||||
portrule = shortport.port_or_service(8770, "apple-iphoto")
|
||||
|
||||
Driver = {
|
||||
|
||||
|
||||
new = function(self, host, port)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
@@ -43,13 +43,13 @@ Driver = {
|
||||
o.port = port
|
||||
return o
|
||||
end,
|
||||
|
||||
|
||||
connect = function( self )
|
||||
self.socket = nmap.new_socket()
|
||||
self.socket:set_timeout(5000)
|
||||
return self.socket:connect(self.host, self.port, "tcp")
|
||||
end,
|
||||
|
||||
|
||||
login = function( self, username, password )
|
||||
local data = "GET dpap://%s:%d/login HTTP/1.1\r\n" ..
|
||||
"User-Agent: iPhoto/9.1.1 (Macintosh; N; PPC)\r\n" ..
|
||||
@@ -57,31 +57,31 @@ Driver = {
|
||||
"Authorization: Basic %s\r\n" ..
|
||||
"Client-DPAP-Version: 1.1\r\n" ..
|
||||
"\r\n\r\n"
|
||||
|
||||
|
||||
local c = base64.enc("nmap:" .. password)
|
||||
data = data:format( self.host.ip, self.port.number, self.host.ip, c )
|
||||
|
||||
|
||||
local status = self.socket:send( data )
|
||||
if ( not(status) ) then
|
||||
local err = brute.Error:new( "Failed to send data to DPAP server" )
|
||||
err:setRetry( true )
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
status, data = self.socket:receive()
|
||||
if ( not(status) ) then
|
||||
local err = brute.Error:new( "Failed to receive data from DPAP server" )
|
||||
err:setRetry( true )
|
||||
return false, err
|
||||
end
|
||||
|
||||
|
||||
if ( data:match("^HTTP/1.1 200 OK") ) then
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end,
|
||||
|
||||
|
||||
disconnect = function( self )
|
||||
self.socket:close()
|
||||
end,
|
||||
@@ -91,11 +91,11 @@ Driver = {
|
||||
local function checkEmptyPassword(host, port)
|
||||
local d = Driver:new(host, port)
|
||||
local status = d:connect()
|
||||
|
||||
|
||||
if ( not(status) ) then
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
status = d:login("", "")
|
||||
d:disconnect()
|
||||
|
||||
@@ -109,13 +109,13 @@ action = function(host, port)
|
||||
return "Library has no password"
|
||||
end
|
||||
|
||||
local status, result
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver, host, port )
|
||||
|
||||
|
||||
engine.options.firstonly = true
|
||||
engine.options:setOption( "passonly", true )
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
|
||||
status, result = engine:start()
|
||||
|
||||
return result
|
||||
|
||||
@@ -22,7 +22,7 @@ Performs password guessing against databases supporting the IBM DB2 protocol suc
|
||||
--
|
||||
-- @output
|
||||
-- 50000/tcp open drda
|
||||
-- | drda-brute:
|
||||
-- | drda-brute:
|
||||
-- |_ db2admin:db2admin => Valid credentials
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
@@ -73,21 +73,21 @@ doLogin = function( host, port, database, creds, valid_accounts )
|
||||
-- Checks if a password was already discovered for this account
|
||||
if ( nmap.registry.db2users == nil or nmap.registry.db2users[username] == nil ) then
|
||||
helper = drda.Helper:new()
|
||||
helper:connect( host, port )
|
||||
helper:connect( host, port )
|
||||
stdnse.print_debug( "Trying %s/%s against %s...", username, password, host.ip )
|
||||
status, response = helper:login( database, username, password )
|
||||
helper:close()
|
||||
|
||||
|
||||
if ( status ) then
|
||||
-- Add credentials for future drda scripts to use
|
||||
if nmap.registry.db2users == nil then
|
||||
nmap.registry.db2users = {}
|
||||
end
|
||||
end
|
||||
nmap.registry.db2users[username]=password
|
||||
table.insert( valid_accounts, string.format("%s:%s => Valid credentials", username, password:len()>0 and password or "<empty>" ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
condvar("broadcast")
|
||||
end
|
||||
|
||||
@@ -100,9 +100,9 @@ end
|
||||
isValidDb = function( host, port, database )
|
||||
local status, response
|
||||
local helper = drda.Helper:new()
|
||||
|
||||
|
||||
helper:connect( host, port )
|
||||
-- Authenticate with a static probe account to see if the db is valid
|
||||
-- Authenticate with a static probe account to see if the db is valid
|
||||
status, response = helper:login( database, "dbnameprobe1234", "dbnameprobe1234" )
|
||||
helper:close()
|
||||
|
||||
@@ -118,7 +118,7 @@ end
|
||||
-- @return count number containing the number of non-dead threads
|
||||
threadCount = function( threads )
|
||||
local count = 0
|
||||
|
||||
|
||||
for thread in pairs(threads) do
|
||||
if ( coroutine.status(thread) == "dead" ) then
|
||||
threads[thread] = nil
|
||||
@@ -132,7 +132,7 @@ end
|
||||
action = function( host, port )
|
||||
|
||||
local result, response, status = {}, nil, nil
|
||||
local valid_accounts, threads = {}, {}
|
||||
local valid_accounts, threads = {}, {}
|
||||
local usernames, passwords, creds
|
||||
local database = stdnse.get_script_args('drda-brute.dbname') or "SAMPLE"
|
||||
local condvar = nmap.condvar( valid_accounts )
|
||||
@@ -147,18 +147,18 @@ action = function( host, port )
|
||||
if ( not(status) ) then
|
||||
return "Failed to load usernames"
|
||||
end
|
||||
|
||||
|
||||
-- make sure we have a valid pw file
|
||||
status, passwords = unpwdb.passwords()
|
||||
if ( not(status) ) then
|
||||
return "Failed to load passwords"
|
||||
end
|
||||
|
||||
|
||||
creds = new_usrpwd_iterator( usernames, passwords )
|
||||
|
||||
|
||||
stdnse.print_debug("Starting brute force with %d threads", max_threads )
|
||||
|
||||
for i=1,max_threads do
|
||||
|
||||
for i=1,max_threads do
|
||||
local co = stdnse.new_thread( doLogin, host, port, database, creds, valid_accounts )
|
||||
threads[co] = true
|
||||
end
|
||||
@@ -168,6 +168,6 @@ action = function( host, port )
|
||||
condvar("wait")
|
||||
end
|
||||
|
||||
return stdnse.format_output(true, valid_accounts)
|
||||
return stdnse.format_output(true, valid_accounts)
|
||||
|
||||
end
|
||||
|
||||
@@ -19,7 +19,7 @@ command packet and parses the response.
|
||||
-- | Server Platform: QDB2/SUN
|
||||
-- | Instance Name: db2inst1
|
||||
-- |_ External Name: db2inst1db2agent00002B430
|
||||
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
@@ -48,7 +48,7 @@ local function parseVersion( server_version )
|
||||
if pfx == "SQL" or pfx == "IFX" then
|
||||
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
|
||||
if string.sub(major_version,1,1) == "0" then
|
||||
major_version = string.sub(major_version,2)
|
||||
@@ -59,7 +59,7 @@ local function parseVersion( server_version )
|
||||
elseif( pfx == "CSS" ) then
|
||||
return server_version:match("%w+/(.*)")
|
||||
end
|
||||
|
||||
|
||||
return server_version
|
||||
end
|
||||
|
||||
@@ -68,7 +68,7 @@ action = function( host, port )
|
||||
local helper = drda.Helper:new()
|
||||
local status, response
|
||||
local results = {}
|
||||
|
||||
|
||||
status, response = helper:connect(host, port)
|
||||
if( not(status) ) then
|
||||
return response
|
||||
@@ -78,7 +78,7 @@ action = function( host, port )
|
||||
if( not(status) ) then
|
||||
return response
|
||||
end
|
||||
|
||||
|
||||
helper:close()
|
||||
|
||||
-- Set port information
|
||||
@@ -102,13 +102,13 @@ action = function( host, port )
|
||||
end
|
||||
nmap.set_port_state(host, port, "open")
|
||||
if response.srvclass ~= nil then port.version.extrainfo = response.srvclass end
|
||||
|
||||
|
||||
nmap.set_port_version(host, port)
|
||||
|
||||
|
||||
-- Generate results
|
||||
table.insert( results, ("Server Platform: %s"):format( response.srvclass ) )
|
||||
table.insert( results, ("Instance Name: %s"):format( response.srvname ) )
|
||||
table.insert( results, ("External Name: %s"):format( response.extname ) )
|
||||
|
||||
|
||||
return stdnse.format_output( true, results )
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ script to analyze the data.
|
||||
-- sudo nmap -PN -p445,443 --script duplicates,nbstat,ssl-cert <ips>
|
||||
--
|
||||
-- @output
|
||||
-- | duplicates:
|
||||
-- | duplicates:
|
||||
-- | ARP
|
||||
-- | MAC: 01:23:45:67:89:0a
|
||||
-- | 192.168.99.10
|
||||
@@ -62,7 +62,7 @@ hostrule = function() return true end
|
||||
postrule = function() return true end
|
||||
|
||||
local function processSSLCerts(tab)
|
||||
|
||||
|
||||
-- Handle SSL-certificates
|
||||
-- We create a new table using the SHA1 digest as index
|
||||
local ssl_certs = {}
|
||||
@@ -74,7 +74,7 @@ local function processSSLCerts(tab)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local results = {}
|
||||
for sha1, hosts in pairs(ssl_certs) do
|
||||
table.sort(hosts, function(a, b) return ipOps.compare_ip(a, "lt", b) end)
|
||||
@@ -82,7 +82,7 @@ local function processSSLCerts(tab)
|
||||
table.insert(results, { name = ("Certficate (%s)"):format(sha1), hosts } )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
@@ -131,29 +131,29 @@ local function processNBStat(tab)
|
||||
table.insert(name_table[v.server_name], host.ip)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
for mac, hosts in pairs(mac_table) do
|
||||
if ( #hosts > 1 ) then
|
||||
table.sort(hosts, function(a, b) return ipOps.compare_ip(a, "lt", b) end)
|
||||
table.insert(results, { name = ("MAC: %s"):format(mac), hosts })
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
for srvname, hosts in pairs(name_table) do
|
||||
if ( #hosts > 1 ) then
|
||||
table.sort(hosts, function(a, b) return ipOps.compare_ip(a, "lt", b) end)
|
||||
table.insert(results, { name = ("Server Name: %s"):format(srvname), hosts })
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
local function processMAC(tab)
|
||||
|
||||
|
||||
local mac
|
||||
local mac_table = {}
|
||||
|
||||
|
||||
for host in pairs(tab) do
|
||||
if ( host.mac_addr ) then
|
||||
mac = stdnse.format_mac(host.mac_addr)
|
||||
@@ -163,7 +163,7 @@ local function processMAC(tab)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local results = {}
|
||||
for mac, hosts in pairs(mac_table) do
|
||||
if ( #hosts > 1 ) then
|
||||
@@ -171,30 +171,30 @@ local function processMAC(tab)
|
||||
table.insert(results, { name = ("MAC: %s"):format(mac), hosts })
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
postaction = function()
|
||||
|
||||
|
||||
local handlers = {
|
||||
['ssl-cert'] = { func = processSSLCerts, name = "SSL" },
|
||||
['sshhostkey'] = { func = processSSHKeys, name = "SSH" },
|
||||
['nbstat'] = { func = processNBStat, name = "Netbios" },
|
||||
['mac'] = { func = processMAC, name = "ARP" }
|
||||
}
|
||||
|
||||
|
||||
-- temporary re-allocation code for SSH keys
|
||||
for k, v in pairs(nmap.registry.sshhostkey or {}) do
|
||||
nmap.registry['duplicates'] = nmap.registry['duplicates'] or {}
|
||||
nmap.registry['duplicates']['sshhostkey'] = nmap.registry['duplicates']['sshhostkey'] or {}
|
||||
nmap.registry['duplicates']['sshhostkey'][k] = v
|
||||
end
|
||||
|
||||
|
||||
if ( not(nmap.registry['duplicates']) ) then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local results = {}
|
||||
for key, handler in pairs(handlers) do
|
||||
if ( nmap.registry['duplicates'][key] ) then
|
||||
@@ -204,7 +204,7 @@ postaction = function()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return stdnse.format_output(true, results)
|
||||
end
|
||||
|
||||
@@ -220,7 +220,7 @@ hostaction = function(host)
|
||||
nmap.registry['duplicates']['ssl-cert'][host] = nmap.registry['duplicates']['ssl-cert'][host] or {}
|
||||
nmap.registry['duplicates']['ssl-cert'][host][port] = stdnse.tohex(cert:digest("sha1"), { separator = " ", group = 4 })
|
||||
end
|
||||
|
||||
|
||||
if ( host.registry['nbstat'] ) then
|
||||
nmap.registry['duplicates']['nbstat'] = nmap.registry['duplicates']['nbstat'] or {}
|
||||
nmap.registry['duplicates']['nbstat'][host] = host.registry['nbstat']
|
||||
|
||||
@@ -17,7 +17,7 @@ anonymous identity if no argument is passed.
|
||||
--
|
||||
-- @output
|
||||
-- Pre-scan script results:
|
||||
-- | eap-info:
|
||||
-- | eap-info:
|
||||
-- | Available authentication methods with identity="anonymous" on interface eth2
|
||||
-- | true PEAP
|
||||
-- | true EAP-TTLS
|
||||
@@ -72,7 +72,7 @@ action = function()
|
||||
-- failed
|
||||
if not iface then
|
||||
return "please specify an interface with -e"
|
||||
end
|
||||
end
|
||||
stdnse.print_debug(1, "iface: %s", iface.device)
|
||||
|
||||
local timeout = (arg_timeout or 10) * 1000
|
||||
@@ -94,7 +94,7 @@ action = function()
|
||||
scan = default_scan
|
||||
else
|
||||
scan = arg_scan
|
||||
end
|
||||
end
|
||||
|
||||
local valid = false
|
||||
for i,v in ipairs(scan) do
|
||||
@@ -113,15 +113,15 @@ action = function()
|
||||
local tried_all = false
|
||||
|
||||
local start_time = nmap.clock_ms()
|
||||
eap.send_start(iface)
|
||||
eap.send_start(iface)
|
||||
|
||||
while(nmap.clock_ms() - start_time < timeout) and not tried_all do
|
||||
local status, plen, l2_data, l3_data, time = pcap:pcap_receive()
|
||||
local status, plen, l2_data, l3_data, time = pcap:pcap_receive()
|
||||
if (status) then
|
||||
stdnse.print_debug(2, "packet size: 0x%x", plen )
|
||||
local packet = eap.parse(l2_data .. l3_data)
|
||||
|
||||
if packet then
|
||||
if packet then
|
||||
stdnse.print_debug(2, "packet valid")
|
||||
|
||||
-- respond to identity requests, using the same session id
|
||||
@@ -136,13 +136,13 @@ action = function()
|
||||
identity.auth[packet.eap.type] = true
|
||||
|
||||
identity.probe = -1
|
||||
for i,v in pairs(identity.auth) do
|
||||
for i,v in pairs(identity.auth) do
|
||||
stdnse.print_debug(1, "identity.auth: %d %s",i,tostring(v))
|
||||
if v == UNKNOWN then
|
||||
identity.probe = i
|
||||
eap.send_nak_response(iface, packet.eap.id, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if identity.probe == -1 then tried_all = true end
|
||||
end
|
||||
@@ -156,36 +156,36 @@ action = function()
|
||||
-- mac spoofing to avoid to wait too much
|
||||
local d = string.byte(iface.mac,6)
|
||||
d = (d + 1) % 256
|
||||
iface.mac = iface.mac:sub(1,5) .. bin.pack("C",d)
|
||||
iface.mac = iface.mac:sub(1,5) .. bin.pack("C",d)
|
||||
|
||||
tried_all = true
|
||||
for i,v in pairs(identity.auth) do
|
||||
for i,v in pairs(identity.auth) do
|
||||
if v == UNKNOWN then
|
||||
tried_all = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if not tried_all then
|
||||
eap.send_start(iface)
|
||||
end
|
||||
end
|
||||
if not tried_all then
|
||||
eap.send_start(iface)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
stdnse.print_debug(1, "packet invalid! wrong filter?")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local results = { ["name"] = ("Available authentication methods with identity=\"%s\" on interface %s"):format(identity.name, iface.device) }
|
||||
for i,v in pairs(identity.auth) do
|
||||
if v== true then
|
||||
if v== true then
|
||||
table.insert(results, 1, ("%-8s %s"):format(tostring(v), eap.eap_str[i] or "unassigned" ))
|
||||
else
|
||||
table.insert(results, ("%-8s %s"):format(tostring(v), eap.eap_str[i] or "unassigned" ))
|
||||
end
|
||||
end
|
||||
|
||||
for i,v in ipairs(results) do
|
||||
for i,v in ipairs(results) do
|
||||
stdnse.print_debug(1, "%s", tostring(v))
|
||||
end
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Connects to Erlang Port Mapper Daemon (epmd) and retrieves a list of nodes with
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 4369/tcp open epmd
|
||||
-- | epmd-info.nse:
|
||||
-- | epmd-info.nse:
|
||||
-- | epmd running on port 4369
|
||||
-- | name rabbit at port 36804
|
||||
-- |_ name ejabberd at port 46540
|
||||
|
||||
@@ -18,7 +18,7 @@ prior to requesting authentication.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 3031/tcp open eppc
|
||||
-- | eppc-enum-processes:
|
||||
-- | eppc-enum-processes:
|
||||
-- | application uid pid
|
||||
-- | Address Book 501 269
|
||||
-- | Facetime 501 495
|
||||
@@ -39,27 +39,27 @@ categories = {"discovery", "safe"}
|
||||
portrule = shortport.port_or_service(3031, "eppc", "tcp", "open")
|
||||
|
||||
action = function( host, port )
|
||||
|
||||
|
||||
local socket = nmap.new_socket()
|
||||
socket:set_timeout(5000)
|
||||
|
||||
local try = nmap.new_try(
|
||||
function()
|
||||
|
||||
local try = nmap.new_try(
|
||||
function()
|
||||
stdnse.print_debug("%s: failed", SCRIPT_NAME)
|
||||
socket:close()
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
-- a list of application that may or may not be running on the target
|
||||
local apps = {
|
||||
"Address Book",
|
||||
"App Store",
|
||||
"Facetime",
|
||||
"Finder",
|
||||
"Firefox",
|
||||
"Finder",
|
||||
"Firefox",
|
||||
"Google Chrome",
|
||||
"iChat",
|
||||
"iPhoto",
|
||||
"iPhoto",
|
||||
"Keychain Access",
|
||||
"iTunes",
|
||||
"Photo booth",
|
||||
@@ -68,12 +68,12 @@ action = function( host, port )
|
||||
"Safari",
|
||||
"Spotify",
|
||||
"Terminal",
|
||||
"TextMate",
|
||||
"TextMate",
|
||||
"Transmission",
|
||||
"VLC",
|
||||
"VLC media player",
|
||||
}
|
||||
|
||||
|
||||
local results = tab.new(3)
|
||||
tab.addrow( results, "application", "uid", "pid" )
|
||||
|
||||
@@ -81,10 +81,10 @@ action = function( host, port )
|
||||
try( socket:connect(host, port, "tcp") )
|
||||
local data
|
||||
|
||||
local packets = {
|
||||
local packets = {
|
||||
"PPCT\0\0\0\1\0\0\0\1",
|
||||
-- unfortunately I've found no packet specifications, so this has to do
|
||||
bin.pack("HCpH", "e44c50525401e101", 225 + #app, app, "dfdbe302013ddfdfdfdfd500")
|
||||
bin.pack("HCpH", "e44c50525401e101", 225 + #app, app, "dfdbe302013ddfdfdfdfd500")
|
||||
}
|
||||
|
||||
for _, v in ipairs(packets) do
|
||||
@@ -97,7 +97,7 @@ action = function( host, port )
|
||||
|
||||
try( socket:close() )
|
||||
end
|
||||
|
||||
|
||||
return "\n" .. tab.dump(results)
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ Namp scan queue.
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 35871/tcp open flume-master syn-ack
|
||||
--| flume-master-info:
|
||||
--| flume-master-info:
|
||||
--| Version: 0.9.4-cdh3u3
|
||||
--| ServerID: 0
|
||||
--| Flume nodes:
|
||||
@@ -44,7 +44,7 @@ Namp scan queue.
|
||||
--| master1.example.com
|
||||
--| Hbase Master Master:
|
||||
--| hdfs://master1.example.com:8020/hbase
|
||||
--| Enviroment:
|
||||
--| Enviroment:
|
||||
--| java.runtime.name: Java(TM) SE Runtime Environment
|
||||
--| java.runtime.version: 1.6.0_36-a01
|
||||
--| java.version: 1.6.0_36
|
||||
@@ -56,7 +56,7 @@ Namp scan queue.
|
||||
--| os.version: 2.6.32-220.4.2.el6.x86_64
|
||||
--| user.country: US
|
||||
--| user.name: flume
|
||||
--| Config:
|
||||
--| Config:
|
||||
--| dfs.datanode.address: 0.0.0.0:50010
|
||||
--| dfs.datanode.http.address: 0.0.0.0:50075
|
||||
--| dfs.datanode.https.address: 0.0.0.0:50475
|
||||
@@ -92,7 +92,7 @@ portrule = function(host, port)
|
||||
or (shortport.service(shortport.LIKELY_HTTP_SERVICES)(host, port) and not shortport.portnumber(shortport.LIKELY_HTTP_PORTS)(host, port))
|
||||
end
|
||||
|
||||
function add_target(hostname)
|
||||
function add_target(hostname)
|
||||
if target.ALLOW_NEW_TARGETS then
|
||||
stdnse.print_debug(1, ("%s: Added target: %s"):format(SCRIPT_NAME, hostname))
|
||||
local status,err = target.add(hostname)
|
||||
@@ -172,7 +172,7 @@ action = function( host, port )
|
||||
add_target(hostname)
|
||||
end
|
||||
end
|
||||
if next(nodes) ~= nil then
|
||||
if next(nodes) ~= nil then
|
||||
table.insert(result, "Flume nodes:")
|
||||
result[#result+1] = nodes
|
||||
end
|
||||
@@ -182,7 +182,7 @@ action = function( host, port )
|
||||
add_target(zookeeper)
|
||||
end
|
||||
end
|
||||
if next(zookeepers) ~= nil then
|
||||
if next(zookeepers) ~= nil then
|
||||
result[#result+1] = "Zookeeper Master:"
|
||||
result[#result+1] = zookeepers
|
||||
end
|
||||
@@ -192,7 +192,7 @@ action = function( host, port )
|
||||
add_target(hbasemaster)
|
||||
end
|
||||
end
|
||||
if next(hbasemasters) ~= nil then
|
||||
if next(hbasemasters) ~= nil then
|
||||
result[#result+1] = "Hbase Master Master:"
|
||||
result[#result+1] = hbasemasters
|
||||
end
|
||||
|
||||
@@ -59,7 +59,7 @@ local function list(socket, target, max_lines)
|
||||
-- The server should answer with something like
|
||||
-- 2xx Entering Passive Mode (a,b,c,d,hp,lp)
|
||||
-- (-- IP--,PORT)
|
||||
-- PORT is (hp x 256) + lp
|
||||
-- PORT is (hp x 256) + lp
|
||||
local high, low = string.match(message, "%(%d+,%d+,%d+,%d+,(%d+),(%d+)%)")
|
||||
if not high then
|
||||
return nil, string.format("Can't parse PASV response: %q", message)
|
||||
@@ -169,7 +169,7 @@ action = function(host, port)
|
||||
if not max_list or max_list > 0 then
|
||||
local status, listing = list(socket, host, max_list)
|
||||
socket:close()
|
||||
|
||||
|
||||
if not status then
|
||||
result[#result + 1] = "Can't get directory listing: " .. listing
|
||||
else
|
||||
|
||||
@@ -23,7 +23,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
-- PORT STATE SERVICE
|
||||
-- 21/tcp open ftp
|
||||
-- |_ftp-bounce: server forbids bouncing to low ports <1025
|
||||
--
|
||||
--
|
||||
-- PORT STATE SERVICE
|
||||
-- 21/tcp open ftp
|
||||
-- |_ftp-bounce: no banner
|
||||
@@ -111,7 +111,7 @@ action = function(host, port)
|
||||
local sendPass = true
|
||||
local user, pass = get_login()
|
||||
local fc
|
||||
|
||||
|
||||
socket:set_timeout(10000)
|
||||
socket:connect(host, port)
|
||||
|
||||
@@ -133,7 +133,7 @@ action = function(host, port)
|
||||
-- return "bad banner (code " .. fc .. ")"
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
socket:set_timeout(5000)
|
||||
-- USER
|
||||
socket:send("USER " .. user .. "\r\n")
|
||||
@@ -147,13 +147,13 @@ action = function(host, port)
|
||||
if fc == 0 then
|
||||
socket:close()
|
||||
-- return "anonymous user timeouted"
|
||||
return
|
||||
return
|
||||
end
|
||||
if fc ~= 230 and fc ~= 331 then
|
||||
socket:close()
|
||||
-- bad code
|
||||
-- return "bad response for anonymous user (code " .. fc .. ")"
|
||||
return
|
||||
return
|
||||
end
|
||||
if fc == 230 then
|
||||
sendPass = false
|
||||
@@ -180,7 +180,7 @@ action = function(host, port)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- PORT scanme.nmap.com:highport
|
||||
socket:send("PORT 205,217,153,62,80,80\r\n")
|
||||
fc = get_ftp_code(socket)
|
||||
|
||||
@@ -17,7 +17,7 @@ Based on old ftp-brute.nse script by Diman Todorov, Vlatko Kosturjak and Ron Bow
|
||||
--
|
||||
-- This script uses brute library to perform password
|
||||
-- guessing.
|
||||
--
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 21/tcp open ftp
|
||||
@@ -60,7 +60,7 @@ Driver = {
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
|
||||
login = function (self, user, pass)
|
||||
local status, err
|
||||
local res = ""
|
||||
@@ -104,22 +104,22 @@ Driver = {
|
||||
return false, brute.Error:new("Login didn't return a proper response")
|
||||
end,
|
||||
|
||||
disconnect = function( self )
|
||||
disconnect = function( self )
|
||||
self.socket:close()
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
action = function( host, port )
|
||||
|
||||
local status, result
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
|
||||
status, result = engine:start()
|
||||
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ Be advised that, if launched against a vulnerable host, this script will crash t
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 21/tcp open ftp
|
||||
-- | ftp-libopie:
|
||||
-- | ftp-libopie:
|
||||
-- | VULNERABLE:
|
||||
-- | OPIE off-by-one stack overflow
|
||||
-- | State: LIKELY VULNERABLE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user