From 0d47952611198ef6b1163f366dc03922d20b1475 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 09:42:04 +0200 Subject: Adding upstream version 7.94+git20230807.3be01efb1+dfsg. Signed-off-by: Daniel Baumann --- scripts/smb-security-mode.nse | 158 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 scripts/smb-security-mode.nse (limited to 'scripts/smb-security-mode.nse') diff --git a/scripts/smb-security-mode.nse b/scripts/smb-security-mode.nse new file mode 100644 index 0000000..8bf823d --- /dev/null +++ b/scripts/smb-security-mode.nse @@ -0,0 +1,158 @@ +local os = require "os" +local datetime = require "datetime" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" + +description = [[ +Returns information about the SMB security level determined by SMB. + +Here is how to interpret the output: + +* User-level authentication: Each user has a separate username/password that + is used to log into the system. This is the default setup of pretty much + everything these days. +* Share-level authentication: The anonymous account should be used to log + in, then the password is given (in plaintext) when a share is accessed. + All users who have access to the share use this password. This was the + original way of doing things, but isn't commonly seen, now. If a server + uses share-level security, it is vulnerable to sniffing. +* Challenge/response passwords supported: If enabled, the server can accept + any type of password (plaintext, LM and NTLM, and LMv2 and NTLMv2). If it + isn't set, the server can only accept plaintext passwords. Most servers + are configured to use challenge/response these days. If a server is + configured to accept plaintext passwords, it is vulnerable to sniffing. LM + and NTLM are fairly secure, although there are some brute-force attacks + against them. Additionally, LM and NTLM can fall victim to + man-in-the-middle attacks or relay attacks (see MS08-068 or my writeup of + it: http://www.skullsecurity.org/blog/?p=110. +* Message signing: If required, all messages between the client and server + must be signed by a shared key, derived from the password and the server + challenge. If supported and not required, message signing is negotiated + between clients and servers and used if both support and request it. By + default, Windows clients don't sign messages, so if message signing isn't + required by the server, messages probably won't be signed; additionally, + if performing a man-in-the-middle attack, an attacker can negotiate no + message signing. If message signing isn't required, the server is + vulnerable to man-in-the-middle attacks or SMB-relay attacks. + +This script will allow you to use the smb* script arguments (to +set the username and password, etc.), but it probably won't ever require +them. +]] + +--- +--@usage +-- nmap --script smb-security-mode.nse -p445 127.0.0.1 +-- sudo nmap -sU -sS --script smb-security-mode.nse -p U:137,T:139 127.0.0.1 +-- +--@output +-- | smb-security-mode: +-- | account_used: guest +-- | authentication_level: user +-- | challenge_response: supported +-- |_ message_signing: disabled (dangerous, but default) +-- +--@xmloutput +-- guest +-- user +-- supported +-- disabled +-- + +author = "Ron Bowes" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"default", "discovery", "safe"} +dependencies = {"smb-brute"} + + +-- Check whether or not this script should be run. +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local function label_warnings (t, w) + local out = {} + for k, v in pairs(t) do + local warn = w[k] + if warn then + warn = string.format(" (%s)", warn) + else + warn = "" + end + out[#out+1] = string.format("\n %s: %s%s", k, v, warn) + end + return table.concat(out) +end + +action = function(host) + + local state + local status, err + local overrides = {} + + status, state = smb.start(host) + if(status == false) then + return stdnse.format_output(false, state) + end + + status, err = smb.negotiate_protocol(state, overrides) + if(status == false) then + smb.stop(state) + return stdnse.format_output(false, err) + end + if state.time then + datetime.record_skew(host, state.time, os.time()) + end + + local security_mode = state['security_mode'] + + local response = stdnse.output_table() + + local result, username, domain = smb.get_account(host) + if(result ~= false) then + if domain and domain ~= "" then + domain = domain .. "\\" + end + response.account_used = string.format("%s%s", domain, stdnse.string_or_blank(username, '')) + end + + local warnings = {} + -- User-level authentication or share-level authentication + if(security_mode & 1) == 1 then + response.authentication_level = "user" + else + response.authentication_level = "share" + warnings.authentication_level = "dangerous" + end + + -- Challenge/response supported? + if(security_mode & 2) == 0 then + response.challenge_response = "plaintext-only" + warnings.challenge_response = "dangerous" + else + response.challenge_response = "supported" + end + + -- Message signing supported/required? + if(security_mode & 8) == 8 then + response.message_signing = "required" + elseif(security_mode & 4) == 4 then + response.message_signing = "supported" + else + response.message_signing = "disabled" + warnings.message_signing = "dangerous, but default" + end + + smb.stop(state) + + local rmeta = getmetatable(response) + rmeta.__tostring = function (t) + return label_warnings(t, warnings) + end + setmetatable(response, rmeta) + return response +end + + -- cgit v1.2.3