Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

detect/ftp.command: Add sticky buffer #12428

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/userguide/upgrade.rst
Original file line number Diff line number Diff line change
@@ -82,6 +82,8 @@ Major changes
- Unknown requirements in the ``requires`` keyword will now be treated
as unmet requirements, causing the rule to not be loaded. See
:ref:`keyword_requires`.
- The following sticky buffers for matching FTP headers have been implemented:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this here. Did you mix up PRs? #12432 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was intentional in introducing the FTP-related sticky buffers.

We've done this for past releases as well, e.g., the 7 to 8 section mentions the newly added sip related keywords.

Copy link
Member

@victorjulien victorjulien Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think either should be there. It's not meant to list new features, just keep note of things that may affect upgrades

- ftp.command

Removals
~~~~~~~~
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
@@ -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 \
2 changes: 2 additions & 0 deletions src/detect-engine-register.c
Original file line number Diff line number Diff line change
@@ -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();
2 changes: 2 additions & 0 deletions src/detect-engine-register.h
Original file line number Diff line number Diff line change
@@ -333,6 +333,8 @@ enum DetectKeywordId {

DETECT_AL_JA4_HASH,

DETECT_FTP_COMMAND,

DETECT_VLAN_ID,
DETECT_VLAN_LAYERS,

103 changes: 103 additions & 0 deletions src/detect-ftp-command.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*
* 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_FTP_COMMAND].name = KEYWORD_NAME;
sigmatch_table[DETECT_FTP_COMMAND].desc = "sticky buffer to match on the FTP command buffer";
sigmatch_table[DETECT_FTP_COMMAND].url = "/rules/" KEYWORD_DOC;
sigmatch_table[DETECT_FTP_COMMAND].Setup = DetectFtpCommandSetup;
sigmatch_table[DETECT_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");
}
29 changes: 29 additions & 0 deletions src/detect-ftp-command.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*/

#ifndef SURICATA_DETECT_FTP_COMMAND_H
#define SURICATA_DETECT_FTP_COMMAND_H

void DetectFtpCommandRegister(void);

#endif /* SURICATA_DETECT_FTP_COMMAND_H */