mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
203 lines
No EOL
4.8 KiB
Text
203 lines
No EOL
4.8 KiB
Text
module SMB;
|
|
|
|
export {
|
|
redef enum Log::ID += {
|
|
CMD_LOG,
|
|
MAPPING_LOG,
|
|
FILES_LOG
|
|
};
|
|
|
|
## Abstracted actions for SMB file actions.
|
|
type FileAction: enum {
|
|
FILE_READ,
|
|
FILE_WRITE,
|
|
FILE_OPEN,
|
|
FILE_CLOSE,
|
|
FILE_UNKNOWN,
|
|
};
|
|
|
|
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",
|
|
};
|
|
|
|
type FileInfo: record {
|
|
## Time when the file was first discovered.
|
|
ts : time &log;
|
|
uid : string &log;
|
|
id : conn_id &log;
|
|
fuid : string &log;
|
|
|
|
## Action this log record represents.
|
|
action : FileAction &log &default=FILE_UNKNOWN;
|
|
|
|
## 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;
|
|
## Last time this file was modified.
|
|
times : SMB::MACTimes &log &optional;
|
|
};
|
|
|
|
type TreeInfo: record {
|
|
## Time when the tree was mapped.
|
|
ts : time &log &optional;
|
|
|
|
uid : string &log;
|
|
id : conn_id &log;
|
|
|
|
## Name of the tree path.
|
|
path : string &log &optional;
|
|
service : string &log &optional;
|
|
native_file_system : string &log &optional;
|
|
|
|
## If this is SMB2, a share type will be included.
|
|
share_type : string &log &optional;
|
|
};
|
|
|
|
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;
|
|
|
|
## Server reply to the client's command
|
|
status: 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;
|
|
|
|
## 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;
|
|
};
|
|
|
|
redef record connection += {
|
|
smb : Info &optional;
|
|
};
|
|
|
|
## 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;
|
|
|
|
## 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;
|
|
|
|
## Maintain a reference to the file record.
|
|
f : fa_file &optional;
|
|
};
|
|
|
|
const ports = { 139/tcp, 445/tcp };
|
|
redef likely_server_ports += { ports };
|
|
|
|
event bro_init() &priority=5
|
|
{
|
|
Log::create_stream(CMD_LOG, [$columns=SMB::Info]);
|
|
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)
|
|
{
|
|
if ( file_id !in smb$fid_map )
|
|
{
|
|
smb$fid_map[file_id] = smb$current_cmd$referenced_file;
|
|
smb$fid_map[file_id]$fid = file_id;
|
|
}
|
|
|
|
smb$current_file = smb$fid_map[file_id];
|
|
}
|
|
|
|
function write_file_log(f: FileInfo)
|
|
{
|
|
if ( f?$name &&
|
|
f$name !in pipe_names &&
|
|
f$action in logged_file_actions )
|
|
{
|
|
Log::write(FILES_LOG, f);
|
|
}
|
|
}
|
|
|
|
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 && c$smb?$current_file)
|
|
{
|
|
write_file_log(c$smb$current_file);
|
|
}
|
|
return;
|
|
}
|
|
} |