]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #5004: ftp_telnet: Handle malformed traffic in ftp to generate alert.
authorRashi Manohar Patil -X (rasmanoh - XORIANT CORPORATION at Cisco) <rasmanoh@cisco.com>
Wed, 17 Dec 2025 06:46:08 +0000 (06:46 +0000)
committerManjunatha Iyli (miyli) <miyli@cisco.com>
Wed, 17 Dec 2025 06:46:08 +0000 (06:46 +0000)
Merge in SNORT/snort3 from ~RASMANOH/snort3:ftp_response_validation to master

Squashed commit of the following:

commit d02c41b518967993cd9c5052d9fad9716013838d
Author: Rashi Manohar Patil <rasmanoh@b18-vms-vm1089.cisco.com>
Date:   Tue Dec 16 15:40:26 2025 +0530

    ftp_telnet: Handle malformed traffic in ftp to generate alert

src/service_inspectors/ftp_telnet/ftp.cc
src/service_inspectors/ftp_telnet/pp_ftp.cc

index 7b33ed6e17425d73ff4c8615353f8c8d0d8afab8..64ec197b18d99e95f72a020eddb5e9eac424fa63 100644 (file)
@@ -118,6 +118,9 @@ static int SnortFTP(
 
         do_detection(p);
     }
+    else if (ret == FTPP_ALERT){
+        return ret;
+    }
 
     assert(FTPsession);
 
index af97806abf6b09f12e6b01e85ebbc0da329bff24..9e717e980ddad349a07f209350d7486d30605bab 100644 (file)
@@ -55,7 +55,35 @@ using namespace snort;
  * that resulted in a
  */
 static THREAD_LOCAL int ftp_cmd_pipe_index = 0;
+/*
+ * Function: is_command_valid
+ *
+ * Purpose: Validates FTP response command format to detect malformed responses
+ *
+ * Arguments: start    => Pointer to start of command
+ *            cmd_size => Size of the command
+ *
+ * Returns: bool => true if command is valid, false if malformed
+ */
+static bool is_command_valid(const char *start, size_t cmd_size) {
+    if (cmd_size >= 3 &&
+        isdigit((unsigned char)start[0]) &&
+        isdigit((unsigned char)start[1]) &&
+        isdigit((unsigned char)start[2])) {
+        return true;
+    }
 
+    if (cmd_size >= 4 &&
+        (start[0] != start[1] || start[0] != start[2] || start[0] != start[3])) {
+        return true;
+    }
+
+    if (cmd_size < 4) {
+        return true;
+    }
+
+    return false;
+}
 /*
  * Function: getIP959(char **ip_start,
  *                 char *last_char,
@@ -1538,7 +1566,17 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
                     ptr++;
                 }
             }
+            //Raise an alert if the response code is not valid
+            if (!is_command_valid(req->cmd_begin, req->cmd_size))
+            {
+                ftpssn->server.response.state = FTP_RESPONSE_INV;
+                Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
 
+                ftpssn->ft_ssn.fallback = true;
+                DetectionEngine::queue_event(GID_FTP, FTP_ABORTED_SESSION);
+                ++ftstats.aborted_sessions;
+                return FTPP_ALERT;
+            }
             if (encrypted)
             {
                 /* If the session wasn't already marked as encrypted...