Store TX id with alerts

When generating an alert and storing it in the packet, store the tx_id
as well. This way the output modules can log the tx_id and access the
proper tx for logging.

Issue #904.
pull/584/merge
Victor Julien 12 years ago
parent 51c2e1eaf6
commit edeeb7ed44

@ -248,6 +248,7 @@ typedef struct PacketAlert_ {
uint8_t action; /* Internal num, used for sorting */ uint8_t action; /* Internal num, used for sorting */
uint8_t flags; uint8_t flags;
struct Signature_ *s; struct Signature_ *s;
uint64_t tx_id;
} PacketAlert; } PacketAlert;
/** After processing an alert by the thresholding module, if at /** After processing an alert by the thresholding module, if at
@ -258,6 +259,8 @@ typedef struct PacketAlert_ {
#define PACKET_ALERT_FLAG_STATE_MATCH 0x02 #define PACKET_ALERT_FLAG_STATE_MATCH 0x02
/** alert was generated based on stream */ /** alert was generated based on stream */
#define PACKET_ALERT_FLAG_STREAM_MATCH 0x04 #define PACKET_ALERT_FLAG_STREAM_MATCH 0x04
/** alert is in a tx, tx_id set */
#define PACKET_ALERT_FLAG_TX 0x08
#define PACKET_ALERT_MAX 15 #define PACKET_ALERT_MAX 15

@ -175,7 +175,7 @@ int PacketAlertRemove(Packet *p, uint16_t pos)
* \param flags alert flags * \param flags alert flags
* \param alert_msg ptr to StreamMsg object that the signature matched on * \param alert_msg ptr to StreamMsg object that the signature matched on
*/ */
int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint8_t flags) int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint64_t tx_id, uint8_t flags)
{ {
int i = 0; int i = 0;
@ -192,6 +192,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
p->alerts.alerts[p->alerts.cnt].action = s->action; p->alerts.alerts[p->alerts.cnt].action = s->action;
p->alerts.alerts[p->alerts.cnt].flags = flags; p->alerts.alerts[p->alerts.cnt].flags = flags;
p->alerts.alerts[p->alerts.cnt].s = s; p->alerts.alerts[p->alerts.cnt].s = s;
p->alerts.alerts[p->alerts.cnt].tx_id = tx_id;
} else { } else {
/* We need to make room for this s->num /* We need to make room for this s->num
(a bit ugly with memcpy but we are planning changes here)*/ (a bit ugly with memcpy but we are planning changes here)*/
@ -205,6 +206,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
p->alerts.alerts[i].action = s->action; p->alerts.alerts[i].action = s->action;
p->alerts.alerts[i].flags = flags; p->alerts.alerts[i].flags = flags;
p->alerts.alerts[i].s = s; p->alerts.alerts[i].s = s;
p->alerts.alerts[i].tx_id = tx_id;
} }
/* Update the count */ /* Update the count */

@ -29,7 +29,7 @@
#include "detect.h" #include "detect.h"
void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *); void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *);
int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t); int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint64_t tx_id, uint8_t);
int PacketAlertCheck(Packet *, uint32_t); int PacketAlertCheck(Packet *, uint32_t);
int PacketAlertRemove(Packet *, uint16_t); int PacketAlertRemove(Packet *, uint16_t);
void PacketAlertTagInit(void); void PacketAlertTagInit(void);

@ -1084,9 +1084,9 @@ void IPOnlyMatchPacket(ThreadVars *tv,
} }
if (!(s->flags & SIG_FLAG_NOALERT)) { if (!(s->flags & SIG_FLAG_NOALERT)) {
if (s->action & ACTION_DROP) if (s->action & ACTION_DROP)
PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW); PacketAlertAppend(det_ctx, s, p, 0, PACKET_ALERT_FLAG_DROP_FLOW);
else else
PacketAlertAppend(det_ctx, s, p, 0); PacketAlertAppend(det_ctx, s, p, 0, 0);
} else { } else {
/* apply actions for noalert/rule suppressed as well */ /* apply actions for noalert/rule suppressed as well */
PACKET_UPDATE_ACTION(p, s->action); PACKET_UPDATE_ACTION(p, s->action);

@ -236,7 +236,7 @@ int DeStateFlowHasInspectableState(Flow *f, uint16_t alproto, uint16_t alversion
int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags, Signature *s, Packet *p, Flow *f, uint8_t flags,
void *alstate, uint16_t alproto, uint16_t alversion) void *alstate, uint16_t alproto, uint16_t alversion)
{ {
DetectEngineAppInspectionEngine *engine = NULL; DetectEngineAppInspectionEngine *engine = NULL;
@ -310,8 +310,17 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
/* all the engines seem to be exhausted at this point. If we /* all the engines seem to be exhausted at this point. If we
* didn't have a match in one of the engines we would have * didn't have a match in one of the engines we would have
* broken off and engine wouldn't be NULL. Hence the alert. */ * broken off and engine wouldn't be NULL. Hence the alert. */
if (engine == NULL && total_matches > 0) if (engine == NULL && total_matches > 0) {
alert_cnt++;
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, tx_id,
PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
} else {
PACKET_UPDATE_ACTION(p, s->action);
}
alert_cnt = 1;
}
if (tx_id == (total_txs - 1)) { if (tx_id == (total_txs - 1)) {
void *tx = AppLayerGetTx(alproto, alstate, tx_id); void *tx = AppLayerGetTx(alproto, alstate, tx_id);
@ -337,12 +346,27 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (smb_state->dcerpc_present && if (smb_state->dcerpc_present &&
DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
flags, &smb_state->dcerpc) == 1) { flags, &smb_state->dcerpc) == 1) {
alert_cnt++; if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, 0,
PACKET_ALERT_FLAG_STATE_MATCH);
} else {
PACKET_UPDATE_ACTION(p, s->action);
}
alert_cnt = 1;
} }
} else { } else {
if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
flags, alstate) == 1) { flags, alstate) == 1) {
alert_cnt++; alert_cnt = 1;
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, 0,
PACKET_ALERT_FLAG_STATE_MATCH);
} else {
PACKET_UPDATE_ACTION(p, s->action);
}
} }
} }
} }
@ -373,8 +397,15 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
store_de_state = 1; store_de_state = 1;
if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) { if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
if (match == 1) if (match == 1) {
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, 0,
PACKET_ALERT_FLAG_STATE_MATCH);
} else {
PACKET_UPDATE_ACTION(p, s->action);
}
alert_cnt = 1; alert_cnt = 1;
}
inspect_flags |= DE_STATE_FLAG_FULL_INSPECT; inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
} }
} }
@ -405,7 +436,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SCMutexUnlock(&f->de_state_m); SCMutexUnlock(&f->de_state_m);
end: end:
return alert_cnt; return alert_cnt ? 1:0;
} }
void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
@ -621,7 +652,12 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s); SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) { if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, 0); if (alproto_supports_txs)
PacketAlertAppend(det_ctx, s, p, inspect_tx_id,
PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
else
PacketAlertAppend(det_ctx, s, p, 0,
PACKET_ALERT_FLAG_STATE_MATCH);
} else { } else {
PACKET_UPDATE_ACTION(p, s->action); PACKET_UPDATE_ACTION(p, s->action);
} }

@ -170,7 +170,7 @@ int DeStateFlowHasInspectableState(Flow *f, uint16_t alproto, uint16_t alversion
*/ */
int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags, Signature *s, Packet *p, Flow *f, uint8_t flags,
void *alstate, uint16_t alproto, void *alstate, uint16_t alproto,
uint16_t alversion); uint16_t alversion);

@ -1103,8 +1103,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SigMatch *sm = NULL; SigMatch *sm = NULL;
uint16_t alversion = 0; uint16_t alversion = 0;
int reset_de_state = 0; int reset_de_state = 0;
int state_alert = 0;
int alerts = 0; int alerts = 0;
int i;
int app_decoder_events = 0; int app_decoder_events = 0;
SCEnter(); SCEnter();
@ -1305,7 +1305,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* inspect the sigs against the packet */ /* inspect the sigs against the packet */
for (idx = 0; idx < det_ctx->match_array_cnt; idx++) { for (idx = 0; idx < det_ctx->match_array_cnt; idx++) {
RULE_PROFILING_START; RULE_PROFILING_START;
alerts = 0; state_alert = 0;
#ifdef PROFILING #ifdef PROFILING
smatch = 0; smatch = 0;
#endif #endif
@ -1492,11 +1492,16 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
} }
SCLogDebug("stateful app layer match inspection starting"); SCLogDebug("stateful app layer match inspection starting");
/* if DeStateDetectStartDetection matches, it's a full
* signature match. It will then call PacketAlertAppend
* itself, so we can skip it below. This is done so it
* can store the tx_id with the alert */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL); PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
alerts = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s, state_alert = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
p->flow, flags, alstate, alproto, alversion); p, p->flow, flags, alstate, alproto, alversion);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL); PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
if (alerts == 0) if (state_alert == 0)
goto next; goto next;
/* match */ /* match */
@ -1506,11 +1511,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
alert_flags |= PACKET_ALERT_FLAG_STATE_MATCH; alert_flags |= PACKET_ALERT_FLAG_STATE_MATCH;
} }
/* If we have reached this stage and we don't have any alerts, it
* indicates that we didn't have a stateful sig, hence we set alerts
* to 1. But if we have an alert set, then the sig is definitely a
* stateful sig and we need to retain the no of alerts */
alerts = (alerts == 0) ? 1 : alerts;
#ifdef PROFILING #ifdef PROFILING
smatch = 1; smatch = 1;
#endif #endif
@ -1518,12 +1518,14 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s); SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) { if (!(s->flags & SIG_FLAG_NOALERT)) {
for (i = 0; i < alerts; i++) /* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */
PacketAlertAppend(det_ctx, s, p, alert_flags); if (!state_alert)
PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
} else { } else {
/* apply actions even if not alerting */ /* apply actions even if not alerting */
PACKET_UPDATE_ACTION(p, s->action); PACKET_UPDATE_ACTION(p, s->action);
} }
alerts++;
next: next:
DetectFlowvarProcessList(det_ctx, p->flow); DetectFlowvarProcessList(det_ctx, p->flow);
DetectReplaceFree(det_ctx->replist); DetectReplaceFree(det_ctx->replist);

Loading…
Cancel
Save