mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 12:41:29 +00:00
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.
86 lines
2.6 KiB
Lua
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)
|