Reference Support

remotes/origin/master-1.0.x
Breno Silva 15 years ago committed by Victor Julien
parent 65c9d00730
commit 89baf93a40

@ -29,6 +29,7 @@
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "detect-reference.h"
#include "util-classification-config.h"
#include "output.h"
@ -91,15 +92,16 @@ static void CreateTimeString (const struct timeval *ts, char *str, size_t size)
uint32_t sec = ts->tv_sec % 86400;
snprintf(str, size, "%02d/%02d/%02d-%02d:%02d:%02d.%06u",
t->tm_mon + 1, t->tm_mday, t->tm_year - 100,
sec / 3600, (sec % 3600) / 60, sec % 60,
(uint32_t) ts->tv_usec);
t->tm_mon + 1, t->tm_mday, t->tm_year - 100,
sec / 3600, (sec % 3600) / 60, sec % 60,
(uint32_t) ts->tv_usec);
}
TmEcode AlertFastLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)
{
AlertFastLogThread *aft = (AlertFastLogThread *)data;
int i;
References *sref = NULL;
char timebuf[64];
if (p->alerts.cnt == 0)
@ -119,8 +121,16 @@ TmEcode AlertFastLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)
inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n",
timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio, IPV4_GET_IPPROTO(p), srcip, p->sp, dstip, p->dp);
fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 " ",
timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio, IPV4_GET_IPPROTO(p), srcip, p->sp, dstip, p->dp);
if(pa->sigref != NULL) {
for (sref = pa->sigref; sref != NULL; sref = sref->next) {
fprintf(aft->file_ctx->fp,"[Xref => %s]",sref->reference);
}
}
fprintf(aft->file_ctx->fp,"\n");
fflush(aft->file_ctx->fp);
}
SCMutexUnlock(&aft->file_ctx->fp_mutex);
@ -132,6 +142,7 @@ TmEcode AlertFastLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)
{
AlertFastLogThread *aft = (AlertFastLogThread *)data;
int i;
References *sref = NULL;
char timebuf[64];
if (p->alerts.cnt == 0)
@ -150,10 +161,19 @@ TmEcode AlertFastLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)
inet_ntop(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
inet_ntop(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n",
fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 " ",
timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio, IPV6_GET_L4PROTO(p), srcip, p->sp, dstip, p->dp);
if(pa->sigref != NULL) {
for (sref = pa->sigref; sref != NULL; sref = sref->next) {
fprintf(aft->file_ctx->fp,"[Xref => %s]",sref->reference);
}
}
fprintf(aft->file_ctx->fp,"\n");
fflush(aft->file_ctx->fp);
}
fflush(aft->file_ctx->fp);
SCMutexUnlock(&aft->file_ctx->fp_mutex);
return TM_ECODE_OK;
@ -237,7 +257,7 @@ OutputCtx *AlertFastLogInitCtx(ConfNode *conf)
OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
if (output_ctx == NULL) {
SCLogError(SC_ERR_MEM_ALLOC,
"Failed to allocated memory for OutputCtx");
"Failed to allocated memory for OutputCtx");
exit(EXIT_FAILURE);
}
output_ctx->data = logfile_ctx;
@ -271,7 +291,7 @@ static int AlertFastLogOpenFileCtx(LogFileCtx *file_ctx, const char *filename)
if (file_ctx->fp == NULL) {
SCLogError(SC_ERR_FOPEN, "ERROR: failed to open %s: %s", log_path,
strerror(errno));
strerror(errno));
return -1;
}
@ -314,8 +334,8 @@ int AlertFastLogTest01()
SCClassConfDeleteDummyClassificationConfigFD();
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"FastLog test\"; content:GET; "
"Classtype:unknown; sid:1;)");
"(msg:\"FastLog test\"; content:GET; "
"Classtype:unknown; sid:1;)");
result = (de_ctx->sig_list != NULL);
SigGroupBuild(de_ctx);
@ -375,8 +395,8 @@ int AlertFastLogTest02()
SCClassConfDeleteDummyClassificationConfigFD();
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"FastLog test\"; content:GET; "
"Classtype:unknown; sid:1;)");
"(msg:\"FastLog test\"; content:GET; "
"Classtype:unknown; sid:1;)");
result = (de_ctx->sig_list != NULL);
if (result == 0) printf("sig parse failed: ");
@ -389,7 +409,7 @@ int AlertFastLogTest02()
result = (strcmp(p.alerts.alerts[0].class_msg, "Unknown Traffic") != 0);
if (result == 0) printf("p.alerts.alerts[0].class_msg %s: ", p.alerts.alerts[0].class_msg);
result = (strcmp(p.alerts.alerts[0].class_msg,
"Unknown are we") == 0);
"Unknown are we") == 0);
if (result == 0) printf("p.alerts.alerts[0].class_msg %s: ", p.alerts.alerts[0].class_msg);
} else {
result = 0;
@ -424,7 +444,7 @@ void AlertFastLogRegisterTests(void)
#ifdef __SC_CUDA_SUPPORT__
UtRegisterTest("AlertFastLogCudaContextInit",
SCCudaHlTestEnvCudaContextInit, 1);
SCCudaHlTestEnvCudaContextInit, 1);
#endif
UtRegisterTest("AlertFastLogTest01", AlertFastLogTest01, 1);
@ -432,7 +452,7 @@ void AlertFastLogRegisterTests(void)
#ifdef __SC_CUDA_SUPPORT__
UtRegisterTest("AlertFastLogCudaContextDeInit",
SCCudaHlTestEnvCudaContextDeInit, 1);
SCCudaHlTestEnvCudaContextDeInit, 1);
#endif
#endif /* UNITTESTS */

@ -34,6 +34,8 @@
#include "decode-raw.h"
#include "decode-vlan.h"
#include "detect-reference.h"
/* forward declaration */
struct DetectionEngineThreadCtx_;
@ -170,6 +172,7 @@ typedef struct PacketAlert_ {
uint8_t prio;
char *msg;
char *class_msg;
References *sigref;
} PacketAlert;
#define PACKET_ALERT_MAX 256

@ -53,7 +53,7 @@ void PacketAlertHandle(DetectEngineCtx *de_ctx, Signature *sig, Packet *p)
/* if have none just alert, otherwise handle thresholding */
if (td == NULL) {
PacketAlertAppend(p, sig->gid, sig->id, sig->rev, sig->prio, sig->msg, sig->class_msg);
PacketAlertAppend(p, sig->gid, sig->id, sig->rev, sig->prio, sig->msg, sig->class_msg, sig->sigref);
} else {
PacketAlertThreshold(de_ctx, td, p, sig);
}
@ -277,20 +277,20 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
if (lookup_tsh != NULL) {
if ((ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
if (lookup_tsh->current_count < td->count) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
}
lookup_tsh->current_count++;
} else {
lookup_tsh->tv_sec1 = ts.tv_sec;
lookup_tsh->current_count = 1;
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
}
} else {
ste->tv_sec1 = ts.tv_sec;
ste->current_count = 1;
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
ThresholdHashAdd(de_ctx, ste, p);
ste = NULL;
@ -307,7 +307,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
lookup_tsh->current_count = 0;
}
} else {
@ -319,7 +319,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
ste->tv_sec1 = ts.tv_sec;
if (td->count == 1) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
ste->current_count = 0;
} else {
ThresholdHashAdd(de_ctx,ste,p);
@ -337,7 +337,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
if ((ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count == td->count) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
}
} else {
lookup_tsh->tv_sec1 = ts.tv_sec;
@ -348,7 +348,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
ste->tv_sec1 = ts.tv_sec;
if (td->count == 1) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
ste->current_count = 0;
} else {
ThresholdHashAdd(de_ctx,ste,p);
@ -367,7 +367,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
if ((ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
}
} else {
lookup_tsh->tv_sec1 = ts.tv_sec;
@ -378,7 +378,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectThresholdData *td, Pack
ste->tv_sec1 = ts.tv_sec;
if (td->count == 1) {
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg);
PacketAlertAppend(p, s->gid, s->id, s->rev, s->prio, s->msg, s->class_msg, s->sigref);
}
ThresholdHashAdd(de_ctx, ste, p);
ste = NULL;

@ -11,6 +11,7 @@
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-reference.h"
#include "flow.h"
@ -683,6 +684,23 @@ Signature *SigAlloc (void) {
return sig;
}
/**
* \brief Free Reference list
*
* \param s Pointer to the signature
*/
void SigRefFree(Signature *s) {
References *sref = NULL;
if (s == NULL)
return;
if(s->sigref != NULL) {
for (sref = s->sigref; sref != NULL; sref = sref->next) {
SCFree(sref);
}
}
}
void SigFree(Signature *s) {
if (s == NULL)
return;
@ -712,6 +730,8 @@ void SigFree(Signature *s) {
if (s->msg != NULL) SCFree(s->msg);
SigRefFree(s);
SCFree(s);
}

@ -1,33 +1,477 @@
/* REFERENCE part of the detection engine. */
/* Copyright (c) 2009 Open Information Security Foundation */
/** \file
* \author Breno Silva <breno.silva@gmail.com>
*/
#include "suricata-common.h"
#include "suricata.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "decode.h"
#include "detect.h"
#include "flow-var.h"
#include "decode-events.h"
#include "stream-tcp.h"
#include "detect-reference.h"
#include "util-unittest.h"
#include "util-byte.h"
#include "util-debug.h"
#define PARSE_REGEX "^\\s*(cve|nessus|url|mcafee|bugtraq|arachnids)\\s*,\\s*([a-zA-Z0-9\\-_\\.\\/\\?\\=]+)\\s*"
/* Static prefix for references - Maybe we should move them to reference.config in the future */
char REFERENCE_BUGTRAQ[] = "http://www.securityfocus.com/bid/";
char REFERENCE_CVE[] = "http://cve.mitre.org/cgi-bin/cvename.cgi?name=";
char REFERENCE_NESSUS[] = "http://cgi.nessus.org/plugins/dump.php3?id=";
char REFERENCE_ARACHNIDS[] = "http://www.whitehats.com/info/IDS";
char REFERENCE_MCAFEE[] = "http://vil.nai.com/vil/dispVirus.asp?virus_k=";
char REFERENCE_URL[] = "http://";
static pcre *parse_regex;
static pcre_extra *parse_regex_study;
static int DetectReferenceSetup (DetectEngineCtx *, Signature *, char *);
static int DetectReferenceSetup (DetectEngineCtx *, Signature *s, char *str);
/**
* \brief Registration function for reference: keyword
*/
void DetectReferenceRegister (void) {
sigmatch_table[DETECT_REFERENCE].name = "reference";
sigmatch_table[DETECT_REFERENCE].Match = NULL;
sigmatch_table[DETECT_REFERENCE].Setup = DetectReferenceSetup;
sigmatch_table[DETECT_REFERENCE].Free = NULL;
sigmatch_table[DETECT_REFERENCE].RegisterTests = NULL;
sigmatch_table[DETECT_REFERENCE].RegisterTests = ReferenceRegisterTests;
const char *eb;
int opts = 0;
int eo;
parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL);
if (parse_regex == NULL)
{
SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb);
goto error;
}
parse_regex_study = pcre_study(parse_regex, 0, &eb);
if (eb != NULL)
{
SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb);
goto error;
}
error:
return;
}
int DetectReferenceSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
/**
* \internal
* \brief This function is used to parse reference options passed via reference: keyword
*
* \param rawstr Pointer to the user provided reference options
*
* \retval sigref pointer to signature reference on success
* \retval NULL on failure
*/
static char *DetectReferenceParse (char *rawstr)
{
char *str = rawstr;
char dubbed = 0;
DetectReferenceData *ref = NULL;
char *sigref = NULL;
#define MAX_SUBSTRINGS 30
int ret = 0, res = 0;
int ov[MAX_SUBSTRINGS];
const char *ref_key = NULL;
const char *ref_content = NULL;
int sig_len = 0;
ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
if (ret < 2) {
SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
goto error;
}
ref = SCMalloc(sizeof(DetectReferenceData));
if (ref == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "malloc failed");
goto error;
}
memset(ref,0,sizeof(DetectReferenceData));
res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,1, &ref_key);
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
goto error;
}
res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,2, &ref_content);
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
goto error;
}
if (ref_key == NULL || ref_content == NULL)
goto error;
if (strcasecmp(ref_key,"cve") == 0) {
ref->reference = REFERENCE_CVE;
} else if (strcasecmp(ref_key,"bugtraq") == 0) {
ref->reference = REFERENCE_BUGTRAQ;
} else if (strcasecmp(ref_key,"nessus") == 0) {
ref->reference = REFERENCE_NESSUS;
} else if (strcasecmp(ref_key,"url") == 0) {
ref->reference = REFERENCE_URL;
} else if (strcasecmp(ref_key,"mcafee") == 0) {
ref->reference = REFERENCE_MCAFEE;
} else if (strcasecmp(ref_key,"arachnids") == 0) {
ref->reference = REFERENCE_ARACHNIDS;
}
sig_len = (strlen(ref->reference) + strlen(ref_content)+1);
/* strip "'s */
if (rawstr[0] == '\"' && rawstr[strlen(rawstr)-1] == '\"') {
str = SCStrdup(rawstr+1);
str[strlen(rawstr)-2] = '\0';
dubbed = 1;
sigref = SCMalloc(sig_len+1);
if (sigref == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "malloc failed");
goto error;
}
/* XXX */
memset(sigref,0,sig_len);
strlcpy(sigref,ref->reference,strlen(ref->reference)+1);
strlcat(sigref,ref_content,sig_len);
sigref[strlen(sigref)] = '\0';
if (ref) SCFree(ref);
if (ref_key) SCFree((char *)ref_key);
if (ref_content) SCFree((char *)ref_content);
return sigref;
error:
if (ref_key) SCFree((char *)ref_key);
if (ref_content) SCFree((char *)ref_content);
if (ref) SCFree(ref);
return NULL;
}
/**
* \internal
* \brief this function is used to add the parsed reference into the current signature
*
* \param de_ctx pointer to the Detection Engine Context
* \param s pointer to the Current Signature
* \param m pointer to the Current SigMatch
* \param rawstr pointer to the user provided reference options
*
* \retval 0 on Success
* \retval -1 on Failure
*/
static int DetectReferenceSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
{
char *ref = NULL;
References *sref = NULL;
References *actual_reference = NULL;
ref = DetectReferenceParse(rawstr);
if (ref == NULL)
goto error;
if(s->sigref == NULL) {
s->sigref = SCMalloc(sizeof(References));
if (s->sigref == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "malloc failed");
goto error;
}
s->sigref->reference = ref;
s->sigref->next = NULL;
} else {
sref = SCMalloc(sizeof(References));
if (sref == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "malloc failed");
goto error;
}
sref->reference = ref;
sref->next = NULL;
actual_reference = s->sigref;
while (actual_reference->next != NULL) {
actual_reference = actual_reference->next;
}
actual_reference->next = sref;
}
if (dubbed) SCFree(str);
return 0;
error:
if (ref) SCFree(ref);
if (sref) SCFree(sref);
return -1;
}
/*
* ONLY TESTS BELOW THIS COMMENT
*/
#ifdef UNITTESTS
/**
* \test DetectReferenceParseTest01 is a test for one valid reference.
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int DetectReferenceParseTest01(void)
{
int result = 0;
uint8_t raw_icmpv4[] = {
0x08, 0x00, 0x42, 0xb4, 0x02, 0x00, 0x08, 0xa8,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69};
Packet p;
Signature *s = NULL;
DecodeThreadVars dtv;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
IPV4Hdr ip4h;
References *sref = NULL;
memset(&p, 0, sizeof(Packet));
memset(&ip4h, 0, sizeof(IPV4Hdr));
memset(&dtv, 0, sizeof(DecodeThreadVars));
memset(&th_v, 0, sizeof(ThreadVars));
FlowInitConfig(FLOW_QUIET);
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.src.addr_data32[0] = 0x01020304;
p.dst.addr_data32[0] = 0x04030201;
ip4h.ip_src.s_addr = p.src.addr_data32[0];
ip4h.ip_dst.s_addr = p.dst.addr_data32[0];
p.ip4h = &ip4h;
DecodeICMPV4(&th_v, &dtv, &p, raw_icmpv4, sizeof(raw_icmpv4), NULL);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (msg:\"One reference\"; reference:cve,001-2010; sid:2;)");
if (s == NULL) {
goto end;
}
if (s->sigref == NULL) {
goto cleanup;
}
for (sref = s->sigref; sref != NULL; sref = sref->next) {
if (strcmp(sref->reference,"http://cve.mitre.org/cgi-bin/cvename.cgi?name=001-2010") != 0) {
goto cleanup;
}
}
result = 1;
cleanup:
if (s) SigFree(s);
if (det_ctx) DetectEngineCtxFree(de_ctx);
FlowShutdown();
end:
return result;
}
/**
* \test DetectReferenceParseTest02 is a test for two valid references.
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int DetectReferenceParseTest02(void)
{
int result = 0;
uint8_t raw_icmpv4[] = {
0x08, 0x00, 0x42, 0xb4, 0x02, 0x00, 0x08, 0xa8,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69};
Packet p;
Signature *s = NULL;
DecodeThreadVars dtv;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
IPV4Hdr ip4h;
References *sref = NULL;
memset(&p, 0, sizeof(Packet));
memset(&ip4h, 0, sizeof(IPV4Hdr));
memset(&dtv, 0, sizeof(DecodeThreadVars));
memset(&th_v, 0, sizeof(ThreadVars));
FlowInitConfig(FLOW_QUIET);
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.src.addr_data32[0] = 0x01020304;
p.dst.addr_data32[0] = 0x04030201;
ip4h.ip_src.s_addr = p.src.addr_data32[0];
ip4h.ip_dst.s_addr = p.dst.addr_data32[0];
p.ip4h = &ip4h;
DecodeICMPV4(&th_v, &dtv, &p, raw_icmpv4, sizeof(raw_icmpv4), NULL);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (msg:\"Two references\"; reference:url,www.openinfosecfoundation.org; reference:cve,001-2010; sid:2;)");
if (s == NULL) {
goto end;
}
if (s->sigref == NULL) {
goto cleanup;
}
for (sref = s->sigref; sref != NULL; sref = sref->next) {
if (strcmp(sref->reference,"http://www.openinfosecfoundation.org") == 0) {
result++;
}
if (strcmp(sref->reference,"http://cve.mitre.org/cgi-bin/cvename.cgi?name=001-2010") == 0) {
result++;
}
}
if (result == 2) {
result = 1;
}
cleanup:
if (s) SigFree(s);
if (det_ctx) DetectEngineCtxFree(de_ctx);
FlowShutdown();
end:
return result;
}
/**
* \test DetectReferenceParseTest03 is a test for one invalid reference.
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int DetectReferenceParseTest03(void)
{
int result = 0;
uint8_t raw_icmpv4[] = {
0x08, 0x00, 0x42, 0xb4, 0x02, 0x00, 0x08, 0xa8,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69};
Packet p;
Signature *s = NULL;
DecodeThreadVars dtv;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
IPV4Hdr ip4h;
References *sref = NULL;
memset(&p, 0, sizeof(Packet));
memset(&ip4h, 0, sizeof(IPV4Hdr));
memset(&dtv, 0, sizeof(DecodeThreadVars));
memset(&th_v, 0, sizeof(ThreadVars));
FlowInitConfig(FLOW_QUIET);
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.src.addr_data32[0] = 0x01020304;
p.dst.addr_data32[0] = 0x04030201;
ip4h.ip_src.s_addr = p.src.addr_data32[0];
ip4h.ip_dst.s_addr = p.dst.addr_data32[0];
p.ip4h = &ip4h;
DecodeICMPV4(&th_v, &dtv, &p, raw_icmpv4, sizeof(raw_icmpv4), NULL);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (msg:\"Two references\"; reference:url,www.openinfosecfoundation.org; reference:oisf,001-2010; sid:2;)");
if (s == NULL) {
goto end;
}
if (s->sigref == NULL) {
goto cleanup;
}
for (sref = s->sigref; sref != NULL; sref = sref->next) {
result++;
}
cleanup:
if (s) SigFree(s);
if (det_ctx) DetectEngineCtxFree(de_ctx);
FlowShutdown();
end:
return result;
}
#endif /* UNITTESTS */
void ReferenceRegisterTests(void) {
#ifdef UNITTESTS
UtRegisterTest("DetectReferenceParseTest01", DetectReferenceParseTest01, 1);
UtRegisterTest("DetectReferenceParseTest02", DetectReferenceParseTest02, 1);
UtRegisterTest("DetectReferenceParseTest03", DetectReferenceParseTest03, 0);
#endif /* UNITTESTS */
}

@ -1,8 +1,42 @@
/* Copyright (c) 2009 Open Information Security Foundation */
/** \file
* \author Breno Silva <breno.silva@gmail.com>
*/
#ifndef __DETECT_REFERENCE_H__
#define __DETECT_REFERENCE_H__
/* prototypes */
#include "decode-events.h"
#include "decode-ipv4.h"
#include "decode-tcp.h"
/** Signature reference list */
typedef struct References_ {
char *reference; /**< reference data */
struct References_ *next; /**< next reference in the signature */
} References;
/**
* \typedef DetectReferenceData
* A typedef for DetectReferenceData_
*/
typedef struct DetectReferenceData_ {
char *reference; /**< 0 reference prefix 1 - reference data */
} DetectReferenceData;
/**
* Registration function for reference: keyword
*/
void DetectReferenceRegister (void);
#endif /* __DETECT_REFERENCE_H__ */
/**
* This function registers unit tests for Reference
*/
void ReferenceRegisterTests(void);
#endif /*__DETECT_REFERENCE_H__ */

@ -389,7 +389,7 @@ int PacketAlertCheck(Packet *p, uint32_t sid)
}
int PacketAlertAppend(Packet *p, uint32_t gid, uint32_t sid, uint8_t rev,
uint8_t prio, char *msg, char *class_msg)
uint8_t prio, char *msg, char *class_msg, References *sigref)
{
if (p->alerts.cnt == PACKET_ALERT_MAX)
return 0;
@ -406,6 +406,7 @@ int PacketAlertAppend(Packet *p, uint32_t gid, uint32_t sid, uint8_t rev,
p->alerts.alerts[p->alerts.cnt].prio = prio;
p->alerts.alerts[p->alerts.cnt].msg = msg;
p->alerts.alerts[p->alerts.cnt].class_msg = class_msg;
p->alerts.alerts[p->alerts.cnt].sigref = sigref;
p->alerts.cnt++;
return 0;

@ -6,6 +6,7 @@
#include "flow.h"
#include "detect-engine-proto.h"
#include "detect-reference.h"
#include "packet-queue.h"
#include "util-mpm.h"
@ -208,6 +209,9 @@ typedef struct Signature_ {
/** classification message */
char *class_msg;
/** Reference */
References *sigref;
/** addresses, ports and proto this sig matches on */
DetectAddressHead src, dst;
DetectProto proto;
@ -660,7 +664,7 @@ int SigGroupCleanup();
void SigAddressPrepareBidirectionals (DetectEngineCtx *);
int PacketAlertAppend(Packet *, uint32_t, uint32_t, uint8_t, uint8_t, char *,
char *);
char *, References *);
int SigLoadSignatures (DetectEngineCtx *, char *);
void SigTableSetup(void);

Loading…
Cancel
Save