Merge in SNORT/snort3 from ~MSONEJA/snort3:ftp_telnet_fallback to master
Squashed commit of the following:
commit
b64420ab2fa645d2c38aa874d26a2a3525c8a6a8
Author: msoneja <msoneja@cisco.com>
Date: Mon Aug 26 06:56:49 2024 +0000
ftp_telnet: adding fallback functionality for ftp
"FTP bounce attempt"
#define FTP_EVASIVE_TELNET_CMD_STR \
"evasive (incomplete) TELNET cmd on FTP command channel"
+#define FTP_ABORTED_SESSION_STR \
+ "FTP session aborted as server response invalid"
+
//-------------------------------------------------------------------------
{ FTP_ENCRYPTED, FTP_ENCRYPTED_STR },
{ FTP_BOUNCE, FTP_BOUNCE_STR },
{ FTP_EVASIVE_TELNET_CMD, FTP_EVASIVE_TELNET_CMD_STR },
+ { FTP_ABORTED_SESSION, FTP_ABORTED_SESSION_STR },
{ 0, nullptr }
};
{ CountType::SUM, "ssl_srch_abandoned_early", "total SSL search abandoned too soon" },
{ CountType::SUM, "pkt_segment_size_changed", "total number of FTP data packets with segment size change" },
{ CountType::SUM, "flow_segment_size_changed", "total number of FTP sessions with segment size change" },
+ { CountType::SUM, "total_aborted_sessions", "total aborted sessions" },
+
{ CountType::END, nullptr, nullptr }
};
#define FTP_ENCRYPTED 7
#define FTP_BOUNCE 8
#define FTP_EVASIVE_TELNET_CMD 9
+#define FTP_ABORTED_SESSION 10
namespace snort
{
typedef struct s_FTP_TELNET_SESSION
{
int proto;
+ bool fallback;
} FTP_TELNET_SESSION;
/*
PegCount ssl_search_abandoned_too_soon;
PegCount total_packets_mss_changed;
PegCount total_sessions_mss_changed;
+ PegCount aborted_sessions;
};
struct TelnetStats
state = FTP_RESPONSE_ENDCONT;
ftpssn->server.response.state = 0;
}
- else
+ else if (req->cmd_size == 3)
{
/* Single line response */
state = FTP_RESPONSE;
}
+ else
+ {
+ ftpssn->server.response.state = FTP_RESPONSE_INV;
+ }
+
}
}
- if (ftpssn->server.response.state != 0)
+ if (ftpssn->server.response.state > FTP_RESPONSE_INV)
{
req->cmd_begin = nullptr;
req->cmd_end = nullptr;
/* Continuation of previous response */
state = FTP_RESPONSE_CONT;
}
- else
+ else if (req->cmd_size == 3)
{
/* Start of response, state stays as -2 */
state = FTP_RESPONSE_2BCONT;
ftpssn->server.response.state = resp_code;
rsp_code = resp_code;
}
+ else
+ {
+ ftpssn->server.response.state = FTP_RESPONSE_INV;
+ }
}
else
{
req->pipeline_req = (const char*)read_ptr;
else
req->pipeline_req = nullptr;
+
+
+ if (ftpssn->server.response.state == FTP_RESPONSE_INV)
+ {
+ ftpssn->ft_ssn.fallback = true;
+ DetectionEngine::queue_event(GID_FTP, FTP_ABORTED_SESSION);
+ ++ftstats.aborted_sessions;
+ return FTPP_ALERT;
+ }
switch (state)
{
#include <cstring>
+#include "ftpp_si.h"
#include "protocols/ssl.h"
#include "protocols/packet.h"
#include "utils/util.h"
Packet* p, const uint8_t* data, uint32_t len,
uint32_t, uint32_t* fp)
{
+ if (p->flow)
+ {
+ FTP_TELNET_SESSION* ft_ssn = nullptr;
+
+ FtpFlowData* fd = (FtpFlowData*)p->flow->get_flow_data(FtpFlowData::inspector_id);
+ ft_ssn = fd ? &fd->session.ft_ssn : nullptr;
+
+ if (ft_ssn && ft_ssn->fallback)
+ return ABORT;
+ }
+
if ( IsSSL(data, len, p->packet_flags) )
{
*fp = len;