1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 12:41:29 +00:00
Files
nmap/scripts/ms-sql-dac.nse
dmiller c3d54f1fac Change how ms-sql NSE scripts run
MS SQL NSE scripts run on database instances, which can be TCP or named
pipes. With this change, all TCP instances on scanned ports will have
script output attached under the port as a portrule script. Named pipe
instances and TCP instances on unscanned ports will be displayed in the
hostrule script output at the end of the host's output. Utility function
mssql.Helper.InitScript makes it easy to write scripts that just work on
a per-instance basis, without bothering where to put the output.
Discovery will be done once per host, regardless of how many scripts are
run, and can be guaranteed to be done before the script's action takes
place.
2022-01-03 21:08:52 +00:00

86 lines
2.6 KiB
Lua

local mssql = require "mssql"
local nmap = require "nmap"
local stdnse = require "stdnse"
description = [[
Queries the Microsoft SQL Browser service for the DAC (Dedicated Admin
Connection) port of a given (or all) SQL Server instance. The DAC port
is used to connect to the database instance when normal connection
attempts fail, for example, when server is hanging, out of memory or
in other bad states. In addition, the DAC port provides an admin with
access to system objects otherwise not accessible over normal
connections.
The DAC feature is accessible on the loopback adapter per default, but
can be activated for remote access by setting the 'remote admin
connection' configuration value to 1. In some cases, when DAC has been
remotely enabled but later disabled, the sql browser service may
incorrectly report it as available. The script therefore attempts to
connect to the reported port in order to verify whether it's
accessible or not.
]]
---
-- @usage
-- sudo nmap -sU -p 1434 --script ms-sql-dac <ip>
--
-- @output
-- | ms-sql-dac:
-- | SQLSERVER:
-- | port: 1533
-- |_ state: open
--
author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}
dependencies = {"broadcast-ms-sql-discover"}
local function checkPort(host, port)
local scanport = nmap.get_port_state(host, {number=port, protocol="tcp"})
if scanport then
return scanport.state
end
local s = nmap.new_socket()
s:set_timeout(5000)
local status, err = s:connect(host, port, "tcp")
s:close()
return (status and "open" or "closed"), err
end
local function discoverDAC(instance)
stdnse.debug2("Discovering DAC port on instance: %s", instance:GetName())
local port = mssql.Helper.DiscoverDACPort(instance)
if not port then
return nil
end
local result = stdnse.output_table()
result.port = port
local state, err = checkPort(instance.host, port)
result.state = state
result.error = err
return result
end
local lib_portrule, lib_hostrule
action, lib_portrule, lib_hostrule = mssql.Helper.InitScript(discoverDAC)
local function rule_if_browser_open(lib_rule)
return function (host, ...)
if not lib_rule(host, ...) then
return false
end
local bport = nmap.get_port_state(host, {number=1434, protocol="udp"})
-- If port is nil, we don't know the state
return bport == nil or (
-- we know the state, so it has to be a good one
bport.state == "open" or bport.state == "open|filtered"
)
end
end
portrule = rule_if_browser_open(lib_portrule)
hostrule = rule_if_browser_open(lib_hostrule)