Skip to content

Bug: SMB dialect versions are broken due to a bug in stdnse.tohex #2744

@yammesicka

Description

@yammesicka

Bug Description

There is a discrepancy in the formatting of SMB version detection in Nmap's SMB-related scripts. Notably, there is an inconsistency in the use of colons (:) and periods (.) in version formatting.

Observations

Nmap Version 7.94

docker run --rm -it instrumentisto/nmap:7.94 -Pn -T4 -p445 --script smb-protocols $SMB_SERVER_IP                                                                     
[...]
PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
| smb-protocols: 
|   dialects: 
|     2:0:2
|     2:1:0
|     3:0:0
|     3:0:2
|_    3:1:1

Nmap done: 1 IP address (1 host up) scanned in 6.18 seconds

Detected SMB dialects: 2:0:2, 2:1:0, 3:0:0, 3:0:2, 3:1:1

Nmap Version 7.93

docker run --rm -it instrumentisto/nmap:7.93 -Pn -T4 -p445 --script smb-protocols $SMB_SERVER_IP
[...]

PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
| smb-protocols: 
|   dialects: 
|     202
|     210
|     300
|     302
|_    311

Nmap done: 1 IP address (1 host up) scanned in 4.86 seconds

Detected SMB dialects: 202, 210, 300, 302, 311

Nmap Version 7.92

docker run --rm -it instrumentisto/nmap:7.92 -Pn -T4 -p445 --script smb-protocols $SMB_SERVER_IP

[...]
PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
| smb-protocols: 
|   dialects: 
|     2.0.2
|     2.1
|     3.0
|     3.0.2
|_    3.1.1

Nmap done: 1 IP address (1 host up) scanned in 5.89 seconds

Detected SMB dialects: 2.0.2, 2.1, 3.0, 3.0.2, 3.1.1

Steps to Reproduce

Analysis

Potential issue in stdnse.tohex function, potentially related to regex changes in a specific commit.

I believe the line:

      hex, subs = gsub(hex, pat, "%1:%2")

Should be something like:

      hex, subs = gsub(hex, pat, "%1" .. separator .. "%2")

Test Script

local stdnse = require "stdnse"

-- Most of the code here is taken from smb2.lua
local smb2_dialects = {0x0202, 0x0210, 0x0300, 0x0302, 0x0311}
local smb2_dialect_names = {}
for _, d in ipairs(smb2_dialects) do
  -- convert 0x0abc to "a.b.c"
  local name = stdnse.tohex(d, {separator = ".", group = 1})
  -- trim trailing ".0" at sub-minor level
  smb2_dialect_names[d] = name:find(".0", 4, true) and name:sub(1, 3) or name
end

hostrule = function(host)
  return true
end

action = function(host,port)
  stdnse.debug1(smb2_dialect_names[0x0311])
end

Execution

for version in 7.92 7.93 7.94; do
    echo "Running Nmap version $version"
    docker run --rm -it -v $(pwd)/meow.nse:/meow.nse instrumentisto/nmap:$version -p445 --script /meow.nse 127.0.0.1 -d > /tmp/del.txt
    grep -e "NSE.*meow.*3" /tmp/del.txt
done

Results

Running Nmap version 7.92
NSE: [meow 127.0.0.1] 3.1.1
Running Nmap version 7.93
NSE: [meow 127.0.0.1] 311
Running Nmap version 7.94
NSE: [meow 127.0.0.1] 3:1:1

Expected Behavior

Based on Nmap's changelog, the SMB version format should be consistent with version 7.92's output, i.e., 3.1.1.

Environment

> nmap --version

Nmap version 7.94 ( https://nmap.org )
Platform: x86_64-pc-linux-gnu
Compiled with: liblua-5.4.6 openssl-3.1.4 libssh2-1.11.0 libz-1.3 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: epoll poll select

Impact

This issue potentially affects multiple SMB version-dependent scripts, such as Example 1 and Example 2 analysis scripts.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions