|
|
|
/* Copyright (C) 2013-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
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \ingroup dnslayer
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
*
|
|
|
|
* \author Victor Julien <victor@inliniac.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "suricata-common.h"
|
|
|
|
#include "threads.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "decode.h"
|
|
|
|
#include "detect.h"
|
|
|
|
|
|
|
|
#include "detect-parse.h"
|
|
|
|
#include "detect-engine.h"
|
|
|
|
#include "detect-engine-mpm.h"
|
|
|
|
#include "detect-engine-prefilter.h"
|
|
|
|
#include "detect-engine-content-inspection.h"
|
|
|
|
#include "detect-content.h"
|
|
|
|
#include "detect-pcre.h"
|
|
|
|
|
|
|
|
#include "flow.h"
|
|
|
|
#include "flow-util.h"
|
|
|
|
#include "flow-var.h"
|
|
|
|
|
|
|
|
#include "util-debug.h"
|
|
|
|
#include "util-unittest.h"
|
|
|
|
#include "util-spm.h"
|
|
|
|
#include "util-print.h"
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
#include "stream-tcp.h"
|
|
|
|
|
|
|
|
#include "app-layer.h"
|
|
|
|
#include "app-layer-dns-common.h"
|
|
|
|
#include "detect-dns-query.h"
|
|
|
|
#include "detect-engine-dns.h"
|
|
|
|
|
|
|
|
#include "util-unittest-helper.h"
|
|
|
|
|
|
|
|
#include "rust-dns-dns-gen.h"
|
|
|
|
|
|
|
|
static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, const char *);
|
|
|
|
static void DetectDnsQueryRegisterTests(void);
|
|
|
|
static int g_dns_query_buffer_id = 0;
|
|
|
|
|
|
|
|
struct DnsQueryGetDataArgs {
|
|
|
|
int local_id; /**< used as index into thread inspect array */
|
|
|
|
void *txv;
|
|
|
|
};
|
|
|
|
|
|
|
|
static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx,
|
|
|
|
const DetectEngineTransforms *transforms,
|
|
|
|
Flow *f, struct DnsQueryGetDataArgs *cbdata, int list_id, bool first)
|
|
|
|
{
|
|
|
|
SCEnter();
|
|
|
|
|
|
|
|
InspectionBufferMultipleForList *fb = InspectionBufferGetMulti(det_ctx, list_id);
|
|
|
|
InspectionBuffer *buffer = InspectionBufferMultipleForListGet(fb, cbdata->local_id);
|
|
|
|
if (buffer == NULL)
|
|
|
|
return NULL;
|
|
|
|
if (!first && buffer->inspect != NULL)
|
|
|
|
return buffer;
|
|
|
|
|
|
|
|
const uint8_t *data;
|
|
|
|
uint32_t data_len;
|
|
|
|
if (rs_dns_tx_get_query_name(cbdata->txv, (uint16_t)cbdata->local_id,
|
|
|
|
&data, &data_len) == 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
InspectionBufferSetup(buffer, data, data_len);
|
|
|
|
InspectionBufferApplyTransforms(buffer, transforms);
|
|
|
|
|
|
|
|
SCReturnPtr(buffer, "InspectionBuffer");
|
|
|
|
}
|
|
|
|
|
|
|
|
static int DetectEngineInspectDnsQuery(
|
|
|
|
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
|
|
|
|
const DetectEngineAppInspectionEngine *engine,
|
|
|
|
const Signature *s,
|
|
|
|
Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
|
|
|
|
{
|
|
|
|
int local_id = 0;
|
|
|
|
|
|
|
|
const DetectEngineTransforms *transforms = NULL;
|
|
|
|
if (!engine->mpm) {
|
|
|
|
transforms = engine->v2.transforms;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
struct DnsQueryGetDataArgs cbdata = { local_id, txv, };
|
|
|
|
InspectionBuffer *buffer = DnsQueryGetData(det_ctx,
|
|
|
|
transforms, f, &cbdata, engine->sm_list, false);
|
|
|
|
if (buffer == NULL || buffer->inspect == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
det_ctx->buffer_offset = 0;
|
|
|
|
det_ctx->discontinue_matching = 0;
|
|
|
|
det_ctx->inspection_recursion_counter = 0;
|
|
|
|
|
|
|
|
const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
|
|
|
|
NULL, f,
|
|
|
|
(uint8_t *)buffer->inspect,
|
|
|
|
buffer->inspect_len,
|
|
|
|
buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE,
|
|
|
|
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
|
|
|
|
if (match == 1) {
|
|
|
|
return DETECT_ENGINE_INSPECT_SIG_MATCH;
|
|
|
|
}
|
|
|
|
local_id++;
|
|
|
|
}
|
|
|
|
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct PrefilterMpmDnsQuery {
|
|
|
|
int list_id;
|
|
|
|
const MpmCtx *mpm_ctx;
|
|
|
|
const DetectEngineTransforms *transforms;
|
|
|
|
} PrefilterMpmDnsQuery;
|
|
|
|
|
|
|
|
/** \brief DnsQuery DnsQuery Mpm prefilter callback
|
|
|
|
*
|
|
|
|
* \param det_ctx detection engine thread ctx
|
|
|
|
* \param p packet to inspect
|
|
|
|
* \param f flow to inspect
|
|
|
|
* \param txv tx to inspect
|
|
|
|
* \param pectx inspection context
|
|
|
|
*/
|
|
|
|
static void PrefilterTxDnsQuery(DetectEngineThreadCtx *det_ctx,
|
|
|
|
const void *pectx,
|
|
|
|
Packet *p, Flow *f, void *txv,
|
|
|
|
const uint64_t idx, const uint8_t flags)
|
|
|
|
{
|
|
|
|
SCEnter();
|
|
|
|
|
|
|
|
const PrefilterMpmDnsQuery *ctx = (const PrefilterMpmDnsQuery *)pectx;
|
|
|
|
const MpmCtx *mpm_ctx = ctx->mpm_ctx;
|
|
|
|
const int list_id = ctx->list_id;
|
|
|
|
|
|
|
|
int local_id = 0;
|
|
|
|
while(1) {
|
|
|
|
// loop until we get a NULL
|
|
|
|
|
|
|
|
struct DnsQueryGetDataArgs cbdata = { local_id, txv };
|
|
|
|
InspectionBuffer *buffer = DnsQueryGetData(det_ctx, ctx->transforms,
|
|
|
|
f, &cbdata, list_id, true);
|
|
|
|
if (buffer == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (buffer->inspect_len >= mpm_ctx->minlen) {
|
|
|
|
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
|
|
|
|
&det_ctx->mtcu, &det_ctx->pmq,
|
|
|
|
buffer->inspect, buffer->inspect_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
local_id++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void PrefilterMpmDnsQueryFree(void *ptr)
|
|
|
|
{
|
|
|
|
SCFree(ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int PrefilterMpmDnsQueryRegister(DetectEngineCtx *de_ctx,
|
|
|
|
SigGroupHead *sgh, MpmCtx *mpm_ctx,
|
|
|
|
const DetectBufferMpmRegistery *mpm_reg, int list_id)
|
|
|
|
{
|
|
|
|
PrefilterMpmDnsQuery *pectx = SCCalloc(1, sizeof(*pectx));
|
|
|
|
if (pectx == NULL)
|
|
|
|
return -1;
|
|
|
|
pectx->list_id = list_id;
|
|
|
|
pectx->mpm_ctx = mpm_ctx;
|
|
|
|
pectx->transforms = &mpm_reg->transforms;
|
|
|
|
|
|
|
|
return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxDnsQuery,
|
|
|
|
mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress,
|
|
|
|
pectx, PrefilterMpmDnsQueryFree, mpm_reg->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Registration function for keyword: dns_query
|
|
|
|
*/
|
|
|
|
void DetectDnsQueryRegister (void)
|
|
|
|
{
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].name = "dns.query";
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].alias = "dns_query";
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].desc = "sticky buffer to match DNS query-buffer";
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup;
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = DetectDnsQueryRegisterTests;
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_NOOPT;
|
|
|
|
sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_INFO_STICKY_BUFFER;
|
|
|
|
|
|
|
|
DetectAppLayerMpmRegister2("dns_query", SIG_FLAG_TOSERVER, 2,
|
|
|
|
PrefilterMpmDnsQueryRegister, NULL,
|
|
|
|
ALPROTO_DNS, 1);
|
|
|
|
|
|
|
|
DetectAppLayerInspectEngineRegister2("dns_query",
|
|
|
|
ALPROTO_DNS, SIG_FLAG_TOSERVER, 1,
|
|
|
|
DetectEngineInspectDnsQuery, NULL);
|
|
|
|
|
|
|
|
DetectBufferTypeSetDescriptionByName("dns_query",
|
|
|
|
"dns request query");
|
|
|
|
|
|
|
|
g_dns_query_buffer_id = DetectBufferTypeGetByName("dns_query");
|
|
|
|
|
|
|
|
/* register these generic engines from here for now */
|
|
|
|
DetectAppLayerInspectEngineRegister("dns_request",
|
|
|
|
ALPROTO_DNS, SIG_FLAG_TOSERVER, 1,
|
|
|
|
DetectEngineInspectDnsRequest);
|
|
|
|
DetectAppLayerInspectEngineRegister("dns_response",
|
|
|
|
ALPROTO_DNS, SIG_FLAG_TOCLIENT, 1,
|
|
|
|
DetectEngineInspectDnsResponse);
|
|
|
|
|
|
|
|
DetectBufferTypeSetDescriptionByName("dns_request",
|
|
|
|
"dns requests");
|
|
|
|
DetectBufferTypeSetDescriptionByName("dns_response",
|
|
|
|
"dns responses");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief setup the dns_query sticky buffer keyword used in the rule
|
|
|
|
*
|
|
|
|
* \param de_ctx Pointer to the Detection Engine Context
|
|
|
|
* \param s Pointer to the Signature to which the current keyword belongs
|
|
|
|
* \param str Should hold an empty string always
|
|
|
|
*
|
|
|
|
* \retval 0 On success
|
|
|
|
* \retval -1 On failure
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
|
|
|
|
{
|
|
|
|
if (DetectBufferSetActiveList(s, g_dns_query_buffer_id) < 0)
|
|
|
|
return -1;
|
|
|
|
if (DetectSignatureSetAppProto(s, ALPROTO_DNS) < 0)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
#include "detect-isdataat.h"
|
|
|
|
|
|
|
|
/** \test simple google.com query matching */
|
|
|
|
static int DetectDnsQueryTest01(void)
|
|
|
|
{
|
|
|
|
/* google.com */
|
|
|
|
uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
|
|
|
|
p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_UDP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
|
|
|
|
|
|
|
p->flow = &f;
|
|
|
|
p->flags |= PKT_HAS_FLOW;
|
|
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google\"; nocase; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf, sizeof(buf));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p, 1))) {
|
|
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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);
|
|
|
|
|
|
|
|
FLOW_DESTROY(&f);
|
|
|
|
UTHFreePacket(p);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \test multi tx google.(com|net) query matching */
|
|
|
|
static int DetectDnsQueryTest02(void)
|
|
|
|
{
|
|
|
|
/* google.com */
|
|
|
|
uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x01, 0x00, 0x01, };
|
|
|
|
|
|
|
|
uint8_t buf2[] = { 0x10, 0x32, /* tx id */
|
|
|
|
0x81, 0x80, /* flags: resp, recursion desired, recusion available */
|
|
|
|
0x00, 0x01, /* 1 query */
|
|
|
|
0x00, 0x01, /* 1 answer */
|
|
|
|
0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
|
|
|
|
/* query record */
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
|
|
|
|
0x00, 0x01, 0x00, 0x01, /* type a, class in */
|
|
|
|
/* answer */
|
|
|
|
0xc0, 0x0c, /* ref to name in query above */
|
|
|
|
0x00, 0x01, 0x00, 0x01, /* type a, class in */
|
|
|
|
0x00, 0x01, 0x40, 0xef, /* ttl */
|
|
|
|
0x00, 0x04, /* data len */
|
|
|
|
0x01, 0x02, 0x03, 0x04 }; /* addr */
|
|
|
|
|
|
|
|
/* google.net */
|
|
|
|
uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
|
|
|
|
p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_UDP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
p1->flow = &f;
|
|
|
|
p1->flags |= PKT_HAS_FLOW;
|
|
|
|
p1->flowflags |= FLOW_PKT_TOSERVER;
|
|
|
|
p1->pcap_cnt = 1;
|
|
|
|
|
|
|
|
p2->flow = &f;
|
|
|
|
p2->flags |= PKT_HAS_FLOW;
|
|
|
|
p2->flowflags |= FLOW_PKT_TOCLIENT;
|
|
|
|
p2->pcap_cnt = 2;
|
|
|
|
|
|
|
|
p3->flow = &f;
|
|
|
|
p3->flags |= PKT_HAS_FLOW;
|
|
|
|
p3->flowflags |= FLOW_PKT_TOSERVER;
|
|
|
|
p3->pcap_cnt = 3;
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google.com\"; nocase; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google.net\"; nocase; sid:2;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf1, sizeof(buf1));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p1, 1))) {
|
|
|
|
printf("(p1) sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p1, 2)) {
|
|
|
|
printf("(p1) sig 2 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
|
|
|
|
buf2, sizeof(buf2));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver client 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p2, 1)) {
|
|
|
|
printf("(p2) sig 1 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p2, 2)) {
|
|
|
|
printf("(p2) sig 2 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
|
|
|
|
buf3, sizeof(buf3));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p3, 1)) {
|
|
|
|
printf("(p3) sig 1 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (!(PacketAlertCheck(p3, 2))) {
|
|
|
|
printf("(p3) sig 2 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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);
|
|
|
|
|
|
|
|
FLOW_DESTROY(&f);
|
|
|
|
UTHFreePacket(p1);
|
|
|
|
UTHFreePacket(p2);
|
|
|
|
UTHFreePacket(p3);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \test simple google.com query matching (TCP) */
|
|
|
|
static int DetectDnsQueryTest03(void)
|
|
|
|
{
|
|
|
|
/* google.com */
|
|
|
|
uint8_t buf[] = { 0x00, 28,
|
|
|
|
0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
TcpSession ssn;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
|
|
|
|
p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.protoctx = (void *)&ssn;
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_TCP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
|
|
|
|
|
|
|
p->flow = &f;
|
|
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google\"; nocase; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf, sizeof(buf));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p, 1))) {
|
|
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \test simple google.com query matching (TCP splicing) */
|
|
|
|
static int DetectDnsQueryTest04(void)
|
|
|
|
{
|
|
|
|
/* google.com */
|
|
|
|
uint8_t buf1[] = { 0x00, 28,
|
|
|
|
0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
|
|
|
|
uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p1 = NULL, *p2 = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
TcpSession ssn;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
|
|
|
|
p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.protoctx = (void *)&ssn;
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_TCP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
p1->flow = &f;
|
|
|
|
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p1->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
|
|
|
|
|
|
|
|
p2->flow = &f;
|
|
|
|
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
|
|
|
|
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google\"; nocase; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf1, sizeof(buf1));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p1, 1)) {
|
|
|
|
printf("sig 1 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
|
|
|
|
buf2, sizeof(buf2));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0\n", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p2, 1))) {
|
|
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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(p1);
|
|
|
|
UTHFreePacket(p2);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \test simple google.com query matching (TCP splicing) */
|
|
|
|
static int DetectDnsQueryTest05(void)
|
|
|
|
{
|
|
|
|
/* google.com in 2 chunks (buf1 and buf2) */
|
|
|
|
uint8_t buf1[] = { 0x00, 28, /* len 28 */
|
|
|
|
0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
|
|
|
|
|
|
|
|
uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
|
|
|
|
uint8_t buf3[] = { 0x00, 44, /* len 44 */
|
|
|
|
0x10, 0x32, /* tx id */
|
|
|
|
0x81, 0x80, /* flags: resp, recursion desired, recusion available */
|
|
|
|
0x00, 0x01, /* 1 query */
|
|
|
|
0x00, 0x01, /* 1 answer */
|
|
|
|
0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
|
|
|
|
/* query record */
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
|
|
|
|
0x00, 0x01, 0x00, 0x01, /* type a, class in */
|
|
|
|
/* answer */
|
|
|
|
0xc0, 0x0c, /* ref to name in query above */
|
|
|
|
0x00, 0x01, 0x00, 0x01, /* type a, class in */
|
|
|
|
0x00, 0x01, 0x40, 0xef, /* ttl */
|
|
|
|
0x00, 0x04, /* data len */
|
|
|
|
0x01, 0x02, 0x03, 0x04 }; /* addr */
|
|
|
|
|
|
|
|
/* google.net */
|
|
|
|
uint8_t buf4[] = { 0x00, 28, /* len 28 */
|
|
|
|
0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
TcpSession ssn;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
|
|
|
|
p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p4 = UTHBuildPacketReal(buf4, sizeof(buf4), IPPROTO_TCP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.protoctx = (void *)&ssn;
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_TCP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
p1->flow = &f;
|
|
|
|
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p1->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
|
|
|
|
|
|
|
|
p2->flow = &f;
|
|
|
|
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
|
|
|
|
|
|
|
|
p3->flow = &f;
|
|
|
|
p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p3->flowflags |= FLOW_PKT_TOCLIENT|FLOW_PKT_ESTABLISHED;
|
|
|
|
|
|
|
|
p4->flow = &f;
|
|
|
|
p4->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
p4->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
|
|
|
|
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google.com\"; nocase; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google.net\"; nocase; sid:2;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf1, sizeof(buf1));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p1, 1)) {
|
|
|
|
printf("(p1) sig 1 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p1, 2)) {
|
|
|
|
printf("(p1) sig 2 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
|
|
|
|
buf2, sizeof(buf2));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p2, 1))) {
|
|
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p2, 2)) {
|
|
|
|
printf("(p2) sig 2 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
|
|
|
|
buf3, sizeof(buf3));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p3, 1)) {
|
|
|
|
printf("sig 1 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p3, 2)) {
|
|
|
|
printf("(p3) sig 2 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
|
|
|
|
buf4, sizeof(buf4));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p4);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p4, 1)) {
|
|
|
|
printf("(p4) sig 1 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (!(PacketAlertCheck(p4, 2))) {
|
|
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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(p1);
|
|
|
|
UTHFreePacket(p2);
|
|
|
|
UTHFreePacket(p3);
|
|
|
|
UTHFreePacket(p4);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \test simple google.com query matching, pcre */
|
|
|
|
static int DetectDnsQueryTest06(void)
|
|
|
|
{
|
|
|
|
/* google.com */
|
|
|
|
uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
|
|
|
|
p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_UDP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
|
|
|
|
|
|
|
p->flow = &f;
|
|
|
|
p->flags |= PKT_HAS_FLOW;
|
|
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google\"; nocase; "
|
|
|
|
"pcre:\"/google\\.com$/i\"; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google\"; nocase; "
|
|
|
|
"pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf, sizeof(buf));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p, 1))) {
|
|
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (!(PacketAlertCheck(p, 2))) {
|
|
|
|
printf("sig 2 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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);
|
|
|
|
|
|
|
|
FLOW_DESTROY(&f);
|
|
|
|
UTHFreePacket(p);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \test multi tx google.(com|net) query matching +
|
|
|
|
* app layer event */
|
|
|
|
static int DetectDnsQueryTest07(void)
|
|
|
|
{
|
|
|
|
/* google.com */
|
|
|
|
uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
|
|
|
|
0x00, 0x01, 0x00, 0x01, };
|
|
|
|
|
|
|
|
uint8_t buf2[] = { 0x10, 0x32, /* tx id */
|
|
|
|
0x81, 0x80|0x40, /* flags: resp, recursion desired, recusion available */
|
|
|
|
0x00, 0x01, /* 1 query */
|
|
|
|
0x00, 0x01, /* 1 answer */
|
|
|
|
0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
|
|
|
|
/* query record */
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
|
|
|
|
0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
|
|
|
|
0x00, 0x01, 0x00, 0x01, /* type a, class in */
|
|
|
|
/* answer */
|
|
|
|
0xc0, 0x0c, /* ref to name in query above */
|
|
|
|
0x00, 0x01, 0x00, 0x01, /* type a, class in */
|
|
|
|
0x00, 0x01, 0x40, 0xef, /* ttl */
|
|
|
|
0x00, 0x04, /* data len */
|
|
|
|
0x01, 0x02, 0x03, 0x04 }; /* addr */
|
|
|
|
|
|
|
|
/* google.net */
|
|
|
|
uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
|
|
|
|
0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
|
|
|
|
0x00, 0x10, 0x00, 0x01, };
|
|
|
|
Flow f;
|
|
|
|
RSDNSState *dns_state = NULL;
|
|
|
|
Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
|
|
|
|
Signature *s = NULL;
|
|
|
|
ThreadVars tv;
|
|
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
|
|
|
|
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
|
|
memset(&f, 0, sizeof(Flow));
|
|
|
|
|
|
|
|
p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP,
|
|
|
|
"192.168.1.5", "192.168.1.1",
|
|
|
|
41424, 53);
|
|
|
|
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
f.proto = IPPROTO_UDP;
|
|
|
|
f.protomap = FlowGetProtoMapping(f.proto);
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
f.alproto = ALPROTO_DNS;
|
|
|
|
|
|
|
|
p1->flow = &f;
|
|
|
|
p1->flags |= PKT_HAS_FLOW;
|
|
|
|
p1->flowflags |= FLOW_PKT_TOSERVER;
|
|
|
|
p1->pcap_cnt = 1;
|
|
|
|
|
|
|
|
p2->flow = &f;
|
|
|
|
p2->flags |= PKT_HAS_FLOW;
|
|
|
|
p2->flowflags |= FLOW_PKT_TOCLIENT;
|
|
|
|
p2->pcap_cnt = 2;
|
|
|
|
|
|
|
|
p3->flow = &f;
|
|
|
|
p3->flags |= PKT_HAS_FLOW;
|
|
|
|
p3->flowflags |= FLOW_PKT_TOSERVER;
|
|
|
|
p3->pcap_cnt = 3;
|
|
|
|
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->mpm_matcher = mpm_default_matcher;
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google.com\"; nocase; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test dns_query option\"; "
|
|
|
|
"dns_query; content:\"google.net\"; nocase; sid:2;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
|
|
|
|
"(msg:\"Test Z flag event\"; "
|
|
|
|
"app-layer-event:dns.z_flag_set; sid:3;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigGroupBuild(de_ctx);
|
|
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
|
|
|
|
STREAM_TOSERVER, buf1, sizeof(buf1));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
dns_state = f.alstate;
|
|
|
|
FAIL_IF_NULL(dns_state);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
|
|
|
|
|
|
|
|
if (!(PacketAlertCheck(p1, 1))) {
|
|
|
|
printf("(p1) sig 1 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p1, 2)) {
|
|
|
|
printf("(p1) sig 2 did alert, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
|
|
|
|
buf2, sizeof(buf2));
|
|
|
|
if (r != -1) {
|
|
|
|
printf("toserver client 1 returned %" PRId32 ", expected -1\n", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p2, 1)) {
|
|
|
|
printf("(p2) sig 1 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (PacketAlertCheck(p2, 2)) {
|
|
|
|
printf("(p2) sig 2 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (!(PacketAlertCheck(p2, 3))) {
|
|
|
|
printf("(p2) sig 3 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(&f);
|
|
|
|
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
|
|
|
|
buf3, sizeof(buf3));
|
|
|
|
if (r != 0) {
|
|
|
|
printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
FLOWLOCK_UNLOCK(&f);
|
|
|
|
|
|
|
|
/* do detect */
|
|
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
|
|
|
|
|
|
|
|
if (PacketAlertCheck(p3, 1)) {
|
|
|
|
printf("(p3) sig 1 alerted, but it should not have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
if (!(PacketAlertCheck(p3, 2))) {
|
|
|
|
printf("(p3) sig 2 didn't alert, but it should have: ");
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
/** \todo should not alert, bug #839
|
|
|
|
if (PacketAlertCheck(p3, 3)) {
|
|
|
|
printf("(p3) sig 3 did alert, but it should not have: ");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
App layer API rewritten. The main files in question are:
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
12 years ago
|
|
|
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);
|
|
|
|
|
|
|
|
FLOW_DESTROY(&f);
|
|
|
|
UTHFreePacket(p1);
|
|
|
|
UTHFreePacket(p2);
|
|
|
|
UTHFreePacket(p3);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int DetectDnsQueryIsdataatParseTest(void)
|
|
|
|
{
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
|
|
FAIL_IF_NULL(de_ctx);
|
|
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
|
|
|
|
Signature *s = DetectEngineAppendSig(de_ctx,
|
|
|
|
"alert dns any any -> any any ("
|
|
|
|
"dns_query; content:\"one\"; "
|
|
|
|
"isdataat:!4,relative; sid:1;)");
|
|
|
|
FAIL_IF_NULL(s);
|
|
|
|
|
|
|
|
SigMatch *sm = s->init_data->smlists_tail[g_dns_query_buffer_id];
|
|
|
|
FAIL_IF_NULL(sm);
|
|
|
|
FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
|
|
|
|
|
|
|
|
DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
|
|
|
|
FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
|
|
|
|
FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
|
|
|
|
FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
|
|
|
|
|
|
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
PASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void DetectDnsQueryRegisterTests(void)
|
|
|
|
{
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
UtRegisterTest("DetectDnsQueryTest01", DetectDnsQueryTest01);
|
|
|
|
UtRegisterTest("DetectDnsQueryTest02", DetectDnsQueryTest02);
|
|
|
|
UtRegisterTest("DetectDnsQueryTest03 -- tcp", DetectDnsQueryTest03);
|
|
|
|
UtRegisterTest("DetectDnsQueryTest04 -- tcp splicing",
|
|
|
|
DetectDnsQueryTest04);
|
|
|
|
UtRegisterTest("DetectDnsQueryTest05 -- tcp splicing/multi tx",
|
|
|
|
DetectDnsQueryTest05);
|
|
|
|
UtRegisterTest("DetectDnsQueryTest06 -- pcre", DetectDnsQueryTest06);
|
|
|
|
UtRegisterTest("DetectDnsQueryTest07 -- app layer event",
|
|
|
|
DetectDnsQueryTest07);
|
|
|
|
|
|
|
|
UtRegisterTest("DetectDnsQueryIsdataatParseTest",
|
|
|
|
DetectDnsQueryIsdataatParseTest);
|
|
|
|
#endif
|
|
|
|
}
|