smb3.1.1 additions to negotiate-response command

This commit is contained in:
mauro 2019-02-04 17:05:50 +01:00
parent 1ee96516e8
commit 4330b7922c
7 changed files with 180 additions and 27 deletions

@ -1 +1 @@
Subproject commit bf734622dceaafaf7a481185efd22bd7cc805f9b Subproject commit c7b1dfd38ec6c42729f8c462eef6457a8dd948b6

2
doc

@ -1 +1 @@
Subproject commit 5acafa0d340a6f4096dccbe69b8fb62d7c9ce87f Subproject commit c0092fab7b28c029eddb6b9b654f6096d8e4456a

View file

@ -3226,6 +3226,49 @@ export {
attrs : SMB2::FileAttrs; 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 ## 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. ## what dialects of the SMB2 protocol the client understands.
## ##
@ -3244,6 +3287,11 @@ export {
system_time : time; system_time : time;
## The SMB2 server start time. ## The SMB2 server start time.
server_start_time : 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 ## The request sent by the client to request a new authenticated session
@ -3327,6 +3375,7 @@ export {
## The action taken in establishing the open. ## The action taken in establishing the open.
create_action : count; create_action : count;
}; };
} }
module GLOBAL; module GLOBAL;

@ -1 +1 @@
Subproject commit 6e93c5546a4770d513fb57213d7b29e39e12bf4d Subproject commit b822eeed58c4a1ee3781f1f8c8a19fd590dc4a04

View file

@ -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 += { refine connection SMB_Conn += {
function proc_smb2_negotiate_request(h: SMB2_Header, val: SMB2_negotiate_request) : bool 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(0, val_mgr->GetCount(${val.dialect_revision}));
nr->Assign(1, val_mgr->GetCount(${val.security_mode})); 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(3, filetime2brotime(${val.system_time}));
nr->Assign(4, filetime2brotime(${val.server_start_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(), BifEvent::generate_smb2_negotiate_response(bro_analyzer(), bro_analyzer()->Conn(),
BuildSMB2HeaderVal(h), BuildSMB2HeaderVal(h),
nr); 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 { type SMB2_negotiate_request(header: SMB2_Header) = record {
structure_size : uint16; # client MUST set this to 36 structure_size : uint16; # client MUST set this to 36
dialect_count : uint16; # must be > 0 dialect_count : uint16; # must be > 0
security_mode : uint16; # there is a list of required modes security_mode : uint16; # there is a list of required modes
reserved : padding[2]; # must be set to 0 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_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]; dialects : uint16[dialect_count];
} &byteorder=littleendian, &let { } &byteorder=littleendian, &let {
proc : bool = $context.connection.proc_smb2_negotiate_request(header, this); 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; structure_size : uint16;
security_mode : uint16; security_mode : uint16;
dialect_revision : uint16; dialect_revision : uint16;
reserved : padding[2]; negotiate_context_count : uint16; # reserved to 0 if not smb 3.1.1
server_guid : SMB2_guid; server_guid : SMB2_guid;
capabilities : uint32; capabilities : uint32;
max_transact_size : uint32; max_transact_size : uint32;
@ -64,8 +115,14 @@ type SMB2_negotiate_response(header: SMB2_Header) = record {
server_start_time : SMB_timestamp; server_start_time : SMB_timestamp;
security_offset : uint16; security_offset : uint16;
security_length : uint16; security_length : uint16;
negotiate_context_offset : uint32;
pad1 : padding to security_offset - header.head_length; pad1 : padding to security_offset - header.head_length;
security_blob : bytestring &length=security_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 { } &byteorder=littleendian, &let {
proc : bool = $context.connection.proc_smb2_negotiate_response(header, this); proc : bool = $context.connection.proc_smb2_negotiate_response(header, this);
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false); gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false);

View file

@ -100,6 +100,48 @@ refine connection SMB_Conn += {
std::map<uint64,uint64> smb2_request_tree_id; 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 function BuildSMB2HeaderVal(hdr: SMB2_Header): BroVal
%{ %{
RecordVal* r = new RecordVal(BifType::Record::SMB2::Header); RecordVal* r = new RecordVal(BifType::Record::SMB2::Header);

View file

@ -5,3 +5,8 @@ type SMB1::Header: record;
type SMB2::Header: record; type SMB2::Header: record;
type SMB2::GUID: record; type SMB2::GUID: record;
type SMB2::FileAttrs: record; type SMB2::FileAttrs: record;
type SMB2::preauth: record;
type SMB2::encryption: record;
type SMB2::context_value: record;
type SMB2::context_values: vector;