coolbins/system/usr/share/nmap/scripts/dns-blacklist.nse

177 lines
5.2 KiB
Lua

local dnsbl = require "dnsbl"
local ipOps = require "ipOps"
local stdnse = require "stdnse"
local table = require "table"
description = [[
Checks target IP addresses against multiple DNS anti-spam and open
proxy blacklists and returns a list of services for which an IP has been flagged. Checks may be limited by service category (eg: SPAM,
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
--
-- @output
-- Pre-scan script results:
-- | dns-blacklist:
-- | 1.2.3.4
-- | PROXY
-- | dnsbl.tornevall.org - PROXY
-- | IP marked as "abusive host".
-- | Proxy is working
-- | Proxy has been scanned
-- | SPAM
-- | dnsbl.inps.de - SPAM
-- | Spam Received See: http://www.sorbs.net/lookup.shtml?1.2.3.4
-- | l2.apews.org - SPAM
-- | list.quorum.to - SPAM
-- | bl.spamcop.net - SPAM
-- |_ spam.dnsbl.sorbs.net - SPAM
--
-- Supported blacklist list mode (--script-args dns-blacklist.list):
-- | dns-blacklist:
-- | PROXY
-- | socks.dnsbl.sorbs.net
-- | http.dnsbl.sorbs.net
-- | misc.dnsbl.sorbs.net
-- | dnsbl.tornevall.org
-- | SPAM
-- | dnsbl.inps.de
-- | bl.nszones.com
-- | l2.apews.org
-- | list.quorum.to
-- | all.spamrats.com
-- | bl.spamcop.net
-- | spam.dnsbl.sorbs.net
-- |_ sbl.spamhaus.org
--
-- @args dns-blacklist.ip string containing the IP to check only needed if
-- running the script as a prerule.
--
-- @args dns-blacklist.mode string containing either "short" or "long"
-- long mode can sometimes provide additional information to why an IP
-- has been blacklisted. (default: long)
--
-- @args dns-blacklist.list lists all services that are available for a
-- certain category.
--
-- @args dns-blacklist.services string containing a comma-separated list of
-- services to query. (default: all)
--
-- @args dns-blacklist.category string containing the service category to query
-- eg. spam or proxy (default: all)
--
--
author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"external", "safe"}
-- The script can be run either as a host- or pre-rule
hostrule = function() return true end
prerule = function() return true end
local arg_IP = stdnse.get_script_args(SCRIPT_NAME .. ".ip")
local arg_mode = stdnse.get_script_args(SCRIPT_NAME .. ".mode") or "long"
local arg_list = stdnse.get_script_args(SCRIPT_NAME .. ".list")
local arg_services = stdnse.get_script_args(SCRIPT_NAME .. ".services")
local arg_category = stdnse.get_script_args(SCRIPT_NAME .. ".category") or "all"
local function listServices()
local result = {}
if ( "all" == arg_category ) then
for cat in pairs(dnsbl.SERVICES) do
local helper = dnsbl.Helper:new(cat, arg_mode)
local cat_res= helper:listServices()
cat_res.name = cat
table.insert(result, cat_res)
end
else
result = dnsbl.Helper:new(arg_category, arg_mode):listServices()
end
return stdnse.format_output(true, result)
end
local function formatResult(result)
local output = {}
for _, svc in ipairs(result) do
if ( svc.result.details ) then
svc.result.details.name = ("%s - %s"):format(svc.name, svc.result.state)
table.insert(output, svc.result.details)
else
table.insert(output, ("%s - %s"):format(svc.name, svc.result.state))
end
end
return output
end
local function fail (err) return stdnse.format_output(false, err) end
dnsblAction = function(host)
local helper
if ( arg_services and ( not(arg_category) or "all" == arg_category:lower() ) ) then
return fail("A service filter can't be used without a specific category")
elseif( "all" ~= arg_category ) then
helper = dnsbl.Helper:new(arg_category, arg_mode)
helper:setFilter(arg_services)
local status, err = helper:validateFilter()
if ( not(status) ) then
return fail(("%s"):format(err))
end
end
local output = {}
if ( helper ) then
local result = helper:checkBL(host.ip)
if ( #result == 0 ) then return end
output = formatResult(result)
else
for cat in pairs(dnsbl.SERVICES) do
helper = dnsbl.Helper:new(cat, arg_mode)
local result = helper:checkBL(host.ip)
local out_part = formatResult(result)
if ( #out_part > 0 ) then
out_part.name = cat
table.insert(output, out_part)
end
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
-- execute the action function corresponding to the current rule
action = function(...)
if ( arg_mode ~= "short" and arg_mode ~= "long" ) then
return fail("Invalid argument supplied, mode should be either 'short' or 'long'")
end
if ( arg_IP and not(ipOps.todword(arg_IP)) ) then
return fail("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
return dnsblAction(...)
end
end