mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
A lot of changes to SMB analyzer.
- Add beginning of infrastructure for pipe support in SMB2. - Improve identification of non-file tree mappings. - Stop passing pipe data to the file analysis framework. - Reduce log volume in smb_files.log by watching for repeated files being seen so that you don't end up with nearly the exact same log line over and over and over. - Lots of little whitespace and indentation changes.
This commit is contained in:
parent
41e2eaa02d
commit
d453dc149c
14 changed files with 252 additions and 138 deletions
|
@ -10,19 +10,42 @@ export {
|
|||
};
|
||||
|
||||
## Abstracted actions for SMB file actions.
|
||||
type FileAction: enum {
|
||||
type Action: enum {
|
||||
FILE_READ,
|
||||
FILE_WRITE,
|
||||
FILE_OPEN,
|
||||
FILE_CLOSE,
|
||||
FILE_UNKNOWN,
|
||||
|
||||
PIPE_READ,
|
||||
PIPE_WRITE,
|
||||
PIPE_OPEN,
|
||||
PIPE_CLOSE,
|
||||
|
||||
PRINT_READ,
|
||||
PRINT_WRITE,
|
||||
PRINT_OPEN,
|
||||
PRINT_CLOSE,
|
||||
|
||||
UNKNOWN_READ,
|
||||
UNKNOWN_WRITE,
|
||||
UNKNOWN_OPEN,
|
||||
UNKNOWN_CLOSE,
|
||||
};
|
||||
|
||||
## The file actions which are logged.
|
||||
const logged_file_actions: set[FileAction] = {
|
||||
const logged_file_actions: set[Action] = {
|
||||
FILE_OPEN,
|
||||
FILE_READ,
|
||||
FILE_WRITE,
|
||||
|
||||
PIPE_OPEN,
|
||||
PIPE_CLOSE,
|
||||
|
||||
PRINT_OPEN,
|
||||
PRINT_CLOSE,
|
||||
|
||||
UNKNOWN_OPEN,
|
||||
} &redef;
|
||||
|
||||
## The server response statuses which are *not* logged.
|
||||
|
@ -42,7 +65,7 @@ export {
|
|||
fuid : string &log &optional;
|
||||
|
||||
## Action this log record represents.
|
||||
action : FileAction &log &default=FILE_UNKNOWN;
|
||||
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.
|
||||
|
@ -50,26 +73,26 @@ export {
|
|||
## Total size of the file.
|
||||
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;
|
||||
ts : time &log &optional;
|
||||
## Unique ID of the connection the tree was mapped over.
|
||||
uid : string &log;
|
||||
uid : string &log;
|
||||
## ID of the connection the tree was mapped over.
|
||||
id : conn_id &log;
|
||||
id : conn_id &log;
|
||||
|
||||
## Name of the tree path.
|
||||
path : 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;
|
||||
service : string &log &optional;
|
||||
## File system of the tree.
|
||||
native_file_system : string &log &optional;
|
||||
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 &default="UNKNOWN";
|
||||
};
|
||||
|
||||
## This record is for the smb_cmd.log
|
||||
|
@ -121,15 +144,20 @@ export {
|
|||
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;
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
redef record connection += {
|
||||
|
@ -154,18 +182,18 @@ export {
|
|||
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;
|
||||
const write_file_log: function(state: State) &redef;
|
||||
}
|
||||
|
||||
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;
|
||||
uuid : string &optional;
|
||||
};
|
||||
|
||||
const ports = { 139/tcp, 445/tcp };
|
||||
|
@ -191,12 +219,33 @@ function set_current_file(smb_state: State, file_id: count)
|
|||
smb_state$current_file = smb_state$fid_map[file_id];
|
||||
}
|
||||
|
||||
function write_file_log(f: FileInfo)
|
||||
function write_file_log(state: State)
|
||||
{
|
||||
local f = state$current_file;
|
||||
if ( f?$name &&
|
||||
f$name !in pipe_names &&
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +260,7 @@ event file_state_remove(f: fa_file) &priority=-5
|
|||
local c = f$conns[id];
|
||||
if ( c?$smb_state && c$smb_state?$current_file)
|
||||
{
|
||||
write_file_log(c$smb_state$current_file);
|
||||
write_file_log(c$smb_state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,25 +6,18 @@ export {
|
|||
};
|
||||
|
||||
type ATSvcInfo: record {
|
||||
## Time of the request
|
||||
ts : time &log;
|
||||
## UID of the connection
|
||||
uid : string &log;
|
||||
## Connection info
|
||||
id : conn_id &log;
|
||||
## Command (add, enum, delete, etc.)
|
||||
command : string &log;
|
||||
## Argument
|
||||
arg : string &log;
|
||||
## Server the command was issued to
|
||||
server : string &log;
|
||||
## Result of the command
|
||||
result : string &log &optional;
|
||||
ts : time &log; ##< Time of the request
|
||||
uid : string &log; ##< UID of the connection
|
||||
id : conn_id &log; ##< Connection info
|
||||
command : string &log; ##< Command (add, enum, delete, etc.)
|
||||
arg : string &log; ##< Argument
|
||||
server : string &log; ##< Server the command was issued to
|
||||
result : string &log &optional; ##< Result of the command
|
||||
};
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
smb_atsvc: ATSvcInfo &optional;
|
||||
redef record SMB::State += {
|
||||
pipe_atsvc: ATSvcInfo &optional;
|
||||
};
|
||||
|
||||
event bro_init() &priority=5
|
||||
|
@ -32,28 +25,28 @@ event bro_init() &priority=5
|
|||
Log::create_stream(ATSVC_LOG, [$columns=ATSvcInfo]);
|
||||
}
|
||||
|
||||
event smb_atsvc_job_add(c: connection, server: string, job: string)
|
||||
event smb_atsvc_job_add(c: connection, server: string, job: string) &priority=5
|
||||
{
|
||||
local info: ATSvcInfo;
|
||||
info$ts = network_time();
|
||||
info$uid = c$uid;
|
||||
info$id = c$id;
|
||||
info$command = "Add job";
|
||||
info$arg = job;
|
||||
info$server = server;
|
||||
|
||||
c$smb_atsvc = info;
|
||||
local info = ATSvcInfo($ts=network_time(),
|
||||
$uid = c$uid,
|
||||
$id = c$id,
|
||||
$command = "Add job",
|
||||
$arg = job,
|
||||
$server = server);
|
||||
c$smb_state$pipe_atsvc = info;
|
||||
}
|
||||
|
||||
event smb_atsvc_job_id(c: connection, id: count, status: count)
|
||||
event smb_atsvc_job_id(c: connection, id: count, status: count) &priority=5
|
||||
{
|
||||
if ( !c?$smb_atsvc )
|
||||
return;
|
||||
if ( status == 0 )
|
||||
c$smb_atsvc$result = "success";
|
||||
else
|
||||
c$smb_atsvc$result = "failed";
|
||||
if ( c$smb_state?$pipe_atsvc )
|
||||
c$smb_state$pipe_atsvc$result = (status==0) ? "success" : "failed";
|
||||
}
|
||||
|
||||
Log::write(ATSVC_LOG, c$smb_atsvc);
|
||||
delete c$smb_atsvc;
|
||||
event smb_atsvc_job_id(c: connection, id: count, status: count) &priority=-5
|
||||
{
|
||||
if ( c$smb_state?$pipe_atsvc )
|
||||
{
|
||||
Log::write(ATSVC_LOG, c$smb_state$pipe_atsvc);
|
||||
delete c$smb_state$pipe_atsvc;
|
||||
}
|
||||
}
|
|
@ -168,7 +168,7 @@ event smb1_nt_create_andx_response(c: connection, hdr: SMB1::Header, file_id: co
|
|||
|
||||
c$smb_state$current_file = c$smb_state$fid_map[file_id];
|
||||
|
||||
SMB::write_file_log(c$smb_state$current_file);
|
||||
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
|
||||
|
@ -237,7 +237,7 @@ event smb1_close_request(c: connection, hdr: SMB1::Header, file_id: count) &prio
|
|||
|
||||
delete c$smb_state$fid_map[file_id];
|
||||
|
||||
SMB::write_file_log(fl);
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ event smb2_message(c: connection, hdr: SMB2::Header, is_orig: bool) &priority=5
|
|||
smb_state$tid_map[tid] = tmp_tree;
|
||||
}
|
||||
smb_state$current_tree = smb_state$tid_map[tid];
|
||||
|
||||
|
||||
if ( mid !in smb_state$pending_cmds )
|
||||
{
|
||||
local tmp_cmd: SMB::CmdInfo = [$ts=network_time(), $uid=c$uid, $id=c$id, $version="SMB2", $command = SMB2::commands[hdr$command]];
|
||||
|
@ -114,30 +114,43 @@ event smb2_tree_connect_response(c: connection, hdr: SMB2::Header, response: SMB
|
|||
|
||||
event smb2_create_request(c: connection, hdr: SMB2::Header, name: string) &priority=5
|
||||
{
|
||||
local tmp_file: SMB::FileInfo = [$ts=network_time(), $uid=c$uid, $id=c$id];
|
||||
local tmp_file: SMB::FileInfo = [$ts=network_time(), $uid=c$uid, $id=c$id, $name=name];
|
||||
|
||||
switch ( c$smb_state$current_cmd$referenced_tree$share_type )
|
||||
{
|
||||
case "DISK":
|
||||
tmp_file$action = SMB::FILE_OPEN;
|
||||
break;
|
||||
case "PIPE":
|
||||
tmp_file$action = SMB::PIPE_OPEN;
|
||||
break;
|
||||
case "PRINT":
|
||||
tmp_file$action = SMB::PRINT_OPEN;
|
||||
break;
|
||||
default:
|
||||
tmp_file$action = SMB::UNKNOWN_OPEN;
|
||||
break;
|
||||
}
|
||||
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
|
||||
{
|
||||
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_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$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);
|
||||
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
|
||||
event smb2_set_info_request(c: connection, hdr: SMB2::Header, request: SMB2::SetInfoRequest) &priority=5
|
||||
|
@ -148,7 +161,22 @@ 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_state, file_id$persistent+file_id$volatile);
|
||||
c$smb_state$current_file$action = SMB::FILE_READ;
|
||||
|
||||
switch ( c$smb_state$current_cmd$referenced_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::UNKNOWN_OPEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=-5
|
||||
|
@ -157,13 +185,28 @@ event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, o
|
|||
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);
|
||||
#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);
|
||||
c$smb_state$current_file$action = SMB::FILE_WRITE;
|
||||
|
||||
switch ( c$smb_state$current_cmd$referenced_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::UNKNOWN_WRITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=-5
|
||||
|
@ -172,13 +215,28 @@ event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID,
|
|||
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);
|
||||
#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);
|
||||
c$smb_state$current_file$action = SMB::FILE_CLOSE;
|
||||
|
||||
switch ( c$smb_state$current_cmd$referenced_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::UNKNOWN_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) &priority=-5
|
||||
|
@ -191,7 +249,7 @@ event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID)
|
|||
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);
|
||||
SMB::write_file_log(c$smb_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,8 +58,8 @@ void SMB_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
|
|||
}
|
||||
catch ( const binpac::Exception& e )
|
||||
{
|
||||
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
|
||||
//printf(fmt("Binpac exception: %s", e.c_msg()));
|
||||
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
|
||||
//printf(fmt("Binpac exception: %s", e.c_msg()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,11 +161,6 @@ void Contents_SMB::DeliverStream(int len, const u_char* data, bool orig)
|
|||
case WAIT_FOR_HDR:
|
||||
{
|
||||
// We have the 4 bytes header now
|
||||
|
||||
// This does not abide the spec, but we've seen it
|
||||
// in real traffic.
|
||||
if (data[1] > 2)
|
||||
Conn()->Weird(fmt("NetBIOS session flags > 2: %d", data[1]));
|
||||
msg_len = 0;
|
||||
msg_type = data[0];
|
||||
for ( int i = 1; i < 4; i++)
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
%}
|
||||
|
||||
refine connection SMB_Conn += {
|
||||
%member{
|
||||
map<uint16,bool> tree_is_pipe_map;
|
||||
%}
|
||||
|
||||
function get_tree_is_pipe(tree_id: uint16): bool
|
||||
%{
|
||||
|
@ -19,13 +22,9 @@ refine connection SMB_Conn += {
|
|||
function set_tree_is_pipe(tree_id: uint16, is_pipe: bool): bool
|
||||
%{
|
||||
tree_is_pipe_map[tree_id] = is_pipe;
|
||||
return true;
|
||||
return true;
|
||||
%}
|
||||
|
||||
%member{
|
||||
map<uint16,bool> tree_is_pipe_map;
|
||||
%}
|
||||
|
||||
function proc_smb_pipe_message(val: SMB_Pipe_message, header: SMB_Header): bool
|
||||
%{
|
||||
switch ( ${val.rpc_header.PTYPE} ) {
|
||||
|
@ -83,45 +82,43 @@ type SMB_Pipe_message(header: SMB_Header, byte_count: uint16) = record {
|
|||
proc: bool = $context.connection.proc_smb_pipe_message(this, header);
|
||||
} &byteorder = littleendian;
|
||||
|
||||
type SMB_RAP_message( unicode: bool, byte_count: uint16 ) = record {
|
||||
|
||||
rap_code : uint16;
|
||||
param_desc : SMB_string(unicode, offsetof(param_desc) );
|
||||
data_desc : SMB_string(unicode, offsetof(data_desc) );
|
||||
data : bytestring &restofdata;
|
||||
|
||||
type SMB_RAP_message(unicode: bool, byte_count: uint16) = record {
|
||||
rap_code : uint16;
|
||||
param_desc : SMB_string(unicode, offsetof(param_desc));
|
||||
data_desc : SMB_string(unicode, offsetof(data_desc));
|
||||
data : bytestring &restofdata;
|
||||
} &byteorder = littleendian;
|
||||
|
||||
type AT_SVC_Request(unicode: bool, opnum: uint8) = record {
|
||||
empty: padding[1];
|
||||
op: case opnum of {
|
||||
0 -> add: AT_SVC_NetrJobAdd(unicode);
|
||||
default -> unknown: bytestring &restofdata;
|
||||
0 -> add : AT_SVC_NetrJobAdd(unicode);
|
||||
default -> unknown : bytestring &restofdata;
|
||||
};
|
||||
};
|
||||
|
||||
type AT_SVC_String_Pointer(unicode: bool) = record {
|
||||
referent_id : uint32;
|
||||
max_count : uint32;
|
||||
offset : uint32;
|
||||
actual_count: uint32;
|
||||
string : SMB_string(unicode, offsetof(string));
|
||||
referent_id : uint32;
|
||||
max_count : uint32;
|
||||
offset : uint32;
|
||||
actual_count : uint32;
|
||||
string : SMB_string(unicode, offsetof(string));
|
||||
};
|
||||
|
||||
type AT_SVC_NetrJobAdd(unicode: bool) = record {
|
||||
server : AT_SVC_String_Pointer(unicode);
|
||||
unknown : padding[2];
|
||||
job_time : uint32;
|
||||
days_of_month: uint32;
|
||||
days_of_week : uint8;
|
||||
flags : uint8;
|
||||
unknown2 : padding[2];
|
||||
command : AT_SVC_String_Pointer(unicode);
|
||||
server : AT_SVC_String_Pointer(unicode);
|
||||
unknown : padding[2];
|
||||
job_time : uint32;
|
||||
days_of_month : uint32;
|
||||
days_of_week : uint8;
|
||||
flags : uint8;
|
||||
unknown2 : padding[2];
|
||||
command : AT_SVC_String_Pointer(unicode);
|
||||
};
|
||||
|
||||
type AT_SVC_Reply(unicode: bool, opnum: uint16) = record {
|
||||
op: case opnum of {
|
||||
0 -> add: AT_SVC_JobID(unicode);
|
||||
0 -> add: AT_SVC_JobID(unicode);
|
||||
default -> unknown: bytestring &restofdata;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,8 +10,11 @@ refine connection SMB_Conn += {
|
|||
function proc_smb1_transaction_request(header: SMB_Header, val: SMB1_transaction_request): bool
|
||||
%{
|
||||
if ( smb1_transaction_request )
|
||||
BifEvent::generate_smb1_transaction_request(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), \
|
||||
smb_string2stringval(${val.name}), ${val.sub_cmd});
|
||||
BifEvent::generate_smb1_transaction_request(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
BuildHeaderVal(header),
|
||||
smb_string2stringval(${val.name}),
|
||||
${val.sub_cmd});
|
||||
return true;
|
||||
%}
|
||||
|
||||
|
@ -24,8 +27,11 @@ refine connection SMB_Conn += {
|
|||
function proc_smb1_transaction_setup(header: SMB_Header, val: SMB1_transaction_setup): bool
|
||||
%{
|
||||
if ( smb1_transaction_setup )
|
||||
BifEvent::generate_smb1_transaction_setup(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), \
|
||||
${val.op_code}, ${val.file_id});
|
||||
BifEvent::generate_smb1_transaction_setup(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
BuildHeaderVal(header),
|
||||
${val.op_code},
|
||||
${val.file_id});
|
||||
return true;
|
||||
%}
|
||||
|
||||
|
@ -33,13 +39,13 @@ refine connection SMB_Conn += {
|
|||
|
||||
|
||||
type SMB1_transaction_data(header: SMB_Header, count: uint16, sub_cmd: uint16,
|
||||
trans_type: TransactionType ) = case trans_type of {
|
||||
trans_type: TransactionType) = case trans_type of {
|
||||
# SMB_MAILSLOT_BROWSE -> mailslot : SMB_MailSlot_message(header.unicode, count);
|
||||
# SMB_MAILSLOT_LANMAN -> lanman : SMB_MailSlot_message(header.unicode, count);
|
||||
# SMB_RAP -> rap : SMB_Pipe_message(header.unicode, count);
|
||||
SMB_PIPE -> pipe : SMB_Pipe_message(header, count);
|
||||
SMB_UNKNOWN -> unknown : bytestring &restofdata;
|
||||
# default -> data : bytestring &restofdata;
|
||||
SMB_UNKNOWN -> unknown : bytestring &restofdata &transient;
|
||||
default -> data : bytestring &restofdata &transient;
|
||||
};
|
||||
|
||||
type SMB1_transaction_setup(header: SMB_Header) = record {
|
||||
|
@ -79,7 +85,6 @@ type SMB1_transaction_request(header: SMB_Header) = record {
|
|||
proc : bool = $context.connection.proc_smb1_transaction_request(header, this);
|
||||
};
|
||||
|
||||
|
||||
type SMB1_transaction_response(header: SMB_Header) = record {
|
||||
word_count : uint8;
|
||||
total_param_count : uint16;
|
||||
|
@ -99,10 +104,8 @@ type SMB1_transaction_response(header: SMB_Header) = record {
|
|||
pad0 : padding to param_offset - SMB_Header_length;
|
||||
parameters : bytestring &length = param_count;
|
||||
pad1 : padding to data_offset - SMB_Header_length;
|
||||
handle_response : case $context.connection.get_tree_is_pipe(header.tid) of {
|
||||
true -> pipe_data : SMB1_transaction_data(header, data_count, 0, SMB_PIPE);
|
||||
false -> unk_data : SMB1_transaction_data(header, data_count, 0, SMB_UNKNOWN);
|
||||
};
|
||||
data : SMB1_transaction_data(header, data_count, 0, is_tree_a_pipe ? SMB_PIPE : SMB_UNKNOWN)[data_count>0 ? 1 : 0];
|
||||
} &let {
|
||||
proc : bool = $context.connection.proc_smb1_transaction_response(header, this);
|
||||
is_tree_a_pipe: bool = $context.connection.get_tree_is_pipe(header.tid);
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ refine connection SMB_Conn += {
|
|||
|
||||
function proc_smb1_tree_connect_andx_response(header: SMB_Header, val: SMB1_tree_connect_andx_response): bool
|
||||
%{
|
||||
set_tree_is_pipe(${header.tid}, strcmp((const char*) smb_string2stringval(${val.service})->Bytes(), "IPC") == 0);
|
||||
set_tree_is_pipe(${header.tid}, strncmp((const char*) smb_string2stringval(${val.service})->Bytes(), "IPC", 3) == 0);
|
||||
if ( smb1_tree_connect_andx_response )
|
||||
BifEvent::generate_smb1_tree_connect_andx_response(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
|
|
|
@ -52,7 +52,7 @@ type SMB1_write_andx_request(header: SMB_Header) = record {
|
|||
|
||||
byte_count : uint16;
|
||||
pad : padding to data_offset - SMB_Header_length;
|
||||
is_pipe : case $context.connection.get_tree_is_pipe(header.tid) of {
|
||||
is_pipe : case $context.connection.get_tree_is_pipe(header.tid) of {
|
||||
true -> pipe_data : SMB_Pipe_message(header, byte_count) &length=data_len;
|
||||
default -> data : bytestring &length=data_len;
|
||||
} &requires(data_len);
|
||||
|
|
|
@ -43,7 +43,7 @@ type SMB2_negotiate_request(header: SMB2_Header) = record {
|
|||
security_mode : uint16; # there is a list of required modes
|
||||
reserved : padding[2]; # must be set to 0
|
||||
capabilities : uint32; # must be set to 0
|
||||
client_guid : SMB2_guid; # guid if client implements SMB 2.1 dialect, otherwise set to 0
|
||||
client_guid : SMB2_guid; # guid if client implements SMB 2.1 dialect, otherwise set to 0
|
||||
client_start_time : SMB_timestamp; # must be set to 0
|
||||
dialects : uint16[dialect_count];
|
||||
} &byteorder=littleendian, &let {
|
||||
|
|
|
@ -25,7 +25,7 @@ refine connection SMB_Conn += {
|
|||
|
||||
function proc_smb2_read_response(h: SMB2_Header, val: SMB2_read_response) : bool
|
||||
%{
|
||||
if ( ${val.data_len} > 0 )
|
||||
if ( ! ${val.is_pipe} && ${val.data_len} > 0 )
|
||||
{
|
||||
uint64 offset = smb2_read_offsets[${h.message_id}];
|
||||
smb2_read_offsets.erase(${h.message_id});
|
||||
|
@ -67,7 +67,13 @@ type SMB2_read_response(header: SMB2_Header) = record {
|
|||
data_remaining : uint32;
|
||||
reserved : uint32;
|
||||
pad : padding to data_offset - header.head_length;
|
||||
data : bytestring &length=data_len;
|
||||
pipe_file_switch : case is_pipe of {
|
||||
# The SMB_Pipe_message type doesn't support smb2 pipes yet.
|
||||
#true -> pipe_data : SMB_Pipe_message(header, data_len) &length=data_len;
|
||||
false -> data : bytestring &length=data_len;
|
||||
};
|
||||
} &let {
|
||||
is_pipe: bool = $context.connection.get_tree_is_pipe(header.tree_id);
|
||||
|
||||
proc: bool = $context.connection.proc_smb2_read_response(header, this);
|
||||
};
|
||||
|
|
|
@ -13,10 +13,11 @@ refine connection SMB_Conn += {
|
|||
|
||||
function proc_smb2_tree_connect_response(header: SMB2_Header, val: SMB2_tree_connect_response): bool
|
||||
%{
|
||||
set_tree_is_pipe(${header.tree_id}, ${val.share_type} == SMB2_SHARE_TYPE_PIPE);
|
||||
|
||||
if ( smb2_tree_connect_response )
|
||||
{
|
||||
RecordVal* resp = new RecordVal(BifType::Record::SMB2::TreeConnectResponse);
|
||||
|
||||
resp->Assign(0, new Val(${val.share_type}, TYPE_COUNT));
|
||||
|
||||
BifEvent::generate_smb2_tree_connect_response(bro_analyzer(),
|
||||
|
|
|
@ -12,7 +12,7 @@ refine connection SMB_Conn += {
|
|||
${val.data_len});
|
||||
}
|
||||
|
||||
if ( ${val.data}.length() > 0 )
|
||||
if ( ! ${val.is_pipe} && ${val.data}.length() > 0 )
|
||||
{
|
||||
file_mgr->DataIn(${val.data}.begin(), ${val.data_len}, ${val.offset},
|
||||
bro_analyzer()->GetAnalyzerTag(),
|
||||
|
@ -32,19 +32,25 @@ refine connection SMB_Conn += {
|
|||
|
||||
|
||||
type SMB2_write_request(header: SMB2_Header) = record {
|
||||
structure_size : uint16;
|
||||
data_offset : uint16;
|
||||
data_len : uint32;
|
||||
offset : uint64;
|
||||
file_id : SMB2_guid;
|
||||
channel : uint32; # ignore
|
||||
data_remaining : uint32;
|
||||
structure_size : uint16;
|
||||
data_offset : uint16;
|
||||
data_len : uint32;
|
||||
offset : uint64;
|
||||
file_id : SMB2_guid;
|
||||
channel : uint32; # ignore
|
||||
data_remaining : uint32;
|
||||
channel_info_offset : uint16; # ignore
|
||||
channel_info_len : uint16; # ignore
|
||||
flags : uint32;
|
||||
pad : padding to data_offset - header.head_length;
|
||||
data : bytestring &length=data_len;
|
||||
channel_info_len : uint16; # ignore
|
||||
flags : uint32;
|
||||
pad : padding to data_offset - header.head_length;
|
||||
pipe_file_switch : case is_pipe of {
|
||||
# The SMB_Pipe_message type doesn't support smb2 pipes yet.
|
||||
#true -> pipe_data : SMB_Pipe_message(header, data_len) &length=data_len;
|
||||
default -> data : bytestring &length=data_len;
|
||||
};
|
||||
} &let {
|
||||
is_pipe: bool = $context.connection.get_tree_is_pipe(header.tree_id);
|
||||
|
||||
proc : bool = $context.connection.proc_smb2_write_request(header, this);
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,12 @@ enum smb2_commands {
|
|||
SMB2_OPLOCK_BREAK = 18,
|
||||
};
|
||||
|
||||
enum smb2_share_types {
|
||||
SMB2_SHARE_TYPE_DISK = 0x01,
|
||||
SMB2_SHARE_TYPE_PIPE = 0x02,
|
||||
SMB2_SHARE_TYPE_PRINT = 0x03,
|
||||
};
|
||||
|
||||
type SMB2_PDU(is_orig: bool) = record {
|
||||
header : SMB2_Header(is_orig);
|
||||
message : case header.status of {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue