]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4432: ftp_telnet: adding fallback functionality
authorManav Soneja (msoneja) <msoneja@cisco.com>
Thu, 19 Sep 2024 07:47:46 +0000 (07:47 +0000)
committerShanmugam S (shanms) <shanms@cisco.com>
Thu, 19 Sep 2024 07:47:46 +0000 (07:47 +0000)
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

src/service_inspectors/ftp_telnet/ftp_module.cc
src/service_inspectors/ftp_telnet/ftp_module.h
src/service_inspectors/ftp_telnet/ftpp_si.h
src/service_inspectors/ftp_telnet/pp_ftp.cc
src/service_inspectors/ftp_telnet/telnet_splitter.cc

index 7d79eb5c1c648e664bbdb339c3b4f13b93b3ef3f..12deefdaa88b0ecbc7def4e3d698c270402c04d8 100644 (file)
@@ -216,6 +216,9 @@ FtpCmd::FtpCmd(const std::string& key, const std::string& fmt, int num)
     "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"
+
 
 //-------------------------------------------------------------------------
 
@@ -316,6 +319,7 @@ static const RuleMap ftp_server_rules[] =
     { 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 }
 };
@@ -331,6 +335,8 @@ static const PegInfo ftp_pegs[] =
     { 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 }
 };
 
index 9186eb84a0eca1afa3b9665f7f41dea3ba329e46..3124db52f75b865fdb9446da15aebc0b8fbbef2f 100644 (file)
@@ -35,6 +35,7 @@
 #define FTP_ENCRYPTED                    7
 #define FTP_BOUNCE                       8
 #define FTP_EVASIVE_TELNET_CMD           9
+#define FTP_ABORTED_SESSION              10
 
 namespace snort
 {
index 730fd428b9d1ffd5c4e557ca1f1b0720008d9a5b..f5b400e5b25d5190a807331ed44940a6a49a7b6e 100644 (file)
@@ -75,6 +75,7 @@
 typedef struct s_FTP_TELNET_SESSION
 {
     int proto;
+    bool fallback;
 } FTP_TELNET_SESSION;
 
 /*
@@ -287,6 +288,7 @@ struct FtpStats
     PegCount ssl_search_abandoned_too_soon;
     PegCount total_packets_mss_changed;
     PegCount total_sessions_mss_changed;
+    PegCount aborted_sessions;
 };
 
 struct TelnetStats
index f7018eab21d17a01910320d8b8cf45271e4864db..01468c5bb1b254e6d7277fdb764456fa61327e18 100644 (file)
@@ -1586,15 +1586,20 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
                                 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;
@@ -1618,13 +1623,17 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
                             /* 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
                     {
@@ -1692,6 +1701,15 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
             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)
         {
index 2ee5abe6905adaafb0f03d1f3fa3b659de3f556e..b042a367336db5318a50691c3ccef21f6dfa3f06 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <cstring>
 
+#include "ftpp_si.h"
 #include "protocols/ssl.h"
 #include "protocols/packet.h"
 #include "utils/util.h"
@@ -40,6 +41,17 @@ StreamSplitter::Status TelnetSplitter::scan(
     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;