mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
smb3.1.1 additions to negotiate-response command
This commit is contained in:
parent
1ee96516e8
commit
4330b7922c
7 changed files with 180 additions and 27 deletions
|
@ -1 +1 @@
|
|||
Subproject commit bf734622dceaafaf7a481185efd22bd7cc805f9b
|
||||
Subproject commit c7b1dfd38ec6c42729f8c462eef6457a8dd948b6
|
2
doc
2
doc
|
@ -1 +1 @@
|
|||
Subproject commit 5acafa0d340a6f4096dccbe69b8fb62d7c9ce87f
|
||||
Subproject commit c0092fab7b28c029eddb6b9b654f6096d8e4456a
|
|
@ -3226,6 +3226,49 @@ export {
|
|||
attrs : SMB2::FileAttrs;
|
||||
};
|
||||
|
||||
## Preauthentication information as defined in SMB v. 3.1.1
|
||||
##
|
||||
## For more information, see MS-SMB2:2.3.1.1
|
||||
##
|
||||
type SMB2::preauth: record {
|
||||
## the number of hash algorithms
|
||||
hash_alg_count : count;
|
||||
## the salt length
|
||||
salt_length : count;
|
||||
## an array of hash algorithms (counts)
|
||||
hash_alg : vector of count;
|
||||
## the salt
|
||||
salt : string;
|
||||
};
|
||||
|
||||
## Encryption information as defined in SMB v. 3.1.1
|
||||
##
|
||||
## For more information, see MS-SMB2:2.3.1.2
|
||||
##
|
||||
type SMB2::encryption: record {
|
||||
## the number of ciphers
|
||||
cipher_count : count;
|
||||
## an array of ciphers
|
||||
ciphers : vector of count;
|
||||
};
|
||||
|
||||
## The context type information as defined in SMB v. 3.1.1
|
||||
##
|
||||
## For more information, see MS-SMB2:2.3.1
|
||||
##
|
||||
type SMB2::context_value: record {
|
||||
## specifies the type of context (preauth or encryption)
|
||||
context_type : count;
|
||||
## the length in byte of the data field
|
||||
data_length : count;
|
||||
## the preauthentication information
|
||||
preauth_info : SMB2::preauth;
|
||||
## the encryption information
|
||||
encryption_info : SMB2::encryption;
|
||||
};
|
||||
|
||||
type SMB2::context_values: vector of context_value;
|
||||
|
||||
## The response to an SMB2 *negotiate* request, which is used by tghe client to notify the server
|
||||
## what dialects of the SMB2 protocol the client understands.
|
||||
##
|
||||
|
@ -3244,6 +3287,11 @@ export {
|
|||
system_time : time;
|
||||
## The SMB2 server start time.
|
||||
server_start_time : time;
|
||||
|
||||
## The number of negotiate context values in SMB v. 3.1.1, otherwise reserved to 0
|
||||
negotiate_context_count : count;
|
||||
## An array of context values in SMB v. 3.1.1
|
||||
negotiate_context_values : context_values;
|
||||
};
|
||||
|
||||
## The request sent by the client to request a new authenticated session
|
||||
|
@ -3327,6 +3375,7 @@ export {
|
|||
## The action taken in establishing the open.
|
||||
create_action : count;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module GLOBAL;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 6e93c5546a4770d513fb57213d7b29e39e12bf4d
|
||||
Subproject commit b822eeed58c4a1ee3781f1f8c8a19fd590dc4a04
|
|
@ -1,3 +1,19 @@
|
|||
enum smb3_capabilities {
|
||||
SMB2_GLOBAL_CAP_DFS = 0,
|
||||
SMB2_GLOBAL_CAP_LEASING = 2,
|
||||
SMB2_GLOBAL_CAP_LARGE_MTU = 4,
|
||||
SMB2_GLOBAL_CAP_MULTI_CHANNEL = 8,
|
||||
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES = 10,
|
||||
SMB2_GLOBAL_CAP_DIRECTORY_LEASING = 20,
|
||||
SMB2_GLOBAL_CAP_ENCRYPTION = 40,
|
||||
};
|
||||
|
||||
enum smb3_context_type {
|
||||
SMB2_PREAUTH_INTEGRITY_CAPABILITIES = 0x0001,
|
||||
SMB2_ENCRYPTION_CAPABILITIES = 0x0002,
|
||||
};
|
||||
|
||||
|
||||
refine connection SMB_Conn += {
|
||||
|
||||
function proc_smb2_negotiate_request(h: SMB2_Header, val: SMB2_negotiate_request) : bool
|
||||
|
@ -25,9 +41,21 @@ refine connection SMB_Conn += {
|
|||
|
||||
nr->Assign(0, val_mgr->GetCount(${val.dialect_revision}));
|
||||
nr->Assign(1, val_mgr->GetCount(${val.security_mode}));
|
||||
nr->Assign(2, BuildSMB2GUID(${val.server_guid})),
|
||||
nr->Assign(2, BuildSMB2GUID(${val.server_guid}));
|
||||
nr->Assign(3, filetime2brotime(${val.system_time}));
|
||||
nr->Assign(4, filetime2brotime(${val.server_start_time}));
|
||||
nr->Assign(5, val_mgr->GetCount(${val.negotiate_context_count}));
|
||||
|
||||
VectorVal* cv = new VectorVal(BifType::Vector::SMB2::context_values);
|
||||
int num_context_values = ${val.negotiate_context_count};
|
||||
if (num_context_values > 0) // check if there are context_values, i.e. SMB v.3.1.1
|
||||
for ( int i = 0; i < num_context_values; ++i )
|
||||
{
|
||||
cv->Assign(i, BuildSMB2ContextVal(${val.smb3_ncl[i]}));
|
||||
}
|
||||
|
||||
nr->Assign(6, cv); // empty vector if not SMB v.3.1.1
|
||||
|
||||
BifEvent::generate_smb2_negotiate_response(bro_analyzer(), bro_analyzer()->Conn(),
|
||||
BuildSMB2HeaderVal(h),
|
||||
nr);
|
||||
|
@ -37,14 +65,37 @@ refine connection SMB_Conn += {
|
|||
%}
|
||||
};
|
||||
|
||||
type SMB3_preauth_integrity_capabilities = record {
|
||||
hash_alg_count : uint16;
|
||||
salt_length : uint16;
|
||||
hash_alg : uint16[hash_alg_count];
|
||||
salt : bytestring &length = salt_length; #TODO is a bytestring ok for this field?
|
||||
};
|
||||
|
||||
type SMB3_encryption_capabilities = record {
|
||||
cipher_count : uint16;
|
||||
ciphers : uint16[cipher_count];
|
||||
};
|
||||
|
||||
type SMB3_negotiate_context_values = record {
|
||||
context_type : uint16; # specify the type of context
|
||||
data_length : uint16; # the length of the data field
|
||||
reserved : uint32; # ignored
|
||||
data : case context_type of {
|
||||
SMB2_PREAUTH_INTEGRITY_CAPABILITIES -> preauth_integrity_capabilities : SMB3_preauth_integrity_capabilities;
|
||||
SMB2_ENCRYPTION_CAPABILITIES -> encryption_capabilities : SMB3_encryption_capabilities;
|
||||
};
|
||||
pad : padding align 4;
|
||||
};
|
||||
|
||||
type SMB2_negotiate_request(header: SMB2_Header) = record {
|
||||
structure_size : uint16; # client MUST set this to 36
|
||||
dialect_count : uint16; # must be > 0
|
||||
security_mode : uint16; # there is a list of required modes
|
||||
reserved : padding[2]; # must be set to 0
|
||||
capabilities : uint32; # must be set to 0
|
||||
capabilities : uint32; # must be set to 0 if SMB 2.x, otherwise if SMB 3.x one of enum smb2_capabilities
|
||||
client_guid : SMB2_guid; # guid if client implements SMB 2.1 dialect, otherwise set to 0
|
||||
client_start_time : SMB_timestamp; # must be set to 0
|
||||
client_start_time : SMB_timestamp;
|
||||
dialects : uint16[dialect_count];
|
||||
} &byteorder=littleendian, &let {
|
||||
proc : bool = $context.connection.proc_smb2_negotiate_request(header, this);
|
||||
|
@ -54,7 +105,7 @@ type SMB2_negotiate_response(header: SMB2_Header) = record {
|
|||
structure_size : uint16;
|
||||
security_mode : uint16;
|
||||
dialect_revision : uint16;
|
||||
reserved : padding[2];
|
||||
negotiate_context_count : uint16; # reserved to 0 if not smb 3.1.1
|
||||
server_guid : SMB2_guid;
|
||||
capabilities : uint32;
|
||||
max_transact_size : uint32;
|
||||
|
@ -64,8 +115,14 @@ type SMB2_negotiate_response(header: SMB2_Header) = record {
|
|||
server_start_time : SMB_timestamp;
|
||||
security_offset : uint16;
|
||||
security_length : uint16;
|
||||
negotiate_context_offset : uint32;
|
||||
pad1 : padding to security_offset - header.head_length;
|
||||
security_blob : bytestring &length=security_length;
|
||||
pad2 : padding align 8; # optional padding
|
||||
negotiate_context_list : case dialect_revision of { # check the dialect
|
||||
0x0311 -> smb3_ncl: SMB3_negotiate_context_values[negotiate_context_count]; # if it is v. 3.1.1
|
||||
default -> unknown : empty; # any other version
|
||||
};
|
||||
} &byteorder=littleendian, &let {
|
||||
proc : bool = $context.connection.proc_smb2_negotiate_response(header, this);
|
||||
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false);
|
||||
|
|
|
@ -100,6 +100,48 @@ refine connection SMB_Conn += {
|
|||
std::map<uint64,uint64> smb2_request_tree_id;
|
||||
%}
|
||||
|
||||
function BuildSMB2ContextVal(ncv: SMB3_negotiate_context_values): BroVal
|
||||
%{
|
||||
RecordVal* r = new RecordVal(BifType::Record::SMB2::context_value);
|
||||
|
||||
r->Assign(0, val_mgr->GetCount(${ncv.context_type}));
|
||||
r->Assign(1, val_mgr->GetCount(${ncv.data_length}));
|
||||
|
||||
RecordVal* rpreauth = new RecordVal(BifType::Record::SMB2::preauth);
|
||||
RecordVal* rencr = new RecordVal(BifType::Record::SMB2::encryption);
|
||||
if (${ncv.context_type} == 1) // it is a preauth context type
|
||||
{
|
||||
rpreauth->Assign(0, val_mgr->GetCount(${ncv.preauth_integrity_capabilities.hash_alg_count}));
|
||||
rpreauth->Assign(1, val_mgr->GetCount(${ncv.preauth_integrity_capabilities.salt_length}));
|
||||
|
||||
VectorVal* ha = new VectorVal(internal_type("index_vec")->AsVectorType());
|
||||
for ( int i = 0; i < (${ncv.preauth_integrity_capabilities.hash_alg_count}); ++i )
|
||||
{
|
||||
ha->Assign(i, val_mgr->GetCount(${ncv.preauth_integrity_capabilities.hash_alg[i]}));
|
||||
}
|
||||
|
||||
rpreauth->Assign(2, ha);
|
||||
rpreauth->Assign(3, bytestring_to_val(${ncv.preauth_integrity_capabilities.salt}));
|
||||
}
|
||||
else if (${ncv.context_type} == 2) // it is a encryption context type
|
||||
{
|
||||
rencr->Assign(0, val_mgr->GetCount(${ncv.encryption_capabilities.cipher_count}));
|
||||
|
||||
VectorVal* c = new VectorVal(internal_type("index_vec")->AsVectorType());
|
||||
for ( int i = 0; i < (${ncv.encryption_capabilities.cipher_count}); ++i )
|
||||
{
|
||||
c->Assign(i, val_mgr->GetCount(${ncv.encryption_capabilities.ciphers[i]}));
|
||||
}
|
||||
|
||||
rencr->Assign(1, c);
|
||||
}
|
||||
|
||||
r->Assign(2, rpreauth);
|
||||
r->Assign(3, rencr);
|
||||
|
||||
return r;
|
||||
%}
|
||||
|
||||
function BuildSMB2HeaderVal(hdr: SMB2_Header): BroVal
|
||||
%{
|
||||
RecordVal* r = new RecordVal(BifType::Record::SMB2::Header);
|
||||
|
|
|
@ -5,3 +5,8 @@ type SMB1::Header: record;
|
|||
type SMB2::Header: record;
|
||||
type SMB2::GUID: record;
|
||||
type SMB2::FileAttrs: record;
|
||||
|
||||
type SMB2::preauth: record;
|
||||
type SMB2::encryption: record;
|
||||
type SMB2::context_value: record;
|
||||
type SMB2::context_values: vector;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue