Skip to content

Commit

Permalink
Merge pull request #19651 from smashery/smb_version_update
Browse files Browse the repository at this point in the history
Give likely Windows versions for SMB v2-3
  • Loading branch information
smcintyre-r7 authored Nov 26, 2024
2 parents 530dbd6 + 6f4ab97 commit 6c76dcb
Show file tree
Hide file tree
Showing 3 changed files with 304 additions and 106 deletions.
191 changes: 154 additions & 37 deletions lib/msf/core/windows_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,112 @@ class WindowsVersion
VER_NT_DOMAIN_CONTROLLER = 2
VER_NT_SERVER = 3

Win2000 = Rex::Version.new('5.0.2195')
XP_SP0 = Rex::Version.new('5.1.2600.0')
XP_SP1 = Rex::Version.new('5.1.2600.1')
XP_SP2 = Rex::Version.new('5.1.2600.2')
XP_SP3 = Rex::Version.new('5.1.2600.3')
Server2003_SP0 = Rex::Version.new('5.2.3790.0')
Server2003_SP1 = Rex::Version.new('5.2.3790.1')
Server2003_SP2 = Rex::Version.new('5.2.3790.2')
Vista_SP0 = Server2008_SP0 = Rex::Version.new('6.0.6000.0')
Vista_SP1 = Server2008_SP1 = Rex::Version.new('6.0.6001.1')
Vista_SP2 = Server2008_SP2 = Rex::Version.new('6.0.6002.2')
Server2008_SP2_Update = Rex::Version.new('6.0.6003.2') # https://support.microsoft.com/en-us/topic/build-number-changing-to-6003-in-windows-server-2008-1335e4d4-c155-52eb-4a45-b85bd1909ca8
Win7_SP0 = Server2008_R2_SP0 = Rex::Version.new('6.1.7600.0')
Win7_SP1 = Server2008_R2_SP1 = Rex::Version.new('6.1.7601.1')
Win8 = Server2012 = Rex::Version.new('6.2.9200.0')
Win81 = Server2012_R2 = Rex::Version.new('6.3.9600.0')
Win10_1507 = Win10_InitialRelease = Rex::Version.new('10.0.10240.0')
Win10_1511 = Rex::Version.new('10.0.10586.0')
Win10_1607 = Server2016 = Rex::Version.new('10.0.14393.0')
Win10_1703 = Rex::Version.new('10.0.15063.0')
Win10_1709 = Rex::Version.new('10.0.16299.0')
Win10_1803 = Rex::Version.new('10.0.17134.0')
Win10_1809 = Server2019 = Rex::Version.new('10.0.17763.0')
Win10_1903 = Rex::Version.new('10.0.18362.0')
Win10_1909 = Rex::Version.new('10.0.18363.0')
Win10_2004 = Rex::Version.new('10.0.19041.0')
Win10_20H2 = Rex::Version.new('10.0.19042.0')
Win10_21H1 = Rex::Version.new('10.0.19043.0')
Win10_21H2 = Rex::Version.new('10.0.19044.0')
Win10_22H2 = Rex::Version.new('10.0.19045.0')
Server2022 = Rex::Version.new('10.0.20348.0')
Win11_21H2 = Rex::Version.new('10.0.22000.0')
Win11_22H2 = Rex::Version.new('10.0.22621.0')
Win11_23H2 = Rex::Version.new('10.0.22631.0')
Server2022_23H2 = Rex::Version.new('10.0.25398.0')
module ServerSpecificVersions
Server2003_SP0 = Rex::Version.new('5.2.3790.0')
Server2003_SP1 = Rex::Version.new('5.2.3790.1')
Server2003_SP2 = Rex::Version.new('5.2.3790.2')
Server2008_SP0 = Rex::Version.new('6.0.6000.0')
Server2008_SP1 = Rex::Version.new('6.0.6001.1')
Server2008_SP2 = Rex::Version.new('6.0.6002.2')
Server2008_SP2_Update = Rex::Version.new('6.0.6003.2') # https://support.microsoft.com/en-us/topic/build-number-changing-to-6003-in-windows-server-2008-1335e4d4-c155-52eb-4a45-b85bd1909ca8
Server2008_R2_SP0 = Rex::Version.new('6.1.7600.0')
Server2008_R2_SP1 = Rex::Version.new('6.1.7601.1')
Server2012 = Rex::Version.new('6.2.9200.0')
Server2012_R2 = Rex::Version.new('6.3.9600.0')
Server2016 = Rex::Version.new('10.0.14393.0')
Server2019 = Rex::Version.new('10.0.17763.0')
Server2022 = Rex::Version.new('10.0.20348.0')
Server2022_23H2 = Rex::Version.new('10.0.25398.0')
end

module WorkstationSpecificVersions
Win2000 = Rex::Version.new('5.0.2195')
XP_SP0 = Rex::Version.new('5.1.2600.0')
XP_SP1 = Rex::Version.new('5.1.2600.1')
XP_SP2 = Rex::Version.new('5.1.2600.2')
XP_SP3 = Rex::Version.new('5.1.2600.3')
Vista_SP0 = Rex::Version.new('6.0.6000.0')
Vista_SP1 = Rex::Version.new('6.0.6001.1')
Vista_SP2 = Rex::Version.new('6.0.6002.2')
Win7_SP0 = Rex::Version.new('6.1.7600.0')
Win7_SP1 = Rex::Version.new('6.1.7601.1')
Win8 = Rex::Version.new('6.2.9200.0')
Win81 = Rex::Version.new('6.3.9600.0')
Win10_1507 = Rex::Version.new('10.0.10240.0')
Win10_1511 = Rex::Version.new('10.0.10586.0')
Win10_1607 = Rex::Version.new('10.0.14393.0')
Win10_1703 = Rex::Version.new('10.0.15063.0')
Win10_1709 = Rex::Version.new('10.0.16299.0')
Win10_1803 = Rex::Version.new('10.0.17134.0')
Win10_1809 = Rex::Version.new('10.0.17763.0')
Win10_1903 = Rex::Version.new('10.0.18362.0')
Win10_1909 = Rex::Version.new('10.0.18363.0')
Win10_2004 = Rex::Version.new('10.0.19041.0')
Win10_20H2 = Rex::Version.new('10.0.19042.0')
Win10_21H1 = Rex::Version.new('10.0.19043.0')
Win10_21H2 = Rex::Version.new('10.0.19044.0')
Win10_22H2 = Rex::Version.new('10.0.19045.0')
Win11_21H2 = Rex::Version.new('10.0.22000.0')
Win11_22H2 = Rex::Version.new('10.0.22621.0')
Win11_23H2 = Rex::Version.new('10.0.22631.0')
Win11_24H2 = Rex::Version.new('10.0.26100.0')
end

include WorkstationSpecificVersions
include ServerSpecificVersions

ServerNameMapping = {
:Server2003_SP0 => "Windows Server 2003",
:Server2003_SP1 => "Windows Server 2003 Service Pack 1",
:Server2003_SP2 => "Windows Server 2003 Service Pack 2",
:Server2008_SP0 => "Windows Server 2008",
:Server2008_SP1 => "Windows Server 2008 Service Pack 1",
:Server2008_SP2 => "Windows Server 2008 Service Pack 2",
:Server2008_SP2_Update => "Windows Server 2008 Service Pack 2 Update",
:Server2008_R2_SP0 => "Windows Server 2008 R2",
:Server2008_R2_SP1 => "Windows Server 2008 R2 Service Pack 1",
:Server2012 => "Windows Server 2012 R2",
:Server2012_R2 => "Windows Server 2012 R2",
:Server2016 => "Windows Server 2016",
:Server2019 => "Windows Server 2019",
:Server2022 => "Windows Server 2022",
:Server2022_23H2 => "Windows Server 2022 version 23H2"
}

WorkstationNameMapping = {
:Win2000 => "Windows 2000",
:XP_SP0 => "Windows XP",
:XP_SP1 => "Windows XP Service Pack 1",
:XP_SP2 => "Windows XP Service Pack 2",
:XP_SP3 => "Windows XP Service Pack 3",
:Vista_SP0 => "Windows Vista",
:Vista_SP1 => "Windows Vista Service Pack 1",
:Vista_SP2 => "Windows Vista Service Pack 2",
:Win7_SP0 => "Windows 7",
:Win7_SP1 => "Windows 7 Service Pack 1",
:Win8 => "Windows 8",
:Win81 => "Windows 8.1",
:Win10_1507 => "Windows 10 version 1507",
:Win10_1511 => "Windows 10 version 1511",
:Win10_1607 => "Windows 10 version 1607",
:Win10_1703 => "Windows 10 version 1703",
:Win10_1709 => "Windows 10 version 1709",
:Win10_1803 => "Windows 10 version 1803",
:Win10_1809 => "Windows 10 version 1809",
:Win10_1903 => "Windows 10 version 1903",
:Win10_1909 => "Windows 10 version 1909",
:Win10_2004 => "Windows 10 version 2004",
:Win10_20H2 => "Windows 10 version 20H2",
:Win10_21H1 => "Windows 10 version 21H1",
:Win10_21H2 => "Windows 10 version 21H2",
:Win10_22H2 => "Windows 10 version 22H2",
:Win11_21H2 => "Windows 11 version 21H2",
:Win11_22H2 => "Windows 11 version 22H2",
:Win11_23H2 => "Windows 11 version 23H2",
:Win11_24H2 => "Windows 11 version 24H2"
}

Win10_InitialRelease = Win10_1507

module MajorRelease
NT351 = 'Windows NT 3.51'.freeze
Expand All @@ -60,7 +131,7 @@ module MajorRelease
Server2008 = 'Windows Server 2008'.freeze

Win7 = 'Windows 7'.freeze
Server2008R2 = 'Windows 2008 R2'.freeze
Server2008R2 = 'Windows Server 2008 R2'.freeze

Win8 = 'Windows 8'.freeze
Server2012 = 'Windows Server 2012'.freeze
Expand Down Expand Up @@ -112,6 +183,15 @@ def domain_controller?

# The name of the OS, as it is most commonly rendered. Includes Service Pack if present, or build number if Win10 or higher.
def product_name
# First check if there's a specific, known version we have a string for
if windows_server?
known_version = self.class.version_string(_major, _minor, _build, ServerSpecificVersions, ServerNameMapping)
else
known_version = self.class.version_string(_major, _minor, _build, WorkstationSpecificVersions, WorkstationNameMapping)
end
return known_version unless known_version.nil?

# Otherwise, build it up from version numbers, to the best of our ability
result = "Unknown Windows version: #{_major}.#{_minor}.#{_build}"
name = major_release_name
result = name unless name.nil?
Expand Down Expand Up @@ -140,6 +220,30 @@ def xp_or_2003?
build_number.between?(XP_SP0, Server2003_SP2)
end

# Get the string representation of the OS, given a major, minor and build number
# (as reported by an NTLM handshake).
# The NTLM structure makes no guarantee that the underlying OS of the server is
# actually Windows, so if we don't find a precise match, return nil
#
# @param major [Integer] The major build number reported in the NTLM handshake
# @param minor [Integer] The minor build number reported in the NTLM handshake
# @param build [Integer] The build build number reported in the NTLM handshake
# @return [String] The possible matching OS versions, or nil if no corresponding match can be found
def self.from_ntlm_os_version(major, minor, build)
workstation_string = self.version_string(major, minor, build, WorkstationSpecificVersions, WorkstationNameMapping)
server_string = self.version_string(major, minor, build, ServerSpecificVersions, ServerNameMapping)

version_strings = []
version_strings.append(workstation_string) unless workstation_string.nil?
version_strings.append(server_string) unless server_string.nil?

if version_strings.length > 0
version_strings.join('/')
else
nil
end
end

private

attr_accessor :_major, :_minor, :_build, :_service_pack, :_revision, :product_type
Expand All @@ -154,7 +258,7 @@ def major_release_name
elsif _minor == 2
return MajorRelease::Server2003 if windows_server?

return MajorRelease::XP
return MajorRelease::XP # x64 Build
end
elsif _major == 6
if _minor == 0
Expand Down Expand Up @@ -183,5 +287,18 @@ def major_release_name
end
return nil
end

# Get a Windows OS version string representation for a given major, minor and build number
def self.version_string(major, minor, build, version_module, mapping)
version_module.constants.each do |version_sym|
version = version_module.const_get(version_sym)
segments = version.segments
if segments[0..2] == [major, minor, build]
return mapping[version_sym]
end
end

nil
end
end
end
Loading

0 comments on commit 6c76dcb

Please sign in to comment.