From: Philippe Antoine Date: Mon, 16 Mar 2020 13:46:51 +0000 (+0100) Subject: ftp: FTPParseResponse bufferizes lines X-Git-Tag: suricata-4.1.8~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F4891%2Fhead;p=thirdparty%2Fsuricata.git ftp: FTPParseResponse bufferizes lines 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 --- diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index 12c04316a5..3f6170d097 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -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; }