]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ftp: FTPParseResponse bufferizes lines 4891/head
authorPhilippe Antoine <contact@catenacyber.fr>
Mon, 16 Mar 2020 13:46:51 +0000 (14:46 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 27 Apr 2020 10:24:53 +0000 (12:24 +0200)
Protects against evasion by TCP packet splitting

The problem arised if the FTP response is split on multiple packets

The fix is to bufferize the content, until we get a complete line

src/app-layer-ftp.c

index 12c04316a5d6d6fe9f96efc9d77ae6bc64b27f8c..3f6170d097d4e3c6eb4a20a315d32def1670c94b 100644 (file)
@@ -544,24 +544,34 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat
 {
     FtpState *state = (FtpState *)ftp_state;
 
-    if (state->command == FTP_COMMAND_AUTH_TLS) {
-        if (input_len >= 4 && SCMemcmp("234 ", input, 4) == 0) {
-            AppLayerRequestProtocolTLSUpgrade(f);
-        }
-    }
+    state->input = input;
+    state->input_len = input_len;
+    /* toclient stream */
+    state->direction = 1;
 
-    if (state->command == FTP_COMMAND_PASV) {
-        if (input_len >= 4 && SCMemcmp("227 ", input, 4) == 0) {
-            FTPParsePassiveResponse(f, ftp_state, input, input_len);
-        }
-    }
+    while (FTPGetLine(state) >= 0) {
+        switch (state->command) {
+            case FTP_COMMAND_AUTH_TLS:
+                if (state->current_line_len >= 4 && SCMemcmp("234 ", state->current_line, 4) == 0) {
+                    AppLayerRequestProtocolTLSUpgrade(f);
+                }
+                break;
 
-    if (state->command == FTP_COMMAND_EPSV) {
-        if (input_len >= 4 && SCMemcmp("229 ", input, 4) == 0) {
-            FTPParsePassiveResponseV6(f, ftp_state, input, input_len);
+            case FTP_COMMAND_PASV:
+                if (state->current_line_len >= 4 && SCMemcmp("227 ", state->current_line, 4) == 0) {
+                    FTPParsePassiveResponse(f, ftp_state, state->current_line, state->current_line_len);
+                }
+                break;
+
+            case FTP_COMMAND_EPSV:
+                if (state->current_line_len >= 4 && SCMemcmp("229 ", state->current_line, 4) == 0) {
+                    FTPParsePassiveResponseV6(f, ftp_state, state->current_line, state->current_line_len);
+                }
+                break;
+            default:
+                break;
         }
     }
-
     return 1;
 }