Bug #8995
opensmtp: rejected BDAT reply leaves parser in data mode
Description
- Summary
A syntactically valid, non-empty SMTP BDAT command can be rejected by the
server before the client sends the advertised chunk octets. Suricata does not
handle the error reply and remains in
`SMTP_PARSER_STATE_COMMAND_DATA_MODE`.
Subsequent client commands and message content are consumed as if they were
part of the missing BDAT chunk, desynchronizing Suricata's SMTP parser from the
actual SMTP session.
- Example sequence
```text
C: EHLO client
S: 250 CHUNKING
C: BDAT 1000000 LAST
S: 503
C: RSET
S: 250
C: MAIL FROM ...
```
After the `503` response, Suricata remains in BDAT mode waiting for the
declared bytes. The following `RSET`, envelope commands, DATA command, and
message content are therefore not parsed correctly.
- Impact
Traffic following the rejected BDAT command can bypass SMTP, MIME, and file
inspection for the remainder of the connection.
The Suricata-Verify reproducer sends an EICAR antivirus test file in a message
after the rejected BDAT command. The corresponding detection rule does not
trigger because the later SMTP commands and message are not parsed.
- Relationship to existing work
This is related to #8741. The fixes for that issue address other BDAT parsing
and transaction handling problems, but do not handle an error response to a
syntactically valid BDAT command before its advertised chunk is received.
- Suggested remediation
When the server returns an error response to a BDAT command, clear
`SMTP_PARSER_STATE_COMMAND_DATA_MODE` so subsequent client commands can be
parsed normally.
- Credit
Please credit Nozomi Networks Labs.