From: Bhargava Jandhyala (bjandhya) Date: Tue, 7 Mar 2023 16:58:31 +0000 (+0000) Subject: Pull request #3690: telnet: added paf based splitter for telnet X-Git-Tag: 3.1.57.0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f0c8b1296300bb058e17f7447c0bad4e7992d15;p=thirdparty%2Fsnort3.git Pull request #3690: telnet: added paf based splitter for telnet Merge in SNORT/snort3 from ~SMANGHAT/snort3:snort_telnet_splitter to master Squashed commit of the following: commit 573f28712abe09bbcdd7d693986fffffa7eb6881 Author: Shailendra Manghate Date: Tue Mar 7 15:38:22 2023 +0530 ftp_telnet: updated flushing around subnegotiation parameters The splitter will flush after EOL or SE. It will ignore EOL between SB and SE. --- diff --git a/src/service_inspectors/ftp_telnet/CMakeLists.txt b/src/service_inspectors/ftp_telnet/CMakeLists.txt index 760a54078..c0ee5e28f 100644 --- a/src/service_inspectors/ftp_telnet/CMakeLists.txt +++ b/src/service_inspectors/ftp_telnet/CMakeLists.txt @@ -17,8 +17,8 @@ set (FILE_LIST ftp_print.cc ftp_print.h ftp_server.h - ftp_splitter.h - ftp_splitter.cc + telnet_splitter.h + telnet_splitter.cc ftpdata_splitter.h ftpdata_splitter.cc ftpp_return_codes.h diff --git a/src/service_inspectors/ftp_telnet/ftp.cc b/src/service_inspectors/ftp_telnet/ftp.cc index 9f65dbe1c..f06405524 100644 --- a/src/service_inspectors/ftp_telnet/ftp.cc +++ b/src/service_inspectors/ftp_telnet/ftp.cc @@ -35,7 +35,7 @@ #include "ftp_module.h" #include "ftp_parse.h" #include "ftp_print.h" -#include "ftp_splitter.h" +#include "telnet_splitter.h" #include "ftpp_return_codes.h" #include "ftpp_si.h" #include "pp_ftp.h" @@ -250,7 +250,7 @@ void FtpServer::show(const SnortConfig*) const StreamSplitter* FtpServer::get_splitter(bool c2s) { - return new FtpSplitter(c2s); + return new TelnetSplitter(c2s); } void FtpServer::eval(Packet* p) diff --git a/src/service_inspectors/ftp_telnet/ftp_splitter.cc b/src/service_inspectors/ftp_telnet/ftp_splitter.cc deleted file mode 100644 index 96059dd00..000000000 --- a/src/service_inspectors/ftp_telnet/ftp_splitter.cc +++ /dev/null @@ -1,65 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2023 Cisco and/or its affiliates. All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- -// ftp_splitter.cc author Russ Combs - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "ftp_splitter.h" -#include "protocols/ssl.h" -#include "protocols/packet.h" -#include "utils/util.h" - -#include - -using namespace snort; - -FtpSplitter::FtpSplitter(bool c2s) : StreamSplitter(c2s) { } - -// flush at last CR or LF in data -// preproc will deal with any pipelined commands -StreamSplitter::Status FtpSplitter::scan( - Packet* p, const uint8_t* data, uint32_t len, - uint32_t, uint32_t* fp) -{ - if ( IsSSL(data, len, p->packet_flags) ) - { - *fp = len; - return FLUSH; - } - - const uint8_t* cr = snort_memrchr(data, '\r', len); - const uint8_t* lf = snort_memrchr(data, '\n', len); - - const uint8_t* ptr = nullptr; - - if ( cr && !lf ) - ptr = cr; - else if ( !cr && lf ) - ptr = lf; - else if ( cr && lf ) - ptr = ( cr > lf ) ? cr : lf; - - if ( !ptr ) - return SEARCH; - - *fp = ptr - data + 1; - return FLUSH; -} - diff --git a/src/service_inspectors/ftp_telnet/telnet.cc b/src/service_inspectors/ftp_telnet/telnet.cc index 4b2ebf7bf..fad8806fa 100644 --- a/src/service_inspectors/ftp_telnet/telnet.cc +++ b/src/service_inspectors/ftp_telnet/telnet.cc @@ -30,7 +30,7 @@ #include "ft_main.h" #include "ftp_print.h" -#include "ftp_splitter.h" +#include "telnet_splitter.h" #include "ftpp_return_codes.h" #include "ftpp_si.h" #include "ftpp_ui_config.h" @@ -192,7 +192,7 @@ public: void clear(Packet*) override; StreamSplitter* get_splitter(bool c2s) override - { return new FtpSplitter(c2s); } + { return new TelnetSplitter(c2s); } private: TELNET_PROTO_CONF* config; diff --git a/src/service_inspectors/ftp_telnet/telnet_splitter.cc b/src/service_inspectors/ftp_telnet/telnet_splitter.cc new file mode 100644 index 000000000..0ba0a6d5e --- /dev/null +++ b/src/service_inspectors/ftp_telnet/telnet_splitter.cc @@ -0,0 +1,126 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2023 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// ftp_splitter.cc author Shailendra Manghate + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "telnet_splitter.h" + +#include + +#include "protocols/ssl.h" +#include "protocols/packet.h" +#include "utils/util.h" + + +using namespace snort; + +TelnetSplitter::TelnetSplitter(bool c2s) : StreamSplitter(c2s) { } + +// flush at last CR or LF in data +// preproc will deal with any pipelined commands +StreamSplitter::Status TelnetSplitter::scan( + Packet* p, const uint8_t* data, uint32_t len, + uint32_t, uint32_t* fp) +{ + if ( IsSSL(data, len, p->packet_flags) ) + { + *fp = len; + return FLUSH; + } + + const uint8_t* read_ptr = data; + const uint8_t* end = data + len; + const uint8_t* fp_ptr = nullptr; + + while ( read_ptr < end ) + { + switch ( state ) + { + case TELNET_NONE: + { + const uint8_t* cr = static_cast(memchr(read_ptr, '\r', end - read_ptr)); + const uint8_t* lf = static_cast(memchr(read_ptr, '\n', end - read_ptr)); + const uint8_t* ptr = nullptr; + if ( cr && !lf ) + ptr = cr; + else if ( !cr && lf ) + ptr = lf; + else if ( cr && lf ) + ptr = ( cr > lf ) ? cr : lf; + if ( ptr ) + { + fp_ptr = ptr; + read_ptr = fp_ptr; + } + + const uint8_t* iac_ptr = static_cast(memchr( read_ptr, TNC_IAC, end - read_ptr)); + if ( iac_ptr ) + { + state = TELNET_IAC; + read_ptr = iac_ptr; + } + break; + } + case TELNET_IAC: + { + if ( *read_ptr == (unsigned char)TNC_SB ) + state = TELNET_IAC_SB; + else if ( *read_ptr != (unsigned char)TNC_IAC ) + state = TELNET_NONE; + break; + } + case TELNET_IAC_SB: + { + const uint8_t* iac_se_ptr = static_cast(memchr(read_ptr, TNC_IAC, end - read_ptr)); + if ( iac_se_ptr ) + { + state = TELNET_IAC_SB_IAC; + read_ptr = iac_se_ptr; + } + else + read_ptr = end; + break; + } + case TELNET_IAC_SB_IAC: + { + if ( *read_ptr == (unsigned char)TNC_SE ) + { + fp_ptr = read_ptr; + state = TELNET_NONE; + } + else + state = TELNET_IAC_SB; + break; + } + } + + if ( read_ptr < end ) + read_ptr++; + } + + if ( fp_ptr ) + { + *fp = fp_ptr - data + 1; + return FLUSH; + } + return SEARCH; +} + diff --git a/src/service_inspectors/ftp_telnet/ftp_splitter.h b/src/service_inspectors/ftp_telnet/telnet_splitter.h similarity index 80% rename from src/service_inspectors/ftp_telnet/ftp_splitter.h rename to src/service_inspectors/ftp_telnet/telnet_splitter.h index de6d19217..aa9c9f65b 100644 --- a/src/service_inspectors/ftp_telnet/ftp_splitter.h +++ b/src/service_inspectors/ftp_telnet/telnet_splitter.h @@ -16,20 +16,24 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -#ifndef FTP_SPLITTER_H -#define FTP_SPLITTER_H +#ifndef TELNET_SPLITTER_H +#define TELNET_SPLITTER_H #include "stream/stream_splitter.h" +#include "pp_telnet.h" -class FtpSplitter : public snort::StreamSplitter +class TelnetSplitter : public snort::StreamSplitter { public: - FtpSplitter(bool c2s); + TelnetSplitter(bool c2s); Status scan(snort::Packet*, const uint8_t* data, uint32_t len, uint32_t flags, uint32_t* fp) override; bool is_paf() override { return true; } +private: + enum TelnetState { TELNET_NONE, TELNET_IAC, TELNET_IAC_SB, TELNET_IAC_SB_IAC }; + TelnetState state { TELNET_NONE }; }; #endif