From 9cbb260f6d74dcd25194083ce3bc9ba1d7b9d076 Mon Sep 17 00:00:00 2001 From: Jeff Lucovsky Date: Sun, 19 Jan 2025 10:38:42 -0500 Subject: [PATCH] detect/ftp.command: Add sticky buffer Issue: 7502 Add a sticky buffer for "ftp.command" for matching on FTP command names. --- src/Makefile.am | 2 + src/detect-engine-register.c | 2 + src/detect-engine-register.h | 2 + src/detect-ftp-command.c | 103 +++++++++++++++++++++++++++++++++++ src/detect-ftp-command.h | 29 ++++++++++ 5 files changed, 138 insertions(+) create mode 100644 src/detect-ftp-command.c create mode 100644 src/detect-ftp-command.h diff --git a/src/Makefile.am b/src/Makefile.am index 615816953542..e6c7772edf72 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -168,6 +168,7 @@ noinst_HEADERS = \ detect-frame.h \ detect-ftpbounce.h \ detect-ftpdata.h \ + detect-ftp-command.h \ detect-geoip.h \ detect-gid.h \ detect.h \ @@ -735,6 +736,7 @@ libsuricata_c_a_SOURCES = \ detect-frame.c \ detect-ftpbounce.c \ detect-ftpdata.c \ + detect-ftp-command.c \ detect-geoip.c \ detect-gid.c \ detect-hostbits.c \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index b9faff49bae8..2b11605bcf8b 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -210,6 +210,7 @@ #include "detect-quic-cyu-hash.h" #include "detect-quic-cyu-string.h" #include "detect-ja4-hash.h" +#include "detect-ftp-command.h" #include "detect-bypass.h" #include "detect-ftpdata.h" @@ -706,6 +707,7 @@ void SigTableSetup(void) DetectQuicCyuHashRegister(); DetectQuicCyuStringRegister(); DetectJa4HashRegister(); + DetectFtpCommandRegister(); DetectBypassRegister(); DetectConfigRegister(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index a9e674159e36..4d8b7858b6a3 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -333,6 +333,8 @@ enum DetectKeywordId { DETECT_AL_JA4_HASH, + DETECT_AL_FTP_COMMAND, + DETECT_VLAN_ID, DETECT_VLAN_LAYERS, diff --git a/src/detect-ftp-command.c b/src/detect-ftp-command.c new file mode 100644 index 000000000000..f7925073aebd --- /dev/null +++ b/src/detect-ftp-command.c @@ -0,0 +1,103 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * + * \author Jeff Lucovsky + * + * Implements the ftp.command sticky buffer + * + */ + +#include "suricata-common.h" +#include "detect.h" + +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-mpm.h" +#include "detect-engine-prefilter.h" +#include "detect-content.h" + +#include "flow.h" + +#include "util-debug.h" + +#include "app-layer.h" +#include "app-layer-ftp.h" + +#include "detect-ftp-command.h" + +#define KEYWORD_NAME "ftp.command" +#define KEYWORD_DOC "ftp-keywords.html#ftp-command" +#define BUFFER_NAME "ftp.command" +#define BUFFER_DESC "ftp command" + +static int g_ftp_cmd_buffer_id = 0; + +static int DetectFtpCommandSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) +{ + if (DetectBufferSetActiveList(de_ctx, s, g_ftp_cmd_buffer_id) < 0) + return -1; + + if (DetectSignatureSetAppProto(s, ALPROTO_FTP) < 0) + return -1; + + return 0; +} + +static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv, + const int list_id) +{ + InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); + if (buffer->inspect == NULL) { + FTPTransaction *tx = (FTPTransaction *)txv; + + if (tx->command_descriptor->command_name == NULL || + tx->command_descriptor->command_length == 0) + return NULL; + + InspectionBufferSetup(det_ctx, list_id, buffer, + (const uint8_t *)tx->command_descriptor->command_name, + tx->command_descriptor->command_length); + InspectionBufferApplyTransforms(buffer, transforms); + } + + return buffer; +} + +void DetectFtpCommandRegister(void) +{ + /* ftp.command sticky buffer */ + sigmatch_table[DETECT_AL_FTP_COMMAND].name = KEYWORD_NAME; + sigmatch_table[DETECT_AL_FTP_COMMAND].desc = "sticky buffer to match on the FTP command buffer"; + sigmatch_table[DETECT_AL_FTP_COMMAND].url = "/rules/" KEYWORD_DOC; + sigmatch_table[DETECT_AL_FTP_COMMAND].Setup = DetectFtpCommandSetup; + sigmatch_table[DETECT_AL_FTP_COMMAND].flags |= SIGMATCH_NOOPT; + + DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_FTP, SIG_FLAG_TOSERVER, 0, + DetectEngineInspectBufferGeneric, GetData); + + DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, + GetData, ALPROTO_FTP, 1); + + DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC); + + g_ftp_cmd_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME); + + SCLogDebug("registering " BUFFER_NAME " rule option"); +} diff --git a/src/detect-ftp-command.h b/src/detect-ftp-command.h new file mode 100644 index 000000000000..b10695ced7f4 --- /dev/null +++ b/src/detect-ftp-command.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Jeff Lucovsky + */ + +#ifndef SURICATA_DETECT_FTP_COMMAND_H +#define SURICATA_DETECT_FTP_COMMAND_H + +void DetectFtpCommandRegister(void); + +#endif /* SURICATA_DETECT_FTP_COMMAND_H */