|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
/* Copyright (C) 2015-2017 Open Information Security Foundation
|
|
|
|
|
/* Copyright (C) 2015-2018 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
|
|
|
|
@ -35,15 +35,16 @@
|
|
|
|
|
#include "detect.h"
|
|
|
|
|
#include "detect-parse.h"
|
|
|
|
|
#include "detect-engine.h"
|
|
|
|
|
#include "detect-engine-content-inspection.h"
|
|
|
|
|
#include "detect-engine-mpm.h"
|
|
|
|
|
#include "detect-engine-prefilter.h"
|
|
|
|
|
#include "app-layer-template.h"
|
|
|
|
|
#include "detect-template-buffer.h"
|
|
|
|
|
|
|
|
|
|
static int DetectTemplateBufferSetup(DetectEngineCtx *, Signature *, const char *);
|
|
|
|
|
static int DetectEngineInspectTemplateBuffer(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 InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
|
|
|
|
|
const DetectEngineTransforms *transforms,
|
|
|
|
|
Flow *_f, const uint8_t flow_flags,
|
|
|
|
|
void *txv, const int list_id);
|
|
|
|
|
static void DetectTemplateBufferRegisterTests(void);
|
|
|
|
|
static int g_template_buffer_id = 0;
|
|
|
|
|
|
|
|
|
@ -63,13 +64,22 @@ void DetectTemplateBufferRegister(void)
|
|
|
|
|
|
|
|
|
|
sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT;
|
|
|
|
|
|
|
|
|
|
/* register inspect engines */
|
|
|
|
|
DetectAppLayerInspectEngineRegister("template_buffer",
|
|
|
|
|
/* register inspect engines - these are called per signature */
|
|
|
|
|
DetectAppLayerInspectEngineRegister2("template_buffer",
|
|
|
|
|
ALPROTO_TEMPLATE, SIG_FLAG_TOSERVER, 0,
|
|
|
|
|
DetectEngineInspectTemplateBuffer);
|
|
|
|
|
DetectAppLayerInspectEngineRegister("template_buffer",
|
|
|
|
|
DetectEngineInspectBufferGeneric, GetData);
|
|
|
|
|
DetectAppLayerInspectEngineRegister2("template_buffer",
|
|
|
|
|
ALPROTO_TEMPLATE, SIG_FLAG_TOCLIENT, 0,
|
|
|
|
|
DetectEngineInspectTemplateBuffer);
|
|
|
|
|
DetectEngineInspectBufferGeneric, GetData);
|
|
|
|
|
|
|
|
|
|
/* register mpm engines - these are called in the prefilter stage */
|
|
|
|
|
DetectAppLayerMpmRegister2("template_buffer", SIG_FLAG_TOSERVER, 0,
|
|
|
|
|
PrefilterGenericMpmRegister, GetData,
|
|
|
|
|
ALPROTO_TEMPLATE, 0);
|
|
|
|
|
DetectAppLayerMpmRegister2("template_buffer", SIG_FLAG_TOCLIENT, 0,
|
|
|
|
|
PrefilterGenericMpmRegister, GetData,
|
|
|
|
|
ALPROTO_TEMPLATE, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_template_buffer_id = DetectBufferTypeGetByName("template_buffer");
|
|
|
|
|
|
|
|
|
@ -79,37 +89,54 @@ void DetectTemplateBufferRegister(void)
|
|
|
|
|
static int DetectTemplateBufferSetup(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_template_buffer_id;
|
|
|
|
|
|
|
|
|
|
/* set the app proto for this signature. This means it will only be
|
|
|
|
|
* evaluated against flows that are ALPROTO_TEMPLATE */
|
|
|
|
|
if (DetectSignatureSetAppProto(s, ALPROTO_TEMPLATE) != 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int DetectEngineInspectTemplateBuffer(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)
|
|
|
|
|
/** \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,
|
|
|
|
|
Flow *_f, const uint8_t flow_flags,
|
|
|
|
|
void *txv, const int list_id)
|
|
|
|
|
{
|
|
|
|
|
TemplateTransaction *tx = (TemplateTransaction *)txv;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) {
|
|
|
|
|
ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
|
|
|
|
|
f, tx->request_buffer, tx->request_buffer_len,
|
|
|
|
|
0, DETECT_CI_FLAGS_SINGLE,
|
|
|
|
|
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
|
|
|
|
|
const uint8_t *data = NULL;
|
|
|
|
|
uint32_t data_len = 0;
|
|
|
|
|
|
|
|
|
|
BUG_ON(det_ctx->inspect_buffers == NULL);
|
|
|
|
|
|
|
|
|
|
InspectionBuffer *buffer = &det_ctx->inspect_buffers[list_id];
|
|
|
|
|
if (buffer->inspect == NULL) {
|
|
|
|
|
const TemplateTransaction *tx = (TemplateTransaction *)txv;
|
|
|
|
|
|
|
|
|
|
if (flow_flags & STREAM_TOSERVER) {
|
|
|
|
|
data = tx->request_buffer;
|
|
|
|
|
data_len = tx->request_buffer_len;
|
|
|
|
|
} else if (flow_flags & STREAM_TOCLIENT) {
|
|
|
|
|
data = tx->response_buffer;
|
|
|
|
|
data_len = tx->response_buffer_len;
|
|
|
|
|
} else {
|
|
|
|
|
return NULL; /* no buffer */
|
|
|
|
|
}
|
|
|
|
|
else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) {
|
|
|
|
|
ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
|
|
|
|
|
f, tx->response_buffer, tx->response_buffer_len,
|
|
|
|
|
0, DETECT_CI_FLAGS_SINGLE,
|
|
|
|
|
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
|
|
|
|
|
|
|
|
|
|
InspectionBufferSetup(buffer, data, data_len);
|
|
|
|
|
InspectionBufferApplyTransforms(buffer, transforms);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCLogNotice("Returning %d.", ret);
|
|
|
|
|
return ret;
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
|