mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Complete breakout of SMB, GSSAPI, and NTLM
- Looser coupling between these analyzers. - New ntlm.log (still pretty early) - Improved string handling for NTLM (convert UTF16 to UTF8) - SMB2 analyzer now supports GSSAPI. - Improved abstraction of DCE_RPC operations (still not finished) - Lots of whitespace cleanup.
This commit is contained in:
parent
ff3437d157
commit
5b5589e167
22 changed files with 446 additions and 926 deletions
|
@ -2315,18 +2315,10 @@ type ntp_msg: record {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module SMB;
|
module NTLM;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
## MAC times for a file.
|
type NTLM::Version: record {
|
||||||
type SMB::MACTimes: record {
|
|
||||||
modified : time &log;
|
|
||||||
accessed : time &log;
|
|
||||||
created : time &log;
|
|
||||||
changed : time &log;
|
|
||||||
} &log;
|
|
||||||
|
|
||||||
type SMB::NTLMVersion: record {
|
|
||||||
## The major version of the Windows operating system in use
|
## The major version of the Windows operating system in use
|
||||||
major : count;
|
major : count;
|
||||||
## The minor version of the Windows operating system in use
|
## The minor version of the Windows operating system in use
|
||||||
|
@ -2337,7 +2329,7 @@ export {
|
||||||
ntlmssp : count;
|
ntlmssp : count;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB::NTLMNegotiateFlags: record {
|
type NTLM::NegotiateFlags: record {
|
||||||
## If set, requires 56-bit encryption
|
## If set, requires 56-bit encryption
|
||||||
negotiate_56 : bool;
|
negotiate_56 : bool;
|
||||||
## If set, requests an explicit key exchange
|
## If set, requests an explicit key exchange
|
||||||
|
@ -2349,7 +2341,6 @@ export {
|
||||||
## If set, indicates that the TargetInfo fields in the
|
## If set, indicates that the TargetInfo fields in the
|
||||||
## CHALLENGE_MESSAGE are populated
|
## CHALLENGE_MESSAGE are populated
|
||||||
negotiate_target_info : bool;
|
negotiate_target_info : bool;
|
||||||
|
|
||||||
## If set, requests the usage of the LMOWF function
|
## If set, requests the usage of the LMOWF function
|
||||||
request_non_nt_session_key : bool;
|
request_non_nt_session_key : bool;
|
||||||
## If set, requests and identify level token
|
## If set, requests and identify level token
|
||||||
|
@ -2393,18 +2384,18 @@ export {
|
||||||
negotiate_unicode : bool;
|
negotiate_unicode : bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB::NTLMNegotiate: record {
|
type NTLM::Negotiate: record {
|
||||||
## The negotiate flags
|
## The negotiate flags
|
||||||
flags : SMB::NTLMNegotiateFlags;
|
flags : NTLM::NegotiateFlags;
|
||||||
## The domain name of the client, if known
|
## The domain name of the client, if known
|
||||||
domain_name : string &optional;
|
domain_name : string &optional;
|
||||||
## The machine name of the client, if known
|
## The machine name of the client, if known
|
||||||
workstation : string &optional;
|
workstation : string &optional;
|
||||||
## The Windows version information, if supplied
|
## The Windows version information, if supplied
|
||||||
version : SMB::NTLMVersion &optional;
|
version : NTLM::Version &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB::NTLMAVs: record {
|
type NTLM::AVs: record {
|
||||||
## The server's NetBIOS computer name
|
## The server's NetBIOS computer name
|
||||||
nb_computer_name : string;
|
nb_computer_name : string;
|
||||||
## The server's NetBIOS domain name
|
## The server's NetBIOS domain name
|
||||||
|
@ -2422,7 +2413,7 @@ export {
|
||||||
## The associated timestamp, if present
|
## The associated timestamp, if present
|
||||||
timestamp : time &optional;
|
timestamp : time &optional;
|
||||||
## Indicates that the client is providing
|
## Indicates that the client is providing
|
||||||
## mess achine ID created at computer startup to
|
## a machine ID created at computer startup to
|
||||||
## identify the calling machine
|
## identify the calling machine
|
||||||
single_host_id : count &optional;
|
single_host_id : count &optional;
|
||||||
|
|
||||||
|
@ -2430,23 +2421,23 @@ export {
|
||||||
target_name : string &optional;
|
target_name : string &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB::NTLMChallenge: record {
|
type NTLM::Challenge: record {
|
||||||
## The negotiate flags
|
## The negotiate flags
|
||||||
flags : SMB::NTLMNegotiateFlags;
|
flags : NTLM::NegotiateFlags;
|
||||||
## The server authentication realm. If the server is
|
## The server authentication realm. If the server is
|
||||||
## domain-joined, the name of the domain. Otherwise
|
## domain-joined, the name of the domain. Otherwise
|
||||||
## the server name. See flags.target_type_domain
|
## the server name. See flags.target_type_domain
|
||||||
## and flags.target_type_server
|
## and flags.target_type_server
|
||||||
target_name : string &optional;
|
target_name : string &optional;
|
||||||
## The Windows version information, if supplied
|
## The Windows version information, if supplied
|
||||||
version : SMB::NTLMVersion &optional;
|
version : NTLM::Version &optional;
|
||||||
## Attribute-value pairs specified by the server
|
## Attribute-value pairs specified by the server
|
||||||
target_info : SMB::NTLMAVs &optional;
|
target_info : NTLM::AVs &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB::NTLMAuthenticate: record {
|
type NTLM::Authenticate: record {
|
||||||
## The negotiate flags
|
## The negotiate flags
|
||||||
flags : SMB::NTLMNegotiateFlags;
|
flags : NTLM::NegotiateFlags;
|
||||||
## The domain or computer name hosting the account
|
## The domain or computer name hosting the account
|
||||||
domain_name : string;
|
domain_name : string;
|
||||||
## The name of the user to be authenticated.
|
## The name of the user to be authenticated.
|
||||||
|
@ -2454,9 +2445,20 @@ export {
|
||||||
## The name of the computer to which the user was logged on.
|
## The name of the computer to which the user was logged on.
|
||||||
workstation : string;
|
workstation : string;
|
||||||
## The Windows version information, if supplied
|
## The Windows version information, if supplied
|
||||||
version : SMB::NTLMVersion &optional;
|
version : NTLM::Version &optional;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module SMB;
|
||||||
|
|
||||||
|
export {
|
||||||
|
## MAC times for a file.
|
||||||
|
type SMB::MACTimes: record {
|
||||||
|
modified : time &log;
|
||||||
|
accessed : time &log;
|
||||||
|
created : time &log;
|
||||||
|
changed : time &log;
|
||||||
|
} &log;
|
||||||
}
|
}
|
||||||
|
|
||||||
module SMB1;
|
module SMB1;
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
@load base/protocols/krb
|
@load base/protocols/krb
|
||||||
@load base/protocols/modbus
|
@load base/protocols/modbus
|
||||||
@load base/protocols/mysql
|
@load base/protocols/mysql
|
||||||
|
@load base/protocols/ntlm
|
||||||
@load base/protocols/pop3
|
@load base/protocols/pop3
|
||||||
@load base/protocols/radius
|
@load base/protocols/radius
|
||||||
@load base/protocols/rdp
|
@load base/protocols/rdp
|
||||||
|
|
1
scripts/base/protocols/ntlm/__load__.bro
Normal file
1
scripts/base/protocols/ntlm/__load__.bro
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@load ./main
|
54
scripts/base/protocols/ntlm/main.bro
Normal file
54
scripts/base/protocols/ntlm/main.bro
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
module NTLM;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
|
type Info: record {
|
||||||
|
## Timestamp for when the event happened.
|
||||||
|
ts : time &log;
|
||||||
|
## Unique ID for the connection.
|
||||||
|
uid : string &log;
|
||||||
|
## The connection's 4-tuple of endpoint addresses/ports.
|
||||||
|
id : conn_id &log;
|
||||||
|
|
||||||
|
username: string &log &optional;
|
||||||
|
hostname: string &log &optional;
|
||||||
|
domainname: string &log &optional;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
redef record connection += {
|
||||||
|
ntlm: Info &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
event bro_init() &priority=5
|
||||||
|
{
|
||||||
|
Log::create_stream(NTLM::LOG, [$columns=Info, $path="ntlm"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
event ntlm_negotiate(c: connection, request: NTLM::Negotiate) &priority=5
|
||||||
|
{
|
||||||
|
#print request;
|
||||||
|
}
|
||||||
|
|
||||||
|
event ntlm_challenge(c: connection, challenge: NTLM::Challenge) &priority=5
|
||||||
|
{
|
||||||
|
#print "challenge!!!!!";
|
||||||
|
#print challenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=5
|
||||||
|
{
|
||||||
|
c$ntlm = NTLM::Info($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||||
|
if ( request?$domain_name )
|
||||||
|
c$ntlm$domainname = request$domain_name;
|
||||||
|
if ( request?$workstation )
|
||||||
|
c$ntlm$hostname = request$workstation;
|
||||||
|
if ( request?$user_name )
|
||||||
|
c$ntlm$username = request$user_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=-5
|
||||||
|
{
|
||||||
|
Log::write(NTLM::LOG, c$ntlm);
|
||||||
|
}
|
|
@ -281,51 +281,6 @@ event smb1_session_setup_andx_response(c: connection, hdr: SMB1::Header, respons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event smb_ntlm_negotiate(c: connection, hdr: SMB1::Header, request: SMB::NTLMNegotiate)
|
|
||||||
{
|
|
||||||
c$smb_state$current_cmd$sub_command = "NTLMSSP_NEGOTIATE";
|
|
||||||
}
|
|
||||||
|
|
||||||
event smb_ntlm_authenticate(c: connection, hdr: SMB1::Header, request: SMB::NTLMAuthenticate) &priority=5
|
|
||||||
{
|
|
||||||
c$smb_state$current_cmd$sub_command = "NTLMSSP_AUTHENTICATE";
|
|
||||||
|
|
||||||
c$smb_state$current_auth = SMB::AuthInfo($ts=network_time(), $uid=c$uid, $id=c$id);
|
|
||||||
if ( request?$domain_name )
|
|
||||||
c$smb_state$current_auth$domainname = request$domain_name;
|
|
||||||
if ( request?$workstation )
|
|
||||||
c$smb_state$current_auth$hostname = request$workstation;
|
|
||||||
if ( request?$user_name )
|
|
||||||
c$smb_state$current_auth$username = request$user_name;
|
|
||||||
|
|
||||||
local user: string = "";
|
|
||||||
if ( ( request?$domain_name && request$domain_name != "" ) && ( request?$user_name && request$user_name != "" ) )
|
|
||||||
user = fmt("%s\\%s", request$domain_name, request$user_name);
|
|
||||||
else if ( ( request?$workstation && request$workstation != "" ) && ( request?$user_name && request$user_name != "" ) )
|
|
||||||
user = fmt("%s\\%s", request$workstation, request$user_name);
|
|
||||||
else if ( request?$user_name && request$user_name != "" )
|
|
||||||
user = request$user_name;
|
|
||||||
else if ( request?$domain_name && request$domain_name != "" )
|
|
||||||
user = fmt("%s\\", request$domain_name);
|
|
||||||
else if ( request?$workstation && request$workstation != "" )
|
|
||||||
user = fmt("%s", request$workstation);
|
|
||||||
|
|
||||||
if ( user != "" )
|
|
||||||
{
|
|
||||||
c$smb_state$current_cmd$argument = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( hdr$uid !in c$smb_state$uid_map )
|
|
||||||
{
|
|
||||||
c$smb_state$uid_map[hdr$uid] = user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event smb_ntlm_authenticate(c: connection, hdr: SMB1::Header, request: SMB::NTLMAuthenticate) &priority=5
|
|
||||||
{
|
|
||||||
Log::write(SMB::AUTH_LOG, c$smb_state$current_auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
event smb1_transaction_request(c: connection, hdr: SMB1::Header, name: string, sub_cmd: count)
|
event smb1_transaction_request(c: connection, hdr: SMB1::Header, name: string, sub_cmd: count)
|
||||||
{
|
{
|
||||||
c$smb_state$current_cmd$sub_command = SMB1::trans_sub_commands[sub_cmd];
|
c$smb_state$current_cmd$sub_command = SMB1::trans_sub_commands[sub_cmd];
|
||||||
|
|
|
@ -12,6 +12,7 @@ add_subdirectory(file)
|
||||||
add_subdirectory(finger)
|
add_subdirectory(finger)
|
||||||
add_subdirectory(ftp)
|
add_subdirectory(ftp)
|
||||||
add_subdirectory(gnutella)
|
add_subdirectory(gnutella)
|
||||||
|
add_subdirectory(gssapi)
|
||||||
add_subdirectory(gtpv1)
|
add_subdirectory(gtpv1)
|
||||||
add_subdirectory(http)
|
add_subdirectory(http)
|
||||||
add_subdirectory(icmp)
|
add_subdirectory(icmp)
|
||||||
|
@ -25,6 +26,7 @@ add_subdirectory(modbus)
|
||||||
add_subdirectory(mysql)
|
add_subdirectory(mysql)
|
||||||
add_subdirectory(ncp)
|
add_subdirectory(ncp)
|
||||||
add_subdirectory(netbios)
|
add_subdirectory(netbios)
|
||||||
|
add_subdirectory(ntlm)
|
||||||
add_subdirectory(ntp)
|
add_subdirectory(ntp)
|
||||||
add_subdirectory(pia)
|
add_subdirectory(pia)
|
||||||
add_subdirectory(pop3)
|
add_subdirectory(pop3)
|
||||||
|
|
|
@ -10,7 +10,9 @@ bro_plugin_pac(
|
||||||
dce_rpc.pac
|
dce_rpc.pac
|
||||||
dce_rpc-protocol.pac
|
dce_rpc-protocol.pac
|
||||||
dce_rpc-analyzer.pac
|
dce_rpc-analyzer.pac
|
||||||
|
dce_rpc-gssapi.pac
|
||||||
|
endpoint-atsvc.pac
|
||||||
endpoint-epmapper.pac
|
endpoint-epmapper.pac
|
||||||
endpoint-atsvc.pac)
|
)
|
||||||
bro_plugin_end()
|
bro_plugin_end()
|
||||||
|
|
||||||
|
|
42
src/analyzer/protocol/dce-rpc/dce_rpc-gssapi.pac
Normal file
42
src/analyzer/protocol/dce-rpc/dce_rpc-gssapi.pac
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
refine connection DCE_RPC_Conn += {
|
||||||
|
%member{
|
||||||
|
analyzer::Analyzer *gssapi;
|
||||||
|
analyzer::Analyzer *ntlm;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%init{
|
||||||
|
gssapi = analyzer_mgr->InstantiateAnalyzer("GSSAPI", bro_analyzer->Conn());
|
||||||
|
ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer->Conn());
|
||||||
|
%}
|
||||||
|
|
||||||
|
%cleanup{
|
||||||
|
if ( gssapi )
|
||||||
|
delete gssapi;
|
||||||
|
if ( ntlm )
|
||||||
|
delete ntlm;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function forward_auth(auth: DCE_RPC_Auth, is_orig: bool): bool
|
||||||
|
%{
|
||||||
|
switch ( ${auth.type} )
|
||||||
|
{
|
||||||
|
case 0x0a:
|
||||||
|
if ( ntlm )
|
||||||
|
ntlm->DeliverStream(${auth.blob}.length(), ${auth.blob}.begin(), is_orig);
|
||||||
|
break;
|
||||||
|
//case 0xXX:
|
||||||
|
// if ( gssapi )
|
||||||
|
// gssapi->DeliverStream(${data}.length(), ${data}.begin(), is_orig);
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
bro_analyzer()->Weird(fmt("unknown_dce_rpc_auth_type_%d",${auth.type}));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr DCE_RPC_Auth += &let {
|
||||||
|
proc = $context.connection.forward_auth(this, true);
|
||||||
|
}
|
|
@ -23,5 +23,6 @@ flow DCE_RPC_Flow(is_orig: bool) {
|
||||||
flowunit = DCE_RPC_PDU(is_orig) withcontext(connection, this);
|
flowunit = DCE_RPC_PDU(is_orig) withcontext(connection, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
%include epmapper.pac
|
%include endpoint-atsvc.pac
|
||||||
|
%include endpoint-epmapper.pac
|
||||||
%include dce_rpc-analyzer.pac
|
%include dce_rpc-analyzer.pac
|
||||||
|
|
|
@ -1,38 +1,41 @@
|
||||||
type ATSVC_Request(unicode: bool, opnum: uint8) = record {
|
#%include ../smb/smb-strings.pac
|
||||||
empty: padding[1];
|
#
|
||||||
op: case opnum of {
|
#type ATSVC_Request(unicode: bool, opnum: uint8) = record {
|
||||||
0 -> add : ATSVC_NetrJobAdd(unicode);
|
# empty: padding[1];
|
||||||
default -> unknown : bytestring &restofdata;
|
# op: case opnum of {
|
||||||
};
|
# 0 -> add : ATSVC_NetrJobAdd(unicode);
|
||||||
};
|
# default -> unknown : bytestring &restofdata;
|
||||||
|
# };
|
||||||
type ATSVC_String_Pointer(unicode: bool) = record {
|
#};
|
||||||
referent_id : uint32;
|
#
|
||||||
max_count : uint32;
|
#type ATSVC_String_Pointer(unicode: bool) = record {
|
||||||
offset : uint32;
|
# referent_id : uint32;
|
||||||
actual_count : uint32;
|
# max_count : uint32;
|
||||||
string : SMB_string(unicode, offsetof(string));
|
# offset : uint32;
|
||||||
};
|
# actual_count : uint32;
|
||||||
|
# string : SMB_string(unicode, offsetof(string));
|
||||||
type ATSVC_NetrJobAdd(unicode: bool) = record {
|
#};
|
||||||
server : ATSVC_String_Pointer(unicode);
|
#
|
||||||
unknown : padding[2];
|
#type ATSVC_NetrJobAdd(unicode: bool) = record {
|
||||||
job_time : uint32;
|
# server : ATSVC_String_Pointer(unicode);
|
||||||
days_of_month : uint32;
|
# unknown : padding[2];
|
||||||
days_of_week : uint8;
|
# job_time : uint32;
|
||||||
flags : uint8;
|
# days_of_month : uint32;
|
||||||
unknown2 : padding[2];
|
# days_of_week : uint8;
|
||||||
command : ATSVC_String_Pointer(unicode);
|
# flags : uint8;
|
||||||
};
|
# unknown2 : padding[2];
|
||||||
|
# command : ATSVC_String_Pointer(unicode);
|
||||||
type ATSVC_Reply(unicode: bool, opnum: uint16) = record {
|
#};
|
||||||
op: case opnum of {
|
#
|
||||||
0 -> add: ATSVC_JobID(unicode);
|
#type ATSVC_Reply(unicode: bool, opnum: uint16) = record {
|
||||||
default -> unknown: bytestring &restofdata;
|
# op: case opnum of {
|
||||||
};
|
# 0 -> add: ATSVC_JobID(unicode);
|
||||||
};
|
# default -> unknown: bytestring &restofdata;
|
||||||
|
# };
|
||||||
type ATSVC_JobID(unicode: bool) = record {
|
#};
|
||||||
id : uint32;
|
#
|
||||||
status : uint32;
|
#type ATSVC_JobID(unicode: bool) = record {
|
||||||
};
|
# id : uint32;
|
||||||
|
# status : uint32;
|
||||||
|
#};
|
||||||
|
#
|
|
@ -6,9 +6,6 @@ include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR}/../dce-rpc)
|
||||||
bro_plugin_begin(Bro SMB)
|
bro_plugin_begin(Bro SMB)
|
||||||
bro_plugin_cc(SMB.cc Plugin.cc)
|
bro_plugin_cc(SMB.cc Plugin.cc)
|
||||||
bro_plugin_bif(
|
bro_plugin_bif(
|
||||||
smb_ntlmssp.bif
|
|
||||||
smb_pipe.bif
|
|
||||||
|
|
||||||
smb1_com_check_directory.bif
|
smb1_com_check_directory.bif
|
||||||
smb1_com_close.bif
|
smb1_com_close.bif
|
||||||
smb1_com_create_directory.bif
|
smb1_com_create_directory.bif
|
||||||
|
@ -40,6 +37,7 @@ bro_plugin_bif(
|
||||||
smb2_com_write.bif
|
smb2_com_write.bif
|
||||||
smb2_events.bif
|
smb2_events.bif
|
||||||
|
|
||||||
|
smb_pipe.bif
|
||||||
types.bif)
|
types.bif)
|
||||||
bro_plugin_pac(
|
bro_plugin_pac(
|
||||||
smb.pac
|
smb.pac
|
||||||
|
@ -47,8 +45,8 @@ bro_plugin_pac(
|
||||||
smb-strings.pac
|
smb-strings.pac
|
||||||
smb-time.pac
|
smb-time.pac
|
||||||
smb-pipe.pac
|
smb-pipe.pac
|
||||||
|
smb-gssapi.pac
|
||||||
smb-mailslot.pac
|
smb-mailslot.pac
|
||||||
smb-ntlmssp.pac
|
|
||||||
|
|
||||||
smb1-protocol.pac
|
smb1-protocol.pac
|
||||||
smb1-com-check-directory.pac
|
smb1-com-check-directory.pac
|
||||||
|
|
|
@ -10,14 +10,6 @@
|
||||||
|
|
||||||
namespace analyzer { namespace smb {
|
namespace analyzer { namespace smb {
|
||||||
|
|
||||||
enum IPC_named_pipe {
|
|
||||||
IPC_NONE,
|
|
||||||
IPC_LOCATOR,
|
|
||||||
IPC_EPMAPPER,
|
|
||||||
IPC_SAMR, // Security Account Manager
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Contents_SMB : public tcp::TCP_SupportAnalyzer {
|
class Contents_SMB : public tcp::TCP_SupportAnalyzer {
|
||||||
public:
|
public:
|
||||||
Contents_SMB(Connection* conn, bool orig);
|
Contents_SMB(Connection* conn, bool orig);
|
||||||
|
|
11
src/analyzer/protocol/smb/smb-gssapi.pac
Normal file
11
src/analyzer/protocol/smb/smb-gssapi.pac
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
refine connection SMB_Conn += {
|
||||||
|
|
||||||
|
function forward_gssapi(data: bytestring, is_orig: bool): bool
|
||||||
|
%{
|
||||||
|
if ( gssapi )
|
||||||
|
gssapi->DeliverStream(${data}.length(), ${data}.begin(), is_orig);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
|
@ -1,57 +0,0 @@
|
||||||
# Supporting types for ASN.1
|
|
||||||
#
|
|
||||||
# From the Kerberos analyzer
|
|
||||||
#
|
|
||||||
# TODO: Figure out a way to include this code only once.
|
|
||||||
|
|
||||||
type ASN1Encoding = record {
|
|
||||||
meta: ASN1EncodingMeta;
|
|
||||||
content: bytestring &length = meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ASN1EncodingMeta = record {
|
|
||||||
tag: uint8;
|
|
||||||
len: uint8;
|
|
||||||
more_len: bytestring &length = long_len ? len & 0x7f : 0;
|
|
||||||
} &let {
|
|
||||||
long_len: bool = len & 0x80;
|
|
||||||
length: uint64 = long_len ? binary_to_int64(more_len) : len & 0x7f;
|
|
||||||
index: uint8 = tag - 160;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ASN1Integer = record {
|
|
||||||
encoding: ASN1Encoding;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ASN1OctetString = record {
|
|
||||||
encoding: ASN1Encoding;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SequenceElement(grab_content: bool) = record {
|
|
||||||
index_meta: ASN1EncodingMeta;
|
|
||||||
have_content: case grab_content of {
|
|
||||||
true -> data: ASN1Encoding;
|
|
||||||
false -> meta: ASN1EncodingMeta;
|
|
||||||
};
|
|
||||||
} &let {
|
|
||||||
index: uint8 = index_meta.index;
|
|
||||||
length: uint64 = index_meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Array = record {
|
|
||||||
array_meta: ASN1EncodingMeta;
|
|
||||||
data: ASN1Encoding[];
|
|
||||||
};
|
|
||||||
|
|
||||||
function binary_to_int64(bs: bytestring): int64
|
|
||||||
%{
|
|
||||||
int64 rval = 0;
|
|
||||||
|
|
||||||
for ( int i = 0; i < bs.length(); ++i )
|
|
||||||
{
|
|
||||||
uint64 byte = bs[i];
|
|
||||||
rval |= byte << (8 * (bs.length() - (i + 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
%}
|
|
|
@ -1,430 +0,0 @@
|
||||||
refine connection SMB_Conn += {
|
|
||||||
function build_negotiate_flag_record(val: SMB_NTLM_Negotiate_Flags): BroVal
|
|
||||||
%{
|
|
||||||
RecordVal* flags = new RecordVal(BifType::Record::SMB::NTLMNegotiateFlags);
|
|
||||||
flags->Assign(0, new Val(${val.negotiate_56}, TYPE_BOOL));
|
|
||||||
flags->Assign(1, new Val(${val.negotiate_key_exch}, TYPE_BOOL));
|
|
||||||
flags->Assign(2, new Val(${val.negotiate_128}, TYPE_BOOL));
|
|
||||||
flags->Assign(3, new Val(${val.negotiate_version}, TYPE_BOOL));
|
|
||||||
flags->Assign(4, new Val(${val.negotiate_target_info}, TYPE_BOOL));
|
|
||||||
|
|
||||||
flags->Assign(5, new Val(${val.request_non_nt_session_key}, TYPE_BOOL));
|
|
||||||
flags->Assign(6, new Val(${val.negotiate_identify}, TYPE_BOOL));
|
|
||||||
flags->Assign(7, new Val(${val.negotiate_extended_sessionsecurity}, TYPE_BOOL));
|
|
||||||
flags->Assign(8, new Val(${val.target_type_server}, TYPE_BOOL));
|
|
||||||
flags->Assign(9, new Val(${val.target_type_domain}, TYPE_BOOL));
|
|
||||||
|
|
||||||
flags->Assign(10, new Val(${val.negotiate_always_sign}, TYPE_BOOL));
|
|
||||||
flags->Assign(11, new Val(${val.negotiate_oem_workstation_supplied}, TYPE_BOOL));
|
|
||||||
flags->Assign(12, new Val(${val.negotiate_oem_domain_supplied}, TYPE_BOOL));
|
|
||||||
flags->Assign(13, new Val(${val.negotiate_anonymous_connection}, TYPE_BOOL));
|
|
||||||
flags->Assign(14, new Val(${val.negotiate_ntlm}, TYPE_BOOL));
|
|
||||||
|
|
||||||
flags->Assign(15, new Val(${val.negotiate_lm_key}, TYPE_BOOL));
|
|
||||||
flags->Assign(16, new Val(${val.negotiate_datagram}, TYPE_BOOL));
|
|
||||||
flags->Assign(17, new Val(${val.negotiate_seal}, TYPE_BOOL));
|
|
||||||
flags->Assign(18, new Val(${val.negotiate_sign}, TYPE_BOOL));
|
|
||||||
flags->Assign(19, new Val(${val.request_target}, TYPE_BOOL));
|
|
||||||
|
|
||||||
flags->Assign(20, new Val(${val.negotiate_oem}, TYPE_BOOL));
|
|
||||||
flags->Assign(21, new Val(${val.negotiate_unicode}, TYPE_BOOL));
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function build_version_record(val: SMB_NTLM_Version): BroVal
|
|
||||||
%{
|
|
||||||
RecordVal* result = new RecordVal(BifType::Record::SMB::NTLMVersion);
|
|
||||||
result->Assign(0, new Val(${val.major_version}, TYPE_COUNT));
|
|
||||||
result->Assign(1, new Val(${val.minor_version}, TYPE_COUNT));
|
|
||||||
result->Assign(2, new Val(${val.build_number}, TYPE_COUNT));
|
|
||||||
result->Assign(3, new Val(${val.ntlm_revision}, TYPE_COUNT));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function build_av_record(val: SMB_NTLM_AV_Pair_Sequence): BroVal
|
|
||||||
%{
|
|
||||||
RecordVal* result = new RecordVal(BifType::Record::SMB::NTLMAVs);
|
|
||||||
for ( uint i = 0; ${val.pairs[i].id} != 0; i++ )
|
|
||||||
{
|
|
||||||
switch ( ${val.pairs[i].id} )
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
result->Assign(0, uint8s_to_stringval(${val.pairs[i].nb_computer_name.data}));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result->Assign(1, uint8s_to_stringval(${val.pairs[i].nb_domain_name.data}));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result->Assign(2, uint8s_to_stringval(${val.pairs[i].dns_computer_name.data}));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
result->Assign(3, uint8s_to_stringval(${val.pairs[i].dns_domain_name.data}));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result->Assign(4, uint8s_to_stringval(${val.pairs[i].dns_tree_name.data}));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
result->Assign(5, new Val(${val.pairs[i].constrained_auth}, TYPE_BOOL));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result->Assign(6, filetime2brotime(${val.pairs[i].timestamp}));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
result->Assign(7, new Val(${val.pairs[i].single_host.machine_id}, TYPE_COUNT));
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
result->Assign(8, uint8s_to_stringval(${val.pairs[i].target_name.data}));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function proc_smb_ntlm_ssp(header: SMB_Header, val:SMB_NTLM_SSP): bool
|
|
||||||
%{
|
|
||||||
if ( ${val.gssapi.is_init} )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for ( uint i = 0; i < ${val.gssapi.resp.args}->size(); ++i )
|
|
||||||
{
|
|
||||||
switch ( ${val.gssapi.resp.args[i].seq_meta.index} )
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if ( ${val.gssapi.resp.args[i].args.neg_state} == 0 )
|
|
||||||
BifEvent::generate_smb_ntlm_accepted(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function proc_smb_ntlm_negotiate(header: SMB_Header, val: SMB_NTLM_Negotiate): bool
|
|
||||||
%{
|
|
||||||
RecordVal* result = new RecordVal(BifType::Record::SMB::NTLMNegotiate);
|
|
||||||
result->Assign(0, build_negotiate_flag_record(${val.flags}));
|
|
||||||
|
|
||||||
if ( ${val.flags.negotiate_oem_domain_supplied} )
|
|
||||||
result->Assign(1, uint8s_to_stringval(${val.domain_name.string.data}));
|
|
||||||
|
|
||||||
if ( ${val.flags.negotiate_oem_workstation_supplied} )
|
|
||||||
result->Assign(2, uint8s_to_stringval(${val.workstation.string.data}));
|
|
||||||
|
|
||||||
if ( ${val.flags.negotiate_version} )
|
|
||||||
result->Assign(3, build_version_record(${val.version}));
|
|
||||||
|
|
||||||
BifEvent::generate_smb_ntlm_negotiate(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), result);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function proc_smb_ntlm_challenge(header: SMB_Header, val: SMB_NTLM_Challenge): bool
|
|
||||||
%{
|
|
||||||
RecordVal* result = new RecordVal(BifType::Record::SMB::NTLMChallenge);
|
|
||||||
result->Assign(0, build_negotiate_flag_record(${val.flags}));
|
|
||||||
|
|
||||||
if ( ${val.flags.request_target} )
|
|
||||||
result->Assign(1, uint8s_to_stringval(${val.target_name.string.data}));
|
|
||||||
|
|
||||||
if ( ${val.flags.negotiate_version} )
|
|
||||||
result->Assign(2, build_version_record(${val.version}));
|
|
||||||
|
|
||||||
if ( ${val.flags.negotiate_target_info} )
|
|
||||||
result->Assign(3, build_av_record(${val.target_info}));
|
|
||||||
|
|
||||||
BifEvent::generate_smb_ntlm_challenge(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), result);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function proc_smb_ntlm_authenticate(header: SMB_Header, val: SMB_NTLM_Authenticate): bool
|
|
||||||
%{
|
|
||||||
RecordVal* result = new RecordVal(BifType::Record::SMB::NTLMAuthenticate);
|
|
||||||
result->Assign(0, build_negotiate_flag_record(${val.flags}));
|
|
||||||
|
|
||||||
if ( ${val.domain_name_fields.length} > 0 )
|
|
||||||
result->Assign(1, uint8s_to_stringval(${val.domain_name.string.data}));
|
|
||||||
|
|
||||||
if ( ${val.user_name_fields.length} > 0 )
|
|
||||||
result->Assign(2, uint8s_to_stringval(${val.user_name.string.data}));
|
|
||||||
|
|
||||||
if ( ${val.workstation_fields.length} > 0 )
|
|
||||||
result->Assign(3, uint8s_to_stringval(${val.workstation.string.data}));
|
|
||||||
|
|
||||||
if ( ${val.flags.negotiate_version} )
|
|
||||||
result->Assign(4, build_version_record(${val.version}));
|
|
||||||
|
|
||||||
BifEvent::generate_smb_ntlm_authenticate(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), result);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
%}
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN(header: SMB_Header) = record {
|
|
||||||
wrapper : ASN1EncodingMeta;
|
|
||||||
have_oid : case is_init of {
|
|
||||||
true -> oid : ASN1Encoding;
|
|
||||||
false -> no_oid : empty;
|
|
||||||
};
|
|
||||||
have_init_wrapper : case is_init of {
|
|
||||||
true -> init_wrapper : ASN1EncodingMeta;
|
|
||||||
false -> no_init_wrapper : empty;
|
|
||||||
};
|
|
||||||
msg_type : case is_init of {
|
|
||||||
true -> init: GSSAPI_NEG_TOKEN_INIT(header);
|
|
||||||
false -> resp: GSSAPI_NEG_TOKEN_RESP(header);
|
|
||||||
};
|
|
||||||
} &let {
|
|
||||||
is_init: bool = (wrapper.tag == 0x60);
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN_INIT(header: SMB_Header) = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
args : GSSAPI_NEG_TOKEN_INIT_Arg(header)[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN_INIT_Arg(header: SMB_Header) = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
args : GSSAPI_NEG_TOKEN_INIT_Arg_Data(header, seq_meta.index) &length=seq_meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN_INIT_Arg_Data(header: SMB_Header, index: uint8) = case index of {
|
|
||||||
0 -> mech_type_list : ASN1Encoding;
|
|
||||||
1 -> req_flags : ASN1Encoding;
|
|
||||||
2 -> mech_token : SMB_NTLM_SSP_Token(header);
|
|
||||||
3 -> mech_list_mic : ASN1OctetString;
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN_RESP(header: SMB_Header) = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
args : GSSAPI_NEG_TOKEN_RESP_Arg(header)[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN_RESP_Arg(header: SMB_Header) = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
args : GSSAPI_NEG_TOKEN_RESP_Arg_Data(header, seq_meta.index) &length=seq_meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type GSSAPI_NEG_TOKEN_RESP_Arg_Data(header: SMB_Header, index: uint8) = case index of {
|
|
||||||
0 -> neg_state : ASN1Integer;
|
|
||||||
1 -> supported_mech : ASN1Encoding;
|
|
||||||
2 -> response_token : SMB_NTLM_SSP_Token(header);
|
|
||||||
3 -> mech_list_mic : ASN1OctetString;
|
|
||||||
default -> def : bytestring &restofdata &transient;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_SSP(header: SMB_Header) = record {
|
|
||||||
gssapi: GSSAPI_NEG_TOKEN(header);
|
|
||||||
} &let {
|
|
||||||
proc: bool = $context.connection.proc_smb_ntlm_ssp(header, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_SSP_Token(header: SMB_Header) = record {
|
|
||||||
meta : ASN1EncodingMeta;
|
|
||||||
signature : bytestring &length=8;
|
|
||||||
msg_type : uint32;
|
|
||||||
msg : case msg_type of {
|
|
||||||
1 -> negotiate : SMB_NTLM_Negotiate(header, offsetof(msg) - offsetof(signature));
|
|
||||||
2 -> challenge : SMB_NTLM_Challenge(header, offsetof(msg) - offsetof(signature));
|
|
||||||
3 -> authenticate : SMB_NTLM_Authenticate(header, offsetof(msg) - offsetof(signature));
|
|
||||||
default -> def : bytestring &restofdata &transient;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Negotiate(header: SMB_Header, offset: uint16) = record {
|
|
||||||
flags : SMB_NTLM_Negotiate_Flags;
|
|
||||||
domain_name_fields : SMB_NTLM_StringData;
|
|
||||||
workstation_fields : SMB_NTLM_StringData;
|
|
||||||
version_present : case flags.negotiate_version of {
|
|
||||||
true -> version : SMB_NTLM_Version;
|
|
||||||
false -> no_version : empty;
|
|
||||||
};
|
|
||||||
payload : bytestring &restofdata;
|
|
||||||
} &let {
|
|
||||||
absolute_offset : uint16 = offsetof(payload) + offset;
|
|
||||||
domain_name : SMB_NTLM_String(domain_name_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(flags.negotiate_oem_domain_supplied);
|
|
||||||
workstation : SMB_NTLM_String(workstation_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(flags.negotiate_oem_workstation_supplied);
|
|
||||||
|
|
||||||
proc : bool = $context.connection.proc_smb_ntlm_negotiate(header, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Challenge(header: SMB_Header, offset: uint16) = record {
|
|
||||||
target_name_fields : SMB_NTLM_StringData;
|
|
||||||
flags : SMB_NTLM_Negotiate_Flags;
|
|
||||||
challenge : uint64;
|
|
||||||
reserved : padding[8];
|
|
||||||
target_info_fields : SMB_NTLM_StringData;
|
|
||||||
version_present : case flags.negotiate_version of {
|
|
||||||
true -> version : SMB_NTLM_Version;
|
|
||||||
false -> no_version : empty;
|
|
||||||
};
|
|
||||||
payload : bytestring &restofdata;
|
|
||||||
} &let {
|
|
||||||
absolute_offset : uint16 = offsetof(payload) + offset;
|
|
||||||
target_name : SMB_NTLM_String(target_name_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(flags.request_target);
|
|
||||||
target_info : SMB_NTLM_AV_Pair_Sequence(target_info_fields.offset - absolute_offset) withinput payload &if(flags.negotiate_target_info);
|
|
||||||
|
|
||||||
proc : bool = $context.connection.proc_smb_ntlm_challenge(header, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Authenticate(header: SMB_Header, offset: uint16) = record {
|
|
||||||
lm_challenge_response_fields : SMB_NTLM_StringData;
|
|
||||||
nt_challenge_response_fields : SMB_NTLM_StringData;
|
|
||||||
domain_name_fields : SMB_NTLM_StringData;
|
|
||||||
user_name_fields : SMB_NTLM_StringData;
|
|
||||||
workstation_fields : SMB_NTLM_StringData;
|
|
||||||
encrypted_session_key_fields : SMB_NTLM_StringData;
|
|
||||||
flags : SMB_NTLM_Negotiate_Flags;
|
|
||||||
version_present : case flags.negotiate_version of {
|
|
||||||
true -> version : SMB_NTLM_Version;
|
|
||||||
false -> no_version : empty;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Windows NT, 2000, XP, and 2003 don't have the MIC field
|
|
||||||
# TODO - figure out how to parse this for those that do have it
|
|
||||||
# mic : bytestring &length=16;
|
|
||||||
|
|
||||||
payload : bytestring &restofdata;
|
|
||||||
} &let {
|
|
||||||
absolute_offset : uint16 = offsetof(payload) + offset;
|
|
||||||
domain_name : SMB_NTLM_String(domain_name_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(domain_name_fields.length > 0);
|
|
||||||
user_name : SMB_NTLM_String(user_name_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(user_name_fields.length > 0);
|
|
||||||
workstation : SMB_NTLM_String(workstation_fields, absolute_offset , flags.negotiate_unicode) withinput payload &if(workstation_fields.length > 0);
|
|
||||||
encrypted_session_key : SMB_NTLM_String(encrypted_session_key_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(flags.negotiate_key_exch);
|
|
||||||
|
|
||||||
proc : bool = $context.connection.proc_smb_ntlm_authenticate(header, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Version = record {
|
|
||||||
major_version : uint8;
|
|
||||||
minor_version : uint8;
|
|
||||||
build_number : uint16;
|
|
||||||
reserved : padding[3];
|
|
||||||
ntlm_revision : uint8;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_StringData = record {
|
|
||||||
length : uint16;
|
|
||||||
max_length : uint16;
|
|
||||||
offset : uint32;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_Fixed_Length_String(unicode: bool) = record {
|
|
||||||
data: uint8[] &restofdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_String(fields: SMB_NTLM_StringData, offset: uint16, unicode: bool) = record {
|
|
||||||
pad1 : padding to fields.offset - offset;
|
|
||||||
string : SMB_Fixed_Length_String(unicode) &length=fields.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_AV_Pair_Sequence(offset: uint16) = record {
|
|
||||||
pad1 : padding to offset;
|
|
||||||
pairs : SMB_NTLM_AV_Pair[] &until($element.last);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_AV_Pair = record {
|
|
||||||
id : uint16;
|
|
||||||
length : uint16;
|
|
||||||
value_case : case id of {
|
|
||||||
0x0000 -> av_eol : empty;
|
|
||||||
0x0001 -> nb_computer_name : SMB_Fixed_Length_String(true) &length=length;
|
|
||||||
0x0002 -> nb_domain_name : SMB_Fixed_Length_String(true) &length=length;
|
|
||||||
0x0003 -> dns_computer_name : SMB_Fixed_Length_String(true) &length=length;
|
|
||||||
0x0004 -> dns_domain_name : SMB_Fixed_Length_String(true) &length=length;
|
|
||||||
0x0005 -> dns_tree_name : SMB_Fixed_Length_String(true) &length=length;
|
|
||||||
0x0006 -> av_flags : uint32;
|
|
||||||
0x0007 -> timestamp : uint64;
|
|
||||||
0x0008 -> single_host : SMB_NTLM_Single_Host;
|
|
||||||
0x0009 -> target_name : SMB_Fixed_Length_String(true) &length=length;
|
|
||||||
0x000a -> channel_bindings : uint16;
|
|
||||||
};
|
|
||||||
} &let {
|
|
||||||
last : bool = ( id == 0x0000);
|
|
||||||
# av_flags refinement
|
|
||||||
constrained_auth: bool = (av_flags & 0x00000001) > 0 &if ( id == 0x0006);
|
|
||||||
mic_present : bool = (av_flags & 0x00000002) > 0 &if ( id == 0x0006);
|
|
||||||
untrusted_source: bool = (av_flags & 0x00000004) > 0 &if ( id == 0x0006);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Single_Host = record {
|
|
||||||
size : uint32;
|
|
||||||
padpad : padding[4];
|
|
||||||
data_present : uint32;
|
|
||||||
optional : case custom_data_present of {
|
|
||||||
true -> custom_data : bytestring &length=4;
|
|
||||||
false -> nothing : empty;
|
|
||||||
};
|
|
||||||
machine_id : uint32;
|
|
||||||
} &let {
|
|
||||||
custom_data_present: bool = (data_present & 0x00000001) > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_LM_Response(offset: uint16) = record {
|
|
||||||
# This can be either LM (24 byte response) or
|
|
||||||
# LMv2 (16 byte response + 8 byte client challenge. No way to
|
|
||||||
# know for sure.
|
|
||||||
padpad : padding to offset;
|
|
||||||
response : bytestring &length=24;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Response(offset: uint16) = record {
|
|
||||||
padpad : padding to offset;
|
|
||||||
response : bytestring &length=24;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLMv2_Response(flags: SMB_NTLM_Negotiate_Flags, offset: uint16) = record {
|
|
||||||
padpad : padding to offset;
|
|
||||||
response : bytestring &length=16;
|
|
||||||
client_challenge : SMB_NTLMv2_Client_Challenge(flags);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLMv2_Client_Challenge(flags: SMB_NTLM_Negotiate_Flags) = record {
|
|
||||||
resp_type : uint8;
|
|
||||||
max_resp_type : uint8;
|
|
||||||
reserved : padding[6];
|
|
||||||
timestamp : uint64;
|
|
||||||
client_challenge : bytestring &length=8;
|
|
||||||
reserved2 : padding[4];
|
|
||||||
av_pairs : SMB_NTLM_AV_Pair_Sequence(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
type SMB_NTLM_Negotiate_Flags = record {
|
|
||||||
flags: uint32;
|
|
||||||
} &let {
|
|
||||||
negotiate_56 : bool = (flags & 0x80000000) > 0;
|
|
||||||
negotiate_key_exch : bool = (flags & 0x40000000) > 0;
|
|
||||||
negotiate_128 : bool = (flags & 0x20000000) > 0;
|
|
||||||
|
|
||||||
negotiate_version : bool = (flags & 0x02000000) > 0;
|
|
||||||
|
|
||||||
negotiate_target_info : bool = (flags & 0x00800000) > 0;
|
|
||||||
request_non_nt_session_key : bool = (flags & 0x00400000) > 0;
|
|
||||||
negotiate_identify : bool = (flags & 0x00100000) > 0;
|
|
||||||
|
|
||||||
negotiate_extended_sessionsecurity : bool = (flags & 0x00040000) > 0;
|
|
||||||
target_type_server : bool = (flags & 0x00020000) > 0;
|
|
||||||
target_type_domain : bool = (flags & 0x00010000) > 0;
|
|
||||||
|
|
||||||
negotiate_always_sign : bool = (flags & 0x00008000) > 0;
|
|
||||||
negotiate_oem_workstation_supplied : bool = (flags & 0x00002000) > 0;
|
|
||||||
negotiate_oem_domain_supplied : bool = (flags & 0x00001000) > 0;
|
|
||||||
|
|
||||||
negotiate_anonymous_connection : bool = (flags & 0x00000400) > 0;
|
|
||||||
negotiate_ntlm : bool = (flags & 0x00000100) > 0;
|
|
||||||
|
|
||||||
negotiate_lm_key : bool = (flags & 0x00000080) > 0;
|
|
||||||
negotiate_datagram : bool = (flags & 0x00000040) > 0;
|
|
||||||
negotiate_seal : bool = (flags & 0x00000020) > 0;
|
|
||||||
|
|
||||||
negotiate_sign : bool = (flags & 0x00000008) > 0;
|
|
||||||
request_target : bool = (flags & 0x00000004) > 0;
|
|
||||||
negotiate_oem : bool = (flags & 0x00000002) > 0;
|
|
||||||
negotiate_unicode : bool = (flags & 0x00000001) > 0;
|
|
||||||
|
|
||||||
is_oem : bool = !negotiate_unicode && negotiate_oem;
|
|
||||||
is_invalid : bool = !negotiate_unicode && !negotiate_oem;
|
|
||||||
};
|
|
|
@ -4,16 +4,12 @@
|
||||||
%extern{
|
%extern{
|
||||||
#include "analyzer/Manager.h"
|
#include "analyzer/Manager.h"
|
||||||
#include "analyzer/Analyzer.h"
|
#include "analyzer/Analyzer.h"
|
||||||
// #include "analyzer/protocol/dce-rpc/DCE_RPC.h"
|
|
||||||
|
|
||||||
#include "smb1_events.bif.h"
|
#include "smb1_events.bif.h"
|
||||||
#include "smb2_events.bif.h"
|
#include "smb2_events.bif.h"
|
||||||
|
|
||||||
#include "types.bif.h"
|
#include "types.bif.h"
|
||||||
|
|
||||||
#include "smb_ntlmssp.bif.h"
|
|
||||||
#include "smb_pipe.bif.h"
|
|
||||||
|
|
||||||
#include "smb1_com_check_directory.bif.h"
|
#include "smb1_com_check_directory.bif.h"
|
||||||
#include "smb1_com_close.bif.h"
|
#include "smb1_com_close.bif.h"
|
||||||
#include "smb1_com_create_directory.bif.h"
|
#include "smb1_com_create_directory.bif.h"
|
||||||
|
@ -57,9 +53,9 @@ connection SMB_Conn(bro_analyzer: BroAnalyzer) {
|
||||||
%include smb-strings.pac
|
%include smb-strings.pac
|
||||||
%include smb-common.pac
|
%include smb-common.pac
|
||||||
%include smb-time.pac
|
%include smb-time.pac
|
||||||
|
%include smb-mailslot.pac
|
||||||
%include smb-ntlmssp-asn1.pac
|
%include smb-pipe.pac
|
||||||
%include smb-ntlmssp.pac
|
%include smb-gssapi.pac
|
||||||
|
|
||||||
# SMB1 Commands
|
# SMB1 Commands
|
||||||
%include smb1-com-check-directory.pac
|
%include smb1-com-check-directory.pac
|
||||||
|
@ -82,9 +78,6 @@ connection SMB_Conn(bro_analyzer: BroAnalyzer) {
|
||||||
%include smb1-com-tree-disconnect.pac
|
%include smb1-com-tree-disconnect.pac
|
||||||
%include smb1-com-write-andx.pac
|
%include smb1-com-write-andx.pac
|
||||||
|
|
||||||
%include smb-mailslot.pac
|
|
||||||
%include smb-pipe.pac
|
|
||||||
|
|
||||||
# SMB2 Commands
|
# SMB2 Commands
|
||||||
%include smb2-com-close.pac
|
%include smb2-com-close.pac
|
||||||
%include smb2-com-create.pac
|
%include smb2-com-create.pac
|
||||||
|
@ -146,14 +139,18 @@ flow SMB_Flow(is_orig: bool) {
|
||||||
refine connection SMB_Conn += {
|
refine connection SMB_Conn += {
|
||||||
%member{
|
%member{
|
||||||
analyzer::Analyzer *dcerpc;
|
analyzer::Analyzer *dcerpc;
|
||||||
|
analyzer::Analyzer *gssapi;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%init{
|
%init{
|
||||||
dcerpc = analyzer_mgr->InstantiateAnalyzer("DCE_RPC", bro_analyzer->Conn());
|
dcerpc = analyzer_mgr->InstantiateAnalyzer("DCE_RPC", bro_analyzer->Conn());
|
||||||
|
gssapi = analyzer_mgr->InstantiateAnalyzer("GSSAPI", bro_analyzer->Conn());
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%cleanup{
|
%cleanup{
|
||||||
if ( dcerpc )
|
if ( dcerpc )
|
||||||
delete dcerpc;
|
delete dcerpc;
|
||||||
|
if ( gssapi )
|
||||||
|
delete gssapi;
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
|
|
@ -161,7 +161,6 @@ refine connection SMB_Conn += {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ntlm->Assign(12, bytestring_to_val(${val.ntlm.server_guid}));
|
ntlm->Assign(12, bytestring_to_val(${val.ntlm.server_guid}));
|
||||||
// ntlm->Assign(13, bytestring_to_val(${val.ntlm.security_blob}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response->Assign(2, ntlm);
|
response->Assign(2, ntlm);
|
||||||
|
@ -204,78 +203,80 @@ type SMB1_negotiate_core_response = record {
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB1_negotiate_lanman_response(header: SMB_Header) = record {
|
type SMB1_negotiate_lanman_response(header: SMB_Header) = record {
|
||||||
security_flags: uint16; # expanded in &let
|
security_flags : uint16; # expanded in &let
|
||||||
max_buffer_size: uint16;
|
max_buffer_size : uint16;
|
||||||
max_mpx_count: uint16;
|
max_mpx_count : uint16;
|
||||||
max_number_vcs: uint16;
|
max_number_vcs : uint16;
|
||||||
raw_mode: uint16; # expanded in &let
|
raw_mode : uint16; # expanded in &let
|
||||||
session_key: uint32;
|
session_key : uint32;
|
||||||
server_time: SMB_time;
|
server_time : SMB_time;
|
||||||
server_date: SMB_date;
|
server_date : SMB_date;
|
||||||
server_tz: uint16;
|
server_tz : uint16;
|
||||||
encryption_key_length: uint16;
|
encryption_key_length : uint16;
|
||||||
reserved: uint16; # must be zero
|
reserved : uint16; # must be zero
|
||||||
byte_count: uint16; # count of data bytes
|
byte_count : uint16; # count of data bytes
|
||||||
encryption_key: bytestring &length=encryption_key_length;
|
encryption_key : bytestring &length=encryption_key_length;
|
||||||
primary_domain: SMB_string(header.unicode, offsetof(primary_domain));
|
primary_domain : SMB_string(header.unicode, offsetof(primary_domain));
|
||||||
} &let {
|
} &let {
|
||||||
security_user_level: bool = ( security_flags & 0x1 ) > 0;
|
security_user_level : bool = ( security_flags & 0x1 ) > 0;
|
||||||
security_challenge_response: bool = ( security_flags & 0x2 ) > 0;
|
security_challenge_response : bool = ( security_flags & 0x2 ) > 0;
|
||||||
raw_read_supported: bool = ( raw_mode & 0x1 ) > 0;
|
raw_read_supported : bool = ( raw_mode & 0x1 ) > 0;
|
||||||
raw_write_supported: bool = ( raw_mode & 0x2 ) > 0;
|
raw_write_supported : bool = ( raw_mode & 0x2 ) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB1_negotiate_ntlm_response(header: SMB_Header) = record {
|
type SMB1_negotiate_ntlm_response(header: SMB_Header) = record {
|
||||||
security_flags: uint8; # Expanded in &let
|
security_flags : uint8; # Expanded in &let
|
||||||
max_mpx_count: uint16;
|
max_mpx_count : uint16;
|
||||||
max_number_vcs: uint16;
|
max_number_vcs : uint16;
|
||||||
max_buffer_size: uint32;
|
max_buffer_size : uint32;
|
||||||
max_raw_size: uint32;
|
max_raw_size : uint32;
|
||||||
session_key: uint32;
|
session_key : uint32;
|
||||||
capabilities: uint32; # Expanded in &let
|
capabilities : uint32; # Expanded in &let
|
||||||
server_time: uint64;
|
server_time : uint64;
|
||||||
server_tz: uint16;
|
server_tz : uint16;
|
||||||
encryption_key_length: uint8;
|
encryption_key_length : uint8;
|
||||||
byte_count: uint16;
|
byte_count : uint16;
|
||||||
encryption_key_present: case capabilities_extended_security of {
|
encryption_key_present: case capabilities_extended_security of {
|
||||||
false -> encryption_key: bytestring &length=encryption_key_length;
|
false -> encryption_key : bytestring &length=encryption_key_length;
|
||||||
true -> no_key: empty;
|
true -> no_key : empty;
|
||||||
} &requires(capabilities_extended_security);
|
} &requires(capabilities_extended_security);
|
||||||
domain_name_present: case capabilities_extended_security of {
|
domain_name_present: case capabilities_extended_security of {
|
||||||
false -> domain_name: SMB_string(header.unicode, offsetof(domain_name_present));
|
false -> domain_name : SMB_string(header.unicode, offsetof(domain_name_present));
|
||||||
true -> no_name: empty;
|
true -> no_name : empty;
|
||||||
} &requires(capabilities_extended_security);
|
} &requires(capabilities_extended_security);
|
||||||
server_guid_present: case capabilities_extended_security of {
|
server_guid_present: case capabilities_extended_security of {
|
||||||
true -> server_guid: bytestring &length=16;
|
true -> server_guid : bytestring &length=16;
|
||||||
false -> no_guid: empty;
|
false -> no_guid : empty;
|
||||||
} &requires(capabilities_extended_security);
|
} &requires(capabilities_extended_security);
|
||||||
security_blob_present: case capabilities_extended_security of {
|
security_blob_present: case capabilities_extended_security of {
|
||||||
true -> security_blob: SMB_NTLM_SSP(header) &length=(byte_count-16);
|
true -> security_blob : bytestring &length=(byte_count-16);
|
||||||
false -> no_blob: empty;
|
false -> no_blob : empty;
|
||||||
} &requires(capabilities_extended_security);
|
} &requires(capabilities_extended_security);
|
||||||
} &let {
|
} &let {
|
||||||
security_user_level: bool = ( security_flags & 0x1 ) > 0;
|
security_user_level : bool = (security_flags & 0x1) > 0;
|
||||||
security_challenge_response: bool = ( security_flags & 0x2 ) > 0;
|
security_challenge_response : bool = (security_flags & 0x2) > 0;
|
||||||
security_signatures_enabled: bool = ( security_flags & 0x4 ) > 0;
|
security_signatures_enabled : bool = (security_flags & 0x4) > 0;
|
||||||
security_signatures_required: bool = ( security_flags & 0x8 ) > 0;
|
security_signatures_required : bool = (security_flags & 0x8) > 0;
|
||||||
capabilities_raw_mode: bool = (capabilities & 0x1 ) > 0;
|
capabilities_raw_mode : bool = (capabilities & 0x1) > 0;
|
||||||
capabilities_mpx_mode: bool = (capabilities & 0x2 ) > 0;
|
capabilities_mpx_mode : bool = (capabilities & 0x2) > 0;
|
||||||
capabilities_unicode: bool = (capabilities & 0x4 ) > 0;
|
capabilities_unicode : bool = (capabilities & 0x4) > 0;
|
||||||
capabilities_large_files: bool = (capabilities & 0x8 ) > 0;
|
capabilities_large_files : bool = (capabilities & 0x8) > 0;
|
||||||
capabilities_nt_smbs: bool = (capabilities & 0x10 ) > 0;
|
capabilities_nt_smbs : bool = (capabilities & 0x10) > 0;
|
||||||
capabilities_rpc_remote_apis: bool = (capabilities & 0x20 ) > 0;
|
capabilities_rpc_remote_apis : bool = (capabilities & 0x20) > 0;
|
||||||
capabilities_status32: bool = (capabilities & 0x40 ) > 0;
|
capabilities_status32 : bool = (capabilities & 0x40) > 0;
|
||||||
capabilities_level_2_oplocks: bool = (capabilities & 0x80 ) > 0;
|
capabilities_level_2_oplocks : bool = (capabilities & 0x80) > 0;
|
||||||
capabilities_lock_and_read: bool = (capabilities & 0x100 ) > 0;
|
capabilities_lock_and_read : bool = (capabilities & 0x100) > 0;
|
||||||
capabilities_nt_find: bool = (capabilities & 0x200 ) > 0;
|
capabilities_nt_find : bool = (capabilities & 0x200) > 0;
|
||||||
capabilities_dfs: bool = (capabilities & 0x1000 ) > 0;
|
capabilities_dfs : bool = (capabilities & 0x1000) > 0;
|
||||||
capabilities_infolevel_passthru: bool = (capabilities & 0x2000 ) > 0;
|
capabilities_infolevel_passthru : bool = (capabilities & 0x2000) > 0;
|
||||||
capabilities_large_readx: bool = (capabilities & 0x4000 ) > 0;
|
capabilities_large_readx : bool = (capabilities & 0x4000) > 0;
|
||||||
capabilities_large_writex: bool = (capabilities & 0x8000 ) > 0;
|
capabilities_large_writex : bool = (capabilities & 0x8000) > 0;
|
||||||
capabilities_unix: bool = (capabilities & 0x00800000 ) > 0;
|
capabilities_unix : bool = (capabilities & 0x00800000) > 0;
|
||||||
capabilities_reserved: bool = (capabilities & 0x02000000 ) > 0;
|
capabilities_reserved : bool = (capabilities & 0x02000000) > 0;
|
||||||
capabilities_bulk_transfer: bool = (capabilities & 0x20000000 ) > 0;
|
capabilities_bulk_transfer : bool = (capabilities & 0x20000000) > 0;
|
||||||
capabilities_compressed_data: bool = (capabilities & 0x40000000 ) > 0;
|
capabilities_compressed_data : bool = (capabilities & 0x40000000) > 0;
|
||||||
capabilities_extended_security: bool = (capabilities & 0x80000000 ) > 0;
|
capabilities_extended_security : bool = (capabilities & 0x80000000) > 0;
|
||||||
|
|
||||||
|
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false) &if(capabilities_extended_security);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ refine connection SMB_Conn += {
|
||||||
request->Assign(5, smb_string2stringval(${val.ntlm_extended_security.native_os}));
|
request->Assign(5, smb_string2stringval(${val.ntlm_extended_security.native_os}));
|
||||||
request->Assign(6, smb_string2stringval(${val.ntlm_extended_security.native_lanman}));
|
request->Assign(6, smb_string2stringval(${val.ntlm_extended_security.native_lanman}));
|
||||||
|
|
||||||
//request->Assign(12, bytestring_to_val(${val.ntlm_extended_security.security_blob}));
|
|
||||||
request->Assign(13, capabilities);
|
request->Assign(13, capabilities);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -107,7 +106,10 @@ refine connection SMB_Conn += {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BifEvent::generate_smb1_session_setup_andx_response(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), response);
|
BifEvent::generate_smb1_session_setup_andx_response(bro_analyzer(),
|
||||||
|
bro_analyzer()->Conn(),
|
||||||
|
BuildHeaderVal(header),
|
||||||
|
response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -118,9 +120,9 @@ refine connection SMB_Conn += {
|
||||||
type SMB1_session_setup_andx_request(header: SMB_Header) = record {
|
type SMB1_session_setup_andx_request(header: SMB_Header) = record {
|
||||||
word_count : uint8;
|
word_count : uint8;
|
||||||
lanman_or_ntlm : case word_count of {
|
lanman_or_ntlm : case word_count of {
|
||||||
0x0a -> lanman: SMB1_session_setup_andx_request_lanman(header);
|
0x0a -> lanman : SMB1_session_setup_andx_request_lanman(header);
|
||||||
0x0c -> ntlm_extended_security: SMB1_session_setup_andx_request_ntlm_extended_security(header);
|
0x0c -> ntlm_extended_security : SMB1_session_setup_andx_request_ntlm_extended_security(header);
|
||||||
0x0d -> ntlm_nonextended_security: SMB1_session_setup_andx_request_ntlm_nonextended_security(header);
|
0x0d -> ntlm_nonextended_security : SMB1_session_setup_andx_request_ntlm_nonextended_security(header);
|
||||||
};
|
};
|
||||||
} &let {
|
} &let {
|
||||||
proc: bool = $context.connection.proc_smb1_session_setup_andx_request(header, this);
|
proc: bool = $context.connection.proc_smb1_session_setup_andx_request(header, this);
|
||||||
|
@ -167,7 +169,7 @@ type SMB1_session_setup_andx_response_lanman(header: SMB_Header) = record {
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB1_session_setup_andx_request_ntlm_capabilities = record {
|
type SMB1_session_setup_andx_request_ntlm_capabilities = record {
|
||||||
capabilities : uint32;
|
capabilities: uint32;
|
||||||
} &let {
|
} &let {
|
||||||
unicode : bool = ( capabilities & 0x0004 ) > 0;
|
unicode : bool = ( capabilities & 0x0004 ) > 0;
|
||||||
large_files : bool = ( capabilities & 0x0008 ) > 0;
|
large_files : bool = ( capabilities & 0x0008 ) > 0;
|
||||||
|
@ -207,10 +209,12 @@ type SMB1_session_setup_andx_request_ntlm_extended_security(header: SMB_Header)
|
||||||
reserved : uint32;
|
reserved : uint32;
|
||||||
capabilities : SMB1_session_setup_andx_request_ntlm_capabilities;
|
capabilities : SMB1_session_setup_andx_request_ntlm_capabilities;
|
||||||
byte_count : uint16;
|
byte_count : uint16;
|
||||||
security_blob : SMB_NTLM_SSP(header) &length=security_blob_length;
|
security_blob : bytestring &length=security_blob_length;
|
||||||
# offset + 1 due to word_count in the parent type
|
# offset + 1 due to word_count in the parent type
|
||||||
native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
|
native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
|
||||||
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
|
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
|
||||||
|
} &let {
|
||||||
|
pipe_proc : bool = $context.connection.forward_gssapi(security_blob, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB1_session_setup_andx_response_ntlm(header: SMB_Header) = record {
|
type SMB1_session_setup_andx_response_ntlm(header: SMB_Header) = record {
|
||||||
|
@ -218,12 +222,13 @@ type SMB1_session_setup_andx_response_ntlm(header: SMB_Header) = record {
|
||||||
action : uint16;
|
action : uint16;
|
||||||
security_blob_length : uint16;
|
security_blob_length : uint16;
|
||||||
byte_count : uint16;
|
byte_count : uint16;
|
||||||
security_blob : SMB_NTLM_SSP(header) &length=security_blob_length;
|
security_blob : bytestring &length=security_blob_length;
|
||||||
# offset + 1 due to word_count in the parent type
|
# offset + 1 due to word_count in the parent type
|
||||||
native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
|
native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
|
||||||
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
|
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
|
||||||
primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1);
|
primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1);
|
||||||
} &let {
|
} &let {
|
||||||
is_guest: bool = ( action & 0x1 ) > 0;
|
is_guest : bool = ( action & 0x1 ) > 0;
|
||||||
|
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,12 @@ type SMB2_negotiate_response(header: SMB2_Header) = record {
|
||||||
max_write_size : uint32;
|
max_write_size : uint32;
|
||||||
system_time : SMB_timestamp;
|
system_time : SMB_timestamp;
|
||||||
server_start_time : SMB_timestamp;
|
server_start_time : SMB_timestamp;
|
||||||
security : SMB2_security;
|
security_offset : uint16;
|
||||||
|
security_length : uint16;
|
||||||
|
pad1 : padding to security_offset - header.head_length;
|
||||||
|
security_blob : bytestring &length=security_length;
|
||||||
} &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);
|
||||||
|
|
||||||
};
|
};
|
|
@ -45,20 +45,27 @@ type SMB2_session_setup_request(header: SMB2_Header) = record {
|
||||||
security_mode : uint8;
|
security_mode : uint8;
|
||||||
capabilities : uint32;
|
capabilities : uint32;
|
||||||
channel : uint32;
|
channel : uint32;
|
||||||
security : SMB2_security;
|
security_offset : uint16;
|
||||||
|
security_length : uint16;
|
||||||
|
pad1 : padding to security_offset - header.head_length;
|
||||||
|
security_blob : bytestring &length=security_length;
|
||||||
} &let {
|
} &let {
|
||||||
proc: bool = $context.connection.proc_smb2_session_setup_request(header, this);
|
proc: bool = $context.connection.proc_smb2_session_setup_request(header, this);
|
||||||
|
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
type SMB2_session_setup_response(header: SMB2_Header) = record {
|
type SMB2_session_setup_response(header: SMB2_Header) = record {
|
||||||
structure_size : uint16;
|
structure_size : uint16;
|
||||||
session_flags : uint16;
|
session_flags : uint16;
|
||||||
security : SMB2_security;
|
security_offset : uint16;
|
||||||
|
security_length : uint16;
|
||||||
|
pad1 : padding to security_offset - header.head_length;
|
||||||
|
security_blob : bytestring &length=security_length;
|
||||||
} &let {
|
} &let {
|
||||||
flag_guest = (session_flags & 0x1) > 0;
|
flag_guest = (session_flags & 0x1) > 0;
|
||||||
flag_anonymous = (session_flags & 0x2) > 0;
|
flag_anonymous = (session_flags & 0x2) > 0;
|
||||||
flag_encrypt = (session_flags & 0x4) > 0;
|
flag_encrypt = (session_flags & 0x4) > 0;
|
||||||
|
|
||||||
} &let {
|
|
||||||
proc: bool = $context.connection.proc_smb2_session_setup_response(header, this);
|
proc: bool = $context.connection.proc_smb2_session_setup_response(header, this);
|
||||||
|
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false);
|
||||||
};
|
};
|
||||||
|
|
|
@ -202,14 +202,6 @@ type SMB2_Header(is_orig: bool) = record {
|
||||||
proc : bool = $context.connection.proc_smb2_message(this, is_orig);
|
proc : bool = $context.connection.proc_smb2_message(this, is_orig);
|
||||||
} &byteorder=littleendian;
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
type SMB2_security = record {
|
|
||||||
buffer_offset : uint16;
|
|
||||||
buffer_len : uint16;
|
|
||||||
# TODO: handle previous session IDs
|
|
||||||
sec_buffer : bytestring &length = buffer_len;
|
|
||||||
} &byteorder = littleendian;
|
|
||||||
|
|
||||||
|
|
||||||
# file ids and guids are the same thing and need unified somehow.
|
# file ids and guids are the same thing and need unified somehow.
|
||||||
type SMB2_guid = record {
|
type SMB2_guid = record {
|
||||||
persistent : uint64;
|
persistent : uint64;
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
## Generated for SMB/CIFS requests that contain a security blob with a GSSAPI NTLM message of type *negotiate*.
|
|
||||||
##
|
|
||||||
## See `Wikipedia <http://en.wikipedia.org/wiki/Server_Message_Block>`__ for
|
|
||||||
## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses
|
|
||||||
## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445.
|
|
||||||
##
|
|
||||||
## c: The connection.
|
|
||||||
##
|
|
||||||
## hdr: The parsed header of the SMB message.
|
|
||||||
##
|
|
||||||
## negotiate: The parsed data of the NTLM message. See init-bare for more details.
|
|
||||||
##
|
|
||||||
event smb_ntlm_negotiate%(c: connection, hdr: SMB1::Header, request: SMB::NTLMNegotiate%);
|
|
||||||
|
|
||||||
## Generated for SMB/CIFS requests that contain a security blob with a GSSAPI NTLM message of type *challenge*.
|
|
||||||
##
|
|
||||||
## See `Wikipedia <http://en.wikipedia.org/wiki/Server_Message_Block>`__ for
|
|
||||||
## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses
|
|
||||||
## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445.
|
|
||||||
##
|
|
||||||
## c: The connection.
|
|
||||||
##
|
|
||||||
## hdr: The parsed header of the SMB message.
|
|
||||||
##
|
|
||||||
## negotiate: The parsed data of the NTLM message. See init-bare for more details.
|
|
||||||
##
|
|
||||||
event smb_ntlm_challenge%(c: connection, hdr: SMB1::Header, request: SMB::NTLMChallenge%);
|
|
||||||
|
|
||||||
## Generated for SMB/CIFS requests that contain a security blob with a GSSAPI NTLM message of type *authenticate*.
|
|
||||||
##
|
|
||||||
## See `Wikipedia <http://en.wikipedia.org/wiki/Server_Message_Block>`__ for
|
|
||||||
## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses
|
|
||||||
## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445.
|
|
||||||
##
|
|
||||||
## c: The connection.
|
|
||||||
##
|
|
||||||
## hdr: The parsed header of the SMB message.
|
|
||||||
##
|
|
||||||
## negotiate: The parsed data of the NTLM message. See init-bare for more details.
|
|
||||||
##
|
|
||||||
event smb_ntlm_authenticate%(c: connection, hdr: SMB1::Header, request: SMB::NTLMAuthenticate%);
|
|
||||||
|
|
||||||
## Generated for SMB/CIFS requests that contain a security blob with a GSSAPI message of type *accept-completed*.
|
|
||||||
##
|
|
||||||
## See `Wikipedia <http://en.wikipedia.org/wiki/Server_Message_Block>`__ for
|
|
||||||
## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses
|
|
||||||
## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445.
|
|
||||||
##
|
|
||||||
## c: The connection.
|
|
||||||
##
|
|
||||||
## hdr: The parsed header of the SMB message.
|
|
||||||
##
|
|
||||||
event smb_ntlm_accepted%(c: connection, hdr: SMB1::Header%);
|
|
||||||
|
|
||||||
|
|
||||||
#### Types
|
|
||||||
|
|
||||||
type SMB::NTLMNegotiate: record;
|
|
||||||
type SMB::NTLMChallenge: record;
|
|
||||||
type SMB::NTLMAuthenticate: record;
|
|
||||||
|
|
||||||
type SMB::NTLMNegotiateFlags: record;
|
|
||||||
type SMB::NTLMVersion: record;
|
|
||||||
type SMB::NTLMAVs: record;
|
|
Loading…
Add table
Add a link
Reference in a new issue