From: Philippe Antoine Date: Tue, 14 Apr 2020 12:24:22 +0000 (+0200) Subject: smb: resistance against padding evasions X-Git-Tag: suricata-6.0.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aaa69fe3c5366996348f2ad97d030b11b46889f2;p=thirdparty%2Fsuricata.git smb: resistance against padding evasions Scenario is use of dummy padding in write AndX request or other similar commands using a data offset. Parsing skips now these dummy bytes, and generates one event --- diff --git a/rust/src/smb/smb1_records.rs b/rust/src/smb/smb1_records.rs index 20a4a22e69..2112304c5c 100644 --- a/rust/src/smb/smb1_records.rs +++ b/rust/src/smb/smb1_records.rs @@ -80,11 +80,12 @@ named!(pub parse_smb1_write_andx_request_record, >> _remaining: le_u16 >> data_len_high: le_u16 >> data_len_low: le_u16 - >> _data_offset: le_u16 + >> data_offset: le_u16 >> high_offset: cond!(wct==14,le_u32) >> bcc: le_u16 - //>> padding: cond!(data_offset > 32, take!(data_offset - 32)) + //spec [MS-CIFS].pdf says always take one byte padding >> _padding: cond!(bcc > data_len_low, take!(bcc - data_len_low)) // TODO figure out how this works with data_len_high + >> _padding_evasion: cond!(data_offset > 36+2*(wct as u16), take!(data_offset - (36+2*(wct as u16)))) >> file_data: rest >> (Smb1WriteRequestRecord { offset: if high_offset != None { ((high_offset.unwrap() as u64) << 32)|(offset as u64) } else { 0 }, @@ -370,7 +371,7 @@ named!(pub parse_smb_trans_response_error_record, named!(pub parse_smb_trans_response_regular_record, do_parse!( - _wct: le_u8 + wct: le_u8 >> _total_param_cnt: le_u16 >> _total_data_count: le_u16 >> take!(2) // reserved @@ -378,12 +379,13 @@ named!(pub parse_smb_trans_response_regular_record, >> _param_offset: le_u16 >> _param_displacement: le_u16 >> data_cnt: le_u16 - >> _data_offset: le_u16 + >> data_offset: le_u16 >> _data_displacement: le_u16 >> _setup_cnt: le_u8 >> take!(1) // reserved >> bcc: le_u16 >> take!(1) // padding + >> _padding_evasion: cond!(data_offset > 36+2*(wct as u16), take!(data_offset - (36+2*(wct as u16)))) >> data: take!(data_cnt) >> (SmbRecordTransResponse { data_cnt, @@ -491,17 +493,18 @@ pub struct SmbResponseReadAndXRecord<'a> { named!(pub parse_smb_read_andx_response_record, do_parse!( - _wct: le_u8 + wct: le_u8 >> _andx_command: le_u8 >> take!(1) // reserved >> _andx_offset: le_u16 >> take!(6) >> data_len_low: le_u16 - >> _data_offset: le_u16 + >> data_offset: le_u16 >> data_len_high: le_u32 >> take!(6) // reserved >> bcc: le_u16 >> _padding: cond!(bcc > data_len_low, take!(bcc - data_len_low)) // TODO figure out how this works with data_len_high + >> _padding_evasion: cond!(data_offset > 36+2*(wct as u16), take!(data_offset - (36+2*(wct as u16)))) >> file_data: rest >> (SmbResponseReadAndXRecord { @@ -671,6 +674,7 @@ named!(pub parse_smb_trans2_request_record, >> subcmd: le_u16 >> _bcc: le_u16 >> _padding: take!(3) + //TODO test and use _param_offset and _data_offset >> setup_blob: take!(param_cnt) >> data_blob: take!(data_cnt)