mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'security/topic/awelzel/125-ftp-timeout-three'
* security/topic/awelzel/125-ftp-timeout-three: testing/ftp: Add tests and pcaps with invalid reply lines ftp: Harden reply handing a bit and don't raise bad replies to script-land ftp: ignore invalid commands
This commit is contained in:
commit
9a0dc30e35
18 changed files with 203 additions and 11 deletions
|
@ -63,6 +63,20 @@ static uint32_t get_reply_code(int len, const char* line)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// The minimal length of an FTP command is 3 characters (PWD, MKD,
|
||||
// RMD, ...) and should only contain printable ascii.
|
||||
static bool is_ftp_cmd(int len, const char* s)
|
||||
{
|
||||
if ( len < 3 )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < len; i++ )
|
||||
if ( ! isprint(s[i]) || isspace(s[i]) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FTP_Analyzer::DeliverStream(int length, const u_char* data, bool orig)
|
||||
{
|
||||
analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(length, data, orig);
|
||||
|
@ -91,10 +105,13 @@ void FTP_Analyzer::DeliverStream(int length, const u_char* data, bool orig)
|
|||
util::get_word(end_of_line - line, line, cmd_len, cmd);
|
||||
line = util::skip_whitespace(line + cmd_len, end_of_line);
|
||||
|
||||
if ( cmd_len == 0 )
|
||||
if ( ! is_ftp_cmd(cmd_len, cmd) )
|
||||
{
|
||||
// Weird("FTP command missing", end_of_line - orig_line, orig_line);
|
||||
cmd_str = new StringVal("<missing>");
|
||||
if ( AnalyzerConfirmed() )
|
||||
Weird("FTP_invalid_command");
|
||||
|
||||
// Ignore the whole line.
|
||||
return;
|
||||
}
|
||||
else if ( BifConst::FTP::max_command_length > 0 &&
|
||||
static_cast<zeek_uint_t>(cmd_len) > BifConst::FTP::max_command_length )
|
||||
|
@ -149,25 +166,39 @@ void FTP_Analyzer::DeliverStream(int length, const u_char* data, bool orig)
|
|||
}
|
||||
else
|
||||
{ // a new reply
|
||||
if ( reply_code > 0 && length > 3 && line[3] == '-' )
|
||||
cont_resp = 0;
|
||||
|
||||
if ( reply_code == 0 )
|
||||
{
|
||||
AnalyzerViolation("non-numeric reply code", (const char*)data, length);
|
||||
return;
|
||||
}
|
||||
else if ( reply_code < 100 )
|
||||
{
|
||||
AnalyzerViolation("invalid reply code", (const char*)data, length);
|
||||
return;
|
||||
}
|
||||
else if ( length > 3 && line[3] == '-' )
|
||||
{ // a continued reply
|
||||
pending_reply = reply_code;
|
||||
line = util::skip_whitespace(line + 4, end_of_line);
|
||||
cont_resp = 1;
|
||||
}
|
||||
else if ( length > 3 && line[3] != ' ' )
|
||||
{
|
||||
// This is a proper reply code, but there's no space after
|
||||
// the reply code even though the line is long enough.
|
||||
AnalyzerViolation("invalid reply line", (const char*)data, length);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // a self-contained reply
|
||||
if ( reply_code > 0 )
|
||||
line += 3;
|
||||
else
|
||||
AnalyzerViolation("non-numeric reply code", (const char*)data, length);
|
||||
line += 3;
|
||||
|
||||
if ( line < end_of_line )
|
||||
line = util::skip_whitespace(line, end_of_line);
|
||||
else
|
||||
line = end_of_line;
|
||||
|
||||
cont_resp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue