mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 15:18:20 +00:00
251 lines
6.2 KiB
Text
251 lines
6.2 KiB
Text
@load app-summary
|
|
|
|
redef capture_filters += {
|
|
["netbios-dgm"] = "udp port 138",
|
|
["netbios-ssn"] = "tcp port 139",
|
|
["microsft-ds"] = "tcp port 445",
|
|
};
|
|
|
|
module SMB_summary;
|
|
|
|
global smb_log = open_log_file("smb-summary") &redef;
|
|
global chris_log = open_log_file("chris-summary") &redef;
|
|
|
|
#const smb_transaction_func = {
|
|
# ["SMB_COM_TRANSACTION", 0x0 ] = "\\PIPE\\LANMAN\\",
|
|
# ["SMB_COM_TRANSACTION", 0x1 ] = "\\MAILSLOT\\",
|
|
# ["SMB_COM_TRANSACTION", 0x54] = "CallNamedPipe",
|
|
# ["SMB_COM_TRANSACTION", 0x53] = "WaitNamedPipe",
|
|
# ["SMB_COM_TRANSACTION", 0x26] = "TransactNmPipe",
|
|
#
|
|
# ["SMB_COM_TRANSACTION2", 0x0] = "TRANS2_OPEN2",
|
|
# ["SMB_COM_TRANSACTION2", 0x1] = "TRANS2_FIND_FIRST2",
|
|
# ["SMB_COM_TRANSACTION2", 0x2] = "TRANS2_FIND_NEXT2",
|
|
# ["SMB_COM_TRANSACTION2", 0x3] = "TRANS2_QUERY_FS_INFORMATION",
|
|
# ["SMB_COM_TRANSACTION2", 0x5] = "TRANS2_QUERY_PATH_INFORMATION",
|
|
# ["SMB_COM_TRANSACTION2", 0x6] = "TRANS2_SET_PATH_INFORMATION",
|
|
# ["SMB_COM_TRANSACTION2", 0x7] = "TRANS2_QUERY_FILE_INFORMATION",
|
|
# ["SMB_COM_TRANSACTION2", 0x8] = "TRANS2_SET_FILE_INFORMATION",
|
|
# ["SMB_COM_TRANSACTION2", 0x0d] = "TRANS2_CREATE_DIRECTORY",
|
|
# ["SMB_COM_TRANSACTION2", 0x0e] = "TRANS2_SESSION_SETUP",
|
|
# ["SMB_COM_TRANSACTION2", 0x10] = "TRANS2_GET_DFS_REFERRAL",
|
|
#} &default = function(cmd: string, subcmd: count): string
|
|
# {
|
|
# return fmt("%s/%d", cmd, subcmd);
|
|
# };
|
|
|
|
type smb_req_resp: record {
|
|
connection_id: conn_id;
|
|
conn_start: time;
|
|
func: string;
|
|
cmd: string;
|
|
start: time;
|
|
num_req: count;
|
|
req_size: count;
|
|
num_resp: count;
|
|
resp_size: count;
|
|
};
|
|
|
|
type smb_req_reply_group: record {
|
|
trans: table[count] of smb_req_resp;
|
|
first_req: count;
|
|
last_req: count;
|
|
};
|
|
|
|
global smb_trans_table: table[conn_id] of smb_req_reply_group;
|
|
|
|
function lookup_smb_req_reply_group(id: conn_id, create: bool): smb_req_reply_group
|
|
{
|
|
if ( id !in smb_trans_table )
|
|
{
|
|
if ( create )
|
|
{
|
|
local trans: table[count] of smb_req_resp;
|
|
smb_trans_table[id] = [
|
|
$trans = trans, $first_req = 1, $last_req = 0];
|
|
}
|
|
else
|
|
print fmt("SMB req_reply_group not found: %s",
|
|
conn_id_string(id));
|
|
}
|
|
|
|
return smb_trans_table[id];
|
|
}
|
|
|
|
function new_smb_req_resp(c: connection, cmd: string): smb_req_resp
|
|
{
|
|
local id = c$id;
|
|
local g = lookup_smb_req_reply_group(id, T);
|
|
|
|
if( is_udp_port(id$orig_p) || is_udp_port(id$resp_p) )
|
|
print fmt("%.6f %s a new req_resp was triggered on a UDP connection!: %s",
|
|
network_time(), conn_id_string(id), cmd);
|
|
|
|
local t = [
|
|
$connection_id = id, $conn_start = c$start_time,
|
|
$cmd = cmd, $func = cmd,
|
|
$start = network_time(),
|
|
$num_req = 0, $req_size = 0,
|
|
$num_resp = 0, $resp_size = 0
|
|
];
|
|
|
|
++g$last_req;
|
|
g$trans[g$last_req] = t;
|
|
|
|
return g$trans[g$last_req];
|
|
}
|
|
|
|
function end_smb_req_resp(t: smb_req_resp)
|
|
{
|
|
print_app_summary(smb_log, t$connection_id, t$conn_start,
|
|
t$func, t$start,
|
|
t$num_req, t$req_size,
|
|
t$num_resp, t$resp_size,
|
|
fmt("cmd %s", t$cmd));
|
|
}
|
|
|
|
function lookup_smb_req_resp(c: connection, is_orig: bool, cmd: string): smb_req_resp
|
|
{
|
|
local id = c$id;
|
|
local g = lookup_smb_req_reply_group(id, T);
|
|
|
|
if( is_udp_port(id$orig_p) || is_udp_port(id$resp_p) )
|
|
print fmt("%.6f %s a lookup was triggered on a UDP connection!: %s",
|
|
network_time(), conn_id_string(id), cmd);
|
|
|
|
if ( g$first_req > g$last_req )
|
|
{
|
|
print fmt("%.6f %s request missing: %s",
|
|
network_time(), conn_id_string(id), cmd);
|
|
return new_smb_req_resp(c, cmd);
|
|
}
|
|
|
|
if ( is_orig )
|
|
{
|
|
return g$trans[g$last_req];
|
|
}
|
|
else if ( cmd == "(current)" )
|
|
{
|
|
return g$trans[g$first_req];
|
|
}
|
|
else
|
|
{
|
|
local t = g$trans[g$first_req];
|
|
if ( g$first_req < g$last_req )
|
|
{
|
|
end_smb_req_resp(t);
|
|
++g$first_req;
|
|
t = g$trans[g$first_req];
|
|
}
|
|
if ( t$cmd != cmd )
|
|
{
|
|
if ( g$first_req < g$last_req )
|
|
return lookup_smb_req_resp(c, is_orig, cmd);
|
|
print fmt("%.6f %s SMB command-reply mismatch",
|
|
network_time(), conn_id_string(id));
|
|
}
|
|
return t;
|
|
}
|
|
}
|
|
|
|
event smb_message(c: connection, hdr: smb_hdr, is_orig: bool, cmd:
|
|
string, body_length: count, body : string)
|
|
{
|
|
print chris_log, fmt("%.6f %s %s", network_time(), conn_id_string(c$id), cmd);
|
|
|
|
local t: smb_req_resp;
|
|
|
|
if ( is_udp_port( c$id$orig_p ) || is_udp_port ( c$id$resp_p ) )
|
|
{
|
|
# dont need to keep track of UDP smb commands
|
|
print_app_summary(smb_log, c$id, network_time(),
|
|
cmd, network_time(),
|
|
0, 0, 0, 0,
|
|
fmt("cmd %s", cmd));
|
|
}
|
|
else if ( is_orig )
|
|
{
|
|
t = new_smb_req_resp(c, cmd);
|
|
++t$num_req;
|
|
t$req_size = t$req_size + body_length;
|
|
}
|
|
else
|
|
{
|
|
t = lookup_smb_req_resp(c, is_orig, cmd);
|
|
++t$num_resp;
|
|
t$resp_size = t$resp_size + body_length;
|
|
}
|
|
}
|
|
|
|
event smb_error(c: connection, hdr: smb_hdr, cmd: count, cmd_str: string, data: string)
|
|
{
|
|
print chris_log, fmt("%.6f %s SMB_ERROR:%s", network_time(), conn_id_string(c$id), cmd_str);
|
|
}
|
|
|
|
event dce_rpc_bind(c: connection, uuid: string)
|
|
{
|
|
local id = c$id;
|
|
if ( id !in smb_trans_table )
|
|
return;
|
|
local t = lookup_smb_req_resp(c, T, "(current)");
|
|
t$func = "DCE_RPC_BIND";
|
|
}
|
|
|
|
event dce_rpc_request(c: connection, opnum: count, stub: string)
|
|
{
|
|
local id = c$id;
|
|
if ( id !in smb_trans_table )
|
|
return;
|
|
local t = lookup_smb_req_resp(c, T, "(current)");
|
|
t$func = "DCE_RPC_CALL";
|
|
}
|
|
|
|
event dce_rpc_response(c: connection, opnum: count, stub: string)
|
|
{
|
|
local id = c$id;
|
|
if ( id !in smb_trans_table )
|
|
return;
|
|
local t = lookup_smb_req_resp(c, F, "(current)");
|
|
t$func = "DCE_RPC_CALL";
|
|
}
|
|
|
|
event smb_com_transaction(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool)
|
|
{
|
|
if ( is_orig && !is_udp_port( c$id$orig_p ) )
|
|
{
|
|
local t = lookup_smb_req_resp(c, T, "(current)");
|
|
}
|
|
}
|
|
|
|
event smb_com_transaction2(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool)
|
|
{
|
|
if ( is_orig && !is_udp_port( c$id$orig_p ) )
|
|
{
|
|
local t = lookup_smb_req_resp(c, T, "(current)");
|
|
}
|
|
}
|
|
|
|
function end_smb_req_reply_group(g: smb_req_reply_group, index: count)
|
|
{
|
|
if ( index > g$last_req )
|
|
return;
|
|
|
|
if ( index >= g$first_req && index in g$trans )
|
|
end_smb_req_resp(g$trans[index]);
|
|
|
|
if( index in g$trans )
|
|
{
|
|
delete g$trans[index];
|
|
end_smb_req_reply_group(g, index + 1);
|
|
}
|
|
}
|
|
|
|
event connection_state_remove(c: connection)
|
|
{
|
|
local id = c$id;
|
|
if ( !is_udp_port( id$orig_p ) && id in smb_trans_table )
|
|
{
|
|
local g = smb_trans_table[id];
|
|
end_smb_req_reply_group(g, 1);
|
|
}
|
|
}
|