From: Jason Ish Date: Wed, 19 Sep 2018 17:15:47 +0000 (-0600) Subject: rust: app-layer detect template for rust parsers X-Git-Tag: suricata-4.1.0-rc2~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35fd10bc2ea2c7542035a3611d438d6bbc5483fd;p=thirdparty%2Fsuricata.git rust: app-layer detect template for rust parsers --- diff --git a/src/Makefile.am b/src/Makefile.am index a0d3a7d192..dac22fe3ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -258,6 +258,7 @@ detect-target.c detect-target.h \ detect-template.c detect-template.h \ detect-template2.c detect-template2.h \ detect-ftpdata.c detect-ftpdata.h \ +detect-template-rust-buffer.c detect-template-rust-buffer.h \ detect-template-buffer.c detect-template-buffer.h \ detect-threshold.c detect-threshold.h \ detect-tls.c detect-tls.h \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 0fbc376b81..5f5c6a5d5c 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -184,6 +184,7 @@ #include "detect-krb5-msgtype.h" #include "detect-krb5-sname.h" #include "detect-target.h" +#include "detect-template-rust-buffer.h" #include "detect-template-buffer.h" #include "detect-bypass.h" #include "detect-ftpdata.h" @@ -512,6 +513,7 @@ void SigTableSetup(void) DetectKrb5MsgTypeRegister(); DetectKrb5SNameRegister(); DetectTargetRegister(); + DetectTemplateRustBufferRegister(); DetectTemplateBufferRegister(); DetectBypassRegister(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index 762a01b439..f2b862c2d5 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -206,6 +206,7 @@ enum { DETECT_TEMPLATE2, DETECT_FTPDATA, DETECT_TARGET, + DETECT_AL_TEMPLATE_RUST_BUFFER, DETECT_AL_TEMPLATE_BUFFER, DETECT_BYPASS, diff --git a/src/detect-template-rust-buffer.c b/src/detect-template-rust-buffer.c new file mode 100644 index 0000000000..7d876a3a3c --- /dev/null +++ b/src/detect-template-rust-buffer.c @@ -0,0 +1,226 @@ +/* Copyright (C) 2015-2017 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. + */ + +/* + * TODO: Update the \author in this file and detect-template.h. + * TODO: Update description in the \file section below. + * TODO: Remove SCLogNotice statements or convert to debug. + */ + +/** + * \file + * + * \author FirstName LastName + * + * Set up of the "template_rust" keyword to allow content + * inspections on the decoded template application layer buffers. + */ + +#include "suricata-common.h" +#include "conf.h" +#include "detect.h" +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-content-inspection.h" +#include "detect-template-rust-buffer.h" +#include "app-layer-parser.h" + +#ifndef HAVE_RUST + +void DetectTemplateRustBufferRegister(void) +{ +} + +#else + +#include "rust-applayertemplate-template-gen.h" + +static int DetectTemplateRustBufferSetup(DetectEngineCtx *, Signature *, + const char *); +static int DetectEngineInspectTemplateRustBuffer(ThreadVars *tv, + DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, + const Signature *s, const SigMatchData *smd, + Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id); +static void DetectTemplateRustBufferRegisterTests(void); +static int g_template_rust_id = 0; + +void DetectTemplateRustBufferRegister(void) +{ + /* TEMPLATE_START_REMOVE */ + if (ConfGetNode("app-layer.protocols.template-rust") == NULL) { + return; + } + /* TEMPLATE_END_REMOVE */ + sigmatch_table[DETECT_AL_TEMPLATE_RUST_BUFFER].name = + "template_rust_buffer"; + sigmatch_table[DETECT_AL_TEMPLATE_RUST_BUFFER].desc = + "Template content modififier to match on the template buffers"; + sigmatch_table[DETECT_AL_TEMPLATE_RUST_BUFFER].Setup = + DetectTemplateRustBufferSetup; + sigmatch_table[DETECT_AL_TEMPLATE_RUST_BUFFER].RegisterTests = + DetectTemplateRustBufferRegisterTests; + + sigmatch_table[DETECT_AL_TEMPLATE_RUST_BUFFER].flags |= SIGMATCH_NOOPT; + + /* register inspect engines */ + DetectAppLayerInspectEngineRegister("template_rust_buffer", + ALPROTO_TEMPLATE, SIG_FLAG_TOSERVER, 0, + DetectEngineInspectTemplateRustBuffer); + DetectAppLayerInspectEngineRegister("template_rust_buffer", + ALPROTO_TEMPLATE, SIG_FLAG_TOCLIENT, 0, + DetectEngineInspectTemplateRustBuffer); + + g_template_rust_id = DetectBufferTypeGetByName("template_rust_buffer"); + + SCLogNotice("Template application layer detect registered."); +} + +static int DetectTemplateRustBufferSetup(DetectEngineCtx *de_ctx, Signature *s, + const char *str) +{ + s->init_data->list = g_template_rust_id; + + if (DetectSignatureSetAppProto(s, ALPROTO_TEMPLATE_RUST) != 0) + return -1; + + return 0; +} + +static int DetectEngineInspectTemplateRustBuffer(ThreadVars *tv, + DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, + const Signature *s, const SigMatchData *smd, + Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) +{ + int ret = 0; + const uint8_t *data = NULL; + uint32_t data_len = 0; + + if (flags & STREAM_TOSERVER) { + rs_template_get_request_buffer(txv, (uint8_t **)&data, &data_len); + } else if (flags & STREAM_TOCLIENT) { + rs_template_get_response_buffer(txv, (uint8_t **)&data, &data_len); + } + + if (data != NULL) { + ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd, + f, (uint8_t *)data, data_len, 0, DETECT_CI_FLAGS_SINGLE, + DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); + } + + SCLogNotice("Returning %d.", ret); + return ret; +} + +#ifdef UNITTESTS + +#include "util-unittest.h" +#include "util-unittest-helper.h" +#include "app-layer-parser.h" +#include "detect-engine.h" +#include "detect-parse.h" +#include "flow-util.h" +#include "stream-tcp.h" + +static int DetectTemplateRustBufferTest(void) +{ + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + DetectEngineThreadCtx *det_ctx = NULL; + DetectEngineCtx *de_ctx = NULL; + Flow f; + Packet *p; + TcpSession tcp; + ThreadVars tv; + Signature *s; + + uint8_t request[] = "12:Hello World!"; + + /* Setup flow. */ + memset(&f, 0, sizeof(Flow)); + memset(&tcp, 0, sizeof(TcpSession)); + memset(&tv, 0, sizeof(ThreadVars)); + p = UTHBuildPacket(request, sizeof(request), IPPROTO_TCP); + FLOW_INITIALIZE(&f); + f.alproto = ALPROTO_TEMPLATE_RUST; + f.protoctx = (void *)&tcp; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + + /* This rule should match. */ + s = DetectEngineAppendSig(de_ctx, + "alert tcp any any -> any any (" + "msg:\"TEMPLATE Test Rule\"; " + "template_rust_buffer; content:\"World!\"; " + "sid:1; rev:1;)"); + FAIL_IF_NULL(s); + + /* This rule should not match. */ + s = DetectEngineAppendSig(de_ctx, + "alert tcp any any -> any any (" + "msg:\"TEMPLATE Test Rule\"; " + "template_rust_buffer; content:\"W0rld!\"; " + "sid:2; rev:1;)"); + FAIL_IF_NULL(s); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TEMPLATE_RUST, + STREAM_TOSERVER, request, sizeof(request)); + FLOWLOCK_UNLOCK(&f); + + /* Check that we have app-layer state. */ + FAIL_IF_NULL(f.alstate); + + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + FAIL_IF(!PacketAlertCheck(p, 1)); + FAIL_IF(PacketAlertCheck(p, 2)); + + /* Cleanup. */ + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + + PASS; +} + +#endif + +static void DetectTemplateRustBufferRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectTemplateRustBufferTest", + DetectTemplateRustBufferTest); +#endif /* UNITTESTS */ +} + +#endif diff --git a/src/detect-template-rust-buffer.h b/src/detect-template-rust-buffer.h new file mode 100644 index 0000000000..59059a76b8 --- /dev/null +++ b/src/detect-template-rust-buffer.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2015-2017 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 FirstName LastName + */ + +#ifndef __DETECT_TEMPLATE_RUST_BUFFER_H__ +#define __DETECT_TEMPLATE_RUST_BUFFER_H__ + +#include "app-layer-template.h" + +void DetectTemplateRustBufferRegister(void); + +#endif /* __DETECT_TEMPLATE_RUST_BUFFER_H__ */