smb: parse smb1 session setup with word count 13

Ticket: 5845
pull/15185/head
Philippe Antoine 4 months ago committed by Victor Julien
parent 98469b0f56
commit 0a24f0afe2

@ -18,6 +18,7 @@
use crate::kerberos::*;
use crate::smb::smb::*;
use crate::smb::smb1_session::*;
use crate::smb::smb1_records::SessionSetupRequest;
use crate::smb::auth::*;
#[derive(Default, Debug)]

@ -446,16 +446,115 @@ pub fn parse_smb_trans_response_record(i: &[u8]) -> IResult<&[u8], SmbRecordTran
#[derive(Debug,PartialEq, Eq)]
pub struct SmbRecordSetupAndX<'a> {
pub sec_blob: &'a[u8],
pub request_host: SessionSetupRequest,
}
pub fn parse_smb_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbRecordSetupAndX<'_>> {
let (i, _skip1) = take(15_usize).parse(i)?;
let (i, sec_blob_len) = le_u16.parse(i)?;
let (i, _skip2) = take(8_usize).parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, sec_blob) = take(sec_blob_len).parse(i)?;
let record = SmbRecordSetupAndX { sec_blob };
Ok((i, record))
#[derive(Debug,PartialEq, Eq)]
pub struct SessionSetupRequest {
pub native_os: Vec<u8>,
pub native_lm: Vec<u8>,
pub primary_domain: Vec<u8>,
}
pub fn smb1_session_setup_request_host_info(r: &SmbRecord, blob: &[u8]) -> SessionSetupRequest
{
if blob.len() > 1 && r.has_unicode_support() {
let offset = r.data.len() - blob.len();
let blob = if offset % 2 == 1 { &blob[1..] } else { blob };
let (native_os, native_lm, primary_domain) = match smb_get_unicode_string(blob) {
Ok((rem, n1)) => {
match smb_get_unicode_string(rem) {
Ok((rem, n2)) => {
match smb_get_unicode_string(rem) {
Ok((_, n3)) => { (n1, n2, n3) },
_ => { (n1, n2, Vec::new()) },
}
},
_ => { (n1, Vec::new(), Vec::new()) },
}
},
_ => { (Vec::new(), Vec::new(), Vec::new()) },
};
SCLogDebug!("name1 {:?} name2 {:?} name3 {:?}", native_os,native_lm,primary_domain);
SessionSetupRequest {
native_os,
native_lm,
primary_domain,
}
} else {
let (native_os, native_lm, primary_domain) = match smb_get_ascii_string(blob) {
Ok((rem, n1)) => {
match smb_get_ascii_string(rem) {
Ok((rem, n2)) => {
match smb_get_ascii_string(rem) {
Ok((_, n3)) => { (n1, n2, n3) },
_ => { (n1, n2, Vec::new()) },
}
},
_ => { (n1, Vec::new(), Vec::new()) },
}
},
_ => { (Vec::new(), Vec::new(), Vec::new()) },
};
SCLogDebug!("session_setup_request_host_info: not unicode");
SessionSetupRequest {
native_os,
native_lm,
primary_domain,
}
}
}
pub fn smb1_session_setup_parse_wct13<'a>(r: &'a SmbRecord, blob: &'a [u8]) -> (&'a [u8], SessionSetupRequest) {
if let Ok((rem, primary_domain)) = smb1_get_string(blob, r, 0) {
if let Ok((rem, native_os)) = smb1_get_string(rem, r, 0) {
if let Ok((rem, native_lm)) = smb1_get_string(rem, r, 0) {
return (rem, SessionSetupRequest {
native_os,
native_lm,
primary_domain,
});
}
}
}
return (blob, SessionSetupRequest {
native_os: Vec::new(),
native_lm: Vec::new(),
primary_domain: Vec::new(),
});
}
pub fn parse_smb_setup_andx_record<'a>(i: &'a [u8], r: &'a SmbRecord) -> IResult<&'a [u8], SmbRecordSetupAndX<'a>> {
let (i, wct) = le_u8.parse(i)?;
if wct == 12 {
let (i, _skip1) = take(14_usize).parse(i)?;
let (i, sec_blob_len) = le_u16.parse(i)?;
let (i, _skip2) = take(8_usize).parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, sec_blob) = take(sec_blob_len).parse(i)?;
let record = SmbRecordSetupAndX { sec_blob, request_host: smb1_session_setup_request_host_info(r, i) };
Ok((i, record))
} else if wct == 13 {
let (i, _skip1) = take(14_usize).parse(i)?;
let (i, oem_pass_len) = le_u16.parse(i)?;
let (i, uni_pass_len) = le_u16.parse(i)?;
let (i, _skip2) = take(8_usize).parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, _oem_pass) = take(oem_pass_len).parse(i)?;
let (i, _uni_pass) = take(uni_pass_len).parse(i)?;
let (i, _pad) = cond((oem_pass_len + uni_pass_len) % 2 == 1, le_u8).parse(i)?;
if let Ok((i, _account_name)) = smb1_get_string(i, r, 0) {
let (i, request_host) = smb1_session_setup_parse_wct13(r, i);
let record = SmbRecordSetupAndX { sec_blob: &[], request_host };
Ok((i, record))
} else {
Err(Err::Error(make_error(i, ErrorKind::LengthValue)))
}
} else {
return Err(Err::Error(make_error(i, ErrorKind::LengthValue)));
}
}
#[derive(Debug,PartialEq, Eq)]

@ -21,70 +21,12 @@ use crate::smb::smb::*;
use crate::smb::events::*;
use crate::smb::auth::*;
#[derive(Debug)]
pub struct SessionSetupRequest {
pub native_os: Vec<u8>,
pub native_lm: Vec<u8>,
pub primary_domain: Vec<u8>,
}
#[derive(Debug)]
pub struct SessionSetupResponse {
pub native_os: Vec<u8>,
pub native_lm: Vec<u8>,
}
pub fn smb1_session_setup_request_host_info(r: &SmbRecord, blob: &[u8]) -> SessionSetupRequest
{
if blob.len() > 1 && r.has_unicode_support() {
let offset = r.data.len() - blob.len();
let blob = if offset % 2 == 1 { &blob[1..] } else { blob };
let (native_os, native_lm, primary_domain) = match smb_get_unicode_string(blob) {
Ok((rem, n1)) => {
match smb_get_unicode_string(rem) {
Ok((rem, n2)) => {
match smb_get_unicode_string(rem) {
Ok((_, n3)) => { (n1, n2, n3) },
_ => { (n1, n2, Vec::new()) },
}
},
_ => { (n1, Vec::new(), Vec::new()) },
}
},
_ => { (Vec::new(), Vec::new(), Vec::new()) },
};
SCLogDebug!("name1 {:?} name2 {:?} name3 {:?}", native_os,native_lm,primary_domain);
SessionSetupRequest {
native_os,
native_lm,
primary_domain,
}
} else {
let (native_os, native_lm, primary_domain) = match smb_get_ascii_string(blob) {
Ok((rem, n1)) => {
match smb_get_ascii_string(rem) {
Ok((rem, n2)) => {
match smb_get_ascii_string(rem) {
Ok((_, n3)) => { (n1, n2, n3) },
_ => { (n1, n2, Vec::new()) },
}
},
_ => { (n1, Vec::new(), Vec::new()) },
}
},
_ => { (Vec::new(), Vec::new(), Vec::new()) },
};
SCLogDebug!("session_setup_request_host_info: not unicode");
SessionSetupRequest {
native_os,
native_lm,
primary_domain,
}
}
}
pub fn smb1_session_setup_response_host_info(r: &SmbRecord, blob: &[u8]) -> SessionSetupResponse
{
if blob.len() > 1 && r.has_unicode_support() {
@ -127,15 +69,15 @@ pub fn smb1_session_setup_request(state: &mut SMBState, r: &SmbRecord, andx_offs
{
SCLogDebug!("SMB1_COMMAND_SESSION_SETUP_ANDX user_id {}", r.user_id);
#[allow(clippy::single_match)]
match parse_smb_setup_andx_record(&r.data[andx_offset-SMB1_HEADER_SIZE..]) {
Ok((rem, setup)) => {
match parse_smb_setup_andx_record(&r.data[andx_offset-SMB1_HEADER_SIZE..], r) {
Ok((_rem, setup)) => {
let hdr = SMBCommonHdr::new(SMBHDR_TYPE_HEADER,
r.ssn_id as u64, 0, r.multiplex_id as u64);
let tx = state.new_sessionsetup_tx(hdr);
tx.vercmd.set_smb1_cmd(r.command);
if let Some(SMBTransactionTypeData::SESSIONSETUP(ref mut td)) = tx.type_data {
td.request_host = Some(smb1_session_setup_request_host_info(r, rem));
td.request_host = Some(setup.request_host);
if let Some(s) = parse_secblob(setup.sec_blob) {
td.ntlmssp = s.ntlmssp;
td.krb_ticket = s.krb;

Loading…
Cancel
Save