mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
checkpoint
This commit is contained in:
parent
1b638eec0c
commit
b002160f02
5 changed files with 173 additions and 40 deletions
|
@ -49,10 +49,25 @@ global next_fid = 0;
|
||||||
# request/reply matching, but the more specific event takes care of printing.
|
# request/reply matching, but the more specific event takes care of printing.
|
||||||
# It's all a hack....
|
# It's all a hack....
|
||||||
global more_specific_cmds: set[count];
|
global more_specific_cmds: set[count];
|
||||||
|
# Transaction commands and other commands for which request/reply matching
|
||||||
|
# doesn't work. We ignore them all.
|
||||||
|
# transaction commands re-use PID:MID. We'd have to look into the actual
|
||||||
|
# transaction command to match requests/replies.
|
||||||
|
global smb_ignore_cmds: set[count];
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
add more_specific_cmds[0x2e]; # read_andx
|
add more_specific_cmds[0x2e]; # read_andx
|
||||||
add more_specific_cmds[0x2f]; # write_andx
|
add more_specific_cmds[0x2f]; # write_andx
|
||||||
|
|
||||||
|
add smb_ignore_cmds[0x25]; # transaction
|
||||||
|
add smb_ignore_cmds[0x26]; # transaction_secondary
|
||||||
|
add smb_ignore_cmds[0x32]; # transaction2
|
||||||
|
add smb_ignore_cmds[0x33]; # transaction2_secondary
|
||||||
|
add smb_ignore_cmds[0xA0]; # nt_transact
|
||||||
|
add smb_ignore_cmds[0xA1]; # nt_transact_secondary
|
||||||
|
|
||||||
|
add smb_ignore_cmds[0xA4]; # nt_cancel
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function smb_new_cmd_info(hdr: smb_hdr, body_len: count): smb_cmd_info
|
function smb_new_cmd_info(hdr: smb_hdr, body_len: count): smb_cmd_info
|
||||||
|
@ -112,11 +127,11 @@ function fmt_msg_prefix(cid: conn_id, is_orig: bool, hdr: smb_hdr): string
|
||||||
function smb_log_cmd(c: connection, info: smb_cmd_info)
|
function smb_log_cmd(c: connection, info: smb_cmd_info)
|
||||||
{
|
{
|
||||||
local msg = "";
|
local msg = "";
|
||||||
msg = fmt("COMMAND %s (%d) %d:%d %.6f %.6f %d %.6f %.6f %d %s",
|
msg = fmt("COMMAND %s (%d) %d:%d %.6f %.6f %d %.6f %.6f %d %s %d %s %s %d",
|
||||||
info$cmdstr, info$cmd, info$pid, info$mid,
|
info$cmdstr, info$cmd, info$pid, info$mid,
|
||||||
info$req_first_time, info$req_last_time, info$req_body_len,
|
info$req_first_time, info$req_last_time, info$req_body_len,
|
||||||
info$rep_first_time, info$rep_last_time, info$rep_body_len,
|
info$rep_first_time, info$rep_last_time, info$rep_body_len,
|
||||||
get_fid(c$id, info$fid));
|
get_fid(c$id, info$fid), info$file_payload, c$id$orig_h, c$id$resp_h, c$id$resp_p);
|
||||||
print smb_log, msg;
|
print smb_log, msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +161,8 @@ function smb_set_fid(cid: conn_id, hdr: smb_hdr, fid: count)
|
||||||
{
|
{
|
||||||
# smb_messge takes care of error / mismatch handling, so we can
|
# smb_messge takes care of error / mismatch handling, so we can
|
||||||
# just punt here
|
# just punt here
|
||||||
|
if (hdr$command == 0x2f)
|
||||||
|
print fmt("in set_fid: %d", fid);
|
||||||
if (cid !in smb_sessions)
|
if (cid !in smb_sessions)
|
||||||
return;
|
return;
|
||||||
local cur_session = smb_sessions[cid];
|
local cur_session = smb_sessions[cid];
|
||||||
|
@ -154,6 +171,8 @@ function smb_set_fid(cid: conn_id, hdr: smb_hdr, fid: count)
|
||||||
local info = cur_session[hdr$pid, hdr$mid];
|
local info = cur_session[hdr$pid, hdr$mid];
|
||||||
|
|
||||||
info$fid = fid;
|
info$fid = fid;
|
||||||
|
if (hdr$command == 0x2f)
|
||||||
|
print fmt("end of set_fid: %d %d", info$fid, fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function smb_set_file_payload(cid: conn_id, hdr: smb_hdr, payload_len: count)
|
function smb_set_file_payload(cid: conn_id, hdr: smb_hdr, payload_len: count)
|
||||||
|
@ -176,6 +195,14 @@ function smb_set_file_payload(cid: conn_id, hdr: smb_hdr, payload_len: count)
|
||||||
event smb_message(c: connection, hdr: smb_hdr, is_orig: bool, cmd: string, body_length: count, body: string)
|
event smb_message(c: connection, hdr: smb_hdr, is_orig: bool, cmd: string, body_length: count, body: string)
|
||||||
{
|
{
|
||||||
###print smb_log, fmt("%s %s %d", fmt_msg_prefix(c$id, is_orig, hdr), cmd, body_length);
|
###print smb_log, fmt("%s %s %d", fmt_msg_prefix(c$id, is_orig, hdr), cmd, body_length);
|
||||||
|
|
||||||
|
if (hdr$command==0x24 && hdr$mid == 0xffff)
|
||||||
|
# opLock break notification event from server.
|
||||||
|
# ignore it.
|
||||||
|
return;
|
||||||
|
if (hdr$command in smb_ignore_cmds)
|
||||||
|
return;
|
||||||
|
|
||||||
if (c$id !in smb_sessions)
|
if (c$id !in smb_sessions)
|
||||||
smb_sessions[c$id] = table();
|
smb_sessions[c$id] = table();
|
||||||
local cur_session = smb_sessions[c$id];
|
local cur_session = smb_sessions[c$id];
|
||||||
|
@ -188,15 +215,15 @@ event smb_message(c: connection, hdr: smb_hdr, is_orig: bool, cmd: string, body_
|
||||||
if (is_orig)
|
if (is_orig)
|
||||||
{
|
{
|
||||||
if ([hdr$pid,hdr$mid] in cur_session)
|
if ([hdr$pid,hdr$mid] in cur_session)
|
||||||
print smb_log, fmt("Mismatch: got a request but already have request queued: %s %s",
|
print smb_log, fmt("Mismatch: got a request but already have request queued: %s %s %s",
|
||||||
mismatch_fmt_info(cur_session[hdr$pid,hdr$mid]), mismatch_fmt_hdr(hdr,cmd));
|
mismatch_fmt_info(cur_session[hdr$pid,hdr$mid]), mismatch_fmt_hdr(hdr,cmd), id_string(c$id));
|
||||||
cur_session[hdr$pid, hdr$mid] = smb_new_cmd_info(hdr, body_length);
|
cur_session[hdr$pid, hdr$mid] = smb_new_cmd_info(hdr, body_length);
|
||||||
cur_session[hdr$pid, hdr$mid]$cmdstr = cmd;
|
cur_session[hdr$pid, hdr$mid]$cmdstr = cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ([hdr$pid,hdr$mid] !in cur_session)
|
if ([hdr$pid,hdr$mid] !in cur_session)
|
||||||
print smb_log, fmt("Mismatch: got a reply but no request queued: %s", mismatch_fmt_hdr(hdr,cmd));
|
print smb_log, fmt("Mismatch: got a reply but no request queued: %s %s", mismatch_fmt_hdr(hdr,cmd), id_string(c$id));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
local info = cur_session[hdr$pid, hdr$mid];
|
local info = cur_session[hdr$pid, hdr$mid];
|
||||||
|
@ -249,6 +276,11 @@ event smb_com_write_andx_response(c: connection, hdr: smb_hdr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event smb_error(c: connection, hdr: smb_hdr, cmd: count, cmd_str: string, errtype: count, error: count)
|
||||||
|
{
|
||||||
|
print smb_log, fmt("ERROR: %s %s (0x%2x): %d %08x", id_string(c$id), cmd_str, cmd, errtype, error);
|
||||||
|
}
|
||||||
|
|
||||||
event connection_state_remove(c: connection)
|
event connection_state_remove(c: connection)
|
||||||
{
|
{
|
||||||
delete smb_sessions[c$id];
|
delete smb_sessions[c$id];
|
||||||
|
|
151
src/SMB.cc
151
src/SMB.cc
|
@ -157,8 +157,8 @@ void SMB_Session::Deliver(int is_orig, int len, const u_char* data,
|
||||||
|
|
||||||
int next_command = hdr.command();
|
int next_command = hdr.command();
|
||||||
|
|
||||||
fprintf(stderr, "SMB command: %02x %s len %-7d dur %.6lf\n", next_command,
|
fprintf(stderr, "SMB command: 0x%02x %s (%d) len %-7d dur %.6lf\n", next_command,
|
||||||
SMB_command_name[next_command], len,
|
SMB_command_name[next_command], is_orig, len,
|
||||||
last_time-first_time);
|
last_time-first_time);
|
||||||
int ncmds = 0;
|
int ncmds = 0;
|
||||||
|
|
||||||
|
@ -218,25 +218,23 @@ void SMB_Session::ParseMessage(int is_orig, int cmd,
|
||||||
// What if there's an error?
|
// What if there's an error?
|
||||||
// if ( hdr.status->status() || hdr.status->dos_error() )
|
// if ( hdr.status->status() || hdr.status->dos_error() )
|
||||||
// The command code in the header might be right, but
|
// The command code in the header might be right, but
|
||||||
// the response is probably mangled :-(.
|
// the response is probably mangled :-.
|
||||||
|
|
||||||
int ci = hdr.status()->val_case_index();
|
int ci = hdr.status()->val_case_index();
|
||||||
if ( (ci == 1 && hdr.status()->status()) ||
|
unsigned int error = 0;
|
||||||
(ci == 0 && (hdr.status()->dos_error()->error_class() ||
|
|
||||||
hdr.status()->dos_error()->error())) )
|
switch ( ci ) {
|
||||||
|
case 0:
|
||||||
|
error = hdr.status()->dos_error()->error_class() << 24 ||
|
||||||
|
hdr.status()->dos_error()->error();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
error = hdr.status()->status();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
unsigned int error = 0;
|
|
||||||
|
|
||||||
switch ( ci ) {
|
|
||||||
case 0:
|
|
||||||
error = hdr.status()->dos_error()->error_class() << 24 ||
|
|
||||||
hdr.status()->dos_error()->error();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
error = hdr.status()->status();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
StringVal* cmd_str = get_SMB_command_str(cmd);
|
StringVal* cmd_str = get_SMB_command_str(cmd);
|
||||||
Ref(cmd_str);
|
Ref(cmd_str);
|
||||||
|
@ -245,11 +243,10 @@ void SMB_Session::ParseMessage(int is_orig, int cmd,
|
||||||
vl->append(BuildHeaderVal(hdr));
|
vl->append(BuildHeaderVal(hdr));
|
||||||
vl->append(new Val(cmd, TYPE_COUNT));
|
vl->append(new Val(cmd, TYPE_COUNT));
|
||||||
vl->append(cmd_str);
|
vl->append(cmd_str);
|
||||||
vl->append(new StringVal(body.length(),
|
vl->append(new Val(ci, TYPE_COUNT));
|
||||||
(const char*) body.data()));
|
vl->append(new Val(error, TYPE_COUNT));
|
||||||
|
|
||||||
analyzer->ConnectionEvent(smb_error, vl);
|
analyzer->ConnectionEvent(smb_error, vl);
|
||||||
|
|
||||||
// Is this the right behavior?
|
// Is this the right behavior?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +591,8 @@ int SMB_Session::ParseReadAndxResponse(binpac::SMB::SMB_header const& hdr,
|
||||||
resp.Parse(body.data(), body.data() + body.length());
|
resp.Parse(body.data(), body.data() + body.length());
|
||||||
set_andx(0, resp.andx());
|
set_andx(0, resp.andx());
|
||||||
|
|
||||||
int data_count = resp.data_length();
|
uint32_t data_len = resp.data_len_high();
|
||||||
|
data_len = (data_len<<16) + resp.data_len();
|
||||||
const u_char* data = resp.data().begin();
|
const u_char* data = resp.data().begin();
|
||||||
|
|
||||||
if ( smb_com_read_andx_response )
|
if ( smb_com_read_andx_response )
|
||||||
|
@ -602,13 +600,13 @@ int SMB_Session::ParseReadAndxResponse(binpac::SMB::SMB_header const& hdr,
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(analyzer->BuildConnVal());
|
vl->append(analyzer->BuildConnVal());
|
||||||
vl->append(BuildHeaderVal(hdr));
|
vl->append(BuildHeaderVal(hdr));
|
||||||
vl->append(new Val((resp.data_len_high()<<16)+(resp.data_len()), TYPE_COUNT));
|
vl->append(new Val(data_len, TYPE_COUNT));
|
||||||
//vl->append(new StringVal(data_count, (const char*) data));
|
//vl->append(new StringVal(data_count, (const char*) data));
|
||||||
|
|
||||||
analyzer->ConnectionEvent(smb_com_read_andx, vl);
|
analyzer->ConnectionEvent(smb_com_read_andx_response, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckRPC(0, data_count, data);
|
CheckRPC(0, data_len, data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -620,7 +618,8 @@ int SMB_Session::ParseWriteAndx(binpac::SMB::SMB_header const& hdr,
|
||||||
req.Parse(body.data(), body.data() + body.length());
|
req.Parse(body.data(), body.data() + body.length());
|
||||||
set_andx(1, req.andx());
|
set_andx(1, req.andx());
|
||||||
|
|
||||||
int data_count = req.data_length();
|
uint32_t data_len = req.data_len_high();
|
||||||
|
data_len = (data_len<<16) + req.data_len();
|
||||||
const u_char* data = req.data().begin();
|
const u_char* data = req.data().begin();
|
||||||
|
|
||||||
if ( smb_com_write_andx )
|
if ( smb_com_write_andx )
|
||||||
|
@ -629,13 +628,13 @@ int SMB_Session::ParseWriteAndx(binpac::SMB::SMB_header const& hdr,
|
||||||
vl->append(analyzer->BuildConnVal());
|
vl->append(analyzer->BuildConnVal());
|
||||||
vl->append(BuildHeaderVal(hdr));
|
vl->append(BuildHeaderVal(hdr));
|
||||||
vl->append(new Val(req.fid(), TYPE_COUNT));
|
vl->append(new Val(req.fid(), TYPE_COUNT));
|
||||||
vl->append(new Val((req.data_len_high()<<16)+(req.data_len()), TYPE_COUNT));
|
vl->append(new Val(data_len, TYPE_COUNT));
|
||||||
//vl->append(new StringVal(data_count, (const char*) data));
|
//vl->append(new StringVal(data_count, (const char*) data));
|
||||||
|
|
||||||
analyzer->ConnectionEvent(smb_com_write_andx, vl);
|
analyzer->ConnectionEvent(smb_com_write_andx, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckRPC(1, data_count, data);
|
CheckRPC(1, data_len, data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1012,6 +1011,7 @@ Val* SMB_Session::BuildHeaderVal(binpac::SMB::SMB_header const& hdr)
|
||||||
|
|
||||||
unsigned int status = 0;
|
unsigned int status = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// FIXME: does this work? We need to catch exceptions :-(
|
// FIXME: does this work? We need to catch exceptions :-(
|
||||||
|
@ -1023,13 +1023,16 @@ Val* SMB_Session::BuildHeaderVal(binpac::SMB::SMB_header const& hdr)
|
||||||
catch ( const binpac::Exception& )
|
catch ( const binpac::Exception& )
|
||||||
{ // do nothing
|
{ // do nothing
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t pid = hdr.pid_high();
|
||||||
|
pid = (pid<<16) + hdr.pid();
|
||||||
r->Assign(0, new Val(hdr.command(), TYPE_COUNT));
|
r->Assign(0, new Val(hdr.command(), TYPE_COUNT));
|
||||||
r->Assign(1, new Val(status, TYPE_COUNT));
|
r->Assign(1, new Val(status, TYPE_COUNT));
|
||||||
r->Assign(2, new Val(hdr.flags(), TYPE_COUNT));
|
r->Assign(2, new Val(hdr.flags(), TYPE_COUNT));
|
||||||
r->Assign(3, new Val(hdr.flags2(), TYPE_COUNT));
|
r->Assign(3, new Val(hdr.flags2(), TYPE_COUNT));
|
||||||
r->Assign(4, new Val(hdr.tid(), TYPE_COUNT));
|
r->Assign(4, new Val(hdr.tid(), TYPE_COUNT));
|
||||||
r->Assign(5, new Val(hdr.pid(), TYPE_COUNT));
|
r->Assign(5, new Val(pid, TYPE_COUNT));
|
||||||
r->Assign(6, new Val(hdr.uid(), TYPE_COUNT));
|
r->Assign(6, new Val(hdr.uid(), TYPE_COUNT));
|
||||||
r->Assign(7, new Val(hdr.mid(), TYPE_COUNT));
|
r->Assign(7, new Val(hdr.mid(), TYPE_COUNT));
|
||||||
r->Assign(8, new Val(first_time, TYPE_TIME));
|
r->Assign(8, new Val(first_time, TYPE_TIME));
|
||||||
|
@ -1127,17 +1130,31 @@ Contents_SMB::Contents_SMB(Connection* conn, bool orig, SMB_Session* s)
|
||||||
{
|
{
|
||||||
smb_session = s;
|
smb_session = s;
|
||||||
state = WAIT_FOR_HDR;
|
state = WAIT_FOR_HDR;
|
||||||
|
resync_state = INSYNC;
|
||||||
first_time = last_time = 0.0;
|
first_time = last_time = 0.0;
|
||||||
hdr_buf.Init(4,4);
|
hdr_buf.Init(4,4);
|
||||||
msg_len = 0;
|
msg_len = 0;
|
||||||
msg_type = 0;
|
msg_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Contents_SMB::Init()
|
||||||
|
{
|
||||||
|
TCP_SupportAnalyzer::Init();
|
||||||
|
|
||||||
|
NeedResync();
|
||||||
|
}
|
||||||
|
|
||||||
Contents_SMB::~Contents_SMB()
|
Contents_SMB::~Contents_SMB()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Contents_SMB::Undelivered(int seq, int len, bool orig)
|
||||||
|
{
|
||||||
|
TCP_SupportAnalyzer::Undelivered(seq, len, orig);
|
||||||
|
NeedResync();
|
||||||
|
}
|
||||||
|
|
||||||
void Contents_SMB::DeliverSMB(int len, const u_char* data)
|
void Contents_SMB::DeliverSMB(int len, const u_char* data)
|
||||||
{
|
{
|
||||||
// Check the 4-byte header.
|
// Check the 4-byte header.
|
||||||
|
@ -1147,18 +1164,83 @@ void Contents_SMB::DeliverSMB(int len, const u_char* data)
|
||||||
//dshdr[0], dshdr[1], dshdr[2], dshdr[3],
|
//dshdr[0], dshdr[1], dshdr[2], dshdr[3],
|
||||||
msg_type, msg_len,
|
msg_type, msg_len,
|
||||||
data[0], data[1], data[2], data[3]));
|
data[0], data[1], data[2], data[3]));
|
||||||
SetSkip(1);
|
NeedResync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
smb_session->Deliver(IsOrig(), len, data, first_time, last_time);
|
smb_session->Deliver(IsOrig(), len, data, first_time, last_time);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Contents_SMB::CheckResync(int& len, const u_char*& data, bool orig)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (resync_state == INSYNC)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// This is an attempt to re-synchronize the stream after a content gap.
|
||||||
|
// Returns true if we are in sync.
|
||||||
|
// Returns false otherwise (we are in resync mode)
|
||||||
|
//
|
||||||
|
// We try to look for the beginning of a SMB message, assuming
|
||||||
|
// SMB messages start at packet boundaries (though they may span
|
||||||
|
// over multiple packets) (note that the data* of DeliverStream()
|
||||||
|
// usually starts at a packet boundrary).
|
||||||
|
//
|
||||||
|
|
||||||
|
// Now lets see whether data points to the beginning of a
|
||||||
|
// SMB message. If the resync processs is successful, we should
|
||||||
|
// be at the beginning of a frame.
|
||||||
|
|
||||||
|
|
||||||
|
if ( len < 36 )
|
||||||
|
{
|
||||||
|
// Ignore small chunks.
|
||||||
|
// 4 byte NetBIOS header (or length field) + 32 Byte SMB header
|
||||||
|
Conn()->Weird(fmt("SMB resync: discard %d bytes\n",
|
||||||
|
len));
|
||||||
|
NeedResync();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const u_char *xdata = data;
|
||||||
|
int xlen = len;
|
||||||
|
bool discard_this_chunk = false;
|
||||||
|
|
||||||
|
// Check if it's a data message
|
||||||
|
if (xdata[0]!=0x00)
|
||||||
|
discard_this_chunk = true;
|
||||||
|
|
||||||
|
// Check if the flags / high-byte of the message length is < 1
|
||||||
|
if (xdata[1] > 1)
|
||||||
|
discard_this_chunk = true;
|
||||||
|
|
||||||
|
// check if the SMB header starts with \xFFSMB
|
||||||
|
if (strncmp((const char*) (xdata+4), "\xffSMB", 4)!=0)
|
||||||
|
discard_this_chunk = true;
|
||||||
|
|
||||||
|
if (discard_this_chunk)
|
||||||
|
{
|
||||||
|
NeedResync();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
resync_state = INSYNC;
|
||||||
|
first_time = last_time = 0.0;
|
||||||
|
hdr_buf.Init(4,4);
|
||||||
|
msg_len = 0;
|
||||||
|
msg_type = 0;
|
||||||
|
fprintf(stderr, "Resync successful\n");
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Contents_SMB::DeliverStream(int len, const u_char* data, bool orig)
|
void Contents_SMB::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
{
|
{
|
||||||
TCP_SupportAnalyzer::DeliverStream(len, data, orig);
|
TCP_SupportAnalyzer::DeliverStream(len, data, orig);
|
||||||
if (Skipping())
|
|
||||||
return;
|
if (!CheckResync(len, data, orig))
|
||||||
|
return; // Not in sync yet. Still resyncing
|
||||||
|
|
||||||
last_time = network_time;
|
last_time = network_time;
|
||||||
while ( len > 0 )
|
while ( len > 0 )
|
||||||
|
@ -1191,10 +1273,13 @@ void Contents_SMB::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
{
|
{
|
||||||
const u_char *dummy_p = msg_buf.GetBuf();
|
const u_char *dummy_p = msg_buf.GetBuf();
|
||||||
int dummy_len = (int) msg_buf.GetFill();
|
int dummy_len = (int) msg_buf.GetFill();
|
||||||
if (msg_type == 0x00 && dummy_len >= 4)
|
if (msg_type == 0x00 && dummy_len >= 32)
|
||||||
DeliverSMB(dummy_len, dummy_p);
|
DeliverSMB(dummy_len, dummy_p);
|
||||||
else if (msg_type == 0x00)
|
else if (msg_type == 0x00)
|
||||||
|
{
|
||||||
Conn()->Weird(fmt("SMB too short: len=%d", msg_len));
|
Conn()->Weird(fmt("SMB too short: len=%d", msg_len));
|
||||||
|
NeedResync();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Conn()->Weird(fmt("SMB other msg type: %x", msg_type));
|
Conn()->Weird(fmt("SMB other msg type: %x", msg_type));
|
||||||
state = WAIT_FOR_HDR;
|
state = WAIT_FOR_HDR;
|
||||||
|
|
13
src/SMB.h
13
src/SMB.h
|
@ -188,6 +188,18 @@ protected:
|
||||||
WAIT_FOR_HDR,
|
WAIT_FOR_HDR,
|
||||||
WAIT_FOR_DATA
|
WAIT_FOR_DATA
|
||||||
} state_t;
|
} state_t;
|
||||||
|
typedef enum {
|
||||||
|
NEED_RESYNC,
|
||||||
|
INSYNC,
|
||||||
|
} resync_state_t;
|
||||||
|
virtual void Init();
|
||||||
|
virtual bool CheckResync(int& len, const u_char*& data, bool orig);
|
||||||
|
virtual void Undelivered(int seq, int len, bool orig);
|
||||||
|
virtual void NeedResync() {
|
||||||
|
resync_state = NEED_RESYNC;
|
||||||
|
state = WAIT_FOR_HDR;
|
||||||
|
}
|
||||||
|
|
||||||
void DeliverSMB(int len, const u_char* data);
|
void DeliverSMB(int len, const u_char* data);
|
||||||
|
|
||||||
SMB_Session* smb_session;
|
SMB_Session* smb_session;
|
||||||
|
@ -199,6 +211,7 @@ protected:
|
||||||
double first_time; // timestamp of first packet of current message
|
double first_time; // timestamp of first packet of current message
|
||||||
double last_time; // timestamp of last pakcet of current message
|
double last_time; // timestamp of last pakcet of current message
|
||||||
state_t state;
|
state_t state;
|
||||||
|
resync_state_t resync_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SMB_Analyzer : public TCP_ApplicationAnalyzer {
|
class SMB_Analyzer : public TCP_ApplicationAnalyzer {
|
||||||
|
|
|
@ -232,7 +232,7 @@ event smb_com_setup_andx%(c: connection, hdr: smb_hdr%);
|
||||||
event smb_com_generic_andx%(c: connection, hdr: smb_hdr%);
|
event smb_com_generic_andx%(c: connection, hdr: smb_hdr%);
|
||||||
event smb_com_close%(c: connection, hdr: smb_hdr%);
|
event smb_com_close%(c: connection, hdr: smb_hdr%);
|
||||||
event smb_com_logoff_andx%(c: connection, hdr: smb_hdr%);
|
event smb_com_logoff_andx%(c: connection, hdr: smb_hdr%);
|
||||||
event smb_error%(c: connection, hdr: smb_hdr, cmd: count, cmd_str: string, data: string%);
|
event smb_error%(c: connection, hdr: smb_hdr, cmd: count, cmd_str: string, errtype: count, error: count%);
|
||||||
|
|
||||||
event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%) &group="dns";
|
event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%) &group="dns";
|
||||||
event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%) &group="dns";
|
event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%) &group="dns";
|
||||||
|
|
|
@ -115,7 +115,10 @@ type SMB_header = record {
|
||||||
status : SMB_error(err_status_type);
|
status : SMB_error(err_status_type);
|
||||||
flags : uint8;
|
flags : uint8;
|
||||||
flags2 : uint16;
|
flags2 : uint16;
|
||||||
pad : padding[12];
|
#pad : padding[12];
|
||||||
|
pid_high : uint16;
|
||||||
|
security_features: uint8[8];
|
||||||
|
reserved : uint16;
|
||||||
tid : uint16;
|
tid : uint16;
|
||||||
pid : uint16;
|
pid : uint16;
|
||||||
uid : uint16;
|
uid : uint16;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue