From: Eric Leblond Date: Sat, 11 Jun 2022 21:28:37 +0000 (+0200) Subject: detect: add ip.src keyword X-Git-Tag: suricata-7.0.0-rc1~466 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e516aad94bd2dec45aa9da8f295629747b56404;p=thirdparty%2Fsuricata.git detect: add ip.src keyword It is a sticky buffer matching on src_ip. Feature: #5383 --- diff --git a/src/Makefile.am b/src/Makefile.am index 8b0e58ba39..73f4d097ff 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 325d3ea326..488c5c4bd0 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -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(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index a4fcc9beaf..dc91b695a8 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -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 index 0000000000..c5494b084e --- /dev/null +++ b/src/detect-ipaddr.c @@ -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 + * + * 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 index 0000000000..d9eba7a55e --- /dev/null +++ b/src/detect-ipaddr.h @@ -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 + */ + +#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 index 0000000000..712aac7381 --- /dev/null +++ b/src/tests/detect-ipaddr.c @@ -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); +}