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)
|