From 79a96f08ae9b4b211afda2be6e38884a1501d565 Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Fri, 24 May 2019 09:38:40 -0400 Subject: [PATCH] SMB: Parse SMB Versions and Dialects. This parses the SMB Version response, and the dialect, to determine the full SMB version. This is done in accordance to "[MS-SMB2] - v20190430" from Microsoft, Section 2.2.4. --- lib/smb/smb/zgrab.go | 64 +++++++++++++++++++++++++++++++++++- zgrab2_schemas/zgrab2/smb.py | 7 ++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/smb/smb/zgrab.go b/lib/smb/smb/zgrab.go index 63f08ac..566f622 100644 --- a/lib/smb/smb/zgrab.go +++ b/lib/smb/smb/zgrab.go @@ -81,12 +81,32 @@ type SessionSetupLog struct { NegotiateFlags uint32 `json:"negotiate_flags"` } +// Parse the SMB version and dialect; version string +// will be of the form: Major.Minor.Revision. +// +// 'Revisions' are set to 0 if not specified (e.g. 2.1 is 2.1.0) +// The following versions/dialects are known: +// SMB 1.0.0 +// SMB 2.0.2 +// SMB 2.1.0 +// SMB 3.0.0 +// SMB 3.0.2 +// SMB 3.1.1 +type SMBVersions struct { + Major int `json:"major"` + Minor int `json:"minor"` + Revision int `json:"revision"` + VerString string `json:"version_string"` +} + // SMBLog logs the relevant information about the session. type SMBLog struct { // SupportV1 is true if the server's protocol ID indicates support for // version 1. SupportV1 bool `json:"smbv1_support"` + Version *SMBVersions `json:"smb_version,omitempty"` + // HasNTLM is true if the server supports the NTLM authentication method. HasNTLM bool `json:"has_ntlm"` @@ -214,7 +234,49 @@ func (ls *LoggedSession) LoggedNegotiateProtocol(setup bool) error { logStruct := new(SMBLog) ls.Log = logStruct - ls.Log.SupportV1 = string(negRes.Header.ProtocolID) == ProtocolSmb + + switch string(negRes.Header.ProtocolID) { + case ProtocolSmb: + ls.Log.SupportV1 = true + ls.Log.Version = &SMBVersions{Major: 1, + Minor: 0, + Revision: 0, + VerString: "SMB 1.0"} + case ProtocolSmb2: + switch negRes.DialectRevision { + case 0x0202: + ls.Log.Version = &SMBVersions{ + Major: 2, + Minor: 0, + Revision: 2, + VerString: "SMB 2.0.2"} + case 0x0210: + ls.Log.Version = &SMBVersions{ + Major: 2, + Minor: 1, + Revision: 0, + VerString: "SMB 2.1"} + case 0x0300: + ls.Log.Version = &SMBVersions{ + Major: 3, + Minor: 0, + Revision: 0, + VerString: "SMB 3.0"} + case 0x0302: + ls.Log.Version = &SMBVersions{ + Major: 3, + Minor: 0, + Revision: 2, + VerString: "SMB 3.0.2"} + case 0x0311: + ls.Log.Version = &SMBVersions{ + Major: 3, + Minor: 1, + Revision: 1, + VerString: "SMB 3.1.1"} + } + } + logStruct.NegotiationLog = &NegotiationLog{ HeaderLog: getHeaderLog(&negRes.Header), SecurityMode: negRes.SecurityMode, diff --git a/zgrab2_schemas/zgrab2/smb.py b/zgrab2_schemas/zgrab2/smb.py index 33e1a80..f0c978b 100644 --- a/zgrab2_schemas/zgrab2/smb.py +++ b/zgrab2_schemas/zgrab2/smb.py @@ -42,9 +42,16 @@ session_setup_log = SubRecord(extended(header_log, { 'negotiate_flags': Unsigned32BitInteger(), })) + smb_scan_response = SubRecord({ 'result': SubRecord({ 'smbv1_support': Boolean(), + "smb_version": SubRecord({ + "major": Uinsigned8BitInteger(doc="Major version"), + "minor": Unsigned8BitInteger(doc="Minor version"), + "revision": Unsigned8BitInteger(doc="Protocol Revision"), + "version_string": String(doc="Full SBM Version String"), + }), 'negotiation_log': negotiate_log, 'has_ntlm': Boolean(), 'session_setup_log': session_setup_log,