Fix drop (and other actions) not being applied to thresholded packets. Bug #613.

pull/152/merge
Victor Julien 13 years ago
parent bca1b7c52a
commit 80d62b59ec

@ -536,7 +536,102 @@ end:
return result;
}
/**
* \test drops
*/
static int DetectDetectionFilterTestSig3(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (msg:\"detection_filter Test 2\"; detection_filter: track by_dst, count 2, seconds 60; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 3 && drops == 3)
result = 1;
else {
if (alerts != 3)
printf("alerts: %d != 3: ", alerts);
if (drops != 3)
printf("drops: %d != 3: ", drops);
}
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
#endif /* UNITTESTS */
void DetectDetectionFilterRegisterTests(void) {
@ -549,6 +644,7 @@ void DetectDetectionFilterRegisterTests(void) {
UtRegisterTest("DetectDetectionFilterTestParse06", DetectDetectionFilterTestParse06, 0);
UtRegisterTest("DetectDetectionFilterTestSig1", DetectDetectionFilterTestSig1, 1);
UtRegisterTest("DetectDetectionFilterTestSig2", DetectDetectionFilterTestSig2, 1);
UtRegisterTest("DetectDetectionFilterTestSig3", DetectDetectionFilterTestSig3, 1);
#endif /* UNITTESTS */
}

@ -54,6 +54,7 @@ PacketAlert *PacketAlertGetTag(void) {
/**
* \brief Handle a packet and check if needs a threshold logic
* Also apply rule action if necessary.
*
* \param de_ctx Detection Context
* \param sig Signature pointer
@ -78,16 +79,18 @@ static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det
td = SigGetThresholdTypeIter(s, p, &sm);
if (td != NULL) {
SCLogDebug("td %p", td);
/* PacketAlertThreshold returns 2 if the alert is suppressed but
* we do need to apply rule actions to the packet. */
ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s);
if (ret == 0) {
if (ret == 0 || ret == 2) {
/* It doesn't match threshold, remove it */
PacketAlertRemove(p, pos);
break;
SCReturnInt(ret);
}
}
} while (sm != NULL);
SCReturnInt(ret);
SCReturnInt(1);
}
@ -126,8 +129,11 @@ int PacketAlertRemove(Packet *p, uint16_t pos)
{
uint16_t i = 0;
int match = 0;
if (pos > p->alerts.cnt)
if (pos > p->alerts.cnt) {
SCLogDebug("removing %u failed, pos > cnt %u", pos, p->alerts.cnt);
return 0;
}
for (i = pos; i <= p->alerts.cnt - 1; i++) {
memcpy(&p->alerts.alerts[i], &p->alerts.alerts[i + 1], sizeof(PacketAlert));
@ -198,20 +204,16 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
*/
void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) {
SCEnter();
int i = 0;
Signature *s = NULL;
SigMatch *sm = NULL;
for (i = 0; i < p->alerts.cnt; i++) {
while (i < p->alerts.cnt) {
SCLogDebug("Sig->num: %"PRIu16, p->alerts.alerts[i].num);
s = de_ctx->sig_array[p->alerts.alerts[i].num];
int res = PacketAlertHandle(de_ctx, det_ctx, s, p, i);
/* Thresholding might remove one alert */
if (res == 0) {
i--;
} else {
if (res > 0) {
/* Now, if we have an alert, we have to check if we want
* to tag this session or src/dst host */
sm = s->sm_lists[DETECT_SM_LIST_TMATCH];
@ -267,9 +269,16 @@ void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
FLOWLOCK_UNLOCK(p->flow);
}
}
/* Because we removed the alert from the array, we should
* have compacted the array and decreased cnt by one, so
* process again the same position (with different alert now) */
/* Thresholding removes this alert */
if (res == 0 || res == 2) {
PacketAlertRemove(p, i);
if (p->alerts.cnt == 0)
break;
} else {
i++;
}
}
/* At this point, we should have all the new alerts. Now check the tag

@ -1074,11 +1074,14 @@ void IPOnlyMatchPacket(ThreadVars *tv,
(void)sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm);
}
}
if ( !(s->flags & SIG_FLAG_NOALERT)) {
if (!(s->flags & SIG_FLAG_NOALERT)) {
if (s->action & ACTION_DROP)
PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW);
else
PacketAlertAppend(det_ctx, s, p, 0);
} else {
/* apply actions for noalert/rule suppressed as well */
p->action |= s->action;
}
}
}

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2012 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
@ -201,6 +201,11 @@ static DetectThresholdEntry *ThresholdHostLookupEntry(Host *h, uint32_t sid, uin
return e;
}
/**
* \retval 2 silent match (no alert but apply actions)
* \retval 1 normal match
* \retval 0 no match
*/
int ThresholdHandlePacketHost(Host *h, Packet *p, DetectThresholdData *td, uint32_t sid, uint32_t gid) {
int ret = 0;
@ -218,6 +223,8 @@ int ThresholdHandlePacketHost(Host *h, Packet *p, DetectThresholdData *td, uint3
if (lookup_tsh->current_count <= td->count) {
ret = 1;
} else {
ret = 2;
}
} else {
lookup_tsh->tv_sec1 = p->ts.tv_sec;
@ -286,6 +293,9 @@ int ThresholdHandlePacketHost(Host *h, Packet *p, DetectThresholdData *td, uint3
lookup_tsh->current_count++;
if (lookup_tsh->current_count == td->count) {
ret = 1;
} else if (lookup_tsh->current_count > td->count) {
/* silent match */
ret = 2;
}
} else {
/* expired, so reset */
@ -462,6 +472,8 @@ int ThresholdHandlePacketHost(Host *h, Packet *p, DetectThresholdData *td, uint3
}
if (res == 0)
ret = 1;
else
ret = 2; /* suppressed but still need actions */
break;
}
default:
@ -564,6 +576,7 @@ static int ThresholdHandlePacketRule(DetectEngineCtx *de_ctx, Packet *p, DetectT
* \param p Packet structure
* \param s Signature structure
*
* \retval 2 silent match (no alert but apply actions)
* \retval 1 alert on this event
* \retval 0 do not alert on this event
*/

@ -817,8 +817,10 @@ static int DetectThresholdTestSig5(void) {
if(alerts == 10)
result = 1;
else
else {
printf("alerts %d != 10: ", alerts);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
@ -914,6 +916,565 @@ end:
HostShutdown();
return result;
}
/**
* \test Test drop action being set even if thresholded
*/
static int DetectThresholdTestSig7(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 1, seconds 300; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 1 && drops == 6)
result = 1;
else {
if (alerts != 1)
printf("alerts: %d != 1: ", alerts);
if (drops != 6)
printf("drops: %d != 6: ", drops);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
/**
* \test Test drop action being set even if thresholded
*/
static int DetectThresholdTestSig8(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 2, seconds 300; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 2 && drops == 6)
result = 1;
else {
if (alerts != 1)
printf("alerts: %d != 1: ", alerts);
if (drops != 6)
printf("drops: %d != 6: ", drops);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
/**
* \test Test drop action being set even if thresholded
*/
static int DetectThresholdTestSig9(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 3, seconds 100; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 2 && drops == 2)
result = 1;
else {
if (alerts != 2)
printf("alerts: %d != 2: ", alerts);
if (drops != 2)
printf("drops: %d != 2: ", drops);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
/**
* \test Test drop action being set even if thresholded
*/
static int DetectThresholdTestSig10(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 5, seconds 300; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 1 && drops == 1)
result = 1;
else {
if (alerts != 1)
printf("alerts: %d != 1: ", alerts);
if (drops != 1)
printf("drops: %d != 1: ", drops);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
/**
* \test Test drop action being set even if thresholded
*/
static int DetectThresholdTestSig11(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type both, track by_src, count 3, seconds 300; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 1 && drops == 4)
result = 1;
else {
if (alerts != 1)
printf("alerts: %d != 1: ", alerts);
if (drops != 4)
printf("drops: %d != 4: ", drops);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
/**
* \test Test drop action being set even if thresholded
*/
static int DetectThresholdTestSig12(void) {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
int drops = 0;
struct timeval ts;
HostInitConfig(HOST_QUIET);
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type both, track by_src, count 5, seconds 300; sid:10;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts = PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
TimeSetIncrementTime(200);
TimeGet(&p->ts);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
alerts += PacketAlertCheck(p, 10);
drops += ((p->action & ACTION_DROP)?1:0);
p->action = 0;
if (alerts == 1 && drops == 2)
result = 1;
else {
if (alerts != 1)
printf("alerts: %d != 1: ", alerts);
if (drops != 2)
printf("drops: %d != 2: ", drops);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1);
HostShutdown();
return result;
}
#endif /* UNITTESTS */
void ThresholdRegisterTests(void) {
@ -929,6 +1490,12 @@ void ThresholdRegisterTests(void) {
UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4, 1);
UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5, 1);
UtRegisterTest("DetectThresholdTestSig6Ticks", DetectThresholdTestSig6Ticks, 1);
UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7, 1);
UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8, 1);
UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9, 1);
UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10, 1);
UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11, 1);
UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12, 1);
#endif /* UNITTESTS */
}

@ -1858,6 +1858,9 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, alert_flags);
} else {
/* apply actions even if not alerting */
p->action |= s->action;
}
next:
DetectReplaceFree(det_ctx->replist);

@ -2169,6 +2169,213 @@ end:
return result;
}
/**
* \test Check if the suppress rules work
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int SCThresholdConfTest15(void)
{
Signature *sig = NULL;
int result = 0;
FILE *fd = NULL;
HostInitConfig(HOST_QUIET);
Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10",
"192.168.0.100", 1234, 24);
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&th_v, 0, sizeof(th_v));
struct timeval ts;
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL || p == NULL)
return result;
de_ctx->flags |= DE_QUIET;
sig = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any any (msg:\"suppress test\"; content:\"lalala\"; gid:1; sid:10000;)");
if (sig == NULL) {
goto end;
}
fd = SCThresholdConfGenerateValidDummyFD11();
SCThresholdConfInitContext(de_ctx,fd);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
/* 10000 shouldn't match */
if (PacketAlertCheck(p, 10000) != 0) {
printf("sid 10000 should not have alerted: ");
goto end;
}
/* however, it should have set the drop flag */
if (!(p->action & ACTION_DROP)) {
printf("sid 10000 should have set DROP flag even if suppressed: ");
goto end;
}
result = 1;
end:
UTHFreePacket(p);
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
HostShutdown();
return result;
}
/**
* \test Check if the suppress rules work
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int SCThresholdConfTest16(void)
{
Signature *sig = NULL;
int result = 0;
FILE *fd = NULL;
HostInitConfig(HOST_QUIET);
Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.1.1",
"192.168.0.100", 1234, 24);
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&th_v, 0, sizeof(th_v));
struct timeval ts;
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL || p == NULL)
return result;
de_ctx->flags |= DE_QUIET;
sig = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any any (msg:\"suppress test\"; gid:1; sid:1000;)");
if (sig == NULL) {
goto end;
}
fd = SCThresholdConfGenerateValidDummyFD11();
SCThresholdConfInitContext(de_ctx,fd);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
/* 10000 shouldn't match */
if (PacketAlertCheck(p, 1000) != 0) {
printf("sid 1000 should not have alerted: ");
goto end;
}
/* however, it should have set the drop flag */
if (!(p->action & ACTION_DROP)) {
printf("sid 1000 should have set DROP flag even if suppressed: ");
goto end;
}
result = 1;
end:
UTHFreePacket(p);
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
HostShutdown();
return result;
}
/**
* \test Check if the suppress rules work - ip only rule
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int SCThresholdConfTest17(void)
{
Signature *sig = NULL;
int result = 0;
FILE *fd = NULL;
HostInitConfig(HOST_QUIET);
Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10",
"192.168.0.100", 1234, 24);
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&th_v, 0, sizeof(th_v));
struct timeval ts;
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL || p == NULL)
return result;
de_ctx->flags |= DE_QUIET;
sig = de_ctx->sig_list = SigInit(de_ctx,"drop tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:10000;)");
if (sig == NULL) {
goto end;
}
fd = SCThresholdConfGenerateValidDummyFD11();
SCThresholdConfInitContext(de_ctx,fd);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
/* 10000 shouldn't match */
if (PacketAlertCheck(p, 10000) != 0) {
printf("sid 10000 should not have alerted: ");
goto end;
}
/* however, it should have set the drop flag */
if (!(p->action & ACTION_DROP)) {
printf("sid 10000 should have set DROP flag even if suppressed: ");
goto end;
}
result = 1;
end:
UTHFreePacket(p);
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
HostShutdown();
return result;
}
#endif /* UNITTESTS */
/**
@ -2191,6 +2398,9 @@ void SCThresholdConfRegisterTests(void)
UtRegisterTest("SCThresholdConfTest12 - event_filter", SCThresholdConfTest12, 1);
UtRegisterTest("SCThresholdConfTest13", SCThresholdConfTest13, 1);
UtRegisterTest("SCThresholdConfTest14 - suppress", SCThresholdConfTest14, 1);
UtRegisterTest("SCThresholdConfTest15 - suppress drop", SCThresholdConfTest15, 1);
UtRegisterTest("SCThresholdConfTest16 - suppress drop", SCThresholdConfTest16, 1);
UtRegisterTest("SCThresholdConfTest17 - suppress drop", SCThresholdConfTest17, 1);
#endif /* UNITTESTS */
}

Loading…
Cancel
Save