]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ssh: handles incomplete record after banner
authorPhilippe Antoine <contact@catenacyber.fr>
Tue, 26 May 2020 06:46:24 +0000 (08:46 +0200)
committerVictor Julien <victor@inliniac.net>
Sat, 30 May 2020 18:39:34 +0000 (20:39 +0200)
To signal incomplete data, we must return the number of
consumed bytes. When we get a banner and some records, we have
to take into account the number of bytes already consumed by
the banner parsing before reaching an incomplete record.

rust/src/ssh/ssh.rs

index eba07c63c6be2028157b96e159350e23b83bfe0a..1f8601ecf8ce2d7cad23ef68cad8dad1d679b9cf 100644 (file)
@@ -224,7 +224,16 @@ impl SSHState {
         if hdr.flags == SSHConnectionState::SshStateBannerWaitEol {
             match parser::ssh_parse_line(input) {
                 Ok((rem, _)) => {
-                    return self.parse_record(rem, resp, pstate);
+                    let r = self.parse_record(rem, resp, pstate);
+                    if r.status == 1 {
+                        //adds bytes consumed by banner to incomplete result
+                        return AppLayerResult::incomplete(
+                            r.consumed + (input.len() - rem.len()) as u32,
+                            r.needed,
+                        );
+                    } else {
+                        return r;
+                    }
                 }
                 Err(nom::Err::Incomplete(_)) => {
                     return AppLayerResult::incomplete(0 as u32, (input.len() + 1) as u32);
@@ -257,7 +266,16 @@ impl SSHState {
                     );
                     self.set_event(SSHEvent::LongBanner);
                 }
-                return self.parse_record(rem, resp, pstate);
+                let r = self.parse_record(rem, resp, pstate);
+                if r.status == 1 {
+                    //adds bytes consumed by banner to incomplete result
+                    return AppLayerResult::incomplete(
+                        r.consumed + (input.len() - rem.len()) as u32,
+                        r.needed,
+                    );
+                } else {
+                    return r;
+                }
             }
             Err(nom::Err::Incomplete(_)) => {
                 if input.len() < SSH_MAX_BANNER_LEN {