1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
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)
|