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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
local os = require "os"
local datetime = require "datetime"
local mssql = require "mssql"
local stdnse = require "stdnse"
local smbauth = require "smbauth"
local string = require "string"
description = [[
This script enumerates information from remote Microsoft SQL services with NTLM
authentication enabled.
Sending a MS-TDS NTLM authentication request with an invalid domain and null
credentials will cause the remote service to respond with a NTLMSSP message
disclosing information to include NetBIOS, DNS, and OS build version.
]]
---
-- @usage
-- nmap -p 1433 --script ms-sql-ntlm-info <target>
--
-- @output
-- 1433/tcp open ms-sql-s
-- | ms-sql-ntlm-info:
-- | Target_Name: ACTIVESQL
-- | NetBIOS_Domain_Name: ACTIVESQL
-- | NetBIOS_Computer_Name: DB-TEST2
-- | DNS_Domain_Name: somedomain.com
-- | DNS_Computer_Name: db-test2.somedomain.com
-- | DNS_Tree_Name: somedomain.com
-- |_ Product_Version: 6.1.7601
--
--@xmloutput
-- <elem key="Target_Name">ACTIVESQL</elem>
-- <elem key="NetBIOS_Domain_Name">ACTIVESQL</elem>
-- <elem key="NetBIOS_Computer_Name">DB-TEST2</elem>
-- <elem key="DNS_Domain_Name">somedomain.com</elem>
-- <elem key="DNS_Computer_Name">db-test2.somedomain.com</elem>
-- <elem key="DNS_Tree_Name">somedomain.com</elem>
-- <elem key="Product_Version">6.1.7601</elem>
author = "Justin Cacak"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "safe"}
dependencies = {"broadcast-ms-sql-discover"}
local do_action = function(host, port)
local output = stdnse.output_table()
local tdsstream = mssql.TDSStream:new()
local status, result = tdsstream:Connect(host, port)
if not status then
return nil
end
local lp = mssql.LoginPacket:new()
lp:SetUsername("")
lp:SetPassword("")
lp:SetDatabase("")
lp:SetServer(stdnse.get_hostname(host))
-- Setting domain forces NTLM authentication
lp:SetDomain(".")
status, result = tdsstream:Send( lp:ToString() )
if not status then
tdsstream:Disconnect()
return nil
end
local status, response, errorDetail = tdsstream:Receive()
local recvtime = os.time()
tdsstream:Disconnect()
local ttype, pos = string.unpack("B", response)
if ttype ~= mssql.TokenType.NTLMSSP_CHALLENGE then
return nil
end
local data, pos = string.unpack("<s2", response, pos)
if not string.match(data, "^NTLMSSP") then
return nil
end
-- Leverage smbauth.get_host_info_from_security_blob() for decoding
local ntlm_decoded = smbauth.get_host_info_from_security_blob(data)
if ntlm_decoded.timestamp then
-- 64-bit number of 100ns clicks since 1/1/1601
local unixstamp = ntlm_decoded.timestamp // 10000000 - 11644473600
datetime.record_skew(host, unixstamp, recvtime)
end
-- Target Name will always be returned under any implementation
output.Target_Name = ntlm_decoded.target_realm
-- Display information returned & ignore responses with null values
if ntlm_decoded.netbios_domain_name and #ntlm_decoded.netbios_domain_name > 0 then
output.NetBIOS_Domain_Name = ntlm_decoded.netbios_domain_name
end
if ntlm_decoded.netbios_computer_name and #ntlm_decoded.netbios_computer_name > 0 then
output.NetBIOS_Computer_Name = ntlm_decoded.netbios_computer_name
end
if ntlm_decoded.dns_domain_name and #ntlm_decoded.dns_domain_name > 0 then
output.DNS_Domain_Name = ntlm_decoded.dns_domain_name
end
if ntlm_decoded.fqdn and #ntlm_decoded.fqdn > 0 then
output.DNS_Computer_Name = ntlm_decoded.fqdn
end
if ntlm_decoded.dns_forest_name and #ntlm_decoded.dns_forest_name > 0 then
output.DNS_Tree_Name = ntlm_decoded.dns_forest_name
end
if ntlm_decoded.os_major_version then
output.Product_Version = string.format("%d.%d.%d",
ntlm_decoded.os_major_version, ntlm_decoded.os_minor_version, ntlm_decoded.os_build)
end
return output
end
local function process_instance(instance)
return do_action(instance.host, instance.port)
end
action, portrule = mssql.Helper.InitScript(process_instance)
|