mirror of
https://github.com/nmap/nmap.git
synced 2025-12-10 09:49:05 +00:00
Add the latest ASN.nse script. This version uses the new Nmap-specific query
servers, groups output intelligently, and supports IPv6. See sample output at http://seclists.org/nmap-dev/2008/q3/0675.html.
This commit is contained in:
@@ -324,7 +324,7 @@ o The loading of the nmap-services file has been made much
|
||||
o Added a script (ASN.nse) which uses Team Cymru's DNS interface to
|
||||
determine the routing AS numbers of scanned IP addresses. They even
|
||||
set up a special domain just for Nmap queries. The script is still
|
||||
experimental and non-default. [Michael]
|
||||
experimental and non-default. [Jah, Michael]
|
||||
|
||||
o The shtool build helper script has been updated to version 2.0.8. An
|
||||
older version of shutil caused installation to fail when the locale
|
||||
|
||||
819
scripts/ASN.nse
819
scripts/ASN.nse
@@ -1,158 +1,755 @@
|
||||
--[[
|
||||
id = "AS Numbers"
|
||||
description = [[
|
||||
This script performs IP address to Autonomous System Numbers (ASN) lookups. It
|
||||
sends DNS TXT queries to a DNS server which in turn queries a third party service
|
||||
provided by Team Cymru (team-cymru.org) using an in-addr.arpa style zone set-up
|
||||
especially for use by Nmap.
|
||||
\n
|
||||
The respnses to these queries contain both Origin and Peer ASNs and their descriptions,
|
||||
displayed along with the BG Prefix and Country Code.
|
||||
\n
|
||||
The script caches results to reduce the number of queries and should perform a single
|
||||
query for all scanned targets in a BG Prefix present in Team Cymru's database.
|
||||
\n\n
|
||||
Please be aware that any targets for which a query is performed will be revealed
|
||||
to a Team Cymru.
|
||||
]]
|
||||
|
||||
Query Autonomous System Numbers Based on IP
|
||||
-------------------------------------------
|
||||
Uses a 3rd party service provided by team-cymru.org to
|
||||
find the autonomous system numbers of a specific IP.
|
||||
This scan is performed on all hosts in a portscan but
|
||||
will only output a result once for every netblock.
|
||||
|
||||
Be aware that because this scan uses a 3rd party
|
||||
service it may result in a loss of privacy, all hosts
|
||||
that you scan with this script will be sent to team-
|
||||
cymru.org.
|
||||
--]]
|
||||
---
|
||||
-- @usage
|
||||
-- nmap <target> --script asn
|
||||
--
|
||||
-- @args dns Optional recursive nameserver. e.g. --script-args dns=192.168.1.1
|
||||
--
|
||||
-- @output
|
||||
-- Host script results:
|
||||
-- \n| AS Numbers:
|
||||
-- \n| BGP: 64.13.128.0/21 | Country: US
|
||||
-- \n| Origin AS: 10565 SVCOLO-AS - Silicon Valley Colocation, Inc.
|
||||
-- \n| Peer AS: 3561 6461
|
||||
-- \n| BGP: 64.13.128.0/18 | Country: US
|
||||
-- \n| Origin AS: 10565 SVCOLO-AS - Silicon Valley Colocation, Inc.
|
||||
-- \n|_ Peer AS: 174 2914 6461
|
||||
--
|
||||
|
||||
id = "ASN"
|
||||
description = "This script discovers the autonomous system numbers of the \
|
||||
netblock ranges that you scanned. It will return other information as well \
|
||||
such as a country code, and BGP prefix. \
|
||||
Caution: This script access a 3rd party database provided by team-cymru.com \
|
||||
to discover this information. Using this script will expose the hosts that \
|
||||
you scan to team-cymru.com in order to get the results. \
|
||||
Usage: nmap <target> --script asn --script-args dns=<recursion_enabled_dns_server>"
|
||||
|
||||
author = "Jah, Michael"
|
||||
author = "jah, Michael"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery"}
|
||||
runlevel = 1
|
||||
|
||||
require "comm"
|
||||
require "ipOps"
|
||||
|
||||
hostrule = function( host )
|
||||
return true
|
||||
end
|
||||
|
||||
local dns = require "dns"
|
||||
local comm = require "comm"
|
||||
|
||||
|
||||
local mutex = nmap.mutex( id )
|
||||
if not nmap.registry.asn then
|
||||
nmap.registry.asn = {}
|
||||
nmap.registry.asn.cache = {}
|
||||
nmap.registry.asn.descr = {}
|
||||
end
|
||||
|
||||
local mutex = nmap.mutex( id )
|
||||
|
||||
|
||||
---
|
||||
-- This script will run for any non-private IP address.
|
||||
|
||||
hostrule = function( host )
|
||||
return not isPrivate( host.ip )
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Cached results are checked before sending a query for the target and extracting the
|
||||
-- relevent information from the response. Mutual exclusion is used so that results can be
|
||||
-- cached and so a single thread will be active at any time.
|
||||
-- @param host Host Table.
|
||||
-- @return Formatted answers or nil on NXDOMAIN/errors.
|
||||
|
||||
action = function( host )
|
||||
|
||||
-- get args or die
|
||||
local dns_server
|
||||
if nmap.registry.args.dns then
|
||||
dns_server = nmap.registry.args.dns
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
-- wait
|
||||
mutex "lock"
|
||||
|
||||
-- check for cached data
|
||||
for _, cache in ipairs( nmap.registry.asn.cache ) do
|
||||
if ip_in_net( host.ip, cache.bgp) then
|
||||
mutex "done"
|
||||
return " \nBGP Prefix: " .. cache.bgp .. "\nAS number: " .. cache.asn .. "\nCountry Code: " .. cache.co_id
|
||||
local in_cache, records
|
||||
local combined_records = {}
|
||||
|
||||
in_cache, records = check_cache( host.ip )
|
||||
records = records or {}
|
||||
|
||||
if not in_cache then
|
||||
|
||||
---
|
||||
-- @class table
|
||||
-- @name cymru
|
||||
-- Team Cymru zones for rDNS like queries. The zones are as follows:
|
||||
-- \n nmap.asn.cymru.com for IPv4 to Origin AS lookup.
|
||||
-- \n peer-nmap.asn.cymru.com for IPv4 to Peer AS lookup.
|
||||
-- \n nmap6.asn.cymru.com for IPv6 to Origin AS lookup.
|
||||
local cymru = { [4] = { ["Origin"] = ".nmap.asn.cymru.com", ["Peer"] = ".peer-nmap.asn.cymru.com" },
|
||||
[6] = { ["Origin"] = ".nmap6.asn.cymru.com" }
|
||||
}
|
||||
local zone_repl, IPv = "%.in%-addr%.arpa", 4
|
||||
if host.ip:match( ":" ) then
|
||||
zone_repl, IPv = "%.ip6%.arpa", 6
|
||||
end
|
||||
|
||||
-- name to query for
|
||||
local dname = reverse( host.ip )
|
||||
|
||||
-- perform queries for each applicable zone
|
||||
for asn_type, zone in pairs( cymru[IPv] ) do
|
||||
-- replace arpa with cymru zone
|
||||
local temp = dname
|
||||
dname = dname:gsub( zone_repl, zone )
|
||||
-- send query and recognise and organise fields from response
|
||||
local success, retval = result_recog( ip_to_asn( dname ), asn_type, records )
|
||||
-- if success then records = retval end
|
||||
-- un-replace arpa zone
|
||||
dname = temp
|
||||
end
|
||||
|
||||
-- combine records into unique BGP
|
||||
for _, record in ipairs( records ) do
|
||||
if not combined_records[record.cache_bgp] then
|
||||
combined_records[record.cache_bgp] = record
|
||||
elseif combined_records[record.cache_bgp].asn_type ~= record.asn_type then
|
||||
-- origin before peer.
|
||||
if record.asn_type == "Origin" then
|
||||
combined_records[record.cache_bgp].asn = { unpack( record.asn ), unpack( combined_records[record.cache_bgp].asn ) }
|
||||
else
|
||||
combined_records[record.cache_bgp].asn = { unpack( combined_records[record.cache_bgp].asn ), unpack( record.asn ) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- format data
|
||||
-- cache combined records
|
||||
for _, rec in pairs( combined_records ) do
|
||||
table.insert( nmap.registry.asn.cache, rec )
|
||||
end
|
||||
|
||||
else -- records were in the cache
|
||||
combined_records = records
|
||||
end
|
||||
|
||||
-- format each combined_record for output
|
||||
local output = {}
|
||||
for _, rec in pairs( combined_records ) do
|
||||
local r = {}
|
||||
if rec.bgp then r[#r+1] = rec.bgp end
|
||||
if rec.co then r[#r+1] = rec.co end
|
||||
output[#output+1] = ( "%s\n %s" ):format( table.concat( r, " | " ), table.concat( rec.asn, "\n " ) )
|
||||
end
|
||||
|
||||
mutex "done"
|
||||
|
||||
if type( output ) ~= "table" or #output == 0 then return nil end
|
||||
-- sort BGP asc.
|
||||
table.sort( output, function(a,b) return (get_prefix_length(a) or 0) > (get_prefix_length(b) or 0) end )
|
||||
|
||||
-- return combined and formatted answers
|
||||
return (" \n%s"):format( table.concat( output, "\n" ) )
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Checks whether the target IP address is within any BGP prefixes for which a query has
|
||||
-- already been performed and returns any applicable answers.
|
||||
-- @param ip String representing the target IP address.
|
||||
-- @return Boolean True if there are cached answers for the supplied target, otherwise
|
||||
-- false.
|
||||
-- @return Table containing a string for each answer or nil if there are none.
|
||||
|
||||
function check_cache( ip )
|
||||
local ret = {}
|
||||
for _, cache_entry in ipairs( nmap.registry.asn.cache ) do
|
||||
if ip_in_range( ip, cache_entry.cache_bgp ) then
|
||||
ret[#ret+1] = cache_entry
|
||||
end
|
||||
end
|
||||
if #ret > 0 then return true, ret end
|
||||
return false, nil
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Extracts fields from the supplied DNS answer sections.
|
||||
-- @param answers Table containing string DNS answers.
|
||||
-- @param asn_type String denoting whether the query is for Origin or Peer ASN.
|
||||
-- @param recs Table of existing recognised answers to which to add (ref to actions() records{}.
|
||||
-- @return Boolean true if successful otherwise false.
|
||||
|
||||
function result_recog( answers, asn_type, recs )
|
||||
|
||||
if type( answers ) ~= "table" or #answers == 0 then return false end
|
||||
|
||||
for _, answer in ipairs( answers ) do
|
||||
local t = {}
|
||||
t[4], t[3], t[2], t[1] = host.ip:match( "([^\.]*)\.([^\.]*)\.([^\.]*)\.([^\.]*)" )
|
||||
local tsoh = labels( t )
|
||||
local z = { "nmap", "asn", "cymru", "com" }
|
||||
local zone = labels( z )
|
||||
-- break the answer up into fields and strip whitespace
|
||||
local fields = { answer:match( ("([^|]*)|" ):rep(3) ) }
|
||||
for i, field in ipairs( fields ) do
|
||||
fields[i] = field:gsub( "^%s*(.-)%s*$", "%1" )
|
||||
end
|
||||
-- assign fields with labels to table
|
||||
t.cache_bgp = fields[2]
|
||||
t.asn_type = asn_type
|
||||
t.asn = { asn_type .. " AS: " .. fields[1] }
|
||||
t.bgp = "BGP: " .. fields[2]
|
||||
if fields[3] ~= "" then t.co = "Country: " .. fields[3] end
|
||||
recs[#recs+1] = t
|
||||
-- lookup AS descriptions for Origin AS numbers
|
||||
local asn_descr = nmap.registry.asn.descr
|
||||
local u = {}
|
||||
if asn_type == "Origin" then
|
||||
for num in fields[1]:gmatch( "%d+" ) do
|
||||
if not asn_descr[num] then
|
||||
asn_descr[num] = asn_description( num )
|
||||
end
|
||||
u[#u+1] = ( "%s AS: %s%s%s" ):format( asn_type, num, ( asn_descr[num] ~= "" and " - " ) or "", asn_descr[num] )
|
||||
end
|
||||
t.asn = { table.concat(u, "\n " ) }
|
||||
end
|
||||
end
|
||||
|
||||
local t_id = string.char( tonumber( t[2] ), tonumber( t[3] ) ) -- not at all random...
|
||||
local dns_std = string.char( 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
|
||||
local null_char = string.char( 0x00 )
|
||||
local qtype = string.char( 0x00, 0x10 )
|
||||
local qclass = string.char( 0x00, 0x01 )
|
||||
local query = tsoh .. zone .. null_char .. qtype .. qclass
|
||||
return true
|
||||
|
||||
local data = t_id .. dns_std .. query
|
||||
end
|
||||
|
||||
-- send data
|
||||
|
||||
---
|
||||
-- Performs an IP address to ASN lookup. See http://www.team-cymru.org/Services/ip-to-asn.html#dns
|
||||
-- @param query String - PTR like DNS query.
|
||||
-- @return Table containing string answers or Boolean false.
|
||||
|
||||
function ip_to_asn( query )
|
||||
|
||||
if type( query ) ~= "string" or query == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- dns query options
|
||||
local options = {}
|
||||
options.proto = "udp"
|
||||
options.lines = 1
|
||||
options.timeout = 1000
|
||||
local status, result = comm.exchange( dns_server, 53, data, options )
|
||||
if not status then
|
||||
mutex "done"
|
||||
return
|
||||
options.dtype = "TXT"
|
||||
options.retAll = true
|
||||
if type( nmap.registry.args.dns ) == "string" and nmap.registry.args.dns ~= "" then
|
||||
options.host = nmap.registry.args.dns
|
||||
options.port = 53
|
||||
end
|
||||
|
||||
-- read result - this method is tenuous!!
|
||||
local _, offset = string.find( result, query )
|
||||
local line = string.sub( result, offset + 13 )
|
||||
fields = {line:match( ("([^|]*)|"):rep(3) )}
|
||||
local decoded_response, other_response = dns.query( query, options)
|
||||
|
||||
-- cache result
|
||||
local blob = {}
|
||||
blob.bgp = fields[2]:gsub( "^%s*(.-)%s*$", "%1" )
|
||||
blob.asn = fields[1]:gsub( "^%s*[^0](.-)%s*$", "%1" )
|
||||
blob.co_id = fields[3]:gsub( "^%s*(.-)%s*$", "%1" )
|
||||
table.insert( nmap.registry.asn.cache, blob )
|
||||
mutex "done"
|
||||
|
||||
-- return result
|
||||
return " \nBGP Prefix: " .. blob.bgp .. "\nAS number: " .. blob.asn .. "\nCountry Code: " .. blob.co_id
|
||||
return decoded_response
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- labels
|
||||
-- given a table of strings, return a string made up of concateneted labels
|
||||
-- where each label consists of a length value (cast as char) followed by that number of characters.
|
||||
function labels( t )
|
||||
local ret = ""
|
||||
for _, v in ipairs(t) do
|
||||
ret = ret .. string.char( string.len(v) ) .. v
|
||||
---
|
||||
-- Performs an AS Number to AS Description lookup.
|
||||
-- @param asn String AS Number
|
||||
-- @return String Description or ""
|
||||
|
||||
function asn_description( asn )
|
||||
|
||||
if type( asn ) ~= "string" or asn == "" then
|
||||
return ""
|
||||
end
|
||||
return ret
|
||||
|
||||
-- dns query options
|
||||
local options = {}
|
||||
options.dtype = "TXT"
|
||||
if type( nmap.registry.args.dns ) == "string" and nmap.registry.args.dns ~= "" then
|
||||
options.host = nmap.registry.args.dns
|
||||
options.port = 53
|
||||
end
|
||||
|
||||
-- send query
|
||||
local query = ( "AS%s.asn.cymru.com" ):format( asn )
|
||||
local decoded_response, other_response = dns.query( query, options)
|
||||
if type( decoded_response ) ~= "string" then
|
||||
return ""
|
||||
end
|
||||
|
||||
return decoded_response:match( "|%s*([^|$]+)%s*$" ) or ""
|
||||
|
||||
end
|
||||
|
||||
-- ip_in_net
|
||||
-- returns true if the supplied ip address falls inside the supplied range
|
||||
function ip_in_net(ip, net)
|
||||
local i, j, net_lo, net_hi, dw_ip
|
||||
local m_dotted = "(%d+%.%d+%.%d+%.%d+)[%s]*[-][%s]*(%d+%.%d+%.%d+%.%d+)"
|
||||
local m_cidr = "(%d+)[.]*(%d*)[.]*(%d*)[.]*(%d*)[/]+(%d+)"
|
||||
|
||||
if net:match(m_dotted) then
|
||||
net_lo, net_hi = net:match(m_dotted)
|
||||
net_lo = ipOps.todword(net_lo)
|
||||
net_hi = ipOps.todword(net_hi)
|
||||
elseif net:match(m_cidr) then
|
||||
net_lo, net_hi = two_dwords(net, m_cidr)
|
||||
|
||||
-- *** UTILITY FUNCTIONS ***
|
||||
-- remove when these functions are available in libraries
|
||||
|
||||
|
||||
---
|
||||
-- Formats IP for reverse lookup.
|
||||
-- @param ip String IP address.
|
||||
-- @return "Domain" style representation of IP as subdomain of in-addr.arpa or ip6.arpa
|
||||
|
||||
function reverse(ip)
|
||||
ip = expand_ip(ip)
|
||||
if type(ip) ~= "string" then return nil end
|
||||
local delim = "%."
|
||||
local arpa = ".in-addr.arpa"
|
||||
if ip:match(":") then
|
||||
delim = ":"
|
||||
arpa = ".ip6.arpa"
|
||||
end
|
||||
local ipParts = stdnse.strsplit(delim, ip)
|
||||
if #ipParts == 8 then
|
||||
-- padding
|
||||
local mask = "0000"
|
||||
for i, part in ipairs(ipParts) do
|
||||
ipParts[i] = mask:sub(1, string.len(mask) - string.len(part)) .. part
|
||||
end
|
||||
-- 32 parts from 8
|
||||
local temp = {}
|
||||
for i, hdt in ipairs(ipParts) do
|
||||
for part in hdt:gmatch("%x") do
|
||||
temp[#temp+1] = part
|
||||
end
|
||||
end
|
||||
ipParts = temp
|
||||
end
|
||||
local ipReverse = {}
|
||||
for i = #ipParts, 1, -1 do
|
||||
table.insert(ipReverse, ipParts[i])
|
||||
end
|
||||
return table.concat(ipReverse, ".") .. arpa
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Checks to see if the supplied IP address is part of the following non-internet-routable address spaces:
|
||||
-- IPv4 Loopback (RFC3330),
|
||||
-- IPv4 Private Use (RFC1918),
|
||||
-- IPv4 Link Local (RFC3330),
|
||||
-- IPv6 Unspecified and Loopback (RFC3513),
|
||||
-- IPv6 Unique Local Unicast (RFC4193),
|
||||
-- IPv6 Link Local Unicast (RFC4291)
|
||||
-- @param ip String representing an IPv4 or IPv6 address. Shortened notation is permitted.
|
||||
-- @usage local is_private = isPrivate( "192.168.1.1" )
|
||||
-- @return Boolean True or False (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
isPrivate = function( ip )
|
||||
|
||||
ip, err = expand_ip( ip )
|
||||
if err then return nil, err end
|
||||
|
||||
local ipv4_private = { "10/8", "127/8", "169.254/16", "172.15/12", "192.168/16" }
|
||||
local ipv6_private = { "::/127", "FC00::/7", "FE80::/10" }
|
||||
local t, is_private = {}
|
||||
if ip:match( ":" ) then
|
||||
t = ipv6_private
|
||||
else
|
||||
t = ipv4_private
|
||||
end
|
||||
|
||||
dw_ip = ipOps.todword(ip)
|
||||
if net_lo <= dw_ip and dw_ip <= net_hi then return true end
|
||||
for _, range in ipairs( t ) do
|
||||
is_private, err = ip_in_range( ip, range )
|
||||
-- return as soon as is_private is true or err
|
||||
if is_private then return true end
|
||||
if err then return nil, err end
|
||||
end
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
-- two_dwords
|
||||
-- returns the two ip addresses at either end of a cidr range, as dwords
|
||||
function two_dwords(str, patt)
|
||||
local a, b, c, d, e, lo_net, host
|
||||
a, b, c, d, e = str:match(patt)
|
||||
local ipt = {b, c, d}
|
||||
local strip = ""
|
||||
for _, cap in ipairs(ipt) do
|
||||
if cap == "" then cap = "0" end
|
||||
strip = strip .. "." .. cap
|
||||
|
||||
---
|
||||
-- Checks whether the supplied IP address is within the supplied Range of IP addresses if they belong to the same address family.
|
||||
-- @param ip String representing an IPv4 or IPv6 address. Shortened notation is permitted.
|
||||
-- @param range String representing a range of IPv4 or IPv6 addresses in first-last or cidr notation (e.g. "192.168.1.1 - 192.168.255.255" or "2001:0A00::/23").
|
||||
-- @usage if ip_in_range( "192.168.1.1", "192/8" ) then ...
|
||||
-- @return Boolean True or False (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
ip_in_range = function( ip, range )
|
||||
|
||||
local first, last, err = get_ips_from_range( range )
|
||||
if err then return nil, err end
|
||||
ip, err = expand_ip( ip )
|
||||
if err then return nil, err end
|
||||
if ( ip:match( ":" ) and not first:match( ":" ) ) or ( not ip:match( ":" ) and first:match( ":" ) ) then
|
||||
return nil, "Error in ip_in_range: IP address is of a different address family to Range."
|
||||
end
|
||||
lo_net = a .. strip
|
||||
if e ~= "" then e = tonumber(e)
|
||||
if e and e <=32 then
|
||||
host = 32 - e end
|
||||
|
||||
err = {}
|
||||
local ip_ge_first, ip_le_last
|
||||
ip_ge_first, err[#err+1] = compare_ip( ip, "ge", first )
|
||||
ip_le_last, err[#err+1] = compare_ip( ip, "le", last )
|
||||
if #err > 0 then
|
||||
return nil, table.concat( err, " " )
|
||||
end
|
||||
return ipOps.todword(lo_net), ipOps.todword(lo_net) + 2^host - 1
|
||||
|
||||
if ip_ge_first and ip_le_last then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Expands an IP address supplied in shortened notation.
|
||||
-- Serves also to check the well-formedness of an IP address.
|
||||
-- Note: IPv4in6 notated addresses will be returned in pure IPv6 notation unless the IPv4 portion
|
||||
-- is shortened and does not contain a dot - in which case the address will be treated as IPv6.
|
||||
-- @param ip String representing an IPv4 or IPv6 address in shortened or full notation.
|
||||
-- @usage local ip = expand_ip( "2001::" )
|
||||
-- @return String representing a fully expanded IPv4 or IPv6 address (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
expand_ip = function( ip )
|
||||
|
||||
if type( ip ) ~= "string" or ip == "" then
|
||||
return nil, "Error in expand_ip: Expected IP address as a string."
|
||||
end
|
||||
|
||||
local err4 = "Error in expand_ip: An address assumed to be IPv4 was malformed."
|
||||
|
||||
if not ip:match( ":" ) then
|
||||
-- ipv4: missing octets should be "0" appended
|
||||
if ip:match( "[^\.0-9]" ) then
|
||||
return nil, err4
|
||||
end
|
||||
local octets = {}
|
||||
for octet in string.gfind( ip, "%d+" ) do
|
||||
if tonumber( octet, 10 ) > 255 then return nil, err4 end
|
||||
octets[#octets+1] = octet
|
||||
end
|
||||
if #octets > 4 then return nil, err4 end
|
||||
while #octets < 4 do
|
||||
octets[#octets+1] = "0"
|
||||
end
|
||||
return ( table.concat( octets, "." ) )
|
||||
end
|
||||
|
||||
if ip:match( "[^\.:%x]" ) then
|
||||
return nil, ( err4:gsub( "IPv4", "IPv6" ) )
|
||||
end
|
||||
|
||||
-- preserve ::
|
||||
ip = string.gsub(ip, "::", ":z:")
|
||||
|
||||
-- get a table of each hexadectet
|
||||
local hexadectets = {}
|
||||
for hdt in string.gfind( ip, "[\.z%x]+" ) do
|
||||
hexadectets[#hexadectets+1] = hdt
|
||||
end
|
||||
|
||||
-- deal with IPv4in6 (last hexadectet only)
|
||||
local t = {}
|
||||
if hexadectets[#hexadectets]:match( "[\.]+" ) then
|
||||
hexadectets[#hexadectets], err = expand_ip( hexadectets[#hexadectets] )
|
||||
if err then return nil, ( err:gsub( "IPv4", "IPv4in6" ) ) end
|
||||
t = stdnse.strsplit( "[\.]+", hexadectets[#hexadectets] )
|
||||
for i, v in ipairs( t ) do
|
||||
t[i] = tonumber( v, 10 )
|
||||
end
|
||||
hexadectets[#hexadectets] = stdnse.tohex( 256*t[1]+t[2] )
|
||||
hexadectets[#hexadectets+1] = stdnse.tohex( 256*t[3]+t[4] )
|
||||
end
|
||||
|
||||
-- deal with :: and check for invalid address
|
||||
local z_done = false
|
||||
for index, value in ipairs( hexadectets ) do
|
||||
if value:match( "[\.]+" ) then
|
||||
-- shouldn't have dots at this point
|
||||
return nil, ( err4:gsub( "IPv4", "IPv6" ) )
|
||||
elseif value == "z" and z_done then
|
||||
-- can't have more than one ::
|
||||
return nil, ( err4:gsub( "IPv4", "IPv6" ) )
|
||||
elseif value == "z" and not z_done then
|
||||
z_done = true
|
||||
hexadectets[index] = "0"
|
||||
local bound = 8 - #hexadectets
|
||||
for i = 1, bound, 1 do
|
||||
table.insert( hexadectets, index+i, "0" )
|
||||
end
|
||||
elseif tonumber( value, 16 ) > 65535 then
|
||||
-- more than FFFF!
|
||||
return nil, ( err4:gsub( "IPv4", "IPv6" ) )
|
||||
end
|
||||
end
|
||||
|
||||
-- make sure we have exactly 8 hexadectets
|
||||
if #hexadectets > 8 then return nil, ( err4:gsub( "IPv4", "IPv6" ) ) end
|
||||
while #hexadectets < 8 do
|
||||
hexadectets[#hexadectets+1] = "0"
|
||||
end
|
||||
|
||||
return ( table.concat( hexadectets, ":" ) )
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Compares two IP addresses (from the same address family).
|
||||
-- @param left String representing an IPv4 or IPv6 address. Shortened notation is permitted.
|
||||
-- @param op A comparison operator which may be one of the following strings: "eq", "ge", "le", "gt" or "lt" (respectively ==, >=, <=, >, <).
|
||||
-- @param right String representing an IPv4 or IPv6 address. Shortened notation is permitted.
|
||||
-- @usage if compare_ip( "2001::DEAD:0:0:0", "eq", "2001:0:0:0:DEAD::" ) then ...
|
||||
-- @return Boolean True or False (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
compare_ip = function( left, op, right )
|
||||
|
||||
if type( left ) ~= "string" or type( right ) ~= "string" then
|
||||
return nil, "Error in compare_ip: Expected IP address as a string."
|
||||
end
|
||||
|
||||
if ( left:match( ":" ) and not right:match( ":" ) ) or ( not left:match( ":" ) and right:match( ":" ) ) then
|
||||
return nil, "Error in compare_ip: IP addresses must be from the same address family."
|
||||
end
|
||||
|
||||
if op == "lt" or op == "le" then
|
||||
left, right = right, left
|
||||
elseif op ~= "eq" and op ~= "ge" and op ~= "gt" then
|
||||
return nil, "Error in compare_ip: Invalid Operator."
|
||||
end
|
||||
|
||||
local err ={}
|
||||
left, err[#err+1] = ip_to_bin( left )
|
||||
right, err[#err+1] = ip_to_bin( right )
|
||||
if #err > 0 then
|
||||
return nil, table.concat( err, " " )
|
||||
end
|
||||
|
||||
if string.len( left ) ~= string.len( right ) then
|
||||
-- shouldn't happen...
|
||||
return nil, "Error in compare_ip: Binary IP addresses were of different lengths."
|
||||
end
|
||||
|
||||
-- equal?
|
||||
if ( op == "eq" or op == "le" or op == "ge" ) and left == right then
|
||||
return true
|
||||
elseif op == "eq" then
|
||||
return false
|
||||
end
|
||||
|
||||
-- starting from the leftmost bit, subtract the bit in right from the bit in left
|
||||
local compare
|
||||
for i = 1, string.len( left ), 1 do
|
||||
compare = tonumber( string.sub( left, i, i ) ) - tonumber( string.sub( right, i, i ) )
|
||||
if compare == 1 then
|
||||
return true
|
||||
elseif compare == -1 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Returns the first and last IP addresses in the supplied range of addresses.
|
||||
-- @param range String representing a range of IPv4 or IPv6 addresses in either cidr or first-last notation.
|
||||
-- @usage first, last = get_ips_from_range( "192.168.0.0/16" )
|
||||
-- @return String representing the first address in the supplied range (or nil in case of an error).
|
||||
-- @return String representing the last address in the supplied range (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
get_ips_from_range = function( range )
|
||||
|
||||
if type( range ) ~= "string" then
|
||||
return nil, nil, "Error in get_ips_from_range: Expected a range as a string."
|
||||
end
|
||||
|
||||
local first, last, prefix
|
||||
if range:match( "/" ) then
|
||||
first, prefix = range:match( "([%x%d:\.]+)/(%d+)" )
|
||||
elseif range:match( "-" ) then
|
||||
first, last = range:match( "([%x%d:\.]+)%s*\-%s*([%x%d:\.]+)" )
|
||||
end
|
||||
|
||||
local err = {}
|
||||
if first and ( last or prefix ) then
|
||||
first, err[#err+1] = expand_ip( first )
|
||||
else
|
||||
return nil, nil, "Error in get_ips_from_range: The range supplied could not be interpreted."
|
||||
end
|
||||
if last then
|
||||
last, err[#err+1] = expand_ip( last )
|
||||
elseif first and prefix then
|
||||
last, err[#err+1] = get_last_ip( first, prefix )
|
||||
end
|
||||
|
||||
if first and last then
|
||||
if ( first:match( ":" ) and not last:match( ":" ) ) or ( not first:match( ":" ) and last:match( ":" ) ) then
|
||||
return nil, nil, "Error in get_ips_from_range: First IP address is of a different address family to last IP address."
|
||||
end
|
||||
return first, last
|
||||
else
|
||||
return nil, nil, table.concat( err, " " )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Calculates the last IP address of a range of addresses given an IP address in the range and prefix length for that range.
|
||||
-- @param ip String representing an IPv4 or IPv6 address. Shortened notation is permitted.
|
||||
-- @param prefix Decimal number or a string representing a decimal number corresponding to a Prefix length.
|
||||
-- @usage last = get_last_ip( "192.0.0.0", 26 )
|
||||
-- @return String representing the last IP address of the range denoted by the supplied parameters (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
get_last_ip = function( ip, prefix )
|
||||
|
||||
local first, err = ip_to_bin( ip )
|
||||
if err then return nil, err end
|
||||
|
||||
prefix = tonumber( prefix )
|
||||
if not prefix or ( prefix < 0 ) or ( prefix > string.len( first ) ) then
|
||||
return nil, "Error in get_last_ip: Invalid prefix length."
|
||||
end
|
||||
|
||||
local hostbits = string.sub( first, prefix + 1 )
|
||||
hostbits = string.gsub( hostbits, "0", "1" )
|
||||
local last = string.sub( first, 1, prefix ) .. hostbits
|
||||
last, err = bin_to_ip( last )
|
||||
if err then return nil, err end
|
||||
return last
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Converts an IP address into a string representing the address as binary digits.
|
||||
-- @param ip String representing an IPv4 or IPv6 address. Shortened notation is permitted.
|
||||
-- @usage bit_string = ip_to_bin( "2001::" )
|
||||
-- @return String representing the supplied IP address as 32 or 128 binary digits (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
ip_to_bin = function( ip )
|
||||
|
||||
ip, err = expand_ip( ip )
|
||||
if err then return nil, err end
|
||||
|
||||
local t, mask = {}
|
||||
|
||||
if not ip:match( ":" ) then
|
||||
-- ipv4 string
|
||||
for octet in string.gfind( ip, "%d+" ) do
|
||||
t[#t+1] = stdnse.tohex( octet )
|
||||
end
|
||||
mask = "00"
|
||||
else
|
||||
-- ipv6 string
|
||||
for hdt in string.gfind( ip, "%x+" ) do
|
||||
t[#t+1] = hdt
|
||||
end
|
||||
mask = "0000"
|
||||
end
|
||||
|
||||
-- padding
|
||||
for i, v in ipairs( t ) do
|
||||
t[i] = mask:sub( 1, string.len( mask ) - string.len( v ) ) .. v
|
||||
end
|
||||
|
||||
return hex_to_bin( table.concat( t ) )
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Converts a string representing binary digits into an IP address.
|
||||
-- @param binstring String representing an IP address as 32 or 128 binary digits.
|
||||
-- @usage ip = bin_to_ip( "01111111000000000000000000000001" )
|
||||
-- @return String representing an IP address (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
bin_to_ip = function( binstring )
|
||||
|
||||
if type( binstring ) ~= "string" or binstring:match( "[^01]+" ) then
|
||||
return nil, "Error in bin_to_ip: Expected string of binary digits."
|
||||
end
|
||||
|
||||
if string.len( binstring ) == 32 then
|
||||
af = 4
|
||||
elseif string.len( binstring ) == 128 then
|
||||
af = 6
|
||||
else
|
||||
return nil, "Error in bin_to_ip: Expected exactly 32 or 128 binary digits."
|
||||
end
|
||||
|
||||
t = {}
|
||||
if af == 6 then
|
||||
local pattern = string.rep( "[01]", 16 )
|
||||
for chunk in string.gfind( binstring, pattern ) do
|
||||
t[#t+1] = stdnse.tohex( tonumber( chunk, 2 ) )
|
||||
end
|
||||
return table.concat( t, ":" )
|
||||
end
|
||||
|
||||
if af == 4 then
|
||||
local pattern = string.rep( "[01]", 8 )
|
||||
for chunk in string.gfind( binstring, pattern ) do
|
||||
t[#t+1] = tonumber( chunk, 2 ) .. ""
|
||||
end
|
||||
return table.concat( t, "." )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Converts a string representing a hexadecimal number into a string representing that number as binary digits.
|
||||
-- Each hex digit results in four bits - this function is really just a wrapper around stdnse.tobinary().
|
||||
-- @param hex String representing a hexadecimal number.
|
||||
-- @usage bin_string = hex_to_bin( "F00D" )
|
||||
-- @return String representing the supplied number in binary digits (or nil in case of an error).
|
||||
-- @return Nil (or String error message in case of an error).
|
||||
|
||||
hex_to_bin = function( hex )
|
||||
|
||||
if type( hex ) ~= "string" or hex == "" or hex:match( "[^%x]+" ) then
|
||||
return nil, "Error in hex_to_bin: Expected string representing a hexadecimal number."
|
||||
end
|
||||
|
||||
local t, mask, binchar = {}, "0000"
|
||||
for hexchar in string.gfind( hex, "%x" ) do
|
||||
binchar = stdnse.tobinary( tonumber( hexchar, 16 ) )
|
||||
t[#t+1] = mask:sub( 1, string.len( mask ) - string.len( binchar ) ) .. binchar
|
||||
end
|
||||
return table.concat( t )
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Calculates the prefix length for the given IP address range.
|
||||
-- @param range String representing an IP address range
|
||||
-- @return Number - prefix length of the range
|
||||
|
||||
function get_prefix_length( range )
|
||||
|
||||
if type( range ) ~= "string" or range == "" then return nil end
|
||||
|
||||
local first, last, err = get_ips_from_range( range )
|
||||
if err then return nil end
|
||||
|
||||
first = ip_to_bin( first ):reverse()
|
||||
last = ip_to_bin( last ):reverse()
|
||||
|
||||
local hostbits = 0
|
||||
for pos = 1, string.len( first ), 1 do
|
||||
|
||||
if first:sub( pos, pos ) == "0" and last:sub( pos, pos ) == "1" then
|
||||
hostbits = hostbits + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return ( string.len( first ) - hostbits )
|
||||
|
||||
end
|
||||
@@ -1,88 +1,88 @@
|
||||
Entry{ category = "default", filename = "dns-test-open-recursion.nse" }
|
||||
Entry{ category = "intrusive", filename = "dns-test-open-recursion.nse" }
|
||||
Entry{ category = "default", filename = "showOwner.nse" }
|
||||
Entry{ category = "safe", filename = "showOwner.nse" }
|
||||
Entry{ category = "demo", filename = "daytimeTest.nse" }
|
||||
Entry{ category = "default", filename = "RealVNC_auth_bypass.nse" }
|
||||
Entry{ category = "malware", filename = "RealVNC_auth_bypass.nse" }
|
||||
Entry{ category = "vuln", filename = "RealVNC_auth_bypass.nse" }
|
||||
Entry{ category = "intrusive", filename = "dns-safe-recursion-port.nse" }
|
||||
Entry{ category = "intrusive", filename = "SNMPcommunitybrute.nse" }
|
||||
Entry{ category = "auth", filename = "SNMPcommunitybrute.nse" }
|
||||
Entry{ category = "default", filename = "showOwner.nse" }
|
||||
Entry{ category = "safe", filename = "showOwner.nse" }
|
||||
Entry{ category = "default", filename = "SSLv2-support.nse" }
|
||||
Entry{ category = "safe", filename = "SSLv2-support.nse" }
|
||||
Entry{ category = "malware", filename = "ircZombieTest.nse" }
|
||||
Entry{ category = "version", filename = "skype_v2-version.nse" }
|
||||
Entry{ category = "discovery", filename = "HTTPtrace.nse" }
|
||||
Entry{ category = "demo", filename = "echoTest.nse" }
|
||||
Entry{ category = "default", filename = "UPnP-info.nse" }
|
||||
Entry{ category = "safe", filename = "UPnP-info.nse" }
|
||||
Entry{ category = "default", filename = "rpcinfo.nse" }
|
||||
Entry{ category = "safe", filename = "rpcinfo.nse" }
|
||||
Entry{ category = "discovery", filename = "rpcinfo.nse" }
|
||||
Entry{ category = "auth", filename = "bruteTelnet.nse" }
|
||||
Entry{ category = "intrusive", filename = "bruteTelnet.nse" }
|
||||
Entry{ category = "intrusive", filename = "dns-safe-recursion-txid.nse" }
|
||||
Entry{ category = "default", filename = "SMTPcommands.nse" }
|
||||
Entry{ category = "discovery", filename = "SMTPcommands.nse" }
|
||||
Entry{ category = "safe", filename = "SMTPcommands.nse" }
|
||||
Entry{ category = "default", filename = "robots.nse" }
|
||||
Entry{ category = "safe", filename = "robots.nse" }
|
||||
Entry{ category = "default", filename = "zoneTrans.nse" }
|
||||
Entry{ category = "intrusive", filename = "zoneTrans.nse" }
|
||||
Entry{ category = "discovery", filename = "zoneTrans.nse" }
|
||||
Entry{ category = "discovery", filename = "whois.nse" }
|
||||
Entry{ category = "safe", filename = "whois.nse" }
|
||||
Entry{ category = "discovery", filename = "ripeQuery.nse" }
|
||||
Entry{ category = "demo", filename = "chargenTest.nse" }
|
||||
Entry{ category = "malware", filename = "strangeSMTPport.nse" }
|
||||
Entry{ category = "version", filename = "iax2Detect.nse" }
|
||||
Entry{ category = "demo", filename = "showSMTPVersion.nse" }
|
||||
Entry{ category = "discovery", filename = "ASN.nse" }
|
||||
Entry{ category = "default", filename = "showHTMLTitle.nse" }
|
||||
Entry{ category = "demo", filename = "showHTMLTitle.nse" }
|
||||
Entry{ category = "safe", filename = "showHTMLTitle.nse" }
|
||||
Entry{ category = "discovery", filename = "promiscuous.nse" }
|
||||
Entry{ category = "version", filename = "netbios-smb-os-discovery.nse" }
|
||||
Entry{ category = "default", filename = "anonFTP.nse" }
|
||||
Entry{ category = "auth", filename = "anonFTP.nse" }
|
||||
Entry{ category = "intrusive", filename = "anonFTP.nse" }
|
||||
Entry{ category = "intrusive", filename = "SQLInject.nse" }
|
||||
Entry{ category = "vuln", filename = "SQLInject.nse" }
|
||||
Entry{ category = "auth", filename = "bruteTelnet.nse" }
|
||||
Entry{ category = "intrusive", filename = "bruteTelnet.nse" }
|
||||
Entry{ category = "discovery", filename = "HTTPtrace.nse" }
|
||||
Entry{ category = "demo", filename = "SMTP_openrelay_test.nse" }
|
||||
Entry{ category = "default", filename = "nbstat.nse" }
|
||||
Entry{ category = "discovery", filename = "nbstat.nse" }
|
||||
Entry{ category = "safe", filename = "nbstat.nse" }
|
||||
Entry{ category = "default", filename = "HTTPAuth.nse" }
|
||||
Entry{ category = "auth", filename = "HTTPAuth.nse" }
|
||||
Entry{ category = "intrusive", filename = "HTTPAuth.nse" }
|
||||
Entry{ category = "default", filename = "finger.nse" }
|
||||
Entry{ category = "discovery", filename = "finger.nse" }
|
||||
Entry{ category = "demo", filename = "showHTTPVersion.nse" }
|
||||
Entry{ category = "default", filename = "SSHv1-support.nse" }
|
||||
Entry{ category = "safe", filename = "SSHv1-support.nse" }
|
||||
Entry{ category = "default", filename = "popcapa.nse" }
|
||||
Entry{ category = "default", filename = "SNMPsysdescr.nse" }
|
||||
Entry{ category = "discovery", filename = "SNMPsysdescr.nse" }
|
||||
Entry{ category = "safe", filename = "SNMPsysdescr.nse" }
|
||||
Entry{ category = "intrusive", filename = "brutePOP3.nse" }
|
||||
Entry{ category = "auth", filename = "brutePOP3.nse" }
|
||||
Entry{ category = "default", filename = "MySQLinfo.nse" }
|
||||
Entry{ category = "discovery", filename = "MySQLinfo.nse" }
|
||||
Entry{ category = "safe", filename = "MySQLinfo.nse" }
|
||||
Entry{ category = "default", filename = "ftpbounce.nse" }
|
||||
Entry{ category = "intrusive", filename = "ftpbounce.nse" }
|
||||
Entry{ category = "auth", filename = "xamppDefaultPass.nse" }
|
||||
Entry{ category = "vuln", filename = "xamppDefaultPass.nse" }
|
||||
Entry{ category = "intrusive", filename = "HTTPpasswd.nse" }
|
||||
Entry{ category = "vuln", filename = "HTTPpasswd.nse" }
|
||||
Entry{ category = "demo", filename = "showSSHVersion.nse" }
|
||||
Entry{ category = "version", filename = "PPTPversion.nse" }
|
||||
Entry{ category = "default", filename = "ircServerInfo.nse" }
|
||||
Entry{ category = "discovery", filename = "ircServerInfo.nse" }
|
||||
Entry{ category = "default", filename = "dns-test-open-recursion.nse" }
|
||||
Entry{ category = "intrusive", filename = "dns-test-open-recursion.nse" }
|
||||
Entry{ category = "demo", filename = "chargenTest.nse" }
|
||||
Entry{ category = "default", filename = "showHTMLTitle.nse" }
|
||||
Entry{ category = "demo", filename = "showHTMLTitle.nse" }
|
||||
Entry{ category = "safe", filename = "showHTMLTitle.nse" }
|
||||
Entry{ category = "default", filename = "MSSQLm.nse" }
|
||||
Entry{ category = "discovery", filename = "MSSQLm.nse" }
|
||||
Entry{ category = "intrusive", filename = "MSSQLm.nse" }
|
||||
Entry{ category = "demo", filename = "echoTest.nse" }
|
||||
Entry{ category = "default", filename = "SSHv1-support.nse" }
|
||||
Entry{ category = "safe", filename = "SSHv1-support.nse" }
|
||||
Entry{ category = "default", filename = "MySQLinfo.nse" }
|
||||
Entry{ category = "discovery", filename = "MySQLinfo.nse" }
|
||||
Entry{ category = "safe", filename = "MySQLinfo.nse" }
|
||||
Entry{ category = "auth", filename = "xamppDefaultPass.nse" }
|
||||
Entry{ category = "vuln", filename = "xamppDefaultPass.nse" }
|
||||
Entry{ category = "default", filename = "SSLv2-support.nse" }
|
||||
Entry{ category = "safe", filename = "SSLv2-support.nse" }
|
||||
Entry{ category = "default", filename = "zoneTrans.nse" }
|
||||
Entry{ category = "intrusive", filename = "zoneTrans.nse" }
|
||||
Entry{ category = "discovery", filename = "zoneTrans.nse" }
|
||||
Entry{ category = "default", filename = "ftpbounce.nse" }
|
||||
Entry{ category = "intrusive", filename = "ftpbounce.nse" }
|
||||
Entry{ category = "version", filename = "skype_v2-version.nse" }
|
||||
Entry{ category = "discovery", filename = "promiscuous.nse" }
|
||||
Entry{ category = "default", filename = "SNMPsysdescr.nse" }
|
||||
Entry{ category = "discovery", filename = "SNMPsysdescr.nse" }
|
||||
Entry{ category = "safe", filename = "SNMPsysdescr.nse" }
|
||||
Entry{ category = "demo", filename = "showSMTPVersion.nse" }
|
||||
Entry{ category = "default", filename = "nbstat.nse" }
|
||||
Entry{ category = "discovery", filename = "nbstat.nse" }
|
||||
Entry{ category = "safe", filename = "nbstat.nse" }
|
||||
Entry{ category = "version", filename = "iax2Detect.nse" }
|
||||
Entry{ category = "default", filename = "rpcinfo.nse" }
|
||||
Entry{ category = "safe", filename = "rpcinfo.nse" }
|
||||
Entry{ category = "discovery", filename = "rpcinfo.nse" }
|
||||
Entry{ category = "default", filename = "HTTP_open_proxy.nse" }
|
||||
Entry{ category = "discovery", filename = "HTTP_open_proxy.nse" }
|
||||
Entry{ category = "intrusive", filename = "HTTP_open_proxy.nse" }
|
||||
Entry{ category = "demo", filename = "daytimeTest.nse" }
|
||||
Entry{ category = "intrusive", filename = "HTTPpasswd.nse" }
|
||||
Entry{ category = "vuln", filename = "HTTPpasswd.nse" }
|
||||
Entry{ category = "demo", filename = "showSSHVersion.nse" }
|
||||
Entry{ category = "default", filename = "SMTPcommands.nse" }
|
||||
Entry{ category = "discovery", filename = "SMTPcommands.nse" }
|
||||
Entry{ category = "safe", filename = "SMTPcommands.nse" }
|
||||
Entry{ category = "default", filename = "anonFTP.nse" }
|
||||
Entry{ category = "auth", filename = "anonFTP.nse" }
|
||||
Entry{ category = "intrusive", filename = "anonFTP.nse" }
|
||||
Entry{ category = "version", filename = "netbios-smb-os-discovery.nse" }
|
||||
Entry{ category = "default", filename = "robots.nse" }
|
||||
Entry{ category = "safe", filename = "robots.nse" }
|
||||
Entry{ category = "default", filename = "finger.nse" }
|
||||
Entry{ category = "discovery", filename = "finger.nse" }
|
||||
Entry{ category = "default", filename = "UPnP-info.nse" }
|
||||
Entry{ category = "safe", filename = "UPnP-info.nse" }
|
||||
Entry{ category = "malware", filename = "strangeSMTPport.nse" }
|
||||
Entry{ category = "default", filename = "ircServerInfo.nse" }
|
||||
Entry{ category = "discovery", filename = "ircServerInfo.nse" }
|
||||
Entry{ category = "malware", filename = "ircZombieTest.nse" }
|
||||
Entry{ category = "discovery", filename = "ripeQuery.nse" }
|
||||
Entry{ category = "demo", filename = "showHTTPVersion.nse" }
|
||||
Entry{ category = "version", filename = "PPTPversion.nse" }
|
||||
Entry{ category = "discovery", filename = "ASN.nse" }
|
||||
Entry{ category = "intrusive", filename = "brutePOP3.nse" }
|
||||
Entry{ category = "auth", filename = "brutePOP3.nse" }
|
||||
Entry{ category = "default", filename = "popcapa.nse" }
|
||||
Entry{ category = "intrusive", filename = "SNMPcommunitybrute.nse" }
|
||||
Entry{ category = "auth", filename = "SNMPcommunitybrute.nse" }
|
||||
Entry{ category = "discovery", filename = "whois.nse" }
|
||||
Entry{ category = "safe", filename = "whois.nse" }
|
||||
Entry{ category = "intrusive", filename = "dns-safe-recursion-txid.nse" }
|
||||
Entry{ category = "intrusive", filename = "dns-safe-recursion-port.nse" }
|
||||
|
||||
Reference in New Issue
Block a user