1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00
Files
nmap/scripts/ms-sql-ntlm-info.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

135 lines
4.0 KiB
Lua

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)