rust/smb: convert parser to nom7 functions (SMB1)

pull/6705/head
Pierre Chifflier 4 years ago committed by Victor Julien
parent 895a54cea4
commit d67f8f9196

@ -24,7 +24,7 @@ use nom7::multi::count;
use nom7::number::Endianness; use nom7::number::Endianness;
use nom7::number::streaming::{be_u16, le_u8, le_u16, le_u32, u16, u32}; use nom7::number::streaming::{be_u16, le_u8, le_u16, le_u32, u16, u32};
use nom7::sequence::tuple; use nom7::sequence::tuple;
use nom7::IResult; use nom7::{Err, IResult};
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]
pub struct DceRpcResponseRecord<'a> { pub struct DceRpcResponseRecord<'a> {
@ -34,18 +34,15 @@ pub struct DceRpcResponseRecord<'a> {
/// parse a packet type 'response' DCERPC record. Implemented /// parse a packet type 'response' DCERPC record. Implemented
/// as function to be able to pass the fraglen in. /// as function to be able to pass the fraglen in.
pub fn parse_dcerpc_response_record(i:&[u8], frag_len: u16 ) pub fn parse_dcerpc_response_record(i:&[u8], frag_len: u16 )
-> nom::IResult<&[u8], DceRpcResponseRecord, SmbError> -> IResult<&[u8], DceRpcResponseRecord, SmbError>
{ {
if frag_len < 24 { if frag_len < 24 {
return Err(nom::Err::Error(SmbError::RecordTooSmall)); return Err(Err::Error(SmbError::RecordTooSmall));
} }
do_parse!(i, let (i, _) = take(8_usize)(i)?;
take!(8) let (i, data) = take(frag_len - 24)(i)?;
>> data:take!(frag_len - 24) let record = DceRpcResponseRecord { data };
>> (DceRpcResponseRecord { Ok((i, record))
data:data,
})
)
} }
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]
@ -57,22 +54,17 @@ pub struct DceRpcRequestRecord<'a> {
/// parse a packet type 'request' DCERPC record. Implemented /// parse a packet type 'request' DCERPC record. Implemented
/// as function to be able to pass the fraglen in. /// as function to be able to pass the fraglen in.
pub fn parse_dcerpc_request_record(i:&[u8], frag_len: u16, little: bool) pub fn parse_dcerpc_request_record(i:&[u8], frag_len: u16, little: bool)
-> nom::IResult<&[u8], DceRpcRequestRecord, SmbError> -> IResult<&[u8], DceRpcRequestRecord, SmbError>
{ {
use nom::number::Endianness;
if frag_len < 24 { if frag_len < 24 {
return Err(nom::Err::Error(SmbError::RecordTooSmall)); return Err(Err::Error(SmbError::RecordTooSmall));
} }
do_parse!(i, let (i, _) = take(6_usize)(i)?;
take!(6) let endian = if little { Endianness::Little } else { Endianness::Big };
>> endian: value!(if little { Endianness::Little } else { Endianness::Big }) let (i, opnum) = u16(endian)(i)?;
>> opnum: u16!(endian) let (i, data) = take(frag_len - 24)(i)?;
>> data:take!(frag_len - 24) let record = DceRpcRequestRecord { opnum, data };
>> (DceRpcRequestRecord { Ok((i, record))
opnum:opnum,
data:data,
})
)
} }
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]

@ -16,7 +16,7 @@
*/ */
// Author: Pierre Chifflier <chifflier@wzdftpd.net> // Author: Pierre Chifflier <chifflier@wzdftpd.net>
use nom::error::{ErrorKind, ParseError}; use nom7::error::{ErrorKind, ParseError};
#[derive(Debug)] #[derive(Debug)]
pub enum SmbError { pub enum SmbError {

@ -31,7 +31,6 @@ use std::ffi::{self, CString};
use std::collections::HashMap; use std::collections::HashMap;
use nom;
use nom7::{Err, Needed}; use nom7::{Err, Needed};
use crate::core::*; use crate::core::*;
@ -1649,7 +1648,7 @@ impl SMBState {
} }
} }
}, },
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
// not enough data to contain basic SMB hdr // not enough data to contain basic SMB hdr
// TODO event: empty NBSS_MSGTYPE_SESSION_MESSAGE // TODO event: empty NBSS_MSGTYPE_SESSION_MESSAGE
}, },

@ -19,8 +19,6 @@
* - check all parsers for calls on non-SUCCESS status * - check all parsers for calls on non-SUCCESS status
*/ */
use nom;
use crate::core::*; use crate::core::*;
use crate::smb::smb::*; use crate::smb::smb::*;
@ -31,6 +29,8 @@ use crate::smb::files::*;
use crate::smb::smb1_records::*; use crate::smb::smb1_records::*;
use crate::smb::smb1_session::*; use crate::smb::smb1_session::*;
use nom7::Err;
// https://msdn.microsoft.com/en-us/library/ee441741.aspx // https://msdn.microsoft.com/en-us/library/ee441741.aspx
pub const SMB1_COMMAND_CREATE_DIRECTORY: u8 = 0x00; pub const SMB1_COMMAND_CREATE_DIRECTORY: u8 = 0x00;
pub const SMB1_COMMAND_DELETE_DIRECTORY: u8 = 0x01; pub const SMB1_COMMAND_DELETE_DIRECTORY: u8 = 0x01;
@ -251,13 +251,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
true true
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", _e); SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
@ -279,13 +279,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2); tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
true true
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME ERROR {:?}", _e); SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
@ -295,13 +295,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
false false
} }
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS ERROR {:?}", _e); SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
@ -334,13 +334,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
true true
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", _e); SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
@ -367,13 +367,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2); tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
true true
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME ERROR {:?}", _e); SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
@ -383,13 +383,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
false false
} }
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS ERROR {:?}", _e); SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
@ -399,13 +399,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
false false
} }
}, },
Err(nom::Err::Incomplete(_n)) => { Err(Err::Incomplete(_n)) => {
SCLogDebug!("TRANS2 INCOMPLETE {:?}", _n); SCLogDebug!("TRANS2 INCOMPLETE {:?}", _n);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false
}, },
Err(nom::Err::Error(_e)) | Err(Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { Err(Err::Failure(_e)) => {
SCLogDebug!("TRANS2 ERROR {:?}", _e); SCLogDebug!("TRANS2 ERROR {:?}", _e);
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
false false

File diff suppressed because it is too large Load Diff

@ -15,9 +15,9 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use crate::common::nom7::take_until_and_consume;
use crate::smb::error::SmbError; use crate::smb::error::SmbError;
use nom; use nom7::{Err, IResult};
use nom::IResult;
/// parse a UTF16 string that is null terminated. Normally by 2 null /// parse a UTF16 string that is null terminated. Normally by 2 null
/// bytes, but at the end of the data it can also be a single null. /// bytes, but at the end of the data it can also be a single null.
@ -42,13 +42,12 @@ pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError>
name.push(c[0]); name.push(c[0]);
c = &c[2..]; c = &c[2..];
} }
Err(nom::Err::Error(SmbError::BadEncoding)) Err(Err::Error(SmbError::BadEncoding))
} }
// parse an ASCII string that is null terminated // parse an ASCII string that is null terminated
named!(pub smb_get_ascii_string<&[u8], Vec<u8>, SmbError>, pub fn smb_get_ascii_string(i: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError> {
do_parse!( let (i, s) = take_until_and_consume(b"\x00")(i)?;
s: take_until_and_consume!("\x00") Ok((i, s.to_vec()))
>> ( s.to_vec() ) }
));

Loading…
Cancel
Save