]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: add ip.src keyword
authorEric Leblond <el@stamus-networks.com>
Sat, 11 Jun 2022 21:28:37 +0000 (23:28 +0200)
committerVictor Julien <vjulien@oisf.net>
Thu, 27 Oct 2022 07:44:20 +0000 (09:44 +0200)
It is a sticky buffer matching on src_ip.

Feature: #5383

src/Makefile.am
src/detect-engine-register.c
src/detect-engine-register.h
src/detect-ipaddr.c [new file with mode: 0644]
src/detect-ipaddr.h [new file with mode: 0644]
src/tests/detect-ipaddr.c [new file with mode: 0644]

index 8b0e58ba394006f51d2e78d56bba6851f44fecf8..73f4d097ff67d8612959d88ebc0f41320c26a3be 100755 (executable)
@@ -224,6 +224,7 @@ noinst_HEADERS = \
        detect-ike-nonce-payload-length.h \
        detect-ike-nonce-payload.h \
        detect-ike-key-exchange-payload.h \
+       detect-ipaddr.h \
        detect-ipopts.h \
        detect-ipproto.h \
        detect-iprep.h \
@@ -830,6 +831,7 @@ libsuricata_c_a_SOURCES = \
        detect-ike-nonce-payload-length.c \
        detect-ike-nonce-payload.c \
        detect-ike-key-exchange-payload.c \
+       detect-ipaddr.c \
        detect-ipopts.c \
        detect-ipproto.c \
        detect-iprep.c \
@@ -1264,6 +1266,7 @@ EXTRA_DIST = \
        tests/detect-tls-cert-validity.c \
        tests/detect-tls-certs.c \
        tests/detect-tls-version.c \
+       tests/detect-ipaddr.c \
        tests/detect.c \
        tests/stream-tcp.c
 
index 325d3ea326ace41ec85ec9a25c888aecf5d826e0..488c5c4bd0239e4af0baa19b93a09dc0b4649c56 100644 (file)
@@ -79,6 +79,7 @@
 
 #include "detect-base64-decode.h"
 #include "detect-base64-data.h"
+#include "detect-ipaddr.h"
 #include "detect-ipopts.h"
 #include "detect-tcp-flags.h"
 #include "detect-fragbits.h"
@@ -628,6 +629,7 @@ void SigTableSetup(void)
     DetectTcpmssRegister();
     DetectICMPv6hdrRegister();
     DetectICMPv6mtuRegister();
+    DetectIPAddrBufferRegister();
     DetectIpv4hdrRegister();
     DetectIpv6hdrRegister();
     DetectKrb5CNameRegister();
index a4fcc9beafe6ab38fd9b716915d7ff72f265b265..dc91b695a86a30704d716905b25bf17d06a976f3 100644 (file)
@@ -37,6 +37,7 @@ enum DetectKeywordId {
     DETECT_SEQ,
     DETECT_WINDOW,
     DETECT_IPOPTS,
+    DETECT_IPADDR_SRC,
     DETECT_FLAGS,
     DETECT_FRAGBITS,
     DETECT_FRAGOFFSET,
diff --git a/src/detect-ipaddr.c b/src/detect-ipaddr.c
new file mode 100644 (file)
index 0000000..c5494b0
--- /dev/null
@@ -0,0 +1,108 @@
+/* Copyright (C) 2022 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 Eric Leblond <el@stamus-networks.com>
+ *
+ * Offer source or destination IP as a sticky buffer.
+ */
+
+#include "suricata-common.h"
+
+#include "decode.h"
+#include "conf.h"
+#include "detect.h"
+#include "detect-parse.h"
+#include "detect-engine.h"
+#include "detect-engine-mpm.h"
+#include "detect-engine-prefilter.h"
+#include "detect-ipaddr.h"
+
+#define KEYWORD_NAME_SRC "ip.src"
+
+static int DetectIPAddrBufferSetup(DetectEngineCtx *, Signature *, const char *);
+static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
+        const DetectEngineTransforms *transforms, Packet *p, const int list_id);
+
+#ifdef UNITTESTS
+static void DetectIPAddrRegisterTests(void);
+#endif
+static int g_src_ipaddr_buffer_id = 0;
+
+void DetectIPAddrBufferRegister(void)
+{
+    sigmatch_table[DETECT_IPADDR_SRC].name = KEYWORD_NAME_SRC;
+    sigmatch_table[DETECT_IPADDR_SRC].desc = "Sticky buffer for src_ip";
+    sigmatch_table[DETECT_IPADDR_SRC].Setup = DetectIPAddrBufferSetup;
+#ifdef UNITTESTS
+    sigmatch_table[DETECT_IPADDR_SRC].RegisterTests = DetectIPAddrRegisterTests;
+#endif
+
+    sigmatch_table[DETECT_IPADDR_SRC].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
+
+    g_src_ipaddr_buffer_id = DetectBufferTypeRegister(KEYWORD_NAME_SRC);
+    BUG_ON(g_src_ipaddr_buffer_id < 0);
+
+    DetectBufferTypeSupportsPacket(KEYWORD_NAME_SRC);
+
+    DetectPktMpmRegister(KEYWORD_NAME_SRC, 2, PrefilterGenericMpmPktRegister, GetData);
+
+    DetectPktInspectEngineRegister(KEYWORD_NAME_SRC, GetData, DetectEngineInspectPktBufferGeneric);
+
+    SCLogDebug("IPAddr detect registered.");
+}
+
+static int DetectIPAddrBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
+{
+    /* store list id. Content, pcre, etc will be added to the list at this
+     * id. */
+    s->init_data->list = g_src_ipaddr_buffer_id;
+
+    return 0;
+}
+
+/** \internal
+ *  \brief get the data to inspect from the transaction.
+ *  This function gets the data, sets up the InspectionBuffer object
+ *  and applies transformations (if any).
+ *
+ *  \retval buffer or NULL in case of error
+ */
+static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
+        const DetectEngineTransforms *transforms, Packet *p, const int list_id)
+{
+    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
+    if (buffer->inspect == NULL) {
+        if (PKT_IS_IPV4(p)) {
+            /* Suricata stores the IPv4 at the beginning of the field */
+            InspectionBufferSetup(det_ctx, list_id, buffer, p->src.address.address_un_data8, 4);
+        } else if (PKT_IS_IPV6(p)) {
+            InspectionBufferSetup(det_ctx, list_id, buffer, p->src.address.address_un_data8, 16);
+        } else {
+            return NULL;
+        }
+        InspectionBufferApplyTransforms(buffer, transforms);
+    }
+
+    return buffer;
+}
+
+#ifdef UNITTESTS
+#include "tests/detect-ipaddr.c"
+#endif
diff --git a/src/detect-ipaddr.h b/src/detect-ipaddr.h
new file mode 100644 (file)
index 0000000..d9eba7a
--- /dev/null
@@ -0,0 +1,29 @@
+/* Copyright (C) 2022 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 Eric Leblond <el@stamus-networks.com>
+ */
+
+#ifndef __DETECT_IPADDR_BUFFER_H__
+#define __DETECT_IPADDR_BUFFER_H__
+
+void DetectIPAddrBufferRegister(void);
+
+#endif /* __DETECT_IPADDR_BUFFER_H__ */
diff --git a/src/tests/detect-ipaddr.c b/src/tests/detect-ipaddr.c
new file mode 100644 (file)
index 0000000..712aac7
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (C) 2022 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.
+ */
+
+#include "../suricata-common.h"
+
+#include "../detect.h"
+#include "../detect-parse.h"
+#include "../detect-engine-prefilter-common.h"
+
+#include "../detect-ipaddr.h"
+
+#include "../util-unittest.h"
+
+static int DetectIPAddrParseTest01(void)
+{
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+
+    Signature *sig = DetectEngineAppendSig(
+            de_ctx, "alert ip any any -> any any (ip.src; content:\"A\"; sid:1; rev:1;)");
+    FAIL_IF_NULL(sig);
+
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+/**
+ * \brief this function registers unit tests for DetectIpv4hdr
+ */
+void DetectIPAddrRegisterTests(void)
+{
+    UtRegisterTest("DetectIPAddrParseTest01", DetectIPAddrParseTest01);
+}