Make sure decoder event rules are inspected even if the packet is invalid and has no addesses or proto. Update fast log and alert debug log to display the alerts. Fixes #179.

remotes/origin/master-1.0.x
Victor Julien 15 years ago
parent 92858a211d
commit d41b5645ef

@ -323,12 +323,57 @@ TmEcode AlertDebugLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq
return TM_ECODE_OK; return TM_ECODE_OK;
} }
TmEcode AlertDebugLogDecoderEvent(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
AlertDebugLogThread *aft = (AlertDebugLogThread *)data;
int i;
char timebuf[64];
if (p->alerts.cnt == 0)
return TM_ECODE_OK;
CreateTimeString(&p->ts, timebuf, sizeof(timebuf));
SCMutexLock(&aft->file_ctx->fp_mutex);
fprintf(aft->file_ctx->fp, "+================\n");
fprintf(aft->file_ctx->fp, "TIME: %s\n", timebuf);
if (p->pcap_cnt > 0) {
fprintf(aft->file_ctx->fp, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt);
}
fprintf(aft->file_ctx->fp, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt);
for (i = 0; i < p->alerts.cnt; i++) {
PacketAlert *pa = &p->alerts.alerts[i];
fprintf(aft->file_ctx->fp, "ALERT MSG [%02d]: %s\n", i, pa->msg);
fprintf(aft->file_ctx->fp, "ALERT GID [%02d]: %" PRIu32 "\n", i, pa->gid);
fprintf(aft->file_ctx->fp, "ALERT SID [%02d]: %" PRIu32 "\n", i, pa->sid);
fprintf(aft->file_ctx->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->rev);
fprintf(aft->file_ctx->fp, "ALERT CLASS [%02d]: %s\n", i, pa->class_msg);
fprintf(aft->file_ctx->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->prio);
}
aft->file_ctx->alerts += p->alerts.cnt;
fprintf(aft->file_ctx->fp, "PACKET LEN: %" PRIu32 "\n", p->pktlen);
fprintf(aft->file_ctx->fp, "PACKET:\n");
PrintRawDataFp(aft->file_ctx->fp, p->pkt, p->pktlen);
fflush(aft->file_ctx->fp);
SCMutexUnlock(&aft->file_ctx->fp_mutex);
return TM_ECODE_OK;
}
TmEcode AlertDebugLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) TmEcode AlertDebugLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{ {
if (PKT_IS_IPV4(p)) { if (PKT_IS_IPV4(p)) {
return AlertDebugLogIPv4(tv, p, data, pq, postpq); return AlertDebugLogIPv4(tv, p, data, pq, postpq);
} else if (PKT_IS_IPV6(p)) { } else if (PKT_IS_IPV6(p)) {
return AlertDebugLogIPv6(tv, p, data, pq, postpq); return AlertDebugLogIPv6(tv, p, data, pq, postpq);
} else {
return AlertDebugLogDecoderEvent(tv, p, data, pq, postpq);
} }
return TM_ECODE_OK; return TM_ECODE_OK;

@ -55,6 +55,7 @@
#include "util-mpm-b2g-cuda.h" #include "util-mpm-b2g-cuda.h"
#include "util-cuda-handlers.h" #include "util-cuda-handlers.h"
#include "util-privs.h" #include "util-privs.h"
#include "util-print.h"
#define DEFAULT_LOG_FILENAME "fast.log" #define DEFAULT_LOG_FILENAME "fast.log"
@ -202,12 +203,57 @@ TmEcode AlertFastLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
return TM_ECODE_OK; return TM_ECODE_OK;
} }
TmEcode AlertFastLogDecoderEvent(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
AlertFastLogThread *aft = (AlertFastLogThread *)data;
int i;
Reference *ref = NULL;
char timebuf[64];
if (p->alerts.cnt == 0)
return TM_ECODE_OK;
CreateTimeString(&p->ts, timebuf, sizeof(timebuf));
SCMutexLock(&aft->file_ctx->fp_mutex);
aft->file_ctx->alerts += p->alerts.cnt;
for (i = 0; i < p->alerts.cnt; i++) {
PacketAlert *pa = &p->alerts.alerts[i];
fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %" PRIu32 "] [**] [Raw pkt: ",
timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio);
PrintRawLineHexFp(aft->file_ctx->fp, p->pkt, p->pktlen < 32 ? p->pktlen : 32);
if (p->pcap_cnt != 0) {
fprintf(aft->file_ctx->fp, "] [pcap file packet: %"PRIu64"]", p->pcap_cnt);
}
if(pa->references != NULL) {
fprintf(aft->file_ctx->fp," ");
for (ref = pa->references; ref != NULL; ref = ref->next) {
fprintf(aft->file_ctx->fp,"[Xref => %s%s]", ref->key, ref->reference);
}
}
fprintf(aft->file_ctx->fp,"\n");
fflush(aft->file_ctx->fp);
}
SCMutexUnlock(&aft->file_ctx->fp_mutex);
return TM_ECODE_OK;
}
TmEcode AlertFastLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) TmEcode AlertFastLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{ {
if (PKT_IS_IPV4(p)) { if (PKT_IS_IPV4(p)) {
return AlertFastLogIPv4(tv, p, data, pq, postpq); return AlertFastLogIPv4(tv, p, data, pq, postpq);
} else if (PKT_IS_IPV6(p)) { } else if (PKT_IS_IPV6(p)) {
return AlertFastLogIPv6(tv, p, data, pq, postpq); return AlertFastLogIPv6(tv, p, data, pq, postpq);
} else {
return AlertFastLogDecoderEvent(tv, p, data, pq, postpq);
} }
return TM_ECODE_OK; return TM_ECODE_OK;

@ -59,6 +59,7 @@ void DetectDecodeEventRegister (void) {
sigmatch_table[DETECT_DECODE_EVENT].Setup = DetectDecodeEventSetup; sigmatch_table[DETECT_DECODE_EVENT].Setup = DetectDecodeEventSetup;
sigmatch_table[DETECT_DECODE_EVENT].Free = NULL; sigmatch_table[DETECT_DECODE_EVENT].Free = NULL;
sigmatch_table[DETECT_DECODE_EVENT].RegisterTests = DecodeEventRegisterTests; sigmatch_table[DETECT_DECODE_EVENT].RegisterTests = DecodeEventRegisterTests;
sigmatch_table[DETECT_DECODE_EVENT].flags |= SIGMATCH_DEONLY_COMPAT;
const char *eb; const char *eb;
int eo; int eo;

@ -520,6 +520,12 @@ SigGroupHead *SigMatchSignaturesGetSgh(DetectEngineCtx *de_ctx, DetectEngineThre
int f; int f;
SigGroupHead *sgh = NULL; SigGroupHead *sgh = NULL;
/* if the packet proto is 0 (not set), we're inspecting it against
* the decoder events sgh we have. */
if (p->proto == 0 && p->events.cnt > 0) {
SCReturnPtr(de_ctx->decoder_event_sgh, "SigGroupHead");
}
/* select the flow_gh */ /* select the flow_gh */
if (p->flowflags & FLOW_PKT_TOCLIENT) if (p->flowflags & FLOW_PKT_TOCLIENT)
f = 0; f = 0;
@ -1222,7 +1228,9 @@ iponly:
} }
return 1; return 1;
} }
/** /**
* \internal
* \brief Check if the initialized signature is inspecting the packet payload * \brief Check if the initialized signature is inspecting the packet payload
* \param de_ctx detection engine ctx * \param de_ctx detection engine ctx
* \param s the signature * \param s the signature
@ -1250,6 +1258,43 @@ static int SignatureIsInspectingPayload(DetectEngineCtx *de_ctx, Signature *s) {
return 0; return 0;
} }
/**
* \internal
* \brief check if a signature is decoder event matching only
* \param de_ctx detection engine
* \param s the signature to test
* \retval 0 not a DEOnly sig
* \retval 1 DEOnly sig
*/
static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->pmatch != NULL)
return 0;
if (s->umatch != NULL)
return 0;
if (s->amatch != NULL)
return 0;
SigMatch *sm = s->match;
if (sm == NULL)
goto deonly;
for ( ;sm != NULL; sm = sm->next) {
if ( !(sigmatch_table[sm->type].flags & SIGMATCH_DEONLY_COMPAT))
return 0;
}
deonly:
if (!(de_ctx->flags & DE_QUIET)) {
SCLogDebug("DE-ONLY (%" PRIu32 "): source %s, dest %s", s->id,
s->flags & SIG_FLAG_SRC_ANY ? "ANY" : "SET",
s->flags & SIG_FLAG_DST_ANY ? "ANY" : "SET");
}
return 1;
}
/** /**
* \brief Add all signatures to their own source address group * \brief Add all signatures to their own source address group
* *
@ -1303,6 +1348,9 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) {
cnt_payload++; cnt_payload++;
SCLogDebug("Signature %"PRIu32" is considered \"Payload inspecting\"", tmp_s->id); SCLogDebug("Signature %"PRIu32" is considered \"Payload inspecting\"", tmp_s->id);
} else if (SignatureIsDEOnly(de_ctx, tmp_s) == 1) {
tmp_s->flags |= SIG_FLAG_DEONLY;
SCLogDebug("Signature %"PRIu32" is considered \"Decoder Event only\"", tmp_s->id);
} }
if (tmp_s->flags & SIG_FLAG_APPLAYER) { if (tmp_s->flags & SIG_FLAG_APPLAYER) {
@ -1829,6 +1877,15 @@ error:
return -1; return -1;
} }
/**
* \internal
* \brief add a decoder event signature to the detection engine ctx
*/
static void DetectEngineAddDecoderEventSig(DetectEngineCtx *de_ctx, Signature *s) {
SCLogDebug("adding signature %"PRIu32" to the decoder event sgh", s->id);
SigGroupHeadAppendSig(de_ctx, &de_ctx->decoder_event_sgh, s);
}
/** /**
* \brief Fill the global src group head, with the sigs included * \brief Fill the global src group head, with the sigs included
* *
@ -1866,13 +1923,15 @@ int SigAddressPrepareStage2(DetectEngineCtx *de_ctx) {
/* now for every rule add the source group to our temp lists */ /* now for every rule add the source group to our temp lists */
for (tmp_s = de_ctx->sig_list; tmp_s != NULL; tmp_s = tmp_s->next) { for (tmp_s = de_ctx->sig_list; tmp_s != NULL; tmp_s = tmp_s->next) {
//printf("SigAddressPrepareStage2 tmp_s->id %u\n", tmp_s->id); SCLogDebug("tmp_s->id %"PRIu32, tmp_s->id);
if (!(tmp_s->flags & SIG_FLAG_IPONLY)) { if (tmp_s->flags & SIG_FLAG_IPONLY) {
IPOnlyAddSignature(de_ctx, &de_ctx->io_ctx, tmp_s);
} else if (tmp_s->flags & SIG_FLAG_DEONLY) {
DetectEngineAddDecoderEventSig(de_ctx, tmp_s);
} else {
DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_INET); DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_INET);
DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_INET6); DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_INET6);
DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_UNSPEC); DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_UNSPEC);
} else {
IPOnlyAddSignature(de_ctx, &de_ctx->io_ctx, tmp_s);
} }
sigs++; sigs++;
@ -2521,6 +2580,15 @@ error:
return -1; return -1;
} }
static void DetectEngineBuildDecoderEventSgh(DetectEngineCtx *de_ctx) {
if (de_ctx->decoder_event_sgh == NULL)
return;
uint32_t max_idx = DetectEngineGetMaxSigId(de_ctx);
SigGroupHeadSetSigCnt(de_ctx->decoder_event_sgh, max_idx);
SigGroupHeadBuildMatchArray(de_ctx, de_ctx->decoder_event_sgh, max_idx);
}
int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) {
int r; int r;
@ -2587,6 +2655,9 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) {
} }
} }
/* prepare the decoder event sgh */
DetectEngineBuildDecoderEventSgh(de_ctx);
/* cleanup group head (uri)content_array's */ /* cleanup group head (uri)content_array's */
SigGroupHeadFreeMpmArrays(de_ctx); SigGroupHeadFreeMpmArrays(de_ctx);
/* cleanup group head sig arrays */ /* cleanup group head sig arrays */
@ -2716,6 +2787,10 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx) {
SigGroupHeadBuildHeadArray(de_ctx, sgh); SigGroupHeadBuildHeadArray(de_ctx, sgh);
} }
if (de_ctx->decoder_event_sgh != NULL) {
SigGroupHeadBuildHeadArray(de_ctx, de_ctx->decoder_event_sgh);
}
SCFree(de_ctx->sgh_array); SCFree(de_ctx->sgh_array);
de_ctx->sgh_array_cnt = 0; de_ctx->sgh_array_cnt = 0;
de_ctx->sgh_array_size = 0; de_ctx->sgh_array_size = 0;
@ -2740,7 +2815,7 @@ int SigAddressPrepareStage5(DetectEngineCtx *de_ctx) {
for (f = 0; f < FLOW_STATES; f++) { for (f = 0; f < FLOW_STATES; f++) {
printf("\n"); printf("\n");
for (proto = 0; proto < 256; proto++) { for (proto = 0; proto < 256; proto++) {
if (proto != 1) if (proto != 0)
continue; continue;
for (global_src_gr = de_ctx->flow_gh[f].src_gh[proto]->ipv4_head; global_src_gr != NULL; for (global_src_gr = de_ctx->flow_gh[f].src_gh[proto]->ipv4_head; global_src_gr != NULL;

@ -487,6 +487,10 @@ typedef struct DetectEngineCtx_ {
struct SigGroupHead_ **sgh_array; struct SigGroupHead_ **sgh_array;
uint32_t sgh_array_cnt; uint32_t sgh_array_cnt;
uint32_t sgh_array_size; uint32_t sgh_array_size;
/** sgh for signatures that match against invalid packets. In those cases
* we can't lookup by proto, address, port as we don't have these */
struct SigGroupHead_ *decoder_event_sgh;
} DetectEngineCtx; } DetectEngineCtx;
/* Engine groups profiles (low, medium, high, custom) */ /* Engine groups profiles (low, medium, high, custom) */

@ -27,6 +27,28 @@
#include "util-error.h" #include "util-error.h"
#include "util-debug.h" #include "util-debug.h"
/**
* \brief print a buffer as hex on a single line
*
* Prints in the format "00 AA BB"
*
* \param fp FILE pointer to print to
* \param buf buffer to print from
* \param buflen length of the input buffer
*/
void PrintRawLineHexFp(FILE *fp, uint8_t *buf, uint32_t buflen)
{
char nbuf[2048] = "";
char temp[5] = "";
uint32_t u = 0;
for (u = 0; u < buflen; u++) {
snprintf(temp, sizeof(temp), "%02X ", buf[u]);
strlcat(nbuf, temp, sizeof(nbuf));
}
fprintf(fp, "%s", nbuf);
}
void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen) void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen)
{ {
char nbuf[2048] = ""; char nbuf[2048] = "";

@ -24,8 +24,9 @@
#ifndef __UTIL_PRINT_H__ #ifndef __UTIL_PRINT_H__
#define __UTIL_PRINT_H__ #define __UTIL_PRINT_H__
void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen); void PrintRawLineHexFp(FILE *, uint8_t *, uint32_t);
void PrintRawDataFp(FILE *fp, uint8_t *buf, uint32_t buflen); void PrintRawUriFp(FILE *, uint8_t *, uint32_t);
void PrintRawDataFp(FILE *, uint8_t *, uint32_t);
#endif /* __UTIL_PRINT_H__ */ #endif /* __UTIL_PRINT_H__ */

Loading…
Cancel
Save