ssh: fixing incomplete kex parsing

We use the record length from the ssh record header,
and not the size of the parsed data, as is done in other places.
pull/5207/head
Philippe Antoine 5 years ago committed by Victor Julien
parent bcd416e6ba
commit eb5b927787

@ -62,7 +62,6 @@ pub enum SSHConnectionState {
const SSH_MAX_BANNER_LEN: usize = 256;
const SSH_RECORD_HEADER_LEN: usize = 6;
const SSH_RECORD_PADDING_LEN: usize = 4;
const SSH_MAX_REASSEMBLED_RECORD_LEN: usize = 65535;
pub struct SshHeader {
@ -158,24 +157,28 @@ impl SSHState {
if hdr.record_left > 0 {
//should we check for overflow ?
let ilen = input.len() as u32;
if hdr.record_left >= ilen {
if hdr.record_left > ilen {
hdr.record_left -= ilen;
return AppLayerResult::ok();
} else {
let start = hdr.record_left as usize;
match hdr.record_left_msg {
// parse reassembled tcp segments
parser::MessageCode::SshMsgKexinit if hassh_is_enabled() => {
if let Ok((rem, key_exchange)) = parser::ssh_parse_key_exchange(&input) {
key_exchange.generate_hassh(&mut hdr.hassh_string, &mut hdr.hassh, &resp);
input = &rem[SSH_RECORD_PADDING_LEN..];
if let Ok((_rem, key_exchange)) =
parser::ssh_parse_key_exchange(&input[..start])
{
key_exchange.generate_hassh(
&mut hdr.hassh_string,
&mut hdr.hassh,
&resp,
);
}
hdr.record_left_msg = parser::MessageCode::SshMsgUndefined(0);
}
_ => {
let start = hdr.record_left as usize;
input = &input[start..];
}
_ => {}
}
input = &input[start..];
hdr.record_left = 0;
}
}
@ -186,7 +189,9 @@ impl SSHState {
SCLogDebug!("SSH valid record {}", head);
match head.msg_code {
parser::MessageCode::SshMsgKexinit if hassh_is_enabled() => {
if let Ok((_, key_exchange)) = parser::ssh_parse_key_exchange(&input[SSH_RECORD_HEADER_LEN..]) {
//let endkex = SSH_RECORD_HEADER_LEN + head.pkt_len - 2;
let endkex = input.len() - rem.len();
if let Ok((_, key_exchange)) = parser::ssh_parse_key_exchange(&input[SSH_RECORD_HEADER_LEN..endkex]) {
key_exchange.generate_hassh(&mut hdr.hassh_string, &mut hdr.hassh, &resp);
}
}
@ -222,6 +227,7 @@ impl SSHState {
}
parser::MessageCode::SshMsgKexinit if hassh_is_enabled() => {
// check if buffer is bigger than maximum reassembled packet size
hdr.record_left = head.pkt_len - 2;
if hdr.record_left < SSH_MAX_REASSEMBLED_RECORD_LEN as u32 {
// saving type of incomplete kex message
hdr.record_left_msg = parser::MessageCode::SshMsgKexinit;

Loading…
Cancel
Save