Support for sigs with both pkt and applayer detect

Sets a flowbit with the sig id if the packet matches match. Checks
on that if the app layer matches match. Currently misuses the
flowbits api for this in a way that needs fixing.
remotes/origin/master-1.0.x
Victor Julien 16 years ago
parent 0419ad7c9a
commit 9fd46e9425

@ -71,7 +71,7 @@ int DetectHttpCookieMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
DetectHttpCookieData *co = (DetectHttpCookieData *)m->ctx;
HtpState *htp_state = (HtpState *)state;
if (htp_state == NULL) {
SCLogDebug("No HTTP layer state has been received, so no match!!");
SCLogDebug("no HTTP layer state has been received, so no match");
return 0;
}
@ -86,16 +86,15 @@ int DetectHttpCookieMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
htp_header_t *h = NULL;
h = (htp_header_t *)table_getc(tx->request_headers, "Cookie");
if (h == NULL) {
SCLogDebug("No HTTP Cookie hearder in the received request");
SCLogDebug("no HTTP Cookie hearder in the received request");
ret = 0;
}
if (BinSearch(bstr_ptr(h->value), bstr_size(h->value), co->data,
co->data_len) != NULL)
{
SCLogDebug("Match has been found in received request and given http_"
"cookie rule\n");
SCLogDebug("match has been found in received request and given http_"
"cookie rule");
ret = 1;
}
SCMutexUnlock(&f->m);
@ -139,7 +138,7 @@ int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
SCLogWarning(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside "
"the rule, without a content context. Please use a "
"content keyword before using http_cookie");
return -1;
return -1;
}
}
@ -385,9 +384,9 @@ static int DetectHttpCookieSigTest01(void) {
goto end;
}
s = s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP "
s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP "
"cookie\"; content:\"go\"; http_cookie; sid:2;)");
if (s == NULL) {
if (s->next == NULL) {
goto end;
}
@ -414,8 +413,11 @@ static int DetectHttpCookieSigTest01(void) {
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (!(PacketAlertCheck(&p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
} else if (PacketAlertCheck(&p, 2)) {
}
if (PacketAlertCheck(&p, 2)) {
printf("sid 2 matched but shouldn't: ");
goto end;
}

@ -634,6 +634,23 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
}
}
/* set the packet and app layer flags, but only if the
* app layer flag wasn't already set in which case we
* only consider the app layer */
if (!(sig->flags & SIG_FLAG_APPLAYER)) {
if (sig->match != NULL) {
SigMatch *sm = sig->match;
for ( ; sm != NULL; sm = sm->next) {
if (sigmatch_table[sm->type].AppLayerMatch != NULL)
sig->flags |= SIG_FLAG_APPLAYER;
if (sigmatch_table[sm->type].Match != NULL)
sig->flags |= SIG_FLAG_PACKET;
}
} else {
sig->flags |= SIG_FLAG_PACKET;
}
}
return sig;
error:

@ -221,7 +221,6 @@ int DetectTlsVersionSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, c
sm->ctx = (void *)tls;
SigMatchAppend(s,m,sm);
return 0;
error:
@ -329,47 +328,40 @@ static int DetectTlsVersionTestDetect01(void) {
int r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1, FALSE);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2, FALSE);
if (r != 0) {
printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3, FALSE);
if (r != 0) {
printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4, FALSE);
if (r != 0) {
printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
TlsState *tls_state = ssn.aldata[AlpGetStateIdx(ALPROTO_TLS)];
if (tls_state == NULL) {
printf("no tls state: ");
result = 0;
goto end;
}
if (tls_state->client_content_type != 0x16) {
printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, tls_state->client_content_type);
result = 0;
goto end;
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
result = 0;
goto end;
}
@ -395,7 +387,7 @@ end:
}
static int DetectTlsVersionTestDetect02(void) {
int result = 1;
int result = 0;
Flow f;
uint8_t tlsbuf1[] = { 0x16 };
uint32_t tlslen1 = sizeof(tlsbuf1);
@ -426,6 +418,7 @@ static int DetectTlsVersionTestDetect02(void) {
f.protoctx = (void *)&ssn;
p.flow = &f;
p.flowflags |= FLOW_PKT_TOSERVER;
ssn.alproto = ALPROTO_TLS;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
@ -445,54 +438,159 @@ static int DetectTlsVersionTestDetect02(void) {
int r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1, FALSE);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2, FALSE);
if (r != 0) {
printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3, FALSE);
if (r != 0) {
printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4, FALSE);
if (r != 0) {
printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
TlsState *tls_state = ssn.aldata[AlpGetStateIdx(ALPROTO_TLS)];
if (tls_state == NULL) {
printf("no tls state: ");
result = 0;
goto end;
}
if (tls_state->client_content_type != 0x16) {
printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, tls_state->client_content_type);
result = 0;
goto end;
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (PacketAlertCheck(&p, 1)) {
if (!(PacketAlertCheck(&p, 1))) {
printf("signature 1 didn't match while it should have: ");
goto end;
}
result = 1;
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectTlsVersionTestDetect03(void) {
int result = 0;
Flow f;
uint8_t tlsbuf1[] = { 0x16 };
uint32_t tlslen1 = sizeof(tlsbuf1);
uint8_t tlsbuf2[] = { 0x03 };
uint32_t tlslen2 = sizeof(tlsbuf2);
uint8_t tlsbuf3[] = { 0x01 };
uint32_t tlslen3 = sizeof(tlsbuf3);
uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 };
uint32_t tlslen4 = sizeof(tlsbuf4);
TcpSession ssn;
Packet p;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
memset(&th_v, 0, sizeof(th_v));
memset(&p, 0, sizeof(p));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.payload = tlsbuf4;
p.payload_len = tlslen4;
p.proto = IPPROTO_TCP;
StreamL7DataPtrInit(&ssn,StreamL7GetStorageSize());
f.protoctx = (void *)&ssn;
p.flow = &f;
p.flowflags |= FLOW_PKT_TOSERVER;
ssn.alproto = ALPROTO_TLS;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"TLS\"; tls.version:1.0; content:\"|01 00 00 AD|\"; sid:1;)");
if (s == NULL) {
goto end;
}
if (s->flags & SIG_FLAG_PACKET) {
SCLogDebug("SIG_FLAG_PACKET flags");
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1, FALSE);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2, FALSE);
if (r != 0) {
printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3, FALSE);
if (r != 0) {
printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
goto end;
}
r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4, FALSE);
if (r != 0) {
printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
goto end;
}
TlsState *tls_state = ssn.aldata[AlpGetStateIdx(ALPROTO_TLS)];
if (tls_state == NULL) {
printf("no tls state: ");
goto end;
}
if (tls_state->client_content_type != 0x16) {
printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, tls_state->client_content_type);
goto end;
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (!(PacketAlertCheck(&p, 1))) {
printf("signature 1 didn't match while it should have: ");
goto end;
}
@ -519,6 +617,7 @@ void DetectTlsVersionRegisterTests(void) {
UtRegisterTest("DetectTlsVersionTestParse02", DetectTlsVersionTestParse02, 1);
UtRegisterTest("DetectTlsVersionTestDetect01", DetectTlsVersionTestDetect01, 1);
UtRegisterTest("DetectTlsVersionTestDetect02", DetectTlsVersionTestDetect02, 1);
UtRegisterTest("DetectTlsVersionTestDetect03", DetectTlsVersionTestDetect03, 1);
#endif /* UNITTESTS */
}

@ -357,6 +357,8 @@ int PacketAlertAppend(Packet *p, uint32_t gid, uint32_t sid, uint8_t rev, uint8_
{
/* XXX overflow check? */
SCLogDebug("sid %"PRIu32"", sid);
if (gid > 1)
p->alerts.alerts[p->alerts.cnt].gid = gid;
else
@ -425,6 +427,7 @@ inline SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx
SCReturnPtr(sgh, "SigGroupHead");
}
#include "flow-bit.h"
/** \brief application layer detection
*
* \param sgh signature group head for this proto/addrs/ports
@ -466,14 +469,17 @@ static int SigMatchSignaturesAppLayer(ThreadVars *th_v, DetectEngineCtx *de_ctx,
sig = sgh->match_array[idx];
s = de_ctx->sig_array[sig];
SCLogDebug("s->id %"PRIu32"", s->id);
/* only inspect app layer sigs here */
if (!(s->flags & SIG_FLAG_APPLAYER))
continue;
/* filter out the sigs that inspects the payload, if packet
no payload inspection flag is set*/
if ((p->flags & PKT_NOPAYLOAD_INSPECTION) && (s->flags & SIG_FLAG_PAYLOAD))
if ((p->flags & PKT_NOPAYLOAD_INSPECTION) && (s->flags & SIG_FLAG_PAYLOAD)) {
continue;
}
/* check the source & dst port in the sig */
if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) {
@ -503,7 +509,8 @@ static int SigMatchSignaturesAppLayer(ThreadVars *th_v, DetectEngineCtx *de_ctx,
continue;
}
/* if we don't have sigmatches at this point we're a match */
/* if we don't have sigmatches at this point we're a match
* XXX VJ can we ever get here? Applayer inspection w/o sigmatches */
if (s->match == NULL) {
fmatch = 1;
if (!(s->flags & SIG_FLAG_NOALERT)) {
@ -522,10 +529,13 @@ static int SigMatchSignaturesAppLayer(ThreadVars *th_v, DetectEngineCtx *de_ctx,
while (sm) {
if (sigmatch_table[sm->type].AppLayerMatch == NULL) {
/* if no match function we assume this sm is a match */
SCLogDebug("no app layer match function, sigmatch is (pkt)Match only");
match = 1;
} else {
match = sigmatch_table[sm->type].AppLayerMatch(th_v, det_ctx, p->flow, flags, alstate, s, sm);
SCLogDebug("sigmatch AppLayerMatch function returned match %"PRIu32"", match);
}
if (match) {
/* okay, try the next match */
sm = sm->next;
@ -533,12 +543,28 @@ static int SigMatchSignaturesAppLayer(ThreadVars *th_v, DetectEngineCtx *de_ctx,
/* only if the last matched as well, we have a hit */
if (sm == NULL) {
fmatch = 1;
//printf("DE : sig %" PRIu32 " matched\n", s->id);
SCLogDebug("DE : sig %" PRIu32 " matched", s->id);
if (!(s->flags & SIG_FLAG_NOALERT)) {
/* if the sig also has a packet portion see if that has matched already */
if (s->flags & SIG_FLAG_PACKET) {
SCLogDebug("checking sid %"PRIu32"", s->id);
if (FlowBitIsset(p->flow, s->id) ) {
SCLogDebug("flowbit sid %"PRIu32", isset", s->id);
PacketAlertAppend(p, 1, s->id, s->rev, s->prio, s->msg);
/* set verdict on packet */
p->action = s->action;
}
} else {
PacketAlertAppend(p, 1, s->id, s->rev, s->prio, s->msg);
PacketAlertHandle(de_ctx,s,p);
/* set verdict on packet */
p->action = s->action;
/* set verdict on packet */
p->action = s->action;
}
}
}
} else {
@ -635,8 +661,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
continue;
}
/* don't inspect app layer sigs here */
if (s->flags & SIG_FLAG_APPLAYER)
/* don't inspect app layer only sigs here */
if (!(s->flags & SIG_FLAG_PACKET))
continue;
/* filter out sigs that want pattern matches, but
@ -751,8 +777,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SCLogDebug("running match functions, sm %p", sm);
while (sm) {
/* if this sm has no Match function we assume it's a match */
if (sigmatch_table[sm->type].Match == NULL) {
/* if no match function we assume this sm is a match */
match = 1;
} else {
match = sigmatch_table[sm->type].Match(th_v, det_ctx, p, s, sm);
@ -765,10 +791,18 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (sm == NULL) {
fmatch = 1;
if (!(s->flags & SIG_FLAG_NOALERT)) {
SCLogDebug("sig matched, applayer flag set ? %s", s->flags & SIG_FLAG_APPLAYER ? "yes":"no");
PacketAlertHandle(de_ctx,s,p);
/* set verdict on packet */
p->action = s->action;
/* set flowbit for this match */
if (s->flags & SIG_FLAG_APPLAYER) {
SCLogDebug("setting flowbit for sig %"PRIu32"", s->id);
FlowBitSet(p->flow, s->id);
} else {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg);
/* set verdict on packet */
p->action = s->action;
}
}
}
} else {

@ -130,9 +130,11 @@ typedef struct DetectPort_ {
#define SIG_FLAG_PAYLOAD 0x0200 /**< signature is inspecting the packet payload */
#define SIG_FLAG_DSIZE 0x0400 /**< signature has a dsize setting */
#define SIG_FLAG_FLOW 0x0800 /**< signature has a flow setting */
#define SIG_FLAG_MPM_NEGCONTENT 0x1000 /**< sig has negative mpm portion(!content) */
#define SIG_FLAG_APPLAYER 0x2000 /**< signature applies to app layer instead of packets */
#define SIG_FLAG_BIDIREC 0x4000 /**< signature has bidirectional operator */
#define SIG_FLAG_PACKET 0x8000 /**< signature has matches against a packet (as opposed to app layer) */
/* Detection Engine flags */
#define DE_QUIET 0x01 /**< DE is quiet (esp for unittests) */

Loading…
Cancel
Save