Lots of SMB1 parsing fixes.

This commit is contained in:
Seth Hall 2016-08-08 15:36:07 -04:00
parent f03e4ce041
commit 117b5c3ac7
18 changed files with 193 additions and 159 deletions

View file

@ -27,6 +27,9 @@ export {
disabled_aids: set[count]; disabled_aids: set[count];
}; };
## Analyzers which you don't want to throw
const ignore_violations: set[Analyzer::Tag] = set() &redef;
## Ignore violations which go this many bytes into the connection. ## Ignore violations which go this many bytes into the connection.
## Set to 0 to never ignore protocol violations. ## Set to 0 to never ignore protocol violations.
const ignore_violations_after = 10 * 1024 &redef; const ignore_violations_after = 10 * 1024 &redef;
@ -82,6 +85,9 @@ event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason
if ( ignore_violations_after > 0 && size > ignore_violations_after ) if ( ignore_violations_after > 0 && size > ignore_violations_after )
return; return;
if ( atype in ignore_violations )
return;
# Disable the analyzer that raised the last core-generated event. # Disable the analyzer that raised the last core-generated event.
disable_analyzer(c$id, aid); disable_analyzer(c$id, aid);
add c$dpd$disabled_aids[aid]; add c$dpd$disabled_aids[aid];

View file

@ -34,6 +34,8 @@ export {
} &redef; } &redef;
} }
redef DPD::ignore_violations += { Analyzer::ANALYZER_DCE_RPC };
type State: record { type State: record {
uuid : string &optional; uuid : string &optional;
named_pipe : string &optional; named_pipe : string &optional;

View file

@ -46,6 +46,8 @@ export {
} &redef; } &redef;
} }
redef DPD::ignore_violations += { Analyzer::ANALYZER_NTLM };
redef record connection += { redef record connection += {
ntlm: Info &optional; ntlm: Info &optional;
}; };

View file

@ -274,6 +274,11 @@ event smb1_trans2_find_first2_request(c: connection, hdr: SMB1::Header, args: SM
c$smb_state$current_cmd$argument = args$file_name; c$smb_state$current_cmd$argument = args$file_name;
} }
event smb1_session_setup_andx_request(c: connection, hdr: SMB1::Header, request: SMB1::SessionSetupAndXRequest) &priority=5
{
# No behavior yet.
}
event smb1_session_setup_andx_response(c: connection, hdr: SMB1::Header, response: SMB1::SessionSetupAndXResponse) &priority=-5 event smb1_session_setup_andx_response(c: connection, hdr: SMB1::Header, response: SMB1::SessionSetupAndXResponse) &priority=-5
{ {
if ( SMB::write_cmd_log && if ( SMB::write_cmd_log &&

View file

@ -236,15 +236,42 @@ enum SMB_Status {
STATUS_SMB_NO_SUPPORT = 0xFFFF0002, STATUS_SMB_NO_SUPPORT = 0xFFFF0002,
}; };
function determine_transaction_type(setup_count: int, name: SMB_string): TransactionType function determine_transaction_type(header: SMB_Header, name: SMB_string): TransactionType
%{ %{
if ( name == NULL ) if ( name == NULL )
{ {
return SMB_UNKNOWN; return SMB_UNKNOWN;
} }
if ( ${name.u.s}->size() == 14 && ${name.u.s[0]} == '\\' && ${name.u.s[2]} == 'P' && ${name.u.s[4]} == 'I' && ${name.u.s[6]} == 'P' && ${name.u.s[8]} == 'E' && ${name.u.s[10]} == '\\') if ( (${header.unicode} && ${name.u.s}->size() > 10 && ${name.u.s[0]} == '\\' &&
${name.u.s[2]} == 'P' &&
${name.u.s[4]} == 'I' &&
${name.u.s[6]} == 'P' &&
${name.u.s[8]} == 'E' &&
${name.u.s[10]} == '\\') ||
(!${header.unicode} && ${name.a}->size() > 5 && ${name.a}->val()->at(0) == '\\' &&
${name.a}->val()->at(1) == 'P' &&
${name.a}->val()->at(2) == 'I' &&
${name.a}->val()->at(3) == 'P' &&
${name.a}->val()->at(4) == 'E' &&
${name.a}->val()->at(5) == '\\') )
{ {
if ( (${header.unicode} && ${name.u.s}->size() > 22 && ${name.u.s[12]} == 'L' &&
${name.u.s[14]} == 'A' &&
${name.u.s[16]} == 'N' &&
${name.u.s[18]} == 'M' &&
${name.u.s[20]} == 'A' &&
${name.u.s[22]} == 'N') ||
(!${header.unicode} && ${name.a}->size() > 11 && ${name.a}->val()->at(6) == 'L' &&
${name.a}->val()->at(7) == 'A' &&
${name.a}->val()->at(8) == 'N' &&
${name.a}->val()->at(9) == 'M' &&
${name.a}->val()->at(10) == 'A' &&
${name.a}->val()->at(11) == 'N') )
{
return SMB_RAP;
}
return SMB_PIPE; return SMB_PIPE;
} }

View file

@ -12,7 +12,7 @@ function uint8s_to_stringval(data: uint8[]): StringVal
function extract_string(s: SMB_string) : StringVal function extract_string(s: SMB_string) : StringVal
%{ %{
if ( s->unicode() == 0 ) if ( s->unicode() == false )
{ {
int length = s->a()->size(); int length = s->a()->size();
char buf[length]; char buf[length];

View file

@ -28,7 +28,7 @@ type LOCKING_ANDX_RANGE64 = record {
}; };
# http://msdn.microsoft.com/en-us/library/ee442004.aspx # http://msdn.microsoft.com/en-us/library/ee442004.aspx
type SMB1_locking_andx_request(header: SMB_Header) = record { type SMB1_locking_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
file_id : uint16; file_id : uint16;
@ -47,13 +47,16 @@ type SMB1_locking_andx_request(header: SMB_Header) = record {
32 -> locks32 : LOCKING_ANDX_RANGE32[num_requested_locks]; 32 -> locks32 : LOCKING_ANDX_RANGE32[num_requested_locks];
64 -> locks64 : LOCKING_ANDX_RANGE64[num_requested_locks]; 64 -> locks64 : LOCKING_ANDX_RANGE64[num_requested_locks];
}; };
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_locking_andx_request(header, this); proc : bool = $context.connection.proc_smb1_locking_andx_request(header, this);
}; };
# http://msdn.microsoft.com/en-us/library/ee441519.aspx # http://msdn.microsoft.com/en-us/library/ee441519.aspx
type SMB1_locking_andx_response(header: SMB_Header) = record { type SMB1_locking_andx_response(header: SMB_Header) = record {
} &let { } &let {
proc : bool = $context.connection.proc_smb1_locking_andx_response(header, this); proc : bool = $context.connection.proc_smb1_locking_andx_response(header, this);
}; };

View file

@ -10,10 +10,14 @@ refine connection SMB_Conn += {
}; };
type SMB1_logoff_andx(header: SMB_Header, is_orig: bool) = record { type SMB1_logoff_andx(header: SMB_Header, offset: uint16, is_orig: bool) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
byte_count : uint16; byte_count : uint16;
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_logoff_andx(header, this); proc : bool = $context.connection.proc_smb1_logoff_andx(header, this);
}; };

View file

@ -40,7 +40,7 @@ refine connection SMB_Conn += {
}; };
type SMB1_nt_create_andx_request(header: SMB_Header) = record { type SMB1_nt_create_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
reserved : uint8; reserved : uint8;
@ -60,12 +60,14 @@ type SMB1_nt_create_andx_request(header: SMB_Header) = record {
byte_count : uint16; byte_count : uint16;
filename : SMB_string(header.unicode, offsetof(filename)); filename : SMB_string(header.unicode, offsetof(filename));
andx_command : SMB_andx_command(header, 1, andx.command); extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_nt_create_andx_request(header, this); proc : bool = $context.connection.proc_smb1_nt_create_andx_request(header, this);
}; };
type SMB1_nt_create_andx_response(header: SMB_Header) = record { type SMB1_nt_create_andx_response(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
oplock_level : uint8; oplock_level : uint8;
@ -83,6 +85,10 @@ type SMB1_nt_create_andx_response(header: SMB_Header) = record {
directory : uint8; directory : uint8;
byte_count : uint16; byte_count : uint16;
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_nt_create_andx_response(header, this); proc : bool = $context.connection.proc_smb1_nt_create_andx_response(header, this);
}; };

View file

@ -41,7 +41,7 @@ refine connection SMB_Conn += {
type SMB1_open_andx_request(header: SMB_Header) = record { type SMB1_open_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
flags : uint16; flags : uint16;
@ -55,11 +55,15 @@ type SMB1_open_andx_request(header: SMB_Header) = record {
reserved : padding[2]; reserved : padding[2];
byte_count : uint16; byte_count : uint16;
filename : SMB_string(header.unicode, offsetof(filename); filename : SMB_string(header.unicode, offsetof(filename);
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_open_andx_request(header, this); proc : bool = $context.connection.proc_smb1_open_andx_request(header, this);
} &byteorder=littleendian; } &byteorder=littleendian;
type SMB1_open_andx_response(header: SMB_Header) = record { type SMB1_open_andx_response(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
fid : uint16; fid : uint16;
@ -72,6 +76,10 @@ type SMB1_open_andx_response(header: SMB_Header) = record {
open_results : uint16; open_results : uint16;
reserved : padding[3]; reserved : padding[3];
byte_count : uint16; byte_count : uint16;
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_open_andx_response(header, this); proc : bool = $context.connection.proc_smb1_open_andx_response(header, this);
} &byteorder=littleendian; } &byteorder=littleendian;

View file

@ -1,77 +0,0 @@
refine connection SMB_Conn += {
function proc_smb1_open_andx_request(h: SMB_Header, val: SMB1_open_andx_request): bool
%{
if ( smb1_open_andx_request )
BifEvent::generate_smb1_open_andx_request(bro_analyzer(),
bro_analyzer()->Conn(),
BuildHeaderVal(h),
${val.flags},
${val.access_mode},
${val.search_attrs},
${val.file_attrs},
${val.creation_time},
${val.open_mode},
${val.allocation_size},
${val.timeout},
smb_string2stringval(${val.filename}));
return true;
%}
function proc_smb1_open_andx_response(h: SMB_Header, val: SMB1_open_andx_response): bool
%{
if ( smb1_open_andx_response )
BifEvent::generate_smb1_open_andx_response(bro_analyzer(),
bro_analyzer()->Conn(),
BuildHeaderVal(h),
${val.fid},
${val.file_attrs},
${val.last_write_time},
${val.file_data_size},
${val.access_rights},
${val.resource_type},
${val.nm_pipe_status},
${val.open_results});
return true;
%}
};
type SMB1_open_andx_request(header: SMB_Header) = record {
word_count : uint8;
andx : SMB_andx;
flags : uint16;
access_mode : uint16;
search_attrs : uint16;
file_attrs : uint16;
creation_time : uint32;
open_mode : uint16;
allocation_size : uint32;
timeout : uint32;
reserved : padding[2];
byte_count : uint16;
filename : SMB_string(header.unicode, offsetof(filename);
} &let {
proc : bool = $context.connection.proc_smb1_open_andx_request(header, this);
} &byteorder=littleendian;
type SMB1_open_andx_response(header: SMB_Header) = record {
word_count : uint8;
andx : SMB_andx;
fid : uint16;
file_attrs : uint16;
last_write_time : uint32;
file_data_size : uint32;
access_rights : uint16;
resource_type : uint16;
nm_pipe_status : uint16;
open_results : uint16;
reserved : padding[3];
byte_count : uint16;
} &let {
proc : bool = $context.connection.proc_smb1_open_andx_response(header, this);
} &byteorder=littleendian;

View file

@ -13,10 +13,10 @@ refine connection SMB_Conn += {
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
BuildHeaderVal(h), BuildHeaderVal(h),
${val.file_id}, ${val.file_id},
${val.offset}, ${val.read_offset},
${val.max_count}); ${val.max_count});
read_offsets[${h.mid}] = ${val.offset}; read_offsets[${h.mid}] = ${val.read_offset};
return true; return true;
%} %}
@ -45,7 +45,7 @@ refine connection SMB_Conn += {
type SMB1_read_andx_request(header: SMB_Header) = record { type SMB1_read_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
file_id : uint16; file_id : uint16;
@ -53,6 +53,7 @@ type SMB1_read_andx_request(header: SMB_Header) = record {
max_count_low : uint16; max_count_low : uint16;
min_count : uint16; min_count : uint16;
max_count_high : uint32; max_count_high : uint32;
remaining : uint16; remaining : uint16;
offset_high_u : case word_count of { offset_high_u : case word_count of {
0x0C -> offset_high_tmp : uint32; 0x0C -> offset_high_tmp : uint32;
@ -60,14 +61,18 @@ type SMB1_read_andx_request(header: SMB_Header) = record {
}; };
byte_count : uint16; byte_count : uint16;
extra_byte_parameters : bytestring &transient &length=((andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters))));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
offset_high : uint32 = (word_count == 0x0C) ? offset_high_tmp : 0; offset_high : uint32 = (word_count == 0x0C && offset_high_tmp != 0xffffffff) ? offset_high_tmp : 0;
offset : uint64 = (offset_high * 0x10000) + offset_low; read_offset : uint64 = (offset_high * 0x10000) + offset_low;
max_count : uint64 = (max_count_high * 0x10000) + max_count_low; max_count : uint64 = ((max_count_high == 0xffffffff ? 0 : max_count_high) * 0x10000) + max_count_low;
proc : bool = $context.connection.proc_smb1_read_andx_request(header, this); proc : bool = $context.connection.proc_smb1_read_andx_request(header, this);
} &byteorder=littleendian; } &byteorder=littleendian;
type SMB1_read_andx_response(header: SMB_Header) = record { type SMB1_read_andx_response(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
available : uint16; available : uint16;
@ -81,6 +86,10 @@ type SMB1_read_andx_response(header: SMB_Header) = record {
byte_count : uint16; byte_count : uint16;
pad : padding to data_offset - SMB_Header_length; pad : padding to data_offset - SMB_Header_length;
data : bytestring &length=data_len; data : bytestring &length=data_len;
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
is_pipe : bool = $context.connection.get_tree_is_pipe(header.tid); is_pipe : bool = $context.connection.get_tree_is_pipe(header.tid);
pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, false) &if(is_pipe); pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, false) &if(is_pipe);

View file

@ -91,9 +91,9 @@ refine connection SMB_Conn += {
{ {
case 3: // pre NT LM 0.12 case 3: // pre NT LM 0.12
response->Assign(1, new Val(${val.lanman.is_guest}, TYPE_BOOL)); response->Assign(1, new Val(${val.lanman.is_guest}, TYPE_BOOL));
response->Assign(2, smb_string2stringval(${val.lanman.native_os})); response->Assign(2, ${val.lanman.byte_count} == 0 ? new StringVal("") : smb_string2stringval(${val.lanman.native_os[0]}));
response->Assign(3, smb_string2stringval(${val.lanman.native_lanman})); response->Assign(3, ${val.lanman.byte_count} == 0 ? new StringVal("") : smb_string2stringval(${val.lanman.native_lanman[0]}));
response->Assign(4, smb_string2stringval(${val.lanman.primary_domain})); response->Assign(4, ${val.lanman.byte_count} == 0 ? new StringVal("") : smb_string2stringval(${val.lanman.primary_domain[0]}));
break; break;
case 4: // NT LM 0.12 case 4: // NT LM 0.12
response->Assign(1, new Val(${val.ntlm.is_guest}, TYPE_BOOL)); response->Assign(1, new Val(${val.ntlm.is_guest}, TYPE_BOOL));
@ -117,29 +117,29 @@ refine connection SMB_Conn += {
}; };
type SMB1_session_setup_andx_request(header: SMB_Header) = record { type SMB1_session_setup_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
lanman_or_ntlm : case word_count of { lanman_or_ntlm : case word_count of {
0x0a -> lanman : SMB1_session_setup_andx_request_lanman(header); 0x0a -> lanman : SMB1_session_setup_andx_request_lanman(header, offset+offsetof(lanman_or_ntlm));
0x0c -> ntlm_extended_security : SMB1_session_setup_andx_request_ntlm_extended_security(header); 0x0c -> ntlm_extended_security : SMB1_session_setup_andx_request_ntlm_extended_security(header, offset+1);
0x0d -> ntlm_nonextended_security : SMB1_session_setup_andx_request_ntlm_nonextended_security(header); 0x0d -> ntlm_nonextended_security : SMB1_session_setup_andx_request_ntlm_nonextended_security(header, offset+1);
}; };
} &let { } &let {
proc: bool = $context.connection.proc_smb1_session_setup_andx_request(header, this); proc: bool = $context.connection.proc_smb1_session_setup_andx_request(header, this);
}; };
type SMB1_session_setup_andx_response(header: SMB_Header) = record { type SMB1_session_setup_andx_response(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
lanman_or_ntlm : case word_count of { lanman_or_ntlm : case word_count of {
0x03 -> lanman: SMB1_session_setup_andx_response_lanman(header); 0x03 -> lanman: SMB1_session_setup_andx_response_lanman(header, offset+1);
0x04 -> ntlm: SMB1_session_setup_andx_response_ntlm(header); 0x04 -> ntlm: SMB1_session_setup_andx_response_ntlm(header, offset+1);
default -> error: uint16; default -> error: uint16;
}; };
} &let { } &let {
proc: bool = $context.connection.proc_smb1_session_setup_andx_response(header, this); proc: bool = $context.connection.proc_smb1_session_setup_andx_response(header, this);
}; };
type SMB1_session_setup_andx_request_lanman(header: SMB_Header) = record { type SMB1_session_setup_andx_request_lanman(header: SMB_Header, offset: uint16) = record {
andx : SMB_andx; andx : SMB_andx;
max_buffer_size : uint16; max_buffer_size : uint16;
max_mpx_count : uint16; max_mpx_count : uint16;
@ -154,16 +154,24 @@ type SMB1_session_setup_andx_request_lanman(header: SMB_Header) = record {
primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1); primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1);
native_os : SMB_string(header.unicode, offsetof(native_os) + 1); native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1); native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
}; };
type SMB1_session_setup_andx_response_lanman(header: SMB_Header) = record { type SMB1_session_setup_andx_response_lanman(header: SMB_Header, offset: uint16) = record {
andx : SMB_andx; andx : SMB_andx;
action : uint16; action : uint16;
byte_count : uint16; byte_count : uint16;
# offset + 1 due to word_count in the parent type # offset + 1 due to word_count in the parent type
native_os : SMB_string(header.unicode, offsetof(native_os) + 1); native_os : SMB_string(header.unicode, offsetof(native_os) + 1)[byte_count == 0 ? 0 : 1];
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1); native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1)[byte_count == 0 ? 0 : 1];
primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1); primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1)[byte_count == 0 ? 0 : 1];
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
is_guest: bool = ( action & 0x1 ) > 0; is_guest: bool = ( action & 0x1 ) > 0;
}; };
@ -179,7 +187,7 @@ type SMB1_session_setup_andx_request_ntlm_capabilities = record {
nt_find : bool = ( capabilities & 0x0200 ) > 0; nt_find : bool = ( capabilities & 0x0200 ) > 0;
}; };
type SMB1_session_setup_andx_request_ntlm_nonextended_security(header: SMB_Header) = record { type SMB1_session_setup_andx_request_ntlm_nonextended_security(header: SMB_Header, offset: uint16) = record {
andx : SMB_andx; andx : SMB_andx;
max_buffer_size : uint16; max_buffer_size : uint16;
max_mpx_count : uint16; max_mpx_count : uint16;
@ -197,9 +205,13 @@ type SMB1_session_setup_andx_request_ntlm_nonextended_security(header: SMB_Heade
primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1); primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1);
native_os : SMB_string(header.unicode, offsetof(native_os) + 1); native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1); native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
}; };
type SMB1_session_setup_andx_request_ntlm_extended_security(header: SMB_Header) = record { type SMB1_session_setup_andx_request_ntlm_extended_security(header: SMB_Header, offset: uint16) = record {
andx : SMB_andx; andx : SMB_andx;
max_buffer_size : uint16; max_buffer_size : uint16;
max_mpx_count : uint16; max_mpx_count : uint16;
@ -213,11 +225,15 @@ type SMB1_session_setup_andx_request_ntlm_extended_security(header: SMB_Header)
# offset + 1 due to word_count in the parent type # offset + 1 due to word_count in the parent type
native_os : SMB_string(header.unicode, offsetof(native_os) + 1); native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1); native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
extra_byte_parameters : bytestring &transient &length=(andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
pipe_proc : bool = $context.connection.forward_gssapi(security_blob, true); pipe_proc : bool = $context.connection.forward_gssapi(security_blob, true);
}; };
type SMB1_session_setup_andx_response_ntlm(header: SMB_Header) = record { type SMB1_session_setup_andx_response_ntlm(header: SMB_Header, offset: uint16) = record {
andx : SMB_andx; andx : SMB_andx;
action : uint16; action : uint16;
security_blob_length : uint16; security_blob_length : uint16;
@ -227,6 +243,10 @@ type SMB1_session_setup_andx_response_ntlm(header: SMB_Header) = record {
native_os : SMB_string(header.unicode, offsetof(native_os) + 1); native_os : SMB_string(header.unicode, offsetof(native_os) + 1);
native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1); native_lanman : SMB_string(header.unicode, offsetof(native_lanman) + 1);
primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1); primary_domain : SMB_string(header.unicode, offsetof(primary_domain) + 1);
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
is_guest : bool = ( action & 0x1 ) > 0; is_guest : bool = ( action & 0x1 ) > 0;
gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false); gssapi_proc : bool = $context.connection.forward_gssapi(security_blob, false);

View file

@ -13,5 +13,5 @@ type SMB1_transaction_secondary_request(header: SMB_Header) = record {
pad1 : padding to param_offset - SMB_Header_length; pad1 : padding to param_offset - SMB_Header_length;
parameters : bytestring &length = param_count; parameters : bytestring &length = param_count;
pad2 : padding to data_offset - SMB_Header_length; pad2 : padding to data_offset - SMB_Header_length;
data : SMB1_transaction_data(header, true, data_count, 0, SMB_UNKNOWN); data : SMB1_transaction_data(header, true, data_count, 0, SMB_UNKNOWN, false);
}; };

View file

@ -43,14 +43,13 @@ refine connection SMB_Conn += {
function proc_smb1_transaction_response(header: SMB_Header, val: SMB1_transaction_response): bool function proc_smb1_transaction_response(header: SMB_Header, val: SMB1_transaction_response): bool
%{ %{
//printf("transaction_response\n");
return true; return true;
%} %}
}; };
type SMB1_transaction_data(header: SMB_Header, is_orig: bool, count: uint16, sub_cmd: uint16, type SMB1_transaction_data(header: SMB_Header, is_orig: bool, count: uint16, sub_cmd: uint16,
trans_type: int) = case trans_type of { trans_type: int, is_pipe: bool) = case trans_type of {
# SMB_MAILSLOT_BROWSE -> mailslot : SMB_MailSlot_message(header.unicode, count); # SMB_MAILSLOT_BROWSE -> mailslot : SMB_MailSlot_message(header.unicode, count);
# SMB_MAILSLOT_LANMAN -> lanman : 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_RAP -> rap : SMB_Pipe_message(header.unicode, count);
@ -61,7 +60,7 @@ type SMB1_transaction_data(header: SMB_Header, is_orig: bool, count: uint16, sub
pipe_proc : bool = $context.connection.forward_dce_rpc(pipe_data, 0, is_orig) &if(trans_type == SMB_PIPE); pipe_proc : bool = $context.connection.forward_dce_rpc(pipe_data, 0, is_orig) &if(trans_type == SMB_PIPE);
}; };
type SMB1_transaction_setup(header: SMB_Header) = record { type SMB1_transaction_setup = record {
op_code : uint16; op_code : uint16;
file_id : uint16; file_id : uint16;
} }
@ -83,18 +82,19 @@ type SMB1_transaction_request(header: SMB_Header) = record {
data_offset : uint16; data_offset : uint16;
setup_count : uint8; setup_count : uint8;
reserved3 : uint8; reserved3 : uint8;
setup : SMB1_transaction_setup(header); # word_count 16 is a different dialect that behaves a bit differently.
setup : SMB1_transaction_setup[word_count == 16 ? 1 : setup_count];
byte_count : uint16; byte_count : uint16;
name : SMB_string(header.unicode, offsetof(name)); name : SMB_string(header.unicode, offsetof(name));
pad1 : padding to param_offset - SMB_Header_length; pad1 : padding to param_offset - SMB_Header_length;
parameters : bytestring &length = param_count; parameters : bytestring &length = param_count;
pad2 : padding to data_offset - SMB_Header_length; pad2 : padding to data_offset - SMB_Header_length;
data : SMB1_transaction_data(header, true, data_count, sub_cmd, transtype); data : SMB1_transaction_data(header, true, data_count, sub_cmd, transtype, is_pipe);
} &let { } &let {
sub_cmd : uint16 = setup_count ? setup.op_code : 0; sub_cmd : uint16 = (sizeof(setup) && word_count != 16) > 0 ? setup[0].op_code : 0;
transtype : int = determine_transaction_type(setup_count, name); transtype : int = determine_transaction_type(header, name);
is_pipe : bool = (transtype == SMB_PIPE); is_pipe : bool = (transtype == SMB_PIPE || (transtype == SMB_UNKNOWN && $context.connection.get_tree_is_pipe(header.tid)));
proc_set_pipe : bool = $context.connection.set_is_file_a_pipe(header.mid, is_pipe); proc_set_pipe : bool = $context.connection.set_is_file_a_pipe(header.mid, is_pipe);
proc : bool = $context.connection.proc_smb1_transaction_request(header, this); proc : bool = $context.connection.proc_smb1_transaction_request(header, this);
@ -119,7 +119,7 @@ type SMB1_transaction_response(header: SMB_Header) = record {
pad0 : padding to param_offset - SMB_Header_length; pad0 : padding to param_offset - SMB_Header_length;
parameters : bytestring &length = param_count; parameters : bytestring &length = param_count;
pad1 : padding to data_offset - SMB_Header_length; pad1 : padding to data_offset - SMB_Header_length;
data : SMB1_transaction_data(header, false, data_count, 0, is_pipe ? SMB_PIPE : SMB_UNKNOWN)[data_count>0 ? 1 : 0]; data : SMB1_transaction_data(header, false, data_count, 0, is_pipe ? SMB_PIPE : SMB_UNKNOWN, is_pipe)[data_count>0 ? 1 : 0];
} &let { } &let {
proc : bool = $context.connection.proc_smb1_transaction_response(header, this); proc : bool = $context.connection.proc_smb1_transaction_response(header, this);
is_pipe: bool = $context.connection.get_is_file_a_pipe(header.mid); is_pipe: bool = $context.connection.get_is_file_a_pipe(header.mid);

View file

@ -14,41 +14,52 @@ refine connection SMB_Conn += {
function proc_smb1_tree_connect_andx_response(header: SMB_Header, val: SMB1_tree_connect_andx_response): bool function proc_smb1_tree_connect_andx_response(header: SMB_Header, val: SMB1_tree_connect_andx_response): bool
%{ %{
set_tree_is_pipe(${header.tid}, strncmp((const char*) smb_string2stringval(${val.service})->Bytes(), "IPC", 3) == 0); set_tree_is_pipe(${header.tid}, strncmp((const char*) smb_string2stringval(${val.service})->Bytes(), "IPC", 3) == 0);
if ( smb1_tree_connect_andx_response ) if ( smb1_tree_connect_andx_response )
{
BifEvent::generate_smb1_tree_connect_andx_response(bro_analyzer(), BifEvent::generate_smb1_tree_connect_andx_response(bro_analyzer(),
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
BuildHeaderVal(header), BuildHeaderVal(header),
smb_string2stringval(${val.service}), smb_string2stringval(${val.service}),
smb_string2stringval(${val.native_file_system})); ${val.byte_count} > ${val.service.a}->size() ? smb_string2stringval(${val.native_file_system[0]}) : new StringVal(""));
}
return true; return true;
%} %}
}; };
type SMB1_tree_connect_andx_request(header: SMB_Header) = record { type SMB1_tree_connect_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
flags : uint16; flags : uint16;
password_length : uint16; password_length : uint16;
byte_count : uint16; byte_count : uint16;
password : uint8[password_length]; password : uint8[password_length];
path : SMB_string(header.unicode, offsetof(path)); path : SMB_string(header.unicode, offsetof(path));
service : SMB_string(0, offsetof(service)); service : SMB_string(0, offsetof(service));
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_tree_connect_andx_request(header, this); proc : bool = $context.connection.proc_smb1_tree_connect_andx_request(header, this);
}; };
type SMB1_tree_connect_andx_response(header: SMB_Header) = record { type SMB1_tree_connect_andx_response(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
optional_support : uint16; optional_support : uint16[word_count<3 ? 0 : 1];
pad : padding[(word_count-3)*2]; pad : padding[word_count<3 ? 0 : (word_count-3)*2];
byte_count : uint16; byte_count : uint16;
service : SMB_string(0, offsetof(service)); service : SMB_string(0, offsetof(service));
native_file_system : SMB_string(header.unicode, offsetof(native_file_system)); native_file_system : SMB_string(header.unicode, offsetof(native_file_system))[byte_count > sizeof(service) ? 1 : 0];
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
proc : bool = $context.connection.proc_smb1_tree_connect_andx_response(header, this); proc : bool = $context.connection.proc_smb1_tree_connect_andx_response(header, this);
}; };

View file

@ -7,13 +7,13 @@ refine connection SMB_Conn += {
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
BuildHeaderVal(h), BuildHeaderVal(h),
${val.file_id}, ${val.file_id},
${val.offset}, ${val.write_offset},
${val.data_len}); ${val.data_len});
if ( ! ${val.is_pipe} && ${val.data}.length() > 0 ) if ( ! ${val.is_pipe} && ${val.data}.length() > 0 )
{ {
file_mgr->DataIn(${val.data}.begin(), ${val.data}.length(), file_mgr->DataIn(${val.data}.begin(), ${val.data}.length(),
${val.offset}, ${val.write_offset},
bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->GetAnalyzerTag(),
bro_analyzer()->Conn(), h->is_orig()); bro_analyzer()->Conn(), h->is_orig());
} }
@ -34,7 +34,7 @@ refine connection SMB_Conn += {
}; };
type SMB1_write_andx_request(header: SMB_Header) = record { type SMB1_write_andx_request(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
file_id : uint16; file_id : uint16;
@ -53,17 +53,21 @@ type SMB1_write_andx_request(header: SMB_Header) = record {
byte_count : uint16; byte_count : uint16;
pad : padding to data_offset - SMB_Header_length; pad : padding to data_offset - SMB_Header_length;
data : bytestring &length=data_len; data : bytestring &length=data_len;
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command);
} &let { } &let {
is_pipe : bool = $context.connection.get_tree_is_pipe(header.tid); is_pipe : bool = $context.connection.get_tree_is_pipe(header.tid);
pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, true) &if(is_pipe); pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, true) &if(is_pipe);
data_len : uint32 = (data_len_high << 16) + data_len_low; data_len : uint32 = (data_len_high << 16) + data_len_low;
offset_high : uint32 = (word_count == 0x0E) ? offset_high_tmp : 0; offset_high : uint32 = (word_count == 0x0E) ? offset_high_tmp : 0;
offset : uint64 = (offset_high * 0x10000) + offset_low; write_offset: uint64 = (offset_high * 0x10000) + offset_low;
proc : bool = $context.connection.proc_smb1_write_andx_request(header, this); proc : bool = $context.connection.proc_smb1_write_andx_request(header, this);
}; };
type SMB1_write_andx_response(header: SMB_Header) = record { type SMB1_write_andx_response(header: SMB_Header, offset: uint16) = record {
word_count : uint8; word_count : uint8;
andx : SMB_andx; andx : SMB_andx;
written_low : uint16; written_low : uint16;
@ -72,6 +76,10 @@ type SMB1_write_andx_response(header: SMB_Header) = record {
reserved : uint16; reserved : uint16;
byte_count : uint16; byte_count : uint16;
extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters)));
andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command);
} &let { } &let {
written_bytes : uint32 = (written_high * 0x10000) + written_low; written_bytes : uint32 = (written_high * 0x10000) + written_low;
proc : bool = $context.connection.proc_smb1_write_andx_response(header, this); proc : bool = $context.connection.proc_smb1_write_andx_response(header, this);

View file

@ -98,7 +98,7 @@ type SMB_PDU(is_orig: bool, msg_len: uint32) = record {
# Message length of 35 means that the actual message is # Message length of 35 means that the actual message is
# only three bytes which means it's an empty response. # only three bytes which means it's an empty response.
35 -> no_msg : SMB_No_Message(header, is_orig); 35 -> no_msg : SMB_No_Message(header, is_orig);
default -> msg : SMB_Message(header, header.command, is_orig); default -> msg : SMB_Message(header, SMB_Header_length, header.command, is_orig);
}; };
}; };
@ -115,27 +115,27 @@ type SMB_empty_response(header: SMB_Header) = record {
proc : bool = $context.connection.proc_smb_empty_response(header); proc : bool = $context.connection.proc_smb_empty_response(header);
}; };
type SMB_Message(header: SMB_Header, command: uint8, is_orig: bool) = case is_orig of { type SMB_Message(header: SMB_Header, offset: uint16, command: uint8, is_orig: bool) = case is_orig of {
true -> request : SMB_Message_Request(header, command, is_orig); true -> request : SMB_Message_Request(header, offset, command, is_orig);
false -> response : SMB_Message_Response(header, command, is_orig); false -> response : SMB_Message_Response(header, offset, command, is_orig);
}; };
type SMB_andx_command(header: SMB_Header, is_orig: bool, command: uint8) = case command of { type SMB_andx_command(header: SMB_Header, is_orig: bool, offset: uint16, command: uint8) = case command of {
0xff -> no_futher_commands : empty; 0xff -> no_futher_commands : empty;
default -> message : SMB_Message(header, command, is_orig); default -> message : SMB_Message(header, offset, command, is_orig);
}; };
type SMB_Message_Request(header: SMB_Header, command: uint8, is_orig: bool) = case command of { type SMB_Message_Request(header: SMB_Header, offset: uint16, command: uint8, is_orig: bool) = case command of {
# SMB1 Command Extensions # SMB1 Command Extensions
#SMB_COM_OPEN_ANDX -> open_andx : SMB_open_andx_request(header); #SMB_COM_OPEN_ANDX -> open_andx : SMB_open_andx_request(header);
SMB_COM_READ_ANDX -> read_andx : SMB1_read_andx_request(header); SMB_COM_READ_ANDX -> read_andx : SMB1_read_andx_request(header, offset);
SMB_COM_WRITE_ANDX -> write_andx : SMB1_write_andx_request(header); SMB_COM_WRITE_ANDX -> write_andx : SMB1_write_andx_request(header, offset);
SMB_COM_TRANSACTION2 -> transaction2 : SMB1_transaction2_request(header); SMB_COM_TRANSACTION2 -> transaction2 : SMB1_transaction2_request(header);
SMB_COM_NEGOTIATE -> negotiate : SMB1_negotiate_request(header); SMB_COM_NEGOTIATE -> negotiate : SMB1_negotiate_request(header);
SMB_COM_SESSION_SETUP_ANDX -> session_setup_andx : SMB1_session_setup_andx_request(header); SMB_COM_SESSION_SETUP_ANDX -> session_setup_andx : SMB1_session_setup_andx_request(header, offset);
SMB_COM_TREE_CONNECT_ANDX -> tree_connect_andx : SMB1_tree_connect_andx_request(header); SMB_COM_TREE_CONNECT_ANDX -> tree_connect_andx : SMB1_tree_connect_andx_request(header, offset);
SMB_COM_NT_TRANSACT -> nt_transact : SMB1_nt_transact_request(header); SMB_COM_NT_TRANSACT -> nt_transact : SMB1_nt_transact_request(header);
SMB_COM_NT_CREATE_ANDX -> nt_create_andx : SMB1_nt_create_andx_request(header); SMB_COM_NT_CREATE_ANDX -> nt_create_andx : SMB1_nt_create_andx_request(header, offset);
# SMB_COM_CREATE_DIRECTORY -> create_directory : SMB1_create_directory_request(header); # SMB_COM_CREATE_DIRECTORY -> create_directory : SMB1_create_directory_request(header);
# #SMB_COM_DELETE_DIRECTORY -> delete_directory : SMB_delete_directory_request(header); # #SMB_COM_DELETE_DIRECTORY -> delete_directory : SMB_delete_directory_request(header);
@ -168,7 +168,7 @@ type SMB_Message_Request(header: SMB_Header, command: uint8, is_orig: bool) = ca
# #SMB_COM_QUERY_SERVER -> query_server : SMB_query_server_request(header); # #SMB_COM_QUERY_SERVER -> query_server : SMB_query_server_request(header);
# #SMB_COM_SET_INFORMATION2 -> set_information2 : SMB_set_information2_request(header); # #SMB_COM_SET_INFORMATION2 -> set_information2 : SMB_set_information2_request(header);
# #SMB_COM_QUERY_INFORMATION2 -> query_information2 : SMB_query_information2_request(header); # #SMB_COM_QUERY_INFORMATION2 -> query_information2 : SMB_query_information2_request(header);
SMB_COM_LOCKING_ANDX -> locking_andx : SMB1_locking_andx_request(header); SMB_COM_LOCKING_ANDX -> locking_andx : SMB1_locking_andx_request(header, offset);
SMB_COM_TRANSACTION -> transaction : SMB1_transaction_request(header); SMB_COM_TRANSACTION -> transaction : SMB1_transaction_request(header);
# SMB_COM_TRANSACTION_SECONDARY -> transaction_secondary : SMB1_transaction_secondary_request(header); # SMB_COM_TRANSACTION_SECONDARY -> transaction_secondary : SMB1_transaction_secondary_request(header);
# #SMB_COM_IOCTL -> ioctl : SMB_ioctl_request(header); # #SMB_COM_IOCTL -> ioctl : SMB_ioctl_request(header);
@ -184,7 +184,7 @@ type SMB_Message_Request(header: SMB_Header, command: uint8, is_orig: bool) = ca
# #SMB_COM_FIND_NOTIFY_CLOSE -> find_notify_close : SMB_find_notify_close_request(header); # #SMB_COM_FIND_NOTIFY_CLOSE -> find_notify_close : SMB_find_notify_close_request(header);
# #SMB_COM_TREE_CONNECT -> tree_connect : SMB_tree_connect_request(header); # #SMB_COM_TREE_CONNECT -> tree_connect : SMB_tree_connect_request(header);
SMB_COM_TREE_DISCONNECT -> tree_disconnect : SMB1_tree_disconnect(header, is_orig); SMB_COM_TREE_DISCONNECT -> tree_disconnect : SMB1_tree_disconnect(header, is_orig);
SMB_COM_LOGOFF_ANDX -> logoff_andx : SMB1_logoff_andx(header, is_orig); SMB_COM_LOGOFF_ANDX -> logoff_andx : SMB1_logoff_andx(header, offset, is_orig);
# #SMB_COM_QUERY_INFORMATION_DISK -> query_information_disk : SMB_query_information_disk_request(header); # #SMB_COM_QUERY_INFORMATION_DISK -> query_information_disk : SMB_query_information_disk_request(header);
# #SMB_COM_SEARCH -> search : SMB_search_request(header); # #SMB_COM_SEARCH -> search : SMB_search_request(header);
# #SMB_COM_FIND -> find : SMB_find_request(header); # #SMB_COM_FIND -> find : SMB_find_request(header);
@ -203,17 +203,17 @@ type SMB_Message_Request(header: SMB_Header, command: uint8, is_orig: bool) = ca
default -> unknown_msg : bytestring &restofdata; # TODO: do something different here! default -> unknown_msg : bytestring &restofdata; # TODO: do something different here!
} &byteorder = littleendian; } &byteorder = littleendian;
type SMB_Message_Response(header: SMB_Header, command: uint8, is_orig: bool) = case command of { type SMB_Message_Response(header: SMB_Header, offset: uint16, command: uint8, is_orig: bool) = case command of {
# SMB1 Command Extensions # SMB1 Command Extensions
#SMB_COM_OPEN_ANDX -> open_andx : SMB_open_andx_response(header); #SMB_COM_OPEN_ANDX -> open_andx : SMB_open_andx_response(header, offset);
SMB_COM_READ_ANDX -> read_andx : SMB1_read_andx_response(header); SMB_COM_READ_ANDX -> read_andx : SMB1_read_andx_response(header, offset);
SMB_COM_WRITE_ANDX -> write_andx : SMB1_write_andx_response(header); SMB_COM_WRITE_ANDX -> write_andx : SMB1_write_andx_response(header, offset);
SMB_COM_TRANSACTION2 -> transaction2 : SMB1_transaction2_response(header); SMB_COM_TRANSACTION2 -> transaction2 : SMB1_transaction2_response(header);
SMB_COM_NEGOTIATE -> negotiate : SMB1_negotiate_response(header); SMB_COM_NEGOTIATE -> negotiate : SMB1_negotiate_response(header);
SMB_COM_SESSION_SETUP_ANDX -> session_setup_andx : SMB1_session_setup_andx_response(header); SMB_COM_SESSION_SETUP_ANDX -> session_setup_andx : SMB1_session_setup_andx_response(header, offset);
SMB_COM_TREE_CONNECT_ANDX -> tree_connect_andx : SMB1_tree_connect_andx_response(header); SMB_COM_TREE_CONNECT_ANDX -> tree_connect_andx : SMB1_tree_connect_andx_response(header, offset);
SMB_COM_NT_TRANSACT -> nt_transact : SMB1_nt_transact_response(header); SMB_COM_NT_TRANSACT -> nt_transact : SMB1_nt_transact_response(header);
SMB_COM_NT_CREATE_ANDX -> nt_create_andx : SMB1_nt_create_andx_response(header); SMB_COM_NT_CREATE_ANDX -> nt_create_andx : SMB1_nt_create_andx_response(header, offset);
# SMB_COM_CREATE_DIRECTORY -> create_directory : SMB1_create_directory_response(header); # SMB_COM_CREATE_DIRECTORY -> create_directory : SMB1_create_directory_response(header);
# #SMB_COM_DELETE_DIRECTORY -> delete_directory : SMB_delete_directory_response(header); # #SMB_COM_DELETE_DIRECTORY -> delete_directory : SMB_delete_directory_response(header);
@ -261,7 +261,7 @@ type SMB_Message_Response(header: SMB_Header, command: uint8, is_orig: bool) = c
# #SMB_COM_FIND_NOTIFY_CLOSE -> find_notify_close : SMB_find_notify_close_response(header); # #SMB_COM_FIND_NOTIFY_CLOSE -> find_notify_close : SMB_find_notify_close_response(header);
# #SMB_COM_TREE_CONNECT -> tree_connect : SMB_tree_connect_response(header); # #SMB_COM_TREE_CONNECT -> tree_connect : SMB_tree_connect_response(header);
SMB_COM_TREE_DISCONNECT -> tree_disconnect : SMB1_tree_disconnect(header, is_orig); SMB_COM_TREE_DISCONNECT -> tree_disconnect : SMB1_tree_disconnect(header, is_orig);
SMB_COM_LOGOFF_ANDX -> logoff_andx : SMB1_logoff_andx(header, is_orig); SMB_COM_LOGOFF_ANDX -> logoff_andx : SMB1_logoff_andx(header, offset, is_orig);
# #SMB_COM_QUERY_INFORMATION_DISK -> query_information_disk : SMB_query_information_disk_response(header); # #SMB_COM_QUERY_INFORMATION_DISK -> query_information_disk : SMB_query_information_disk_response(header);
# #SMB_COM_SEARCH -> search : SMB_search_response(header); # #SMB_COM_SEARCH -> search : SMB_search_response(header);
# #SMB_COM_FIND -> find : SMB_find_response(header); # #SMB_COM_FIND -> find : SMB_find_response(header);