mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/master' into topic/dnthayer/ticket1963
This commit is contained in:
commit
1a4629b0dc
90 changed files with 851 additions and 777 deletions
|
@ -8,7 +8,9 @@ export {
|
|||
const default_port = 9999/tcp &redef;
|
||||
|
||||
## Default interval to retry listening on a port if it's currently in
|
||||
## use already.
|
||||
## use already. Use of the BRO_DEFAULT_LISTEN_RETRY environment variable
|
||||
## (set as a number of seconds) will override this option and also
|
||||
## any values given to :bro:see:`Broker::listen`.
|
||||
const default_listen_retry = 30sec &redef;
|
||||
|
||||
## Default address on which to listen.
|
||||
|
@ -16,8 +18,11 @@ export {
|
|||
## .. bro:see:: Broker::listen
|
||||
const default_listen_address = getenv("BRO_DEFAULT_LISTEN_ADDRESS") &redef;
|
||||
|
||||
## Default interval to retry connecting to a peer if it cannot be made to work
|
||||
## initially, or if it ever becomes disconnected.
|
||||
## Default interval to retry connecting to a peer if it cannot be made to
|
||||
## work initially, or if it ever becomes disconnected. Use of the
|
||||
## BRO_DEFAULT_CONNECT_RETRY environment variable (set as number of
|
||||
## seconds) will override this option and also any values given to
|
||||
## :bro:see:`Broker::peer`.
|
||||
const default_connect_retry = 30sec &redef;
|
||||
|
||||
## If true, do not use SSL for network connections. By default, SSL will
|
||||
|
@ -194,7 +199,9 @@ export {
|
|||
## the next available free port.
|
||||
##
|
||||
## retry: If non-zero, retries listening in regular intervals if the port cannot be
|
||||
## acquired immediately. 0 disables retries.
|
||||
## acquired immediately. 0 disables retries. If the
|
||||
## BRO_DEFAULT_LISTEN_RETRY environment variable is set (as number
|
||||
## of seconds), it overrides any value given here.
|
||||
##
|
||||
## Returns: the bound port or 0/? on failure.
|
||||
##
|
||||
|
@ -210,7 +217,9 @@ export {
|
|||
##
|
||||
## retry: an interval at which to retry establishing the
|
||||
## connection with the remote peer if it cannot be made initially, or
|
||||
## if it ever becomes disconnected.
|
||||
## if it ever becomes disconnected. If the
|
||||
## BRO_DEFAULT_CONNECT_RETRY environment variable is set (as number
|
||||
## of seconds), it overrides any value given here.
|
||||
##
|
||||
## Returns: true if it's possible to try connecting with the peer and
|
||||
## it's a new peer. The actual connection may not be established
|
||||
|
@ -319,8 +328,16 @@ function listen(a: string, p: port, retry: interval): port
|
|||
{
|
||||
local bound = __listen(a, p);
|
||||
|
||||
if ( bound == 0/tcp && retry != 0secs )
|
||||
schedule retry { retry_listen(a, p, retry) };
|
||||
if ( bound == 0/tcp )
|
||||
{
|
||||
local e = getenv("BRO_DEFAULT_LISTEN_RETRY");
|
||||
|
||||
if ( e != "" )
|
||||
retry = double_to_interval(to_double(e));
|
||||
|
||||
if ( retry != 0secs )
|
||||
schedule retry { retry_listen(a, p, retry) };
|
||||
}
|
||||
|
||||
return bound;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,8 @@ export {
|
|||
const node = getenv("CLUSTER_NODE") &redef;
|
||||
|
||||
## Interval for retrying failed connections between cluster nodes.
|
||||
## If set, the BRO_DEFAULT_CONNECT_RETRY (given in number of seconds)
|
||||
## overrides this option.
|
||||
const retry_interval = 1min &redef;
|
||||
|
||||
## When using broker-enabled cluster framework, nodes broadcast this event
|
||||
|
|
|
@ -270,8 +270,8 @@ function acld_remove_rule_fun(p: PluginState, r: Rule, reason: string) : bool
|
|||
|
||||
function acld_init(p: PluginState)
|
||||
{
|
||||
Broker::peer(cat(p$acld_config$acld_host), p$acld_config$acld_port);
|
||||
Broker::subscribe(p$acld_config$acld_topic);
|
||||
Broker::peer(cat(p$acld_config$acld_host), p$acld_config$acld_port);
|
||||
}
|
||||
|
||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
||||
|
|
|
@ -164,8 +164,8 @@ function broker_remove_rule_fun(p: PluginState, r: Rule, reason: string) : bool
|
|||
|
||||
function broker_init(p: PluginState)
|
||||
{
|
||||
Broker::peer(cat(p$broker_config$host), p$broker_config$bport);
|
||||
Broker::subscribe(p$broker_config$topic);
|
||||
Broker::peer(cat(p$broker_config$host), p$broker_config$bport);
|
||||
}
|
||||
|
||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
@load base/protocols/rfb
|
||||
@load base/protocols/sip
|
||||
@load base/protocols/snmp
|
||||
# This DOES NOT enable the SMB analyzer. It's just some base support
|
||||
# for other protocols.
|
||||
@load base/protocols/smb
|
||||
@load base/protocols/smtp
|
||||
@load base/protocols/socks
|
||||
|
|
|
@ -41,6 +41,13 @@ export {
|
|||
## IP address.
|
||||
server_addr: addr &log &optional;
|
||||
|
||||
## Client port number seen at time of server handing out IP (expected
|
||||
## as 68/udp).
|
||||
client_port: port &optional;
|
||||
## Server port number seen at time of server handing out IP (expected
|
||||
## as 67/udp).
|
||||
server_port: port &optional;
|
||||
|
||||
## Client's hardware address.
|
||||
mac: string &log &optional;
|
||||
|
||||
|
@ -224,6 +231,8 @@ event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, ms
|
|||
id$resp_h != 255.255.255.255 )
|
||||
{
|
||||
log_info$server_addr = id$resp_h;
|
||||
log_info$server_port = id$resp_p;
|
||||
log_info$client_port = id$orig_p;
|
||||
}
|
||||
|
||||
# Only use the client hardware address from the server
|
||||
|
|
|
@ -21,8 +21,8 @@ export {
|
|||
[29] = "LOC", [30] = "EID", [31] = "NIMLOC", [32] = "NB",
|
||||
[33] = "SRV", [34] = "ATMA", [35] = "NAPTR", [36] = "KX",
|
||||
[37] = "CERT", [38] = "A6", [39] = "DNAME", [40] = "SINK",
|
||||
[EDNS] = "EDNS", [42] = "APL", [43] = "DS", [44] = "SINK",
|
||||
[45] = "SSHFP", [46] = "RRSIG", [47] = "NSEC", [48] = "DNSKEY",
|
||||
[EDNS] = "EDNS", [42] = "APL", [43] = "DS", [44] = "SSHFP",
|
||||
[45] = "IPSECKEY", [46] = "RRSIG", [47] = "NSEC", [48] = "DNSKEY",
|
||||
[49] = "DHCID", [99] = "SPF", [100] = "DINFO", [101] = "UID",
|
||||
[102] = "GID", [103] = "UNSPEC", [249] = "TKEY", [250] = "TSIG",
|
||||
[251] = "IXFR", [252] = "AXFR", [253] = "MAILB", [254] = "MAILA",
|
||||
|
|
|
@ -1 +1 @@
|
|||
Definitions of constants used by the SMB protocol.
|
||||
Support for SMB protocol analysis.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
@load ./consts
|
||||
@load ./const-dos-error
|
||||
@load ./const-nt-status
|
||||
|
||||
@load ./main
|
||||
@load ./smb1-main
|
||||
@load ./smb2-main
|
||||
@load ./files
|
||||
|
||||
@load-sigs ./dpd.sig
|
||||
|
|
5
scripts/base/protocols/smb/dpd.sig
Normal file
5
scripts/base/protocols/smb/dpd.sig
Normal file
|
@ -0,0 +1,5 @@
|
|||
signature dpd_smb {
|
||||
ip-proto == tcp
|
||||
payload /^....[\xfe\xff]SMB/
|
||||
enable "smb"
|
||||
}
|
69
scripts/base/protocols/smb/files.bro
Normal file
69
scripts/base/protocols/smb/files.bro
Normal file
|
@ -0,0 +1,69 @@
|
|||
@load base/frameworks/files
|
||||
@load ./main
|
||||
|
||||
module SMB;
|
||||
|
||||
export {
|
||||
## Default file handle provider for SMB.
|
||||
global get_file_handle: function(c: connection, is_orig: bool): string;
|
||||
|
||||
## Default file describer for SMB.
|
||||
global describe_file: function(f: fa_file): string;
|
||||
}
|
||||
|
||||
function get_file_handle(c: connection, is_orig: bool): string
|
||||
{
|
||||
if ( ! (c$smb_state?$current_file &&
|
||||
(c$smb_state$current_file?$name ||
|
||||
c$smb_state$current_file?$path)) )
|
||||
{
|
||||
# TODO - figure out what are the cases where this happens.
|
||||
return "";
|
||||
}
|
||||
local current_file = c$smb_state$current_file;
|
||||
local path_name = current_file?$path ? current_file$path : "";
|
||||
local file_name = current_file?$name ? current_file$name : "";
|
||||
# Include last_mod time if available because if a file has been modified it
|
||||
# should be considered a new file.
|
||||
local last_mod = cat(current_file?$times ? current_file$times$modified : double_to_time(0.0));
|
||||
# TODO: This is doing hexdump to avoid problems due to file analysis handling
|
||||
# using CheckString which is not immune to encapsulated null bytes.
|
||||
# This needs to be fixed lower in the file analysis code later.
|
||||
return hexdump(cat(Analyzer::ANALYZER_SMB, c$id$orig_h, c$id$resp_h, path_name, file_name, last_mod));
|
||||
}
|
||||
|
||||
function describe_file(f: fa_file): string
|
||||
{
|
||||
# This shouldn't be needed, but just in case...
|
||||
if ( f$source != "SMB" )
|
||||
return "";
|
||||
|
||||
for ( cid in f$conns )
|
||||
{
|
||||
local info = f$conns[cid];
|
||||
if ( info?$smb_state && info$smb_state?$current_file && info$smb_state$current_file?$name )
|
||||
return info$smb_state$current_file$name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Files::register_protocol(Analyzer::ANALYZER_SMB,
|
||||
[$get_file_handle = SMB::get_file_handle,
|
||||
$describe = SMB::describe_file]);
|
||||
}
|
||||
|
||||
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5
|
||||
{
|
||||
if ( c?$smb_state && c$smb_state?$current_file )
|
||||
{
|
||||
c$smb_state$current_file$fuid = f$id;
|
||||
|
||||
if ( c$smb_state$current_file$size > 0 )
|
||||
f$total_bytes = c$smb_state$current_file$size;
|
||||
|
||||
if ( c$smb_state$current_file?$name )
|
||||
f$info$filename = c$smb_state$current_file$name;
|
||||
}
|
||||
}
|
250
scripts/base/protocols/smb/main.bro
Normal file
250
scripts/base/protocols/smb/main.bro
Normal file
|
@ -0,0 +1,250 @@
|
|||
@load ./consts
|
||||
@load ./const-dos-error
|
||||
@load ./const-nt-status
|
||||
|
||||
module SMB;
|
||||
|
||||
export {
|
||||
redef enum Log::ID += {
|
||||
AUTH_LOG,
|
||||
MAPPING_LOG,
|
||||
FILES_LOG
|
||||
};
|
||||
|
||||
## Abstracted actions for SMB file actions.
|
||||
type Action: enum {
|
||||
FILE_READ,
|
||||
FILE_WRITE,
|
||||
FILE_OPEN,
|
||||
FILE_CLOSE,
|
||||
FILE_DELETE,
|
||||
FILE_RENAME,
|
||||
FILE_SET_ATTRIBUTE,
|
||||
|
||||
PIPE_READ,
|
||||
PIPE_WRITE,
|
||||
PIPE_OPEN,
|
||||
PIPE_CLOSE,
|
||||
|
||||
PRINT_READ,
|
||||
PRINT_WRITE,
|
||||
PRINT_OPEN,
|
||||
PRINT_CLOSE,
|
||||
};
|
||||
|
||||
## The file actions which are logged.
|
||||
option logged_file_actions: set[Action] = {
|
||||
FILE_OPEN,
|
||||
FILE_RENAME,
|
||||
FILE_DELETE,
|
||||
|
||||
PRINT_OPEN,
|
||||
PRINT_CLOSE,
|
||||
};
|
||||
|
||||
## This record is for the smb_files.log
|
||||
type FileInfo: record {
|
||||
## Time when the file was first discovered.
|
||||
ts : time &log;
|
||||
## Unique ID of the connection the file was sent over.
|
||||
uid : string &log;
|
||||
## ID of the connection the file was sent over.
|
||||
id : conn_id &log;
|
||||
## Unique ID of the file.
|
||||
fuid : string &log &optional;
|
||||
|
||||
## Action this log record represents.
|
||||
action : Action &log &optional;
|
||||
## Path pulled from the tree this file was transferred to or from.
|
||||
path : string &log &optional;
|
||||
## Filename if one was seen.
|
||||
name : string &log &optional;
|
||||
## Total size of the file.
|
||||
size : count &log &default=0;
|
||||
## If the rename action was seen, this will be
|
||||
## the file's previous name.
|
||||
prev_name : string &log &optional;
|
||||
## Last time this file was modified.
|
||||
times : SMB::MACTimes &log &optional;
|
||||
};
|
||||
|
||||
## This record is for the smb_mapping.log
|
||||
type TreeInfo: record {
|
||||
## Time when the tree was mapped.
|
||||
ts : time &log &optional;
|
||||
## Unique ID of the connection the tree was mapped over.
|
||||
uid : string &log;
|
||||
## ID of the connection the tree was mapped over.
|
||||
id : conn_id &log;
|
||||
|
||||
## Name of the tree path.
|
||||
path : string &log &optional;
|
||||
## The type of resource of the tree (disk share, printer share, named pipe, etc.).
|
||||
service : string &log &optional;
|
||||
## File system of the tree.
|
||||
native_file_system : string &log &optional;
|
||||
## If this is SMB2, a share type will be included. For SMB1,
|
||||
## the type of share will be deduced and included as well.
|
||||
share_type : string &log &default="DISK";
|
||||
};
|
||||
|
||||
## This record is for the smb_cmd.log
|
||||
type CmdInfo: record {
|
||||
## Timestamp of the command request.
|
||||
ts : time &log;
|
||||
## Unique ID of the connection the request was sent over.
|
||||
uid : string &log;
|
||||
## ID of the connection the request was sent over.
|
||||
id : conn_id &log;
|
||||
|
||||
## The command sent by the client.
|
||||
command : string &log;
|
||||
## The subcommand sent by the client, if present.
|
||||
sub_command : string &log &optional;
|
||||
## Command argument sent by the client, if any.
|
||||
argument : string &log &optional;
|
||||
|
||||
## Server reply to the client's command.
|
||||
status : string &log &optional;
|
||||
## Round trip time from the request to the response.
|
||||
rtt : interval &log &optional;
|
||||
## Version of SMB for the command.
|
||||
version : string &log;
|
||||
|
||||
## Authenticated username, if available.
|
||||
username : string &log &optional;
|
||||
|
||||
## If this is related to a tree, this is the tree
|
||||
## that was used for the current command.
|
||||
tree : string &log &optional;
|
||||
## The type of tree (disk share, printer share, named pipe, etc.).
|
||||
tree_service : string &log &optional;
|
||||
|
||||
## If the command referenced a file, store it here.
|
||||
referenced_file : FileInfo &log &optional;
|
||||
## If the command referenced a tree, store it here.
|
||||
referenced_tree : TreeInfo &optional;
|
||||
};
|
||||
|
||||
## This record stores the SMB state of in-flight commands,
|
||||
## the file and tree map of the connection.
|
||||
type State: record {
|
||||
## A reference to the current command.
|
||||
current_cmd : CmdInfo &optional;
|
||||
## A reference to the current file.
|
||||
current_file : FileInfo &optional;
|
||||
## A reference to the current tree.
|
||||
current_tree : TreeInfo &optional;
|
||||
|
||||
## Indexed on MID to map responses to requests.
|
||||
pending_cmds : table[count] of CmdInfo &optional;
|
||||
## File map to retrieve file information based on the file ID.
|
||||
fid_map : table[count] of FileInfo &optional;
|
||||
## Tree map to retrieve tree information based on the tree ID.
|
||||
tid_map : table[count] of TreeInfo &optional;
|
||||
## User map to retrieve user name based on the user ID.
|
||||
uid_map : table[count] of string &optional;
|
||||
## Pipe map to retrieve UUID based on the file ID of a pipe.
|
||||
pipe_map : table[count] of string &optional;
|
||||
|
||||
## A set of recent files to avoid logging the same
|
||||
## files over and over in the smb files log.
|
||||
## This only applies to files seen in a single connection.
|
||||
recent_files : set[string] &default=string_set() &read_expire=3min;
|
||||
};
|
||||
|
||||
## Everything below here is used internally in the SMB scripts.
|
||||
|
||||
redef record connection += {
|
||||
smb_state : State &optional;
|
||||
};
|
||||
|
||||
## This is an internally used function.
|
||||
const set_current_file: function(smb_state: State, file_id: count) &redef;
|
||||
|
||||
## This is an internally used function.
|
||||
const write_file_log: function(state: State) &redef;
|
||||
}
|
||||
|
||||
redef record FileInfo += {
|
||||
## ID referencing this file.
|
||||
fid : count &optional;
|
||||
|
||||
## UUID referencing this file if DCE/RPC.
|
||||
uuid : string &optional;
|
||||
};
|
||||
|
||||
const ports = { 139/tcp, 445/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SMB::FILES_LOG, [$columns=SMB::FileInfo, $path="smb_files"]);
|
||||
Log::create_stream(SMB::MAPPING_LOG, [$columns=SMB::TreeInfo, $path="smb_mapping"]);
|
||||
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SMB, ports);
|
||||
}
|
||||
|
||||
function set_current_file(smb_state: State, file_id: count)
|
||||
{
|
||||
if ( file_id !in smb_state$fid_map )
|
||||
{
|
||||
smb_state$fid_map[file_id] = smb_state$current_cmd$referenced_file;
|
||||
smb_state$fid_map[file_id]$fid = file_id;
|
||||
}
|
||||
|
||||
smb_state$current_cmd$referenced_file = smb_state$fid_map[file_id];
|
||||
smb_state$current_file = smb_state$current_cmd$referenced_file;
|
||||
}
|
||||
|
||||
function write_file_log(state: State)
|
||||
{
|
||||
local f = state$current_file;
|
||||
if ( f?$name &&
|
||||
f$action in logged_file_actions )
|
||||
{
|
||||
# Everything in this if statement is to avoid overlogging
|
||||
# of the same data from a single connection based on recently
|
||||
# seen files in the SMB::State $recent_files field.
|
||||
if ( f?$times )
|
||||
{
|
||||
local file_ident = cat(f$action,
|
||||
f?$fuid ? f$fuid : "",
|
||||
f?$name ? f$name : "",
|
||||
f?$path ? f$path : "",
|
||||
f$size,
|
||||
f$times);
|
||||
if ( file_ident in state$recent_files )
|
||||
{
|
||||
# We've already seen this file and don't want to log it again.
|
||||
return;
|
||||
}
|
||||
else
|
||||
add state$recent_files[file_ident];
|
||||
}
|
||||
|
||||
Log::write(FILES_LOG, f);
|
||||
}
|
||||
}
|
||||
|
||||
event smb_pipe_connect_heuristic(c: connection) &priority=5
|
||||
{
|
||||
c$smb_state$current_tree$path = "<unknown>";
|
||||
c$smb_state$current_tree$share_type = "PIPE";
|
||||
}
|
||||
|
||||
event file_state_remove(f: fa_file) &priority=-5
|
||||
{
|
||||
if ( f$source != "SMB" )
|
||||
return;
|
||||
|
||||
for ( id in f$conns )
|
||||
{
|
||||
local c = f$conns[id];
|
||||
if ( c?$smb_state && c$smb_state?$current_file)
|
||||
{
|
||||
write_file_log(c$smb_state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
320
scripts/base/protocols/smb/smb1-main.bro
Normal file
320
scripts/base/protocols/smb/smb1-main.bro
Normal file
|
@ -0,0 +1,320 @@
|
|||
@load ./main
|
||||
|
||||
module SMB1;
|
||||
|
||||
redef record SMB::CmdInfo += {
|
||||
## Dialects offered by the client.
|
||||
smb1_offered_dialects: string_vec &optional;
|
||||
};
|
||||
|
||||
event smb1_message(c: connection, hdr: SMB1::Header, is_orig: bool) &priority=5
|
||||
{
|
||||
if ( ! c?$smb_state )
|
||||
{
|
||||
local state: SMB::State;
|
||||
state$fid_map = table();
|
||||
state$tid_map = table();
|
||||
state$uid_map = table();
|
||||
state$pipe_map = table();
|
||||
state$pending_cmds = table();
|
||||
c$smb_state = state;
|
||||
}
|
||||
|
||||
local smb_state = c$smb_state;
|
||||
local tid = hdr$tid;
|
||||
local uid = hdr$uid;
|
||||
local pid = hdr$pid;
|
||||
local mid = hdr$mid;
|
||||
|
||||
if ( uid in smb_state$uid_map )
|
||||
{
|
||||
smb_state$current_cmd$username = smb_state$uid_map[uid];
|
||||
}
|
||||
|
||||
if ( tid !in smb_state$tid_map )
|
||||
{
|
||||
smb_state$tid_map[tid] = SMB::TreeInfo($uid=c$uid, $id=c$id);
|
||||
}
|
||||
smb_state$current_tree = smb_state$tid_map[tid];
|
||||
if ( smb_state$current_tree?$path )
|
||||
{
|
||||
smb_state$current_cmd$tree = smb_state$current_tree$path;
|
||||
}
|
||||
|
||||
if ( smb_state$current_tree?$service )
|
||||
{
|
||||
smb_state$current_cmd$tree_service = smb_state$current_tree$service;
|
||||
}
|
||||
|
||||
if ( mid !in smb_state$pending_cmds )
|
||||
{
|
||||
local tmp_cmd = SMB::CmdInfo($ts=network_time(), $uid=c$uid, $id=c$id, $version="SMB1", $command = SMB1::commands[hdr$command]);
|
||||
|
||||
local tmp_file = SMB::FileInfo($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||
tmp_cmd$referenced_file = tmp_file;
|
||||
tmp_cmd$referenced_tree = smb_state$current_tree;
|
||||
|
||||
smb_state$pending_cmds[mid] = tmp_cmd;
|
||||
}
|
||||
|
||||
smb_state$current_cmd = smb_state$pending_cmds[mid];
|
||||
|
||||
if ( !is_orig )
|
||||
{
|
||||
smb_state$current_cmd$rtt = network_time() - smb_state$current_cmd$ts;
|
||||
smb_state$current_cmd$status = SMB::statuses[hdr$status]$id;
|
||||
}
|
||||
}
|
||||
|
||||
event smb1_message(c: connection, hdr: SMB1::Header, is_orig: bool) &priority=-5
|
||||
{
|
||||
if ( is_orig )
|
||||
return;
|
||||
|
||||
delete c$smb_state$pending_cmds[hdr$mid];
|
||||
}
|
||||
|
||||
|
||||
event smb1_transaction2_request(c: connection, hdr: SMB1::Header, args: SMB1::Trans2_Args, sub_cmd: count)
|
||||
{
|
||||
c$smb_state$current_cmd$sub_command = SMB1::trans2_sub_commands[sub_cmd];
|
||||
}
|
||||
|
||||
|
||||
event smb1_negotiate_request(c: connection, hdr: SMB1::Header, dialects: string_vec) &priority=5
|
||||
{
|
||||
c$smb_state$current_cmd$smb1_offered_dialects = dialects;
|
||||
}
|
||||
|
||||
event smb1_negotiate_response(c: connection, hdr: SMB1::Header, response: SMB1::NegotiateResponse) &priority=5
|
||||
{
|
||||
if ( c$smb_state$current_cmd?$smb1_offered_dialects )
|
||||
{
|
||||
if ( response?$ntlm )
|
||||
{
|
||||
c$smb_state$current_cmd$argument = c$smb_state$current_cmd$smb1_offered_dialects[response$ntlm$dialect_index];
|
||||
}
|
||||
|
||||
delete c$smb_state$current_cmd$smb1_offered_dialects;
|
||||
}
|
||||
}
|
||||
|
||||
event smb1_negotiate_response(c: connection, hdr: SMB1::Header, response: SMB1::NegotiateResponse) &priority=-5
|
||||
{
|
||||
}
|
||||
|
||||
event smb1_tree_connect_andx_request(c: connection, hdr: SMB1::Header, path: string, service: string) &priority=5
|
||||
{
|
||||
local tmp_tree = SMB::TreeInfo($ts=network_time(), $uid=c$uid, $id=c$id, $path=path, $service=service);
|
||||
|
||||
c$smb_state$current_cmd$referenced_tree = tmp_tree;
|
||||
c$smb_state$current_cmd$argument = path;
|
||||
}
|
||||
|
||||
event smb1_tree_connect_andx_response(c: connection, hdr: SMB1::Header, service: string, native_file_system: string) &priority=5
|
||||
{
|
||||
c$smb_state$current_cmd$referenced_tree$service = service;
|
||||
if ( service == "IPC" )
|
||||
c$smb_state$current_cmd$referenced_tree$share_type = "PIPE";
|
||||
|
||||
c$smb_state$current_cmd$tree_service = service;
|
||||
|
||||
if ( native_file_system != "" )
|
||||
c$smb_state$current_cmd$referenced_tree$native_file_system = native_file_system;
|
||||
|
||||
c$smb_state$current_tree = c$smb_state$current_cmd$referenced_tree;
|
||||
c$smb_state$tid_map[hdr$tid] = c$smb_state$current_tree;
|
||||
}
|
||||
|
||||
event smb1_tree_connect_andx_response(c: connection, hdr: SMB1::Header, service: string, native_file_system: string) &priority=-5
|
||||
{
|
||||
Log::write(SMB::MAPPING_LOG, c$smb_state$current_tree);
|
||||
}
|
||||
|
||||
event smb1_nt_create_andx_request(c: connection, hdr: SMB1::Header, name: string) &priority=5
|
||||
{
|
||||
local tmp_file = SMB::FileInfo($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||
c$smb_state$current_cmd$referenced_file = tmp_file;
|
||||
|
||||
c$smb_state$current_cmd$referenced_file$name = name;
|
||||
c$smb_state$current_cmd$referenced_file$action = SMB::FILE_OPEN;
|
||||
c$smb_state$current_file = c$smb_state$current_cmd$referenced_file;
|
||||
c$smb_state$current_cmd$argument = name;
|
||||
}
|
||||
|
||||
event smb1_nt_create_andx_response(c: connection, hdr: SMB1::Header, file_id: count, file_size: count, times: SMB::MACTimes) &priority=5
|
||||
{
|
||||
c$smb_state$current_cmd$referenced_file$action = SMB::FILE_OPEN;
|
||||
c$smb_state$current_cmd$referenced_file$fid = file_id;
|
||||
c$smb_state$current_cmd$referenced_file$size = file_size;
|
||||
|
||||
# I'm seeing negative data from IPC tree transfers
|
||||
if ( time_to_double(times$modified) > 0.0 )
|
||||
c$smb_state$current_cmd$referenced_file$times = times;
|
||||
|
||||
# We can identify the file by its file id now so let's stick it
|
||||
# in the file map.
|
||||
c$smb_state$fid_map[file_id] = c$smb_state$current_cmd$referenced_file;
|
||||
|
||||
c$smb_state$current_file = c$smb_state$fid_map[file_id];
|
||||
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb1_read_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, length: count) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id);
|
||||
c$smb_state$current_file$action = SMB::FILE_READ;
|
||||
if ( c$smb_state$current_file?$name )
|
||||
c$smb_state$current_cmd$argument = c$smb_state$current_file$name;
|
||||
}
|
||||
|
||||
event smb1_read_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, length: count) &priority=-5
|
||||
{
|
||||
if ( c$smb_state$current_tree?$path && !c$smb_state$current_file?$path )
|
||||
c$smb_state$current_file$path = c$smb_state$current_tree$path;
|
||||
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb1_write_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, data_len: count) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id);
|
||||
c$smb_state$current_file$action = SMB::FILE_WRITE;
|
||||
if ( !c$smb_state$current_cmd?$argument &&
|
||||
# TODO: figure out why name isn't getting set sometimes.
|
||||
c$smb_state$current_file?$name )
|
||||
c$smb_state$current_cmd$argument = c$smb_state$current_file$name;
|
||||
}
|
||||
|
||||
event smb1_write_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, data_len: count) &priority=-5
|
||||
{
|
||||
if ( c$smb_state$current_tree?$path && !c$smb_state$current_file?$path )
|
||||
c$smb_state$current_file$path = c$smb_state$current_tree$path;
|
||||
|
||||
# We don't even try to log reads and writes to the files log.
|
||||
#write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
#event smb1_write_andx_response(c: connection, hdr: SMB1::Header, written_bytes: count) &priority=5
|
||||
# {
|
||||
# # TODO - determine what to do here
|
||||
# }
|
||||
|
||||
event smb1_close_request(c: connection, hdr: SMB1::Header, file_id: count) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id);
|
||||
c$smb_state$current_file$action = SMB::FILE_CLOSE;
|
||||
}
|
||||
|
||||
event smb1_close_request(c: connection, hdr: SMB1::Header, file_id: count) &priority=-5
|
||||
{
|
||||
if ( file_id in c$smb_state$fid_map )
|
||||
{
|
||||
local fl = c$smb_state$fid_map[file_id];
|
||||
# Need to check for existence of path in case tree connect message wasn't seen.
|
||||
if ( c$smb_state$current_tree?$path )
|
||||
fl$path = c$smb_state$current_tree$path;
|
||||
|
||||
if ( fl?$name )
|
||||
c$smb_state$current_cmd$argument = fl$name;
|
||||
|
||||
delete c$smb_state$fid_map[file_id];
|
||||
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
# TODO - Determine correct action
|
||||
# A reporter message is not right...
|
||||
#Reporter::warning("attempting to close an unknown file!");
|
||||
}
|
||||
}
|
||||
|
||||
event smb1_trans2_get_dfs_referral_request(c: connection, hdr: SMB1::Header, file_name: string)
|
||||
{
|
||||
c$smb_state$current_cmd$argument = file_name;
|
||||
}
|
||||
|
||||
event smb1_trans2_query_path_info_request(c: connection, hdr: SMB1::Header, file_name: string)
|
||||
{
|
||||
c$smb_state$current_cmd$argument = file_name;
|
||||
}
|
||||
|
||||
event smb1_trans2_find_first2_request(c: connection, hdr: SMB1::Header, args: SMB1::Find_First2_Request_Args)
|
||||
{
|
||||
c$smb_state$current_cmd$argument = args$file_name;
|
||||
}
|
||||
|
||||
event smb1_session_setup_andx_request(c: connection, hdr: SMB1::Header, request: SMB1::SessionSetupAndXRequest) &priority=5
|
||||
{
|
||||
# No behavior yet.
|
||||
}
|
||||
|
||||
event smb1_session_setup_andx_response(c: connection, hdr: SMB1::Header, response: SMB1::SessionSetupAndXResponse) &priority=-5
|
||||
{
|
||||
# No behavior yet.
|
||||
}
|
||||
|
||||
event smb1_transaction_request(c: connection, hdr: SMB1::Header, name: string, sub_cmd: count, parameters: string, data: string)
|
||||
{
|
||||
c$smb_state$current_cmd$sub_command = SMB1::trans_sub_commands[sub_cmd];
|
||||
}
|
||||
|
||||
event smb1_write_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, data_len: count)
|
||||
{
|
||||
if ( ! c$smb_state?$current_file || ! c$smb_state$current_file?$uuid )
|
||||
{
|
||||
# TODO: figure out why the uuid isn't getting set sometimes.
|
||||
return;
|
||||
}
|
||||
|
||||
c$smb_state$pipe_map[file_id] = c$smb_state$current_file$uuid;
|
||||
}
|
||||
|
||||
event smb_pipe_bind_ack_response(c: connection, hdr: SMB1::Header)
|
||||
{
|
||||
if ( ! c$smb_state?$current_file || ! c$smb_state$current_file?$uuid )
|
||||
{
|
||||
# TODO: figure out why the uuid isn't getting set sometimes.
|
||||
return;
|
||||
}
|
||||
|
||||
c$smb_state$current_cmd$sub_command = "RPC_BIND_ACK";
|
||||
c$smb_state$current_cmd$argument = SMB::rpc_uuids[c$smb_state$current_file$uuid];
|
||||
}
|
||||
|
||||
event smb_pipe_bind_request(c: connection, hdr: SMB1::Header, uuid: string, version: string)
|
||||
{
|
||||
if ( ! c$smb_state?$current_file || ! c$smb_state$current_file?$uuid )
|
||||
{
|
||||
# TODO: figure out why the current_file isn't getting set sometimes.
|
||||
return;
|
||||
}
|
||||
|
||||
c$smb_state$current_cmd$sub_command = "RPC_BIND";
|
||||
c$smb_state$current_file$uuid = uuid;
|
||||
c$smb_state$current_cmd$argument = fmt("%s v%s", SMB::rpc_uuids[uuid], version);
|
||||
}
|
||||
|
||||
event smb_pipe_request(c: connection, hdr: SMB1::Header, op_num: count)
|
||||
{
|
||||
if ( ! c$smb_state?$current_file )
|
||||
{
|
||||
# TODO: figure out why the current file isn't being set sometimes.
|
||||
return;
|
||||
}
|
||||
|
||||
local f = c$smb_state$current_file;
|
||||
if ( ! f?$uuid )
|
||||
{
|
||||
# TODO: figure out why this is happening.
|
||||
event conn_weird("smb_pipe_request_missing_uuid", c, "");
|
||||
return;
|
||||
}
|
||||
local arg = fmt("%s: %s",
|
||||
SMB::rpc_uuids[f$uuid],
|
||||
SMB::rpc_sub_cmds[f$uuid][op_num]);
|
||||
|
||||
c$smb_state$current_cmd$argument = arg;
|
||||
}
|
344
scripts/base/protocols/smb/smb2-main.bro
Normal file
344
scripts/base/protocols/smb/smb2-main.bro
Normal file
|
@ -0,0 +1,344 @@
|
|||
@load ./main
|
||||
|
||||
module SMB2;
|
||||
|
||||
redef record SMB::CmdInfo += {
|
||||
## Dialects offered by the client.
|
||||
smb2_offered_dialects: index_vec &optional;
|
||||
};
|
||||
|
||||
event smb2_message(c: connection, hdr: SMB2::Header, is_orig: bool) &priority=5
|
||||
{
|
||||
if ( ! c?$smb_state )
|
||||
{
|
||||
local state: SMB::State;
|
||||
state$fid_map = table();
|
||||
state$tid_map = table();
|
||||
state$uid_map = table();
|
||||
state$pending_cmds = table();
|
||||
state$pipe_map = table();
|
||||
c$smb_state = state;
|
||||
}
|
||||
|
||||
local smb_state = c$smb_state;
|
||||
local tid = hdr$tree_id;
|
||||
local pid = hdr$process_id;
|
||||
local mid = hdr$message_id;
|
||||
local sid = hdr$session_id;
|
||||
|
||||
if ( mid !in smb_state$pending_cmds )
|
||||
{
|
||||
local tmp_file = SMB::FileInfo($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||
local tmp_cmd = SMB::CmdInfo($ts=network_time(), $uid=c$uid, $id=c$id, $version="SMB2", $command = SMB2::commands[hdr$command]);
|
||||
tmp_cmd$referenced_file = tmp_file;
|
||||
smb_state$pending_cmds[mid] = tmp_cmd;
|
||||
}
|
||||
smb_state$current_cmd = smb_state$pending_cmds[mid];
|
||||
|
||||
if ( tid > 0 )
|
||||
{
|
||||
if ( smb_state$current_cmd?$referenced_tree )
|
||||
{
|
||||
smb_state$tid_map[tid] = smb_state$current_cmd$referenced_tree;
|
||||
}
|
||||
else if ( tid !in smb_state$tid_map )
|
||||
{
|
||||
local tmp_tree = SMB::TreeInfo($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||
smb_state$tid_map[tid] = tmp_tree;
|
||||
}
|
||||
smb_state$current_cmd$referenced_tree = smb_state$tid_map[tid];
|
||||
}
|
||||
else
|
||||
{
|
||||
smb_state$current_cmd$referenced_tree = SMB::TreeInfo($ts=network_time(), $uid=c$uid, $id=c$id);
|
||||
}
|
||||
|
||||
smb_state$current_file = smb_state$current_cmd$referenced_file;
|
||||
smb_state$current_tree = smb_state$current_cmd$referenced_tree;
|
||||
|
||||
if ( !is_orig )
|
||||
{
|
||||
smb_state$current_cmd$rtt = network_time() - smb_state$current_cmd$ts;
|
||||
smb_state$current_cmd$status = SMB::statuses[hdr$status]$id;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_message(c: connection, hdr: SMB2::Header, is_orig: bool) &priority=-5
|
||||
{
|
||||
if ( is_orig )
|
||||
return;
|
||||
|
||||
# If the command that is being looked at right now was
|
||||
# marked as PENDING, then we'll skip all of this and wait
|
||||
# for a reply that isn't marked pending.
|
||||
if ( c$smb_state$current_cmd$status == "PENDING" )
|
||||
return;
|
||||
|
||||
delete c$smb_state$pending_cmds[hdr$message_id];
|
||||
}
|
||||
|
||||
event smb2_negotiate_request(c: connection, hdr: SMB2::Header, dialects: index_vec) &priority=5
|
||||
{
|
||||
c$smb_state$current_cmd$smb2_offered_dialects = dialects;
|
||||
}
|
||||
|
||||
event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2::NegotiateResponse) &priority=5
|
||||
{
|
||||
if ( c$smb_state$current_cmd?$smb2_offered_dialects )
|
||||
{
|
||||
for ( i in c$smb_state$current_cmd$smb2_offered_dialects )
|
||||
{
|
||||
if ( response$dialect_revision == c$smb_state$current_cmd$smb2_offered_dialects[i] )
|
||||
{
|
||||
c$smb_state$current_cmd$argument = SMB2::dialects[response$dialect_revision];
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete c$smb_state$current_cmd$smb2_offered_dialects;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2::NegotiateResponse) &priority=5
|
||||
{
|
||||
# No behavior yet.
|
||||
}
|
||||
|
||||
event smb2_tree_connect_request(c: connection, hdr: SMB2::Header, path: string) &priority=5
|
||||
{
|
||||
c$smb_state$current_tree$path = path;
|
||||
}
|
||||
|
||||
event smb2_tree_connect_response(c: connection, hdr: SMB2::Header, response: SMB2::TreeConnectResponse) &priority=5
|
||||
{
|
||||
c$smb_state$current_tree$share_type = SMB2::share_types[response$share_type];
|
||||
}
|
||||
|
||||
event smb2_tree_connect_response(c: connection, hdr: SMB2::Header, response: SMB2::TreeConnectResponse) &priority=-5
|
||||
{
|
||||
Log::write(SMB::MAPPING_LOG, c$smb_state$current_tree);
|
||||
}
|
||||
|
||||
event smb2_tree_disconnect_request(c: connection, hdr: SMB2::Header) &priority=5
|
||||
{
|
||||
if ( hdr$tree_id in c$smb_state$tid_map )
|
||||
{
|
||||
delete c$smb_state$tid_map[hdr$tree_id];
|
||||
delete c$smb_state$current_tree;
|
||||
delete c$smb_state$current_cmd$referenced_tree;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_create_request(c: connection, hdr: SMB2::Header, request: SMB2::CreateRequest) &priority=5
|
||||
{
|
||||
if ( request$filename == "")
|
||||
request$filename = "<share_root>";
|
||||
|
||||
c$smb_state$current_file$name = request$filename;
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_OPEN;
|
||||
break;
|
||||
case "PIPE":
|
||||
c$smb_state$current_file$action = SMB::PIPE_OPEN;
|
||||
break;
|
||||
case "PRINT":
|
||||
c$smb_state$current_file$action = SMB::PRINT_OPEN;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_OPEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_create_response(c: connection, hdr: SMB2::Header, response: SMB2::CreateResponse) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, response$file_id$persistent+response$file_id$volatile);
|
||||
|
||||
c$smb_state$current_file$fid = response$file_id$persistent+response$file_id$volatile;
|
||||
c$smb_state$current_file$size = response$size;
|
||||
|
||||
if ( c$smb_state$current_tree?$path )
|
||||
c$smb_state$current_file$path = c$smb_state$current_tree$path;
|
||||
|
||||
# I'm seeing negative data from IPC tree transfers
|
||||
if ( time_to_double(response$times$modified) > 0.0 )
|
||||
c$smb_state$current_file$times = response$times;
|
||||
|
||||
# We can identify the file by its file id now so let's stick it
|
||||
# in the file map.
|
||||
c$smb_state$fid_map[response$file_id$persistent+response$file_id$volatile] = c$smb_state$current_file;
|
||||
|
||||
c$smb_state$current_file = c$smb_state$fid_map[response$file_id$persistent+response$file_id$volatile];
|
||||
}
|
||||
|
||||
event smb2_create_response(c: connection, hdr: SMB2::Header, response: SMB2::CreateResponse) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_READ;
|
||||
break;
|
||||
case "PIPE":
|
||||
c$smb_state$current_file$action = SMB::PIPE_READ;
|
||||
break;
|
||||
case "PRINT":
|
||||
c$smb_state$current_file$action = SMB::PRINT_READ;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_READ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_WRITE;
|
||||
break;
|
||||
case "PIPE":
|
||||
c$smb_state$current_file$action = SMB::PIPE_WRITE;
|
||||
break;
|
||||
case "PRINT":
|
||||
c$smb_state$current_file$action = SMB::PRINT_WRITE;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_WRITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_file_sattr(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, times: SMB::MACTimes, attrs: SMB2::FileAttrs) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_file_sattr(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, times: SMB::MACTimes, attrs: SMB2::FileAttrs) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_SET_ATTRIBUTE;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_SET_ATTRIBUTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_file_rename(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, dst_filename: string) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
|
||||
if ( c$smb_state$current_file?$name )
|
||||
c$smb_state$current_file$prev_name = c$smb_state$current_file$name;
|
||||
|
||||
c$smb_state$current_file$name = dst_filename;
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_RENAME;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_RENAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_file_rename(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, dst_filename: string) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_file_delete(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, delete_pending: bool) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
|
||||
if ( ! delete_pending )
|
||||
{
|
||||
# This is weird beause it would mean that someone didn't
|
||||
# set the delete bit in a delete request.
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_DELETE;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_DELETE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_file_delete(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, delete_pending: bool) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
|
||||
switch ( c$smb_state$current_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
c$smb_state$current_file$action = SMB::FILE_CLOSE;
|
||||
break;
|
||||
case "PIPE":
|
||||
c$smb_state$current_file$action = SMB::PIPE_CLOSE;
|
||||
break;
|
||||
case "PRINT":
|
||||
c$smb_state$current_file$action = SMB::PRINT_CLOSE;
|
||||
break;
|
||||
default:
|
||||
c$smb_state$current_file$action = SMB::FILE_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) &priority=-5
|
||||
{
|
||||
if ( file_id$persistent+file_id$volatile in c$smb_state$fid_map )
|
||||
{
|
||||
local fl = c$smb_state$fid_map[file_id$persistent+file_id$volatile];
|
||||
# Need to check for existence of path in case tree connect message wasn't seen.
|
||||
if ( c$smb_state$current_tree?$path )
|
||||
fl$path = c$smb_state$current_tree$path;
|
||||
delete c$smb_state$fid_map[file_id$persistent+file_id$volatile];
|
||||
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
# TODO - Determine correct action
|
||||
# A reporter message is not right...
|
||||
#Reporter::warning("attempting to close an unknown file!");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue