detect-engine-sigorder.c detect-engine-sigorder.h \
detect-engine-state.c detect-engine-state.h \
detect-engine-tag.c detect-engine-tag.h \
+detect-engine-template.c detect-engine-template.h \
detect-engine-threshold.c detect-engine-threshold.h \
detect-engine-uri.c detect-engine-uri.h \
detect-fast-pattern.c detect-fast-pattern.h \
detect-stream_size.c detect-stream_size.h \
detect-tag.c detect-tag.h \
detect-template.c detect-template.h \
+detect-template-buffer.c detect-template-buffer.h \
detect-threshold.c detect-threshold.h \
detect-tls.c detect-tls.h \
detect-tls-version.c detect-tls-version.h \
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHHD,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_DNSQUERY,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_FD_SMTP,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_TEMPLATE_BUFFER,
};
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
#define DE_STATE_FLAG_FD_SMTP_INSPECT (1 << 21)
#define DE_STATE_FLAG_DNSREQUEST_INSPECT (1 << 22)
#define DE_STATE_FLAG_DNSRESPONSE_INSPECT (1 << 23)
+#define DE_STATE_FLAG_TEMPLATE_BUFFER_INSPECT (1 << 24)
/* state flags */
#define DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED 0x0001
--- /dev/null
+/* Copyright (C) 2015 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 "stream.h"
+#include "detect-engine-content-inspection.h"
+
+#include "app-layer-template.h"
+
+int DetectEngineInspectTemplateBuffer(ThreadVars *tv, DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags,
+ void *alstate, void *txv, uint64_t tx_id)
+{
+ TemplateTransaction *tx = (TemplateTransaction *)txv;
+ int ret = 0;
+
+ if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) {
+ ret = DetectEngineContentInspection(de_ctx, det_ctx, s,
+ s->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH], f,
+ tx->request_buffer, tx->request_buffer_len, 0,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_TEMPLATE_BUFFER, NULL);
+ }
+ else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) {
+ ret = DetectEngineContentInspection(de_ctx, det_ctx, s,
+ s->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH], f,
+ tx->response_buffer, tx->response_buffer_len, 0,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_TEMPLATE_BUFFER, NULL);
+ }
+
+ SCLogNotice("Returning %d.", ret);
+ return ret;
+}
--- /dev/null
+/* Copyright (C) 2015 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.
+ */
+
+#ifndef __DETECT_TEMPLATE_ENGINE_H__
+#define __DETECT_TEMPLATE_ENGINE_H__
+
+int DetectEngineInspectTemplateBuffer(ThreadVars *, DetectEngineCtx *,
+ DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, void *, void *,
+ uint64_t);
+
+#endif /* __DETECT_TEMPLATE_ENGINE_H__ */
#include "detect-engine-dns.h"
#include "detect-engine-modbus.h"
#include "detect-engine-filedata-smtp.h"
+#include "detect-engine-template.h"
#include "detect-engine.h"
#include "detect-engine-state.h"
DE_STATE_FLAG_FD_SMTP_INSPECT,
0,
DetectEngineInspectSMTPFiledata },
+ /* Template. */
+ { IPPROTO_TCP,
+ ALPROTO_TEMPLATE,
+ DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH,
+ DE_STATE_FLAG_TEMPLATE_BUFFER_INSPECT,
+ 0,
+ DetectEngineInspectTemplateBuffer },
};
struct tmp_t data_toclient[] = {
DE_STATE_FLAG_DNSRESPONSE_INSPECT,
1,
DetectEngineInspectDnsResponse },
+ /* Template. */
+ { IPPROTO_TCP,
+ ALPROTO_TEMPLATE,
+ DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH,
+ DE_STATE_FLAG_TEMPLATE_BUFFER_INSPECT,
+ 1,
+ DetectEngineInspectTemplateBuffer },
};
size_t i;
case DETECT_SM_LIST_MODBUS_MATCH:
return "modbus";
+ case DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH:
+ return "template_buffer";
+
case DETECT_SM_LIST_POSTMATCH:
return "post-match";
if (sig->sm_lists[DETECT_SM_LIST_HRHHDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
+ /* Template. */
+ if (sig->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH]) {
+ sig->flags |= SIG_FLAG_STATE_MATCH;
+ }
+
/* DNS */
if (sig->sm_lists[DETECT_SM_LIST_DNSQUERYNAME_MATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
--- /dev/null
+/* Copyright (C) 2015 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 Set up of the "template_buffer" keyword to allow content inspections
+ * on the decoded template application layer buffers.
+ */
+
+#include "suricata-common.h"
+#include "detect.h"
+#include "app-layer-template.h"
+
+static int DetectTemplateBufferSetup(DetectEngineCtx *, Signature *, char *);
+static void DetectTemplateBufferRegisterTests(void);
+
+void DetectTemplateBufferRegister(void)
+{
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].name = "template_buffer";
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].desc =
+ "Template content modififier to match on the template buffers";
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].alproto = ALPROTO_TEMPLATE;
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].Setup = DetectTemplateBufferSetup;
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].RegisterTests =
+ DetectTemplateBufferRegisterTests;
+
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT;
+ sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_PAYLOAD;
+
+ SCLogNotice("Template application layer detect registered.");
+}
+
+static int DetectTemplateBufferSetup(DetectEngineCtx *de_ctx, Signature *s,
+ char *str)
+{
+ s->list = DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH;
+ s->alproto = ALPROTO_TEMPLATE;
+ return 0;
+}
+
+#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 DetectTemplateBufferTest(void)
+{
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+ DetectEngineThreadCtx *det_ctx = NULL;
+ DetectEngineCtx *de_ctx = NULL;
+ Flow f;
+ Packet *p;
+ TcpSession tcp;
+ ThreadVars tv;
+ Signature *s;
+
+ int result = 0;
+
+ uint8_t request[] = "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;
+ 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();
+ if (de_ctx == NULL) {
+ goto end;
+ }
+
+ /* This rule should match. */
+ s = DetectEngineAppendSig(de_ctx,
+ "alert tcp any any -> any any ("
+ "msg:\"TEMPLATE Test Rule\"; "
+ "template_buffer; content:\"World!\"; "
+ "sid:1; rev:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ /* This rule should not match. */
+ s = DetectEngineAppendSig(de_ctx,
+ "alert tcp any any -> any any ("
+ "msg:\"TEMPLATE Test Rule\"; "
+ "template_buffer; content:\"W0rld!\"; "
+ "sid:2; rev:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ AppLayerParserParse(alp_tctx, &f, ALPROTO_TEMPLATE, STREAM_TOSERVER,
+ request, sizeof(request));
+ SCMutexUnlock(&f.m);
+
+ /* Check that we have app-layer state. */
+ if (f.alstate == NULL) {
+ goto end;
+ }
+
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+ if (!PacketAlertCheck(p, 1)) {
+ goto end;
+ }
+ if (PacketAlertCheck(p, 2)) {
+ goto end;
+ }
+
+ result = 1;
+end:
+ /* 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);
+
+ return result;
+}
+
+#endif
+
+static void DetectTemplateBufferRegisterTests(void)
+{
+#ifdef UNITTESTS
+ UtRegisterTest("DetectTemplateBufferTest", DetectTemplateBufferTest, 1);
+#endif /* UNITTESTS */
+}
--- /dev/null
+/* Copyright (C) 2015 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.
+ */
+
+#ifndef __DETECT_TEMPLATE_BUFFER_H__
+#define __DETECT_TEMPLATE_BUFFER_H__
+
+#include "app-layer-template.h"
+
+void DetectTemplateBufferRegister(void);
+
+#endif /* __DETECT_TEMPLATE_BUFFER_H__ */
#include "detect-dns-query.h"
#include "detect-app-layer-protocol.h"
#include "detect-template.h"
+#include "detect-template-buffer.h"
#include "util-rule-vars.h"
#include "app-layer-protos.h"
#include "app-layer-htp.h"
#include "app-layer-smtp.h"
+#include "app-layer-template.h"
#include "detect-tls.h"
#include "detect-tls-version.h"
#include "detect-ssh-proto-version.h"
SCLogDebug("packet/flow has smtp state");
(*mask) |= SIG_MASK_REQUIRE_SMTP_STATE;
break;
+ case ALPROTO_TEMPLATE:
+ SCLogDebug("packet/flow has template state");
+ (*mask) |= SIG_MASK_REQUIRE_TEMPLATE_STATE;
+ break;
default:
SCLogDebug("packet/flow has other state");
break;
s->mask |= SIG_MASK_REQUIRE_SMTP_STATE;
SCLogDebug("sig requires smtp state");
}
+ if (s->alproto == ALPROTO_TEMPLATE) {
+ s->mask |= SIG_MASK_REQUIRE_TEMPLATE_STATE;
+ SCLogDebug("sig requires template state");
+ }
if ((s->mask & SIG_MASK_REQUIRE_DCE_STATE) ||
(s->mask & SIG_MASK_REQUIRE_HTTP_STATE) ||
(s->mask & SIG_MASK_REQUIRE_DNS_STATE) ||
(s->mask & SIG_MASK_REQUIRE_FTP_STATE) ||
(s->mask & SIG_MASK_REQUIRE_SMTP_STATE) ||
+ (s->mask & SIG_MASK_REQUIRE_TEMPLATE_STATE) ||
(s->mask & SIG_MASK_REQUIRE_TLS_STATE))
{
s->mask |= SIG_MASK_REQUIRE_FLOW;
DetectModbusRegister();
DetectAppLayerProtocolRegister();
DetectTemplateRegister();
+ DetectTemplateBufferRegister();
}
void SigTableRegisterTests(void)
DETECT_SM_LIST_MODBUS_MATCH,
+ DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH,
+
/* list for post match actions: flowbit set, flowint increment, etc */
DETECT_SM_LIST_POSTMATCH,
#define SIG_MASK_REQUIRE_DNS_STATE (1<<10)
#define SIG_MASK_REQUIRE_FTP_STATE (1<<11)
#define SIG_MASK_REQUIRE_SMTP_STATE (1<<12)
+#define SIG_MASK_REQUIRE_TEMPLATE_STATE (1<<13)
/* for now a uint8_t is enough */
#define SignatureMask uint16_t
DETECT_XBITS,
DETECT_TEMPLATE,
+ DETECT_AL_TEMPLATE_BUFFER,
/* make sure this stays last */
DETECT_TBLSIZE,