smb3: parse transform records

pull/3281/head
Victor Julien 8 years ago
parent 894a73ee06
commit b34392051d

@ -26,6 +26,7 @@ pub mod smb1;
pub mod smb1_session;
pub mod smb2;
pub mod smb2_session;
pub mod smb3;
pub mod dcerpc;
pub mod session;
pub mod log;

@ -44,6 +44,7 @@ use smb::smb2_records::*;
use smb::smb1::*;
use smb::smb2::*;
use smb::smb3::*;
use smb::dcerpc::*;
use smb::session::*;
use smb::events::*;
@ -1053,7 +1054,7 @@ impl SMBState {
match parse_smb_version(&nbss_part_hdr.data) {
IResult::Done(_, ref smb) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 255u8 { // SMB1
if smb.version == 0xff_u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_part_hdr.data) {
IResult::Done(_, ref r) => {
@ -1077,7 +1078,7 @@ impl SMBState {
_ => { },
}
} else if smb.version == 254u8 { // SMB2
} else if smb.version == 0xfe_u8 { // SMB2
SCLogDebug!("SMBv2 record");
match parse_smb2_request_record(&nbss_part_hdr.data) {
IResult::Done(_, ref smb_record) => {
@ -1092,6 +1093,7 @@ impl SMBState {
_ => { },
}
}
// no SMB3 here yet, will buffer full records
},
_ => { },
}
@ -1151,7 +1153,7 @@ impl SMBState {
// gap
if self.ts_gap {
SCLogDebug!("TODO TS trying to catch up after GAP (input {})", cur_i.len());
match search_smb2_record(cur_i) {
match search_smb_record(cur_i) {
IResult::Done(_, pg) => {
SCLogDebug!("smb record found");
let smb2_offset = cur_i.len() - pg.data.len();
@ -1179,7 +1181,7 @@ impl SMBState {
match parse_smb_version(&nbss_hdr.data) {
IResult::Done(_, ref smb) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 255u8 { // SMB1
if smb.version == 0xff_u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_hdr.data) {
IResult::Done(_, ref smb_record) => {
@ -1190,7 +1192,7 @@ impl SMBState {
return 1;
},
}
} else if smb.version == 254u8 { // SMB2
} else if smb.version == 0xfe_u8 { // SMB2
let mut nbss_data = nbss_hdr.data;
while nbss_data.len() > 0 {
SCLogDebug!("SMBv2 record");
@ -1207,6 +1209,20 @@ impl SMBState {
},
}
}
} else if smb.version == 0xfd_u8 { // SMB3 transform
let mut nbss_data = nbss_hdr.data;
while nbss_data.len() > 0 {
SCLogDebug!("SMBv3 transform record");
match parse_smb3_transform_record(&nbss_data) {
IResult::Done(nbss_data_rem, ref _smb3_record) => {
nbss_data = nbss_data_rem;
},
_ => {
self.set_event(SMBEvent::MalformedData);
return 1;
},
}
}
}
},
_ => {
@ -1305,6 +1321,7 @@ impl SMBState {
_ => { },
}
}
// no SMB3 here yet, will buffer full records
},
_ => { },
}
@ -1361,8 +1378,8 @@ impl SMBState {
}
// gap
if self.tc_gap {
SCLogDebug!("TODO TC trying to catch up after GAP (input {})", cur_i.len());
match search_smb2_record(cur_i) {
SCLogDebug!("TC trying to catch up after GAP (input {})", cur_i.len());
match search_smb_record(cur_i) {
IResult::Done(_, pg) => {
SCLogDebug!("smb record found");
let smb2_offset = cur_i.len() - pg.data.len();
@ -1390,7 +1407,7 @@ impl SMBState {
match parse_smb_version(&nbss_hdr.data) {
IResult::Done(_, ref smb) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 255u8 { // SMB1
if smb.version == 0xff_u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_hdr.data) {
IResult::Done(_, ref smb_record) => {
@ -1401,7 +1418,7 @@ impl SMBState {
return 1;
},
}
} else if smb.version == 254u8 { // SMB2
} else if smb.version == 0xfe_u8 { // SMB2
let mut nbss_data = nbss_hdr.data;
while nbss_data.len() > 0 {
SCLogDebug!("SMBv2 record");
@ -1416,6 +1433,20 @@ impl SMBState {
},
}
}
} else if smb.version == 0xfd_u8 { // SMB3 transform
let mut nbss_data = nbss_hdr.data;
while nbss_data.len() > 0 {
SCLogDebug!("SMBv3 transform record");
match parse_smb3_transform_record(&nbss_data) {
IResult::Done(nbss_data_rem, ref _smb3_record) => {
nbss_data = nbss_data_rem;
},
_ => {
self.set_event(SMBEvent::MalformedData);
return 1;
},
}
}
}
},
IResult::Incomplete(_) => {

@ -15,7 +15,7 @@
* 02110-1301, USA.
*/
use nom::{rest, le_u8, le_u16, le_u32, le_u64, IResult, AsBytes};
use nom::{rest, le_u8, le_u16, le_u32, le_u64, AsBytes};
#[derive(Debug,PartialEq)]
pub struct Smb2SecBlobRecord<'a> {
@ -405,28 +405,17 @@ named!(pub parse_smb2_response_record<Smb2Record>,
));
#[derive(Debug,PartialEq)]
pub struct Smb2RecordPostGap<'a> {
pub struct SmbRecordPostGap<'a> {
pub data: &'a[u8],
}
named!(pub search_smb2_record<Smb2RecordPostGap>,
named!(pub search_smb_record<SmbRecordPostGap>,
do_parse!(
alt!(take_until!([0xfe, 0x53, 0x4d, 0x42].as_bytes())| // SMB2
take_until!([0xff, 0x53, 0x4d, 0x42].as_bytes())) // SMB1
take_until!([0xff, 0x53, 0x4d, 0x42].as_bytes())| // SMB1
take_until!([0xfd, 0x53, 0x4d, 0x42].as_bytes())) // SMB3 transform hdr
>> data : rest
>> ( Smb2RecordPostGap {
>> ( SmbRecordPostGap {
data:data,
})
));
pub fn search_smb2_record_f<'a>(input: &'a [u8])
-> IResult<&'a [u8], Smb2RecordPostGap>
{
return closure!(&'a [u8], do_parse!(
take_until!([0xfe, 0x53, 0x4d, 0x42].as_bytes())
>> data : rest
>> ( Smb2RecordPostGap {
data:data,
})
))(input);
}

@ -0,0 +1,42 @@
/* Copyright (C) 2018 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use nom::{le_u16, le_u32, le_u64};
#[derive(Debug,PartialEq)]
pub struct Smb3TransformRecord<'a> {
pub session_id: u64,
pub enc_algo: u16,
pub enc_data: &'a[u8],
}
named!(pub parse_smb3_transform_record<Smb3TransformRecord>,
do_parse!(
tag!(b"\xfdSMB")
>> signature: take!(16)
>> nonce: take!(16)
>> msg_size: le_u32
>> reserved: le_u16
>> enc_algo: le_u16
>> session_id: le_u64
>> enc_data: take!(msg_size)
>> ( Smb3TransformRecord {
session_id: session_id,
enc_algo: enc_algo,
enc_data: enc_data,
})
));
Loading…
Cancel
Save