SMTP STARTTLS command injection attempt.
+124:18
+
+SMTP traffic has a mix of LF and CRLF as end of line
+
125:1
TELNET command is detected on FTP control channel.
static void snort_smtp(SmtpProtoConf* GlobalConf, Packet* p);
static void SMTP_ResetState(Flow*);
+static void update_eol_state(SMTPEol new_eol, SMTPEol& curr_eol_state);
SmtpFlowData::SmtpFlowData() : FlowData(inspector_id)
{
char alert_long_command_line = 0;
/* get end of line and end of line marker */
- SMTP_GetEOL(ptr, end, &eol, &eolm);
+ SMTPEol new_eol = SMTP_GetEOL(ptr, end, &eol, &eolm);
/* calculate length of command line */
cmd_line_len = eol - ptr;
DetectionEngine::queue_event(GID_SMTP, SMTP_STARTTLS_INJECTION_ATTEMPT);
}
+ update_eol_state(new_eol, smtp_ssn->client_eol);
+
return eol;
}
const uint8_t* eol;
const uint8_t* eolm;
- SMTP_GetEOL(ptr, end, &eol, &eolm);
+ SMTPEol new_eol = SMTP_GetEOL(ptr, end, &eol, &eolm);
int resp_line_len = eol - ptr;
}
}
- if ((config->max_response_line_len != 0) &&
- (resp_line_len > config->max_response_line_len) &&
- (smtp_ssn->state != STATE_TLS_DATA))
+ if (smtp_ssn->state != STATE_TLS_DATA)
{
+ update_eol_state(new_eol, smtp_ssn->server_eol);
+ if ((config->max_response_line_len != 0) &&
+ (resp_line_len > config->max_response_line_len))
DetectionEngine::queue_event(GID_SMTP, SMTP_RESPONSE_OVERFLOW);
}
config->xtra_ehdrs_id = Stream::reg_xtra_data_cb(SMTP_GetEmailHdrs);
}
+static void update_eol_state(SMTPEol new_eol, SMTPEol& curr_eol_state)
+{
+ if (new_eol == EOL_NOT_SEEN or curr_eol_state == EOL_MIXED)
+ return;
+
+ if (curr_eol_state == EOL_NOT_SEEN)
+ {
+ curr_eol_state = new_eol;
+ return;
+ }
+
+ if ((new_eol == EOL_LF and curr_eol_state == EOL_CRLF) or
+ (new_eol == EOL_CRLF and curr_eol_state == EOL_LF))
+ {
+ curr_eol_state = EOL_MIXED;
+ DetectionEngine::queue_event(GID_SMTP, SMTP_LF_CRLF_MIX);
+ }
+}
+
int SmtpMime::handle_header_line(
const uint8_t* ptr, const uint8_t* eol, int max_header_len, Packet* p)
{
DATA_END_LAST
};
+enum SMTPEol
+{
+ EOL_NOT_SEEN,
+ EOL_LF,
+ EOL_CRLF,
+ EOL_MIXED
+};
+
struct SMTPSearchInfo
{
int id;
auth_name{nullptr},
client_requested_starttls{false},
pipelined_command_counter{0},
- server_accepted_starttls{false}
+ server_accepted_starttls{false},
+ client_eol{EOL_NOT_SEEN},
+ server_eol{EOL_NOT_SEEN}
{ }
int state;
bool client_requested_starttls;
size_t pipelined_command_counter;
bool server_accepted_starttls;
+ SMTPEol client_eol;
+ SMTPEol server_eol;
};
class SmtpFlowData : public snort::FlowData
{ SMTP_AUTH_COMMAND_OVERFLOW, "attempted authentication command buffer overflow" },
{ SMTP_FILE_DECOMP_FAILED, "file decompression failed" },
{ SMTP_STARTTLS_INJECTION_ATTEMPT, "STARTTLS command injection attempt"},
-
+ { SMTP_LF_CRLF_MIX, "mix of LF and CRLF as end of line" },
{ 0, nullptr }
};
#define SMTP_AUTH_COMMAND_OVERFLOW 15
#define SMTP_FILE_DECOMP_FAILED 16
#define SMTP_STARTTLS_INJECTION_ATTEMPT 17
+#define SMTP_LF_CRLF_MIX 18
#define SMTP_NAME "smtp"
#define SMTP_HELP "smtp inspection"
/*State unknown, start cmd search start from EOL, flush on EOL*/
if (val == '\n')
{
- if (pfdata->cmd_info.cmd_state == SMTP_PAF_CMD_DATA_END_STATE)
+ if ((pfdata->cmd_info.cmd_state == SMTP_PAF_CMD_DATA_END_STATE) or
+ ((pfdata->cmd_info.cmd_state == SMTP_PAF_CMD_DATA_LENGTH_STATE) and
+ (pfdata->cmd_info.search_id == SMTP_PAF_DATA_CMD)))
{
pfdata->smtp_state = SMTP_PAF_DATA_STATE;
reset_data_states(pfdata);
using namespace snort;
-void SMTP_GetEOL(const uint8_t* ptr, const uint8_t* end,
+SMTPEol SMTP_GetEOL(const uint8_t* ptr, const uint8_t* end,
const uint8_t** eol, const uint8_t** eolm)
{
assert(ptr and end and eol and eolm);
const uint8_t* tmp_eolm;
const uint8_t* tmp_eol = (const uint8_t*)memchr(ptr, '\n', end - ptr);
+ SMTPEol eol_state = EOL_NOT_SEEN;
if (tmp_eol == nullptr)
{
if ((tmp_eol > ptr) && (*(tmp_eol - 1) == '\r'))
{
tmp_eolm = tmp_eol - 1;
+ eol_state = EOL_CRLF;
}
else
{
tmp_eolm = tmp_eol;
+ eol_state = EOL_LF;
}
/* move past newline */
*eol = tmp_eol;
*eolm = tmp_eolm;
+ return eol_state;
}
void SMTP_ResetAltBuffer(Packet* p)
// SMTP helper functions
+#include "smtp.h"
#include "smtp_config.h"
namespace snort
struct Packet;
}
-void SMTP_GetEOL(const uint8_t*, const uint8_t*, const uint8_t**, const uint8_t**);
+SMTPEol SMTP_GetEOL(const uint8_t*, const uint8_t*, const uint8_t**, const uint8_t**);
void SMTP_LogFuncs(SmtpProtoConf*, snort::Packet*, snort::MimeSession*);
int SMTP_CopyToAltBuffer(snort::Packet*, const uint8_t*, int);