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.
114 lines
3.5 KiB
Lua
114 lines
3.5 KiB
Lua
local io = require "io"
|
|
local mssql = require "mssql"
|
|
local stdnse = require "stdnse"
|
|
local string = require "string"
|
|
local stringaux = require "stringaux"
|
|
local table = require "table"
|
|
|
|
description = [[
|
|
Dumps the password hashes from an MS-SQL server in a format suitable for
|
|
cracking by tools such as John-the-ripper. In order to do so the user
|
|
needs to have the appropriate DB privileges.
|
|
|
|
Credentials passed as script arguments take precedence over credentials
|
|
discovered by other scripts.
|
|
]]
|
|
|
|
---
|
|
-- @usage
|
|
-- nmap -p 1433 <ip> --script ms-sql-dump-hashes
|
|
--
|
|
-- @args ms-sql-dump-hashes.dir Dump hashes to a file in this directory. File
|
|
-- name is <ip>_<instance>_ms-sql_hashes.txt.
|
|
-- Default: no file is saved.
|
|
--
|
|
-- @output
|
|
-- PORT STATE SERVICE
|
|
-- 1433/tcp open ms-sql-s
|
|
-- | ms-sql-dump-hashes:
|
|
-- | nmap_test:0x01001234567890ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF0123
|
|
-- | sa:0x01001234567890ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF0123
|
|
-- |_ webshop_dbo:0x01001234567890ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF0123
|
|
|
|
--
|
|
--
|
|
-- Version 0.1
|
|
-- Created 08/03/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
|
--
|
|
|
|
author = "Patrik Karlsson"
|
|
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
|
|
categories = {"auth", "discovery", "safe"}
|
|
|
|
dependencies = {"broadcast-ms-sql-discover", "ms-sql-brute", "ms-sql-empty-password"}
|
|
|
|
local function process_instance(instance)
|
|
|
|
local helper = mssql.Helper:new()
|
|
local status, errorMessage = helper:ConnectEx( instance )
|
|
if ( not(status) ) then
|
|
return "ERROR: " .. errorMessage
|
|
end
|
|
|
|
status, errorMessage = helper:LoginEx( instance )
|
|
if ( not(status) ) then
|
|
return "ERROR: " .. errorMessage
|
|
end
|
|
|
|
local result
|
|
local query = [[
|
|
IF ( OBJECT_ID('master..sysxlogins' ) ) <> 0
|
|
SELECT name, password FROM master..sysxlogins WHERE password IS NOT NULL
|
|
ELSE IF ( OBJECT_ID('master.sys.sql_logins') ) <> 0
|
|
SELECT name, password_hash FROM master.sys.sql_logins
|
|
]]
|
|
status, result = helper:Query( query )
|
|
|
|
local output = {}
|
|
|
|
if ( status ) then
|
|
for _, row in ipairs( result.rows ) do
|
|
table.insert(output, ("%s:%s"):format(row[1] or "",row[2] or "") )
|
|
end
|
|
end
|
|
|
|
helper:Disconnect()
|
|
return output
|
|
end
|
|
|
|
-- Saves the hashes to file
|
|
-- @param filename string name of the file
|
|
-- @param response table containing the resultset
|
|
-- @return status true on success, false on failure
|
|
-- @return err string containing the error if status is false
|
|
local function saveToFile(filename, response)
|
|
local f = io.open( filename, "w")
|
|
if ( not(f) ) then
|
|
return false, ("Failed to open file (%s)"):format(filename)
|
|
end
|
|
for _, row in ipairs(response) do
|
|
if ( not(f:write(row .."\n" ) ) ) then
|
|
return false, ("Failed to write file (%s)"):format(filename)
|
|
end
|
|
end
|
|
f:close()
|
|
return true
|
|
end
|
|
|
|
local dir = stdnse.get_script_args("ms-sql-dump-hashes.dir")
|
|
|
|
local function process_and_save (instance)
|
|
local instanceOutput = process_instance( instance )
|
|
if type(instanceOutput) == "table" then
|
|
local inst = instance:GetName():gsub(".*\\", "")
|
|
local filename = dir .. "/" .. stringaux.filename_escape(
|
|
("%s_%s_ms-sql_hashes.txt"):format(instance.host.ip, inst))
|
|
saveToFile(filename, instanceOutput)
|
|
end
|
|
return instanceOutput
|
|
end
|
|
|
|
local do_instance = dir and process_and_save or process_instance
|
|
|
|
action, portrule, hostrule = mssql.Helper.InitScript(do_instance)
|