mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31: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.
135 lines
4.0 KiB
Lua
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)
|