mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/topic/vladg/smb' into topic/seth/smb
# Conflicts: # scripts/base/protocols/smb/files.bro # scripts/base/protocols/smb/main.bro # scripts/base/protocols/smb/smb1-main.bro # scripts/base/protocols/smb/smb2-main.bro
This commit is contained in:
commit
2e2fb6831f
30 changed files with 1990 additions and 550 deletions
|
@ -9,6 +9,113 @@ export {
|
|||
const statuses: table[count] of StatusCode = {
|
||||
[0x00000000] = [$id="SUCCESS", $desc="The operation completed successfully."],
|
||||
} &redef &default=function(i: count):StatusCode { local unknown=fmt("unknown-%d", i); return [$id=unknown, $desc=unknown]; };
|
||||
|
||||
## These are files names that are used for special
|
||||
## cases by the file system and would not be
|
||||
## considered "normal" files.
|
||||
const pipe_names: set[string] = {
|
||||
"\\netdfs",
|
||||
"\\spoolss",
|
||||
"\\NETLOGON",
|
||||
"\\winreg",
|
||||
"\\lsarpc",
|
||||
"\\samr",
|
||||
"\\srvsvc",
|
||||
"srvsvc",
|
||||
"MsFteWds",
|
||||
"\\wkssvc",
|
||||
};
|
||||
|
||||
## The UUIDs used by the various RPC endpoints
|
||||
const rpc_uuids: table[string] of string = {
|
||||
["4b324fc8-1670-01d3-1278-5a47bf6ee188"] = "Server Service",
|
||||
["6bffd098-a112-3610-9833-46c3f87e345a"] = "Workstation Service",
|
||||
} &redef &default=function(i: string):string { return fmt("unknown-uuid-%s", i); };
|
||||
|
||||
## Server service sub commands
|
||||
const srv_cmds: table[count] of string = {
|
||||
[8] = "NetrConnectionEnum",
|
||||
[9] = "NetrFileEnum",
|
||||
[10] = "NetrFileGetInfo",
|
||||
[11] = "NetrFileClose",
|
||||
[12] = "NetrSessionEnum",
|
||||
[13] = "NetrSessionDel",
|
||||
[14] = "NetrShareAdd",
|
||||
[15] = "NetrShareEnum",
|
||||
[16] = "NetrShareGetInfo",
|
||||
[17] = "NetrShareSetInfo",
|
||||
[18] = "NetrShareDel",
|
||||
[19] = "NetrShareDelSticky",
|
||||
[20] = "NetrShareCheck",
|
||||
[21] = "NetrServerGetInfo",
|
||||
[22] = "NetrServerSetInfo",
|
||||
[23] = "NetrServerDiskEnum",
|
||||
[24] = "NetrServerStatisticsGet",
|
||||
[25] = "NetrServerTransportAdd",
|
||||
[26] = "NetrServerTransportEnum",
|
||||
[27] = "NetrServerTransportDel",
|
||||
[28] = "NetrRemoteTOD",
|
||||
[30] = "NetprPathType",
|
||||
[31] = "NetprPathCanonicalize",
|
||||
[32] = "NetprPathCompare",
|
||||
[33] = "NetprNameValidate",
|
||||
[34] = "NetprNameCanonicalize",
|
||||
[35] = "NetprNameCompare",
|
||||
[36] = "NetrShareEnumSticky",
|
||||
[37] = "NetrShareDelStart",
|
||||
[38] = "NetrShareDelCommit",
|
||||
[39] = "NetrGetFileSecurity",
|
||||
[40] = "NetrSetFileSecurity",
|
||||
[41] = "NetrServerTransportAddEx",
|
||||
[43] = "NetrDfsGetVersion",
|
||||
[44] = "NetrDfsCreateLocalPartition",
|
||||
[45] = "NetrDfsDeleteLocalPartition",
|
||||
[46] = "NetrDfsSetLocalVolumeState",
|
||||
[48] = "NetrDfsCreateExitPoint",
|
||||
[49] = "NetrDfsDeleteExitPoint",
|
||||
[50] = "NetrDfsModifyPrefix",
|
||||
[51] = "NetrDfsFixLocalVolume",
|
||||
[52] = "NetrDfsManagerReportSiteInfo",
|
||||
[53] = "NetrServerTransportDelEx",
|
||||
[54] = "NetrServerAliasAdd",
|
||||
[55] = "NetrServerAliasEnum",
|
||||
[56] = "NetrServerAliasDel",
|
||||
[57] = "NetrShareDelEx",
|
||||
} &redef &default=function(i: count):string { return fmt("unknown-srv-command-%d", i); };
|
||||
|
||||
## Workstation service sub commands
|
||||
const wksta_cmds: table[count] of string = {
|
||||
[0] = "NetrWkstaGetInfo",
|
||||
[1] = "NetrWkstaSetInfo",
|
||||
[2] = "NetrWkstaUserEnum",
|
||||
[5] = "NetrWkstaTransportEnum",
|
||||
[6] = "NetrWkstaTransportAdd",
|
||||
[7] = "NetrWkstaTransportDel",
|
||||
[8] = "NetrUseAdd",
|
||||
[9] = "NetrUseGetInfo",
|
||||
[10] = "NetrUseDel",
|
||||
[11] = "NetrUseEnum",
|
||||
[13] = "NetrWorkstationStatisticsGet",
|
||||
[20] = "NetrGetJoinInformation",
|
||||
[22] = "NetrJoinDomain2",
|
||||
[23] = "NetrUnjoinDomain2",
|
||||
[24] = "NetrRenameMachineInDomain2",
|
||||
[25] = "NetrValidateName2",
|
||||
[26] = "NetrGetJoinableOUs2",
|
||||
[27] = "NetrAddAlternateComputerName",
|
||||
[28] = "NetrRemoveAlternateComputerName",
|
||||
[29] = "NetrSetPrimaryComputerName",
|
||||
[30] = "NetrEnumerateComputerNames",
|
||||
} &redef &default=function(i: count):string { return fmt("unknown-wksta-command-%d", i); };
|
||||
|
||||
type rpc_cmd_table: table[count] of string;
|
||||
|
||||
## The subcommands for RPC endpoints
|
||||
const rpc_sub_cmds: table[string] of rpc_cmd_table = {
|
||||
["4b324fc8-1670-01d3-1278-5a47bf6ee188"] = srv_cmds,
|
||||
["6bffd098-a112-3610-9833-46c3f87e345a"] = wksta_cmds,
|
||||
} &redef &default=function(i: string):rpc_cmd_table { return table() &default=function(j: string):string { return fmt("unknown-uuid-%s", j); }; };
|
||||
|
||||
}
|
||||
|
||||
module SMB1;
|
||||
|
@ -88,6 +195,40 @@ export {
|
|||
[0xD9] = "WRITE_BULK",
|
||||
[0xDA] = "WRITE_BULK_DATA",
|
||||
} &default=function(i: count):string { return fmt("unknown-%d", i); };
|
||||
|
||||
const trans2_sub_commands: table[count] of string = {
|
||||
[0x00] = "OPEN2",
|
||||
[0x01] = "FIND_FIRST2",
|
||||
[0x02] = "FIND_NEXT2",
|
||||
[0x03] = "QUERY_FS_INFORMATION",
|
||||
[0x04] = "SET_FS_INFORMATION",
|
||||
[0x05] = "QUERY_PATH_INFORMATION",
|
||||
[0x06] = "SET_PATH_INFORMATION",
|
||||
[0x07] = "QUERY_FILE_INFORMATION",
|
||||
[0x08] = "SET_FILE_INFORMATION",
|
||||
[0x09] = "FSCTL",
|
||||
[0x0A] = "IOCTL",
|
||||
[0x0B] = "FIND_NOTIFY_FIRST",
|
||||
[0x0C] = "FIND_NOTIFY_NEXT",
|
||||
[0x0D] = "CREATE_DIRECTORY",
|
||||
[0x0E] = "SESSION_SETUP",
|
||||
[0x10] = "GET_DFS_REFERRAL",
|
||||
[0x11] = "REPORT_DFS_INCONSISTENCY",
|
||||
} &default=function(i: count):string { return fmt("unknown-trans2-sub-cmd-%d", i); };
|
||||
|
||||
const trans_sub_commands: table[count] of string = {
|
||||
[0x01] = "SET_NMPIPE_STATE",
|
||||
[0x11] = "RAW_READ_NMPIPE",
|
||||
[0x21] = "QUERY_NMPIPE_STATE",
|
||||
[0x22] = "QUERY_NMPIPE_INFO",
|
||||
[0x23] = "PEEK_NMPIPE",
|
||||
[0x26] = "TRANSACT_NMPIPE",
|
||||
[0x31] = "RAW_WRITE_NMPIPE",
|
||||
[0x36] = "READ_NMPIPE",
|
||||
[0x37] = "WRITE_NMPIPE",
|
||||
[0x53] = "WAIT_NMPIPE",
|
||||
[0x54] = "CALL_NMPIPE",
|
||||
} &default=function(i: count):string { return fmt("unknown-trans-sub-cmd-%d", i); };
|
||||
}
|
||||
|
||||
module SMB2;
|
||||
|
|
|
@ -12,15 +12,15 @@ export {
|
|||
|
||||
function get_file_handle(c: connection, is_orig: bool): string
|
||||
{
|
||||
if ( ! (c$smb?$current_file &&
|
||||
((c$smb$current_file?$name && c$smb$current_file$name !in pipe_names) ||
|
||||
c$smb$current_file?$path)) )
|
||||
if ( ! (c$smb_state?$current_file &&
|
||||
((c$smb_state$current_file?$name && c$smb_state$current_file$name !in pipe_names) ||
|
||||
c$smb_state$current_file?$path)) )
|
||||
{
|
||||
# TODO: figure out what are the cases where this happens.
|
||||
# TODO - figure out what are the cases where this happens.
|
||||
return "";
|
||||
}
|
||||
|
||||
local current_file = c$smb$current_file;
|
||||
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
|
||||
|
@ -38,8 +38,8 @@ function describe_file(f: fa_file): string
|
|||
for ( cid in f$conns )
|
||||
{
|
||||
local info = f$conns[cid];
|
||||
if ( info?$smb && info$smb?$current_file && info$smb$current_file?$name )
|
||||
return info$smb$current_file$name;
|
||||
if ( info?$smb_state && info$smb_state?$current_file && info$smb_state$current_file?$name )
|
||||
return info$smb_state$current_file$name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -53,14 +53,14 @@ event bro_init() &priority=5
|
|||
|
||||
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5
|
||||
{
|
||||
if ( c?$smb && c$smb?$current_file )
|
||||
if ( c?$smb_state && c$smb_state?$current_file )
|
||||
{
|
||||
c$smb$current_file$fuid = f$id;
|
||||
c$smb_state$current_file$fuid = f$id;
|
||||
|
||||
if ( c$smb$current_file$size > 0 )
|
||||
f$total_bytes = c$smb$current_file$size;
|
||||
if ( c$smb_state$current_file$size > 0 )
|
||||
f$total_bytes = c$smb_state$current_file$size;
|
||||
|
||||
if ( c$smb$current_file?$name )
|
||||
f$info$filename = c$smb$current_file$name;
|
||||
if ( c$smb_state$current_file?$name )
|
||||
f$info$filename = c$smb_state$current_file$name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@load ./consts
|
||||
|
||||
module SMB;
|
||||
|
||||
export {
|
||||
|
@ -16,141 +18,154 @@ export {
|
|||
FILE_UNKNOWN,
|
||||
};
|
||||
|
||||
## The file actions which are logged.
|
||||
const logged_file_actions: set[FileAction] = {
|
||||
FILE_OPEN,
|
||||
FILE_READ,
|
||||
FILE_WRITE,
|
||||
};
|
||||
|
||||
## These are files names that are used for special
|
||||
## cases by the file system and would not be
|
||||
## considered "normal" files.
|
||||
const pipe_names: set[string] = {
|
||||
"\\netdfs",
|
||||
"\\spoolss",
|
||||
"\\NETLOGON",
|
||||
"\\winreg",
|
||||
"\\lsarpc",
|
||||
"\\samr",
|
||||
"\\srvsvc",
|
||||
"srvsvc",
|
||||
"MsFteWds",
|
||||
"\\wkssvc",
|
||||
};
|
||||
} &redef;
|
||||
|
||||
## The server response statuses which are *not* logged.
|
||||
const ignored_command_statuses: set[string] = {
|
||||
"MORE_PROCESSING_REQUIRED",
|
||||
} &redef;
|
||||
|
||||
## This record is for the smb_files.log
|
||||
type FileInfo: record {
|
||||
## Time when the file was first discovered.
|
||||
ts : time &log;
|
||||
uid : string &log;
|
||||
id : conn_id &log;
|
||||
fuid : string &log;
|
||||
|
||||
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 : FileAction &log &default=FILE_UNKNOWN;
|
||||
|
||||
action : FileAction &log &default=FILE_UNKNOWN;
|
||||
## Path pulled from the tree this file was transferred to or from.
|
||||
path : string &log &optional;
|
||||
path : string &log &optional;
|
||||
## Filename if one was seen.
|
||||
name : string &log &optional;
|
||||
|
||||
name : string &log &optional;
|
||||
## Total size of the file.
|
||||
size : count &log &default=0;
|
||||
size : count &log &default=0;
|
||||
## Last time this file was modified.
|
||||
times : SMB::MACTimes &log &optional;
|
||||
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;
|
||||
|
||||
uid : string &log;
|
||||
id : conn_id &log;
|
||||
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;
|
||||
service : string &log &optional;
|
||||
native_file_system : string &log &optional;
|
||||
|
||||
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.
|
||||
share_type : string &log &optional;
|
||||
share_type : string &log &optional;
|
||||
};
|
||||
|
||||
|
||||
## This record is for the smb_cmd.log
|
||||
type CmdInfo: record {
|
||||
## The command.
|
||||
command : string &optional;
|
||||
|
||||
## If the command referenced a file, store it here.
|
||||
referenced_file : FileInfo &optional;
|
||||
## If the command referenced a tree, store it here.
|
||||
referenced_tree : TreeInfo &optional;
|
||||
};
|
||||
|
||||
type Info: record {
|
||||
ts: time &log;
|
||||
uid: string &log;
|
||||
id: conn_id &log;
|
||||
|
||||
## Version of SMB for the command.
|
||||
version: string &log;
|
||||
|
||||
## Command sent by the client.
|
||||
command: string &log &optional;
|
||||
|
||||
## 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;
|
||||
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 negotiated dialect for the connection.
|
||||
dialect: string &log &optional;
|
||||
|
||||
## Round trip time from the request to the response.
|
||||
rtt: interval &log &optional;
|
||||
## 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 &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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
redef record connection += {
|
||||
smb : Info &optional;
|
||||
smb_state : State &optional;
|
||||
};
|
||||
|
||||
|
||||
## Internal use only
|
||||
## Some commands shouldn't be logged by the smb1_message event
|
||||
const deferred_logging_cmds: set[string] = {
|
||||
"NEGOTIATE",
|
||||
"READ_ANDX",
|
||||
"SESSION_SETUP_ANDX",
|
||||
"TREE_CONNECT_ANDX",
|
||||
};
|
||||
|
||||
## Optionally write out the SMB commands log. This is
|
||||
## primarily useful for debugging so is disabled by default.
|
||||
const write_cmd_log = F &redef;
|
||||
|
||||
## This is an internally used function.
|
||||
const set_current_file: function(smb: Info, file_id: count) &redef;
|
||||
const set_current_file: function(smb_state: State, file_id: count) &redef;
|
||||
|
||||
## This is an internally used function.
|
||||
const write_file_log: function(f: FileInfo) &redef;
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
smb_pending_cmds : table[count, count] of Info &default=table();
|
||||
};
|
||||
|
||||
redef record FileInfo += {
|
||||
## ID referencing this file.
|
||||
fid : count &optional;
|
||||
fid : count &optional;
|
||||
|
||||
## Maintain a reference to the file record.
|
||||
f : fa_file &optional;
|
||||
f : fa_file &optional;
|
||||
|
||||
## UUID referencing this file if DCE/RPC
|
||||
uuid: string &optional;
|
||||
};
|
||||
|
||||
const ports = { 139/tcp, 445/tcp };
|
||||
|
@ -158,22 +173,22 @@ redef likely_server_ports += { ports };
|
|||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(CMD_LOG, [$columns=SMB::Info]);
|
||||
Log::create_stream(CMD_LOG, [$columns=SMB::CmdInfo]);
|
||||
Log::create_stream(FILES_LOG, [$columns=SMB::FileInfo]);
|
||||
Log::create_stream(MAPPING_LOG, [$columns=SMB::TreeInfo]);
|
||||
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SMB, ports);
|
||||
}
|
||||
|
||||
function set_current_file(smb: Info, file_id: count)
|
||||
function set_current_file(smb_state: State, file_id: count)
|
||||
{
|
||||
if ( file_id !in smb$fid_map )
|
||||
if ( file_id !in smb_state$fid_map )
|
||||
{
|
||||
smb$fid_map[file_id] = smb$current_cmd$referenced_file;
|
||||
smb$fid_map[file_id]$fid = file_id;
|
||||
smb_state$fid_map[file_id] = smb_state$current_cmd$referenced_file;
|
||||
smb_state$fid_map[file_id]$fid = file_id;
|
||||
}
|
||||
|
||||
smb$current_file = smb$fid_map[file_id];
|
||||
smb_state$current_file = smb_state$fid_map[file_id];
|
||||
}
|
||||
|
||||
function write_file_log(f: FileInfo)
|
||||
|
@ -194,9 +209,9 @@ event file_state_remove(f: fa_file) &priority=-5
|
|||
for ( id in f$conns )
|
||||
{
|
||||
local c = f$conns[id];
|
||||
if ( c?$smb && c$smb?$current_file)
|
||||
if ( c?$smb_state && c$smb_state?$current_file)
|
||||
{
|
||||
write_file_log(c$smb$current_file);
|
||||
write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,197 +1,355 @@
|
|||
module SMB1;
|
||||
|
||||
redef record SMB::Info += {
|
||||
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 )
|
||||
if ( ! c?$smb_state )
|
||||
{
|
||||
local info: SMB::Info = [$ts=network_time(), $uid=c$uid, $id=c$id, $version="SMB1"];
|
||||
info$fid_map = table();
|
||||
info$tid_map = table();
|
||||
info$pending_cmds = table();
|
||||
c$smb = info;
|
||||
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 = c$smb;
|
||||
|
||||
local smb_state = c$smb_state;
|
||||
local tid = hdr$tid;
|
||||
local pid = hdr$pid;
|
||||
local uid = hdr$uid;
|
||||
local pid = hdr$pid;
|
||||
local mid = hdr$mid;
|
||||
|
||||
if ( tid !in smb$tid_map )
|
||||
|
||||
if ( uid in smb_state$uid_map )
|
||||
{
|
||||
smb_state$current_cmd$username = smb_state$uid_map[uid];
|
||||
}
|
||||
|
||||
if ( tid !in smb_state$tid_map )
|
||||
{
|
||||
local tmp_tree: SMB::TreeInfo = [$uid=c$uid, $id=c$id];
|
||||
smb$tid_map[tid] = tmp_tree;
|
||||
smb_state$tid_map[tid] = tmp_tree;
|
||||
}
|
||||
smb$current_tree = smb$tid_map[tid];
|
||||
|
||||
if ( mid !in smb$pending_cmds )
|
||||
smb_state$current_tree = smb_state$tid_map[tid];
|
||||
if ( smb_state$current_tree?$path )
|
||||
{
|
||||
local tmp_cmd: SMB::CmdInfo;
|
||||
tmp_cmd$command = SMB1::commands[hdr$command];
|
||||
|
||||
local tmp_file: SMB::FileInfo;
|
||||
tmp_file$ts = network_time();
|
||||
tmp_file$id = c$id;
|
||||
tmp_file$uid = c$uid;
|
||||
tmp_cmd$referenced_file = tmp_file;
|
||||
tmp_cmd$referenced_tree = smb$current_tree;
|
||||
smb_state$current_cmd$tree = smb_state$current_tree$path;
|
||||
}
|
||||
|
||||
smb$pending_cmds[mid] = tmp_cmd;
|
||||
if ( smb_state$current_tree?$service )
|
||||
{
|
||||
smb_state$current_cmd$tree_service = smb_state$current_tree$service;
|
||||
}
|
||||
|
||||
smb$current_cmd = smb$pending_cmds[mid];
|
||||
smb$command = smb$current_cmd$command;
|
||||
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]];
|
||||
|
||||
if ( is_orig )
|
||||
{
|
||||
smb$ts = network_time();
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
||||
smb_state$current_cmd = smb_state$pending_cmds[mid];
|
||||
|
||||
if ( !is_orig )
|
||||
{
|
||||
smb$rtt = network_time() - smb$ts;
|
||||
smb$status = SMB::statuses[hdr$status]$id;
|
||||
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
|
||||
{
|
||||
# Is this a response?
|
||||
if ( !is_orig )
|
||||
# This is a response and the command is no longer pending
|
||||
# so let's get rid of it.
|
||||
delete c$smb$pending_cmds[hdr$mid];
|
||||
{
|
||||
if ( SMB::write_cmd_log &&
|
||||
c$smb_state$current_cmd$status !in SMB::ignored_command_statuses &&
|
||||
c$smb_state$current_cmd$command !in SMB::deferred_logging_cmds )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
delete c$smb_state$pending_cmds[hdr$mid];
|
||||
}
|
||||
}
|
||||
|
||||
if ( SMB::write_cmd_log && c?$smb )
|
||||
Log::write(SMB::CMD_LOG, c$smb);
|
||||
|
||||
event smb1_transaction2_request(c: connection, hdr: SMB1::Header, 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$smb1_offered_dialects = dialects;
|
||||
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?$smb1_offered_dialects )
|
||||
if ( c$smb_state$current_cmd?$smb1_offered_dialects )
|
||||
{
|
||||
if ( response?$ntlm )
|
||||
c$smb$dialect = c$smb$smb1_offered_dialects[response$ntlm$dialect_index];
|
||||
delete c$smb$smb1_offered_dialects;
|
||||
{
|
||||
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
|
||||
{
|
||||
if ( c$smb_state$current_cmd$status !in SMB::ignored_command_statuses )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
event smb1_tree_connect_andx_request(c: connection, hdr: SMB1::Header, path: string, service: string) &priority=5
|
||||
{
|
||||
c$smb$current_cmd$referenced_tree$path = path;
|
||||
c$smb$current_cmd$referenced_tree$service = service;
|
||||
c$smb$current_tree$ts=network_time();
|
||||
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$current_cmd$referenced_tree$native_file_system = native_file_system;
|
||||
c$smb$current_tree = c$smb$current_cmd$referenced_tree;
|
||||
c$smb$tid_map[hdr$tid] = c$smb$current_tree;
|
||||
c$smb_state$current_cmd$referenced_tree$service = service;
|
||||
c$smb_state$current_cmd$tree_service = service;
|
||||
|
||||
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$current_tree);
|
||||
Log::write(SMB::MAPPING_LOG, c$smb_state$current_tree);
|
||||
|
||||
if ( c$smb_state$current_cmd$status !in SMB::ignored_command_statuses )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
event smb1_nt_create_andx_request(c: connection, hdr: SMB1::Header, name: string) &priority=5
|
||||
{
|
||||
c$smb$current_cmd$referenced_file$name = name;
|
||||
c$smb$current_file = c$smb$current_cmd$referenced_file;
|
||||
c$smb$current_file$action = SMB::FILE_OPEN;
|
||||
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
|
||||
{
|
||||
if ( ! c$smb?$current_file )
|
||||
{
|
||||
c$smb$current_file = c$smb$current_cmd$referenced_file;
|
||||
c$smb$current_file$action = SMB::FILE_OPEN;
|
||||
}
|
||||
c$smb$current_file$fid = file_id;
|
||||
c$smb$current_file$size = file_size;
|
||||
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$current_file$times = times;
|
||||
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$fid_map[file_id] = c$smb$current_file;
|
||||
}
|
||||
c$smb_state$fid_map[file_id] = c$smb_state$current_cmd$referenced_file;
|
||||
|
||||
event smb1_nt_create_andx_response(c: connection, hdr: SMB1::Header, file_id: count, file_size: count, times: SMB::MACTimes) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb$current_file);
|
||||
c$smb_state$current_file = c$smb_state$fid_map[file_id];
|
||||
|
||||
|
||||
SMB::write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
|
||||
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, file_id);
|
||||
c$smb$current_file$action = SMB::FILE_READ;
|
||||
SMB::set_current_file(c$smb_state, file_id);
|
||||
c$smb_state$current_file$action = SMB::FILE_READ;
|
||||
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;
|
||||
|
||||
if ( c$smb$current_tree?$path && !c$smb$current_file?$path )
|
||||
c$smb$current_file$path = c$smb$current_tree$path;
|
||||
|
||||
#write_file_log(c$smb$current_file);
|
||||
# TODO - Why is this commented out?
|
||||
#write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
|
||||
event smb1_read_andx_response(c: connection, hdr: SMB1::Header, data_len: count) &priority=5
|
||||
{
|
||||
#print "read andx response!";
|
||||
if ( c$smb_state$current_cmd$status !in SMB::ignored_command_statuses )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
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, file_id);
|
||||
c$smb$current_file$action = SMB::FILE_WRITE;
|
||||
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 )
|
||||
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$current_tree?$path && !c$smb$current_file?$path )
|
||||
c$smb$current_file$path = c$smb$current_tree$path;
|
||||
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;
|
||||
|
||||
#write_file_log(c$smb$current_file);
|
||||
# TODO - Why is this commented out?
|
||||
#write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
|
||||
#event smb1_write_andx_response(c: connection, hdr: SMB1::Header, written_bytes: count) &priority=5
|
||||
# {
|
||||
# # Do i really need to do anything here? Maybe do a weird if the number of bytes written is odd?
|
||||
# # 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, file_id);
|
||||
c$smb$current_file$action = SMB::FILE_CLOSE;
|
||||
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$fid_map )
|
||||
if ( file_id in c$smb_state$fid_map )
|
||||
{
|
||||
local fl = c$smb$fid_map[file_id];
|
||||
fl$uid = c$uid;
|
||||
fl$id = c$id;
|
||||
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$current_tree?$path )
|
||||
fl$path = c$smb$current_tree$path;
|
||||
delete c$smb$fid_map[file_id];
|
||||
if ( c$smb_state$current_tree?$path )
|
||||
fl$path = c$smb_state$current_tree$path;
|
||||
|
||||
c$smb_state$current_cmd$argument = fl$name;
|
||||
|
||||
delete c$smb_state$fid_map[file_id];
|
||||
|
||||
SMB::write_file_log(fl);
|
||||
}
|
||||
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, max_referral_level: count)
|
||||
{
|
||||
c$smb_state$current_cmd$argument = file_name;
|
||||
}
|
||||
|
||||
event smb1_trans2_query_path_info_request(c: connection, hdr: SMB1::Header, file_name: string, level_of_interets: count)
|
||||
{
|
||||
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_response(c: connection, hdr: SMB1::Header, response: SMB1::SessionSetupAndXResponse) &priority=-5
|
||||
{
|
||||
if ( c$smb_state$current_cmd$status !in SMB::ignored_command_statuses )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
event smb_ntlm_negotiate(c: connection, hdr: SMB1::Header, request: SMB::NTLMNegotiate)
|
||||
{
|
||||
c$smb_state$current_cmd$sub_command = "NTLMSSP_NEGOTIATE";
|
||||
}
|
||||
|
||||
event smb1_error(c: connection, hdr: SMB1::Header, is_orig: bool)
|
||||
{
|
||||
if ( ! is_orig )
|
||||
{
|
||||
# This is for deferred commands only.
|
||||
# The more specific messages won't fire for errors
|
||||
if ( ( c$smb_state$current_cmd$status !in SMB::ignored_command_statuses ) &&
|
||||
( c$smb_state$current_cmd$command in SMB::deferred_logging_cmds ) )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event smb_ntlm_authenticate(c: connection, hdr: SMB1::Header, request: SMB::NTLMAuthenticate)
|
||||
{
|
||||
c$smb_state$current_cmd$sub_command = "NTLMSSP_AUTHENTICATE";
|
||||
|
||||
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 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];
|
||||
}
|
||||
|
||||
event smb1_write_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, data_len: count)
|
||||
{
|
||||
c$smb_state$pipe_map[file_id] = c$smb_state$current_file$uuid;
|
||||
}
|
||||
|
||||
event smb_pipe_bind_ack_response(c: connection, hdr: SMB1::Header)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
c$smb_state$current_cmd$argument = fmt("%s: %s", SMB::rpc_uuids[c$smb_state$current_file$uuid],
|
||||
SMB::rpc_sub_cmds[c$smb_state$current_file$uuid][op_num]);
|
||||
}
|
||||
|
||||
#event smb1_transaction_setup(c: connection, hdr: SMB1::Header, op_code: count, file_id: count)
|
||||
# {
|
||||
# local uuid = SMB::rpc_uuids[c$smb_state$pipe_map[file_id]];
|
||||
# if ( uuid in SMB::rpc_uuids )
|
||||
# {
|
||||
# print fmt("smb1_transaction_setup %s", SMB::rap_cmds[op_code]);
|
||||
# }
|
||||
# }
|
|
@ -1,141 +1,143 @@
|
|||
module SMB2;
|
||||
|
||||
redef record SMB::Info += {
|
||||
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 )
|
||||
if ( ! c?$smb_state )
|
||||
{
|
||||
local info: SMB::Info = [$ts=network_time(), $uid=c$uid, $id=c$id, $version="SMB2"];
|
||||
info$fid_map = table();
|
||||
info$tid_map = table();
|
||||
info$pending_cmds = table();
|
||||
c$smb = info;
|
||||
local state: SMB::State;
|
||||
state$fid_map = table();
|
||||
state$tid_map = table();
|
||||
state$pending_cmds = table();
|
||||
c$smb_state = state;
|
||||
}
|
||||
|
||||
local smb = c$smb;
|
||||
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 ( tid !in smb$tid_map )
|
||||
if ( tid !in smb_state$tid_map )
|
||||
{
|
||||
local tmp_tree: SMB::TreeInfo = [$uid=c$uid, $id=c$id];
|
||||
smb$tid_map[tid] = tmp_tree;
|
||||
smb_state$tid_map[tid] = tmp_tree;
|
||||
}
|
||||
smb$current_tree = smb$tid_map[tid];
|
||||
smb_state$current_tree = smb_state$tid_map[tid];
|
||||
|
||||
if ( mid !in smb$pending_cmds )
|
||||
if ( mid !in smb_state$pending_cmds )
|
||||
{
|
||||
local tmp_cmd: SMB::CmdInfo;
|
||||
tmp_cmd$command = SMB2::commands[hdr$command];
|
||||
local tmp_cmd: SMB::CmdInfo = [$ts=network_time(), $uid=c$uid, $id=c$id, $version="SMB2", $command = SMB2::commands[hdr$command]];
|
||||
|
||||
local tmp_file: SMB::FileInfo;
|
||||
tmp_file$ts = network_time();
|
||||
tmp_file$id = c$id;
|
||||
tmp_file$uid = c$uid;
|
||||
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$current_tree;
|
||||
tmp_cmd$referenced_tree = smb_state$current_tree;
|
||||
|
||||
smb$pending_cmds[mid] = tmp_cmd;
|
||||
smb_state$pending_cmds[mid] = tmp_cmd;
|
||||
}
|
||||
|
||||
smb$current_cmd = smb$pending_cmds[mid];
|
||||
smb$command = smb$current_cmd$command;
|
||||
smb_state$current_cmd = smb_state$pending_cmds[mid];
|
||||
|
||||
if ( is_orig )
|
||||
if ( !is_orig )
|
||||
{
|
||||
smb$ts = network_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
smb$rtt = network_time() - smb$ts;
|
||||
smb$status = SMB::statuses[hdr$status]$id;
|
||||
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
|
||||
{
|
||||
# Is this a response?
|
||||
if ( !is_orig )
|
||||
# This is a response and the command is no longer pending
|
||||
# so let's get rid of it.
|
||||
delete c$smb$pending_cmds[hdr$message_id];
|
||||
|
||||
if ( SMB::write_cmd_log && c?$smb )
|
||||
Log::write(SMB::CMD_LOG, c$smb);
|
||||
{
|
||||
if ( SMB::write_cmd_log &&
|
||||
c$smb_state$current_cmd$status !in SMB::ignored_command_statuses &&
|
||||
c$smb_state$current_cmd$command !in SMB::deferred_logging_cmds )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
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$smb2_offered_dialects = dialects;
|
||||
c$smb_state$current_cmd$smb2_offered_dialects = dialects;
|
||||
}
|
||||
|
||||
event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2::NegotiateResponse)
|
||||
event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2::NegotiateResponse) &priority=5
|
||||
{
|
||||
if ( c$smb?$smb2_offered_dialects )
|
||||
if ( c$smb_state$current_cmd?$smb2_offered_dialects )
|
||||
{
|
||||
for ( i in c$smb$smb2_offered_dialects )
|
||||
for ( i in c$smb_state$current_cmd$smb2_offered_dialects )
|
||||
{
|
||||
if ( response$dialect_revision == c$smb$smb2_offered_dialects[i] )
|
||||
if ( response$dialect_revision == c$smb_state$current_cmd$smb2_offered_dialects[i] )
|
||||
{
|
||||
c$smb$dialect = SMB2::dialects[response$dialect_revision];
|
||||
c$smb_state$current_cmd$argument = SMB2::dialects[response$dialect_revision];
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete c$smb$smb2_offered_dialects;
|
||||
delete c$smb_state$current_cmd$smb2_offered_dialects;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2::NegotiateResponse) &priority=5
|
||||
{
|
||||
if ( c$smb_state$current_cmd$status !in SMB::ignored_command_statuses )
|
||||
{
|
||||
Log::write(SMB::CMD_LOG, c$smb_state$current_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_tree_connect_request(c: connection, hdr: SMB2::Header, path: string) &priority=5
|
||||
{
|
||||
c$smb$current_cmd$referenced_tree$path = path;
|
||||
c$smb$current_tree$ts=network_time();
|
||||
local tmp_tree: SMB::TreeInfo = [$ts=network_time(), $uid=c$uid, $id=c$id, $path=path];
|
||||
|
||||
c$smb_state$current_cmd$referenced_tree = tmp_tree;
|
||||
}
|
||||
|
||||
event smb2_tree_connect_response(c: connection, hdr: SMB2::Header, response: SMB2::TreeConnectResponse) &priority=5
|
||||
{
|
||||
c$smb$current_tree = c$smb$current_cmd$referenced_tree;
|
||||
c$smb$current_tree$share_type = SMB2::share_types[response$share_type];
|
||||
c$smb$tid_map[hdr$tree_id] = c$smb$current_tree;
|
||||
c$smb_state$current_cmd$referenced_tree$share_type = SMB2::share_types[response$share_type];
|
||||
c$smb_state$current_tree = c$smb_state$current_cmd$referenced_tree;
|
||||
c$smb_state$tid_map[hdr$tree_id] = c$smb_state$current_tree;
|
||||
}
|
||||
|
||||
event smb2_tree_connect_response(c: connection, hdr: SMB2::Header, response: SMB2::TreeConnectResponse) &priority=-5
|
||||
{
|
||||
Log::write(SMB::MAPPING_LOG, c$smb$current_tree);
|
||||
Log::write(SMB::MAPPING_LOG, c$smb_state$current_tree);
|
||||
}
|
||||
|
||||
event smb2_create_request(c: connection, hdr: SMB2::Header, name: string) &priority=5
|
||||
{
|
||||
c$smb$current_cmd$referenced_file$name = name;
|
||||
c$smb$current_file = c$smb$current_cmd$referenced_file;
|
||||
c$smb$current_file$action = SMB::FILE_OPEN;
|
||||
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;
|
||||
}
|
||||
|
||||
event smb2_create_response(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, file_size: count, times: SMB::MACTimes, attrs: SMB2::FileAttrs) &priority=5
|
||||
{
|
||||
if ( ! c$smb?$current_file )
|
||||
{
|
||||
c$smb$current_file = c$smb$current_cmd$referenced_file;
|
||||
c$smb$current_file$action = SMB::FILE_OPEN;
|
||||
}
|
||||
c$smb$current_file$fid = file_id$persistent+file_id$volatile;
|
||||
c$smb$current_file$size = file_size;
|
||||
c$smb_state$current_cmd$referenced_file$action = SMB::FILE_OPEN;
|
||||
c$smb_state$current_cmd$referenced_file$fid = file_id$persistent+file_id$volatile;
|
||||
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$current_file$times = times;
|
||||
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$fid_map[file_id$persistent+file_id$volatile] = c$smb$current_file;
|
||||
}
|
||||
|
||||
event smb2_create_response(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, file_size: count, times: SMB::MACTimes, attrs: SMB2::FileAttrs) &priority=-5
|
||||
{
|
||||
SMB::write_file_log(c$smb$current_file);
|
||||
c$smb_state$fid_map[file_id$persistent+file_id$volatile] = c$smb_state$current_cmd$referenced_file;
|
||||
|
||||
c$smb_state$current_file = c$smb_state$fid_map[file_id$persistent+file_id$volatile];
|
||||
|
||||
SMB::write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
|
||||
event smb2_set_info_request(c: connection, hdr: SMB2::Header, request: SMB2::SetInfoRequest) &priority=5
|
||||
|
@ -145,46 +147,55 @@ event smb2_set_info_request(c: connection, hdr: SMB2::Header, request: SMB2::Set
|
|||
|
||||
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, file_id$persistent+file_id$volatile);
|
||||
c$smb$current_file$action = SMB::FILE_READ;
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
c$smb_state$current_file$action = SMB::FILE_READ;
|
||||
}
|
||||
|
||||
if ( c$smb$current_tree?$path && !c$smb$current_file?$path )
|
||||
c$smb$current_file$path = c$smb$current_tree$path;
|
||||
event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, 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;
|
||||
|
||||
#write_file_log(c$smb$current_file);
|
||||
# TODO - Why is this commented out?
|
||||
#write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
|
||||
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, file_id$persistent+file_id$volatile);
|
||||
c$smb$current_file$action = SMB::FILE_WRITE;
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
c$smb_state$current_file$action = SMB::FILE_WRITE;
|
||||
}
|
||||
|
||||
if ( c$smb$current_tree?$path && ! c$smb$current_file?$path )
|
||||
c$smb$current_file$path = c$smb$current_tree$path;
|
||||
event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, 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;
|
||||
|
||||
# TODO - Why is this commented out?
|
||||
#write_file_log(c$smb_state$current_file);
|
||||
}
|
||||
|
||||
event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) &priority=5
|
||||
{
|
||||
SMB::set_current_file(c$smb, file_id$persistent+file_id$volatile);
|
||||
c$smb$current_file$action = SMB::FILE_CLOSE;
|
||||
SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile);
|
||||
c$smb_state$current_file$action = SMB::FILE_CLOSE;
|
||||
}
|
||||
|
||||
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$fid_map )
|
||||
if ( file_id$persistent+file_id$volatile in c$smb_state$fid_map )
|
||||
{
|
||||
local fl = c$smb$fid_map[file_id$persistent+file_id$volatile];
|
||||
fl$uid = c$uid;
|
||||
fl$id = c$id;
|
||||
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$current_tree?$path )
|
||||
fl$path = c$smb$current_tree$path;
|
||||
delete c$smb$fid_map[file_id$persistent+file_id$volatile];
|
||||
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(fl);
|
||||
}
|
||||
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