Add app layer protocol packet event detection support.

pull/567/head
Anoop Saldanha 13 years ago
parent 5e2d9dbdc3
commit b1dffdfbe0

@ -578,7 +578,7 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
for (uint16_t i = 0; i < pm_matches; i++) {
if (al_proto_table[pm_results[i]].pp_alproto_map[dir] != NULL) {
if (pm_results[i] != al_proto_table[pm_results[i]].pp_alproto_map[dir](buf, buflen, NULL)) {
/* \todo set event */
/* \todo set event - Needs some deliberation */
continue;
}
}

@ -36,6 +36,7 @@
#include "util-print.h"
#include "util-profiling.h"
#include "util-validate.h"
#include "decode-events.h"
//#define PRINT
extern uint8_t engine_mode;
@ -182,7 +183,8 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
if (*alproto != ALPROTO_UNKNOWN) {
if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
/* \todo set event */
AppLayerDecoderEventsSetEventRaw(p->app_layer_events,
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS);
f->alproto = f->alproto_ts = f->alproto_tc = ALPROTO_UNKNOWN;
FlowSetSessionNoApplayerInspectionFlag(f);
ssn->client.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED;
@ -220,7 +222,8 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
if (ssn->data_first_seen_dir != 0x01) {
if (al_proto_table[*alproto].flags && !(al_proto_table[*alproto].flags & ssn->data_first_seen_dir)) {
/* \todo Set event */
AppLayerDecoderEventsSetEventRaw(p->app_layer_events,
APPLAYER_WRONG_DIRECTION_FIRST_DATA);
r = -1;
f->alproto = f->alproto_ts = f->alproto_tc = ALPROTO_UNKNOWN;
FlowSetSessionNoApplayerInspectionFlag(f);
@ -247,7 +250,8 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
data + data_al_so_far, data_len - data_al_so_far);
PACKET_PROFILING_APP_END(dp_ctx, *alproto_otherdir);
if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
/* \todo event. Unable to detect protocol for one direction */
AppLayerDecoderEventsSetEventRaw(p->app_layer_events,
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION);
stream->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED;
f->data_al_so_far[dir] = 0;
} else {

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2011 Open Information Security Foundation
/* Copyright (C) 2007-2013 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
@ -22,7 +22,28 @@
*/
#include "suricata-common.h"
#include "app-layer-parser.h"
#include "decode-events.h"
#include "flow.h"
#include "util-enum.h"
SCEnumCharMap app_layer_event_pkt_table[ ] = {
{ "APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS",
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS },
{ "APPLAYER_WRONG_DIRECTION_FIRST_DATA",
APPLAYER_WRONG_DIRECTION_FIRST_DATA },
{ "APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION",
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION },
{ NULL,
-1 },
};
int AppLayerGetPktEventInfo(const char *event_name, int *event_id)
{
*event_id = SCMapEnumNameToValue(event_name, app_layer_event_pkt_table);
if (*event_id == -1) {
SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in "
"app-layer-event's packet event table.", event_name);
/* this should be treated as fatal */
return -1;
}
return 0;
}

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2013 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
@ -25,8 +25,7 @@
#ifndef __DECODE_EVENTS_H__
#define __DECODE_EVENTS_H__
/***** packet decoder events *****/
/* packet decoder events */
enum {
/* IPV4 EVENTS */
IPV4_PKT_TOO_SMALL = 1, /**< ipv4 pkt smaller than minimum header size */
@ -225,12 +224,20 @@ enum {
DECODE_EVENT_MAX,
};
/* app layer pkt level events */
enum {
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS,
APPLAYER_WRONG_DIRECTION_FIRST_DATA,
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION,
};
#define DECODER_EVENTS_BUFFER_STEPS 5
/* the event types for app events */
typedef enum AppLayerEventType_ {
APP_LAYER_EVENT_TYPE_GENERAL = 1,
APP_LAYER_EVENT_TYPE_TRANSACTION,
APP_LAYER_EVENT_TYPE_PACKET,
} AppLayerEventType;
/**
@ -353,4 +360,6 @@ static inline int AppLayerDecoderEventsIsEventSet(AppLayerDecoderEvents *devents
SCFree((devents)); \
} while (0)
int AppLayerGetPktEventInfo(const char *event_name, int *event_id);
#endif /* __DECODE_EVENTS_H__ */

@ -29,6 +29,7 @@
#include "suricata-common.h"
#include "threadvars.h"
#include "decode-events.h"
#ifdef __SC_CUDA_SUPPORT__
#include "util-cuda-buffer.h"
@ -486,6 +487,8 @@ typedef struct Packet_
/* engine events */
PacketEngineEvents events;
AppLayerDecoderEvents *app_layer_events;
/* double linked list ptrs */
struct Packet_ *next;
struct Packet_ *prev;
@ -701,6 +704,7 @@ typedef struct DecodeThreadVars_
SCMutexDestroy(&(p)->tunnel_mutex); \
SCMutexInit(&(p)->tunnel_mutex, NULL); \
(p)->events.cnt = 0; \
AppLayerDecoderEventsResetEvents((p)->app_layer_events); \
(p)->next = NULL; \
(p)->prev = NULL; \
(p)->root = NULL; \
@ -719,6 +723,7 @@ typedef struct DecodeThreadVars_
PktVarFree((p)->pktvar); \
} \
SCMutexDestroy(&(p)->tunnel_mutex); \
AppLayerDecoderEventsFreeEvents((p)->app_layer_events); \
} while (0)

@ -45,8 +45,10 @@
#include "util-unittest-helper.h"
int DetectAppLayerEventMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *,
uint8_t, void *, Signature *, SigMatch *);
int DetectAppLayerEventPktMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m);
int DetectAppLayerEventAppMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *,
uint8_t, void *, Signature *, SigMatch *);
int DetectAppLayerEventSetup(DetectEngineCtx *, Signature *, char *);
void DetectAppLayerEventRegisterTests(void);
void DetectAppLayerEventFree(void *);
@ -57,9 +59,10 @@ void DetectAppLayerEventFree(void *);
void DetectAppLayerEventRegister(void)
{
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].name = "app-layer-event";
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Match = NULL;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Match =
DetectAppLayerEventPktMatch;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].AppLayerMatch =
DetectAppLayerEventMatch;
DetectAppLayerEventAppMatch;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Setup = DetectAppLayerEventSetup;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Free = DetectAppLayerEventFree;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].RegisterTests =
@ -68,9 +71,19 @@ void DetectAppLayerEventRegister(void)
return;
}
int DetectAppLayerEventMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *m)
int DetectAppLayerEventPktMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m)
{
DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx;
return AppLayerDecoderEventsIsEventSet(p->app_layer_events,
aled->event_id);
}
int DetectAppLayerEventAppMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *m)
{
SCEnter();
AppLayerDecoderEvents *decoder_events = NULL;
@ -87,7 +100,7 @@ int DetectAppLayerEventMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
tx_id = AppLayerTransactionGetInspectId(f, flags);
max_id = AppLayerGetTxCnt(f->alproto, f->alstate);
for ( ; tx_id < max_id; tx_id++) {
for (; tx_id < max_id; tx_id++) {
decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id);
if (decoder_events != NULL &&
AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) {
@ -109,54 +122,68 @@ int DetectAppLayerEventMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
SCReturnInt(r);
}
static DetectAppLayerEventData *DetectAppLayerEventParse(const char *arg)
static DetectAppLayerEventData *DetectAppLayerEventParsePkt(const char *arg,
AppLayerEventType *event_type)
{
/* period index */
const char *p_idx;
int r = 0;
DetectAppLayerEventData *aled;
int event_id = 0;
AppLayerEventType event_type = 0;
uint16_t alproto;
int r = 0;
if (arg == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword supplied "
"with no arguments. This keyword needs an argument.");
r = AppLayerGetPktEventInfo(arg, &event_id);
if (r < 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword "
"supplied with packet based event - \"%s\" that isn't "
"supported yet.", arg);
return NULL;
}
while (*arg != '\0' && isspace((unsigned char)*arg)) {
arg++;
}
p_idx = strchr(arg, '.');
if (p_idx == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword supplied "
"with an argument which is not in the right format. The "
"right format is \"<alproto>.<event>\"");
aled = SCMalloc(sizeof(DetectAppLayerEventData));
if (unlikely(aled == NULL))
return NULL;
}
aled->event_id = event_id;
*event_type = APP_LAYER_EVENT_TYPE_PACKET;
return aled;
}
static DetectAppLayerEventData *DetectAppLayerEventParseApp(const char *arg,
AppLayerEventType *event_type)
{
/* period index */
DetectAppLayerEventData *aled;
uint16_t alproto;
int event_id = 0;
char buffer[50] = "";
strlcpy(buffer, arg, p_idx - arg + 1); /* + 1 for trailing \0 */
const char *p_idx;
char alproto_name[50];
int r = 0;
/** XXX HACK to support "dns" we use this trick */
if (strcasecmp(buffer, "dns") == 0)
strlcpy(buffer, "dnsudp", sizeof(buffer));
p_idx = strchr(arg, '.');
/* + 1 for trailing \0 */
strlcpy(alproto_name, arg, p_idx - arg + 1);
alproto = AppLayerGetProtoByName(buffer);
/* XXX HACK to support "dns" we use this trick */
if (strcasecmp(alproto_name, "dns") == 0)
strlcpy(alproto_name, "dnsudp", sizeof(alproto_name));
alproto = AppLayerGetProtoByName(alproto_name);
if (alproto == ALPROTO_UNKNOWN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword supplied "
"with unknown protocol \"%s\"", buffer);
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword "
"supplied with unknown protocol \"%s\"",
alproto_name);
return NULL;
}
r = AppLayerGetEventInfo(alproto, p_idx + 1, &event_id, &event_type);
r = AppLayerGetEventInfo(alproto, p_idx + 1, &event_id, event_type);
if (r < 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword protocol "
"\"%s\" don't have event \"%s\" registered", buffer, p_idx + 1);
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword's "
"protocol \"%s\" doesn't have event \"%s\" registered",
alproto_name, p_idx + 1);
return NULL;
}
DetectAppLayerEventData *aled = SCMalloc(sizeof(DetectAppLayerEventData));
aled = SCMalloc(sizeof(DetectAppLayerEventData));
if (unlikely(aled == NULL))
return NULL;
aled->alproto = alproto;
@ -165,12 +192,32 @@ static DetectAppLayerEventData *DetectAppLayerEventParse(const char *arg)
return aled;
}
static DetectAppLayerEventData *DetectAppLayerEventParse(const char *arg,
AppLayerEventType *event_type)
{
if (arg == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword supplied "
"with no arguments. This keyword needs an argument.");
return NULL;
}
while (*arg != '\0' && isspace((unsigned char)*arg))
arg++;
if (strchr(arg, '.') == NULL) {
return DetectAppLayerEventParsePkt(arg, event_type);
} else {
return DetectAppLayerEventParseApp(arg, event_type);
}
}
int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
DetectAppLayerEventData *data = NULL;
SigMatch *sm = NULL;
AppLayerEventType event_type;
data = DetectAppLayerEventParse(arg);
data = DetectAppLayerEventParse(arg, &event_type);
if (data == NULL)
goto error;
@ -195,8 +242,12 @@ int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
s->alproto = data->alproto;
}
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
s->flags |= SIG_FLAG_APPLAYER;
if (event_type == APP_LAYER_EVENT_TYPE_PACKET) {
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH);
} else {
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
s->flags |= SIG_FLAG_APPLAYER;
}
return 0;
@ -221,6 +272,11 @@ void DetectAppLayerEventFree(void *ptr)
#ifdef UNITTESTS /* UNITTESTS */
#include "stream-tcp-private.h"
#include "stream-tcp-reassemble.h"
#include "stream-tcp.h"
#include "app-layer.h"
#define APP_LAYER_EVENT_TEST_MAP_EVENT1 0
#define APP_LAYER_EVENT_TEST_MAP_EVENT2 1
#define APP_LAYER_EVENT_TEST_MAP_EVENT3 2
@ -261,9 +317,11 @@ int DetectAppLayerEventTest01(void)
AppLayerRegisterGetEventInfo(ALPROTO_SMTP,
DetectAppLayerEventTestGetEventInfo);
AppLayerEventType event_type;
int result = 0;
DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1");
DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1",
&event_type);
if (aled == NULL)
goto end;
if (aled->alproto != ALPROTO_SMTP ||
@ -294,9 +352,11 @@ int DetectAppLayerEventTest02(void)
AppLayerRegisterGetEventInfo(ALPROTO_FTP,
DetectAppLayerEventTestGetEventInfo);
AppLayerEventType event_type;
int result = 0;
DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1");
DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1",
&event_type);
if (aled == NULL)
goto end;
if (aled->alproto != ALPROTO_SMTP ||
@ -305,7 +365,8 @@ int DetectAppLayerEventTest02(void)
goto end;
}
aled = DetectAppLayerEventParse("smtp.event4");
aled = DetectAppLayerEventParse("smtp.event4",
&event_type);
if (aled == NULL)
goto end;
if (aled->alproto != ALPROTO_SMTP ||
@ -314,7 +375,8 @@ int DetectAppLayerEventTest02(void)
goto end;
}
aled = DetectAppLayerEventParse("http.event2");
aled = DetectAppLayerEventParse("http.event2",
&event_type);
if (aled == NULL)
goto end;
if (aled->alproto != ALPROTO_HTTP ||
@ -323,7 +385,8 @@ int DetectAppLayerEventTest02(void)
goto end;
}
aled = DetectAppLayerEventParse("smb.event3");
aled = DetectAppLayerEventParse("smb.event3",
&event_type);
if (aled == NULL)
goto end;
if (aled->alproto != ALPROTO_SMB ||
@ -332,7 +395,8 @@ int DetectAppLayerEventTest02(void)
goto end;
}
aled = DetectAppLayerEventParse("ftp.event5");
aled = DetectAppLayerEventParse("ftp.event5",
&event_type);
if (aled == NULL)
goto end;
if (aled->alproto != ALPROTO_FTP ||
@ -350,6 +414,331 @@ int DetectAppLayerEventTest02(void)
return result;
}
int DetectAppLayerEventTest03(void)
{
int result = 0;
ThreadVars tv;
TcpReassemblyThreadCtx *ra_ctx = NULL;
Packet *p = NULL;
Flow *f = NULL;
TcpSession ssn;
TcpStream stream_ts, stream_tc;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 115\r\n"
"Connection: keep-alive\r\n"
"\r\n";
uint8_t buf_tc[] = "HTTP/1.1 200 OK\r\n"
"Date: Fri, 22 Oct 2010 12:31:08 GMT\r\n"
"Server: Apache/2.2.15 (Unix) DAV/2\r\n"
"Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT\r\n"
"ETag: \"ab8486-2c-3e9564c23b600\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 44\r\n"
"Keep-Alive: timeout=5, max=100\r\n"
"Connection: Keep-Alive\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><body><h1>It works!</h1></body></html>";
memset(&tv, 0, sizeof (ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&stream_ts, 0, sizeof(TcpStream));
memset(&stream_tc, 0, sizeof(TcpStream));
ssn.data_first_seen_dir = STREAM_TOSERVER;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(app-layer-event: applayer_mismatch_protocol_both_directions; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220);
if (f == NULL)
goto end;
FLOW_INITIALIZE(f);
f->protoctx = &ssn;
f->flags |= FLOW_IPV4;
p = PacketGetFromAlloc();
if (unlikely(p == NULL))
goto end;
p->flow = f;
p->src.family = AF_INET;
p->dst.family = AF_INET;
p->proto = IPPROTO_TCP;
ra_ctx = StreamTcpReassembleInitThreadCtx();
if (ra_ctx == NULL)
goto end;
StreamTcpInitConfig(TRUE);
p->flowflags = FLOW_PKT_TOSERVER;
if (AppLayerHandleTCPData(&tv, ra_ctx, f, &ssn, &stream_ts, buf_ts,
sizeof(buf_ts), p, STREAM_TOSERVER | STREAM_START) < 0) {
printf("AppLayerHandleTCPData failure\n");
goto end;
}
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
p->flowflags = FLOW_PKT_TOCLIENT;
if (AppLayerHandleTCPData(&tv, ra_ctx, f, &ssn, &stream_tc, buf_tc,
sizeof(buf_tc), p, STREAM_TOCLIENT | STREAM_START) < 0) {
printf("AppLayerHandleTCPData failure\n");
goto end;
}
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
result = 1;
end:
return result;
}
int DetectAppLayerEventTest04(void)
{
int result = 0;
ThreadVars tv;
TcpReassemblyThreadCtx *ra_ctx = NULL;
Packet *p = NULL;
Flow *f = NULL;
TcpSession ssn;
TcpStream stream_ts, stream_tc;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 115\r\n"
"Connection: keep-alive\r\n"
"\r\n";
uint8_t buf_tc[] = "XTTP/1.1 200 OK\r\n"
"Date: Fri, 22 Oct 2010 12:31:08 GMT\r\n"
"Server: Apache/2.2.15 (Unix) DAV/2\r\n"
"Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT\r\n"
"ETag: \"ab8486-2c-3e9564c23b600\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 44\r\n"
"Keep-Alive: timeout=5, max=100\r\n"
"Connection: Keep-Alive\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><body><h1>It works!</h1></body></html>";
memset(&tv, 0, sizeof (ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&stream_ts, 0, sizeof(TcpStream));
memset(&stream_tc, 0, sizeof(TcpStream));
ssn.data_first_seen_dir = STREAM_TOSERVER;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(app-layer-event: applayer_detect_protocol_only_one_direction; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220);
if (f == NULL)
goto end;
FLOW_INITIALIZE(f);
f->protoctx = &ssn;
f->flags |= FLOW_IPV4;
p = PacketGetFromAlloc();
if (unlikely(p == NULL))
goto end;
p->flow = f;
p->src.family = AF_INET;
p->dst.family = AF_INET;
p->proto = IPPROTO_TCP;
ra_ctx = StreamTcpReassembleInitThreadCtx();
if (ra_ctx == NULL)
goto end;
StreamTcpInitConfig(TRUE);
p->flowflags = FLOW_PKT_TOSERVER;
if (AppLayerHandleTCPData(&tv, ra_ctx, f, &ssn, &stream_ts, buf_ts,
sizeof(buf_ts), p, STREAM_TOSERVER | STREAM_START) < 0) {
printf("AppLayerHandleTCPData failure\n");
goto end;
}
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
p->flowflags = FLOW_PKT_TOCLIENT;
if (AppLayerHandleTCPData(&tv, ra_ctx, f, &ssn, &stream_tc, buf_tc,
sizeof(buf_tc), p, STREAM_TOCLIENT | STREAM_START) < 0) {
printf("AppLayerHandleTCPData failure\n");
goto end;
}
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sid 1 didn't match but should have\n");
goto end;
}
result = 1;
end:
return result;
}
int DetectAppLayerEventTest05(void)
{
int result = 0;
ThreadVars tv;
TcpReassemblyThreadCtx *ra_ctx = NULL;
Packet *p = NULL;
Flow *f = NULL;
TcpSession ssn;
TcpStream stream_ts, stream_tc;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 115\r\n"
"Connection: keep-alive\r\n"
"\r\n";
/* tls */
uint8_t buf_tc[] = {
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0xd3, 0x6f, 0x1f, 0x63, 0x82,
0x8d, 0x75, 0x77, 0x8c, 0x91, 0xbc, 0xa1, 0x3d,
0xbb, 0xe1, 0xb5, 0xd3, 0x31, 0x92, 0x59, 0x2b,
0x2c, 0x43, 0x96, 0xa3, 0xaa, 0x23, 0x92, 0xd0,
0x91, 0x2a, 0x5e, 0x10, 0x5b, 0xc8, 0xc1, 0xe2,
0xd3, 0x5c, 0x8b, 0x8c, 0x91, 0x9e, 0xc2, 0xf2,
0x9c, 0x3c, 0x4f, 0x37, 0x1e, 0x20, 0x5e, 0x33,
0xd5, 0xf0, 0xd6, 0xaf, 0x89, 0xf5, 0xcc, 0xb2,
0xcf, 0xc1, 0x60, 0x3a, 0x46, 0xd5, 0x4e, 0x2a,
0xb6, 0x6a, 0xb9, 0xfc, 0x32, 0x8b, 0xe0, 0x6e,
0xa0, 0xed, 0x25, 0xa0, 0xa4, 0x82, 0x81, 0x73,
0x90, 0xbf, 0xb5, 0xde, 0xeb, 0x51, 0x8d, 0xde,
0x5b, 0x6f, 0x94, 0xee, 0xba, 0xe5, 0x69, 0xfa,
0x1a, 0x80, 0x30, 0x54, 0xeb, 0x12, 0x01, 0xb9,
0xfe, 0xbf, 0x82, 0x95, 0x01, 0x7b, 0xb0, 0x97,
0x14, 0xc2, 0x06, 0x3c, 0x69, 0xfb, 0x1c, 0x66,
0x47, 0x17, 0xd9, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xf6, 0xbc,
0x0d, 0x6f, 0xe8, 0xbb, 0xaa, 0xbf, 0x14, 0xeb,
0x7b, 0xcc, 0x6c, 0x28, 0xb0, 0xfc, 0xa6, 0x01,
0x2a, 0x97, 0x96, 0x17, 0x5e, 0xe8, 0xb4, 0x4e,
0x78, 0xc9, 0x04, 0x65, 0x53, 0xb6, 0x93, 0x3d,
0xeb, 0x44, 0xee, 0x86, 0xf9, 0x80, 0x49, 0x45,
0x21, 0x34, 0xd1, 0xee, 0xc8, 0x9c,
};
memset(&tv, 0, sizeof (ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&stream_ts, 0, sizeof(TcpStream));
memset(&stream_tc, 0, sizeof(TcpStream));
ssn.data_first_seen_dir = STREAM_TOSERVER;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(app-layer-event: applayer_mismatch_protocol_both_directions; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220);
if (f == NULL)
goto end;
FLOW_INITIALIZE(f);
f->protoctx = &ssn;
f->flags |= FLOW_IPV4;
p = PacketGetFromAlloc();
if (unlikely(p == NULL))
goto end;
p->flow = f;
p->src.family = AF_INET;
p->dst.family = AF_INET;
p->proto = IPPROTO_TCP;
ra_ctx = StreamTcpReassembleInitThreadCtx();
if (ra_ctx == NULL)
goto end;
StreamTcpInitConfig(TRUE);
p->flowflags = FLOW_PKT_TOSERVER;
if (AppLayerHandleTCPData(&tv, ra_ctx, f, &ssn, &stream_ts, buf_ts,
sizeof(buf_ts), p, STREAM_TOSERVER | STREAM_START) < 0) {
printf("AppLayerHandleTCPData failure\n");
goto end;
}
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
p->flowflags = FLOW_PKT_TOCLIENT;
if (AppLayerHandleTCPData(&tv, ra_ctx, f, &ssn, &stream_tc, buf_tc,
sizeof(buf_tc), p, STREAM_TOCLIENT | STREAM_START) < 0) {
printf("AppLayerHandleTCPData failure\n");
goto end;
}
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sid 1 didn't match but should have\n");
goto end;
}
result = 1;
end:
return result;
}
#endif /* UNITTESTS */
/**
@ -360,6 +749,9 @@ void DetectAppLayerEventRegisterTests(void)
#ifdef UNITTESTS /* UNITTESTS */
UtRegisterTest("DetectAppLayerEventTest01", DetectAppLayerEventTest01, 1);
UtRegisterTest("DetectAppLayerEventTest02", DetectAppLayerEventTest02, 1);
UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03, 1);
UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04, 1);
UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05, 1);
#endif /* UNITTESTS */
return;

@ -677,6 +677,8 @@ int DetectByteExtractSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
sm_list = DETECT_SM_LIST_PMATCH;
} else {
sm_list = SigMatchListSMBelongsTo(s, prev_pm);
if (sm_list != DETECT_SM_LIST_PMATCH)
s->flags |= SIG_FLAG_APPLAYER;
}
} else {

@ -269,14 +269,15 @@ int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbounces
*/
sm->ctx = NULL;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
s->alproto = ALPROTO_FTP;
s->flags |= SIG_FLAG_APPLAYER;
SCReturnInt(0);
error:

@ -1427,8 +1427,6 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
if (sig->sm_lists[DETECT_SM_LIST_MATCH] != NULL) {
SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_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->init_flags |= SIG_FLAG_INIT_PACKET;
}
@ -1437,6 +1435,9 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
}
}
if (sig->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
sig->flags |= SIG_FLAG_APPLAYER;
if (sig->sm_lists[DETECT_SM_LIST_UMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_DMATCH])

@ -244,16 +244,17 @@ static int DetectSshVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *s
if (sm == NULL)
goto error;
sm->type = DETECT_AL_SSH_PROTOVERSION;
sm->ctx = (void *)ssh;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_SSH) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
sm->type = DETECT_AL_SSH_PROTOVERSION;
sm->ctx = (void *)ssh;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_SSH;
return 0;

@ -225,17 +225,19 @@ static int DetectSshSoftwareVersionSetup (DetectEngineCtx *de_ctx, Signature *s,
if (sm == NULL)
goto error;
sm->type = DETECT_AL_SSH_SOFTWAREVERSION;
sm->ctx = (void *)ssh;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_SSH) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
sm->type = DETECT_AL_SSH_SOFTWAREVERSION;
sm->ctx = (void *)ssh;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_SSH;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
return 0;
error:

@ -344,17 +344,19 @@ static int DetectTlsSubjectSetup (DetectEngineCtx *de_ctx, Signature *s, char *s
if (sm == NULL)
goto error;
sm->type = DETECT_AL_TLS_SUBJECT;
sm->ctx = (void *)tls;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
sm->type = DETECT_AL_TLS_SUBJECT;
sm->ctx = (void *)tls;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_TLS;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
return 0;
error:
@ -544,17 +546,19 @@ static int DetectTlsIssuerDNSetup (DetectEngineCtx *de_ctx, Signature *s, char *
if (sm == NULL)
goto error;
sm->type = DETECT_AL_TLS_ISSUERDN;
sm->ctx = (void *)tls;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
sm->type = DETECT_AL_TLS_ISSUERDN;
sm->ctx = (void *)tls;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_TLS;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
return 0;
error:
@ -733,17 +737,19 @@ static int DetectTlsFingerprintSetup (DetectEngineCtx *de_ctx, Signature *s, cha
if (sm == NULL)
goto error;
sm->type = DETECT_AL_TLS_FINGERPRINT;
sm->ctx = (void *)tls;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
sm->type = DETECT_AL_TLS_FINGERPRINT;
sm->ctx = (void *)tls;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_TLS;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
return 0;
error:
@ -788,15 +794,17 @@ static int DetectTlsStoreSetup (DetectEngineCtx *de_ctx, Signature *s, char *str
if (sm == NULL)
goto error;
sm->type = DETECT_AL_TLS_STORE;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
goto error;
}
sm->type = DETECT_AL_TLS_STORE;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_TLS;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
return 0;
error:

@ -2043,7 +2043,7 @@ PacketCreateMask(Packet *p, SignatureMask *mask, uint16_t alproto, void *alstate
(*mask) |= SIG_MASK_REQUIRE_NO_PAYLOAD;
}
if (p->events.cnt > 0 || app_decoder_events != 0) {
if (p->events.cnt > 0 || app_decoder_events != 0 || p->app_layer_events != NULL) {
SCLogDebug("packet/flow has events set");
(*mask) |= SIG_MASK_REQUIRE_ENGINE_EVENT;
}
@ -2251,6 +2251,9 @@ static int SignatureCreateMask(Signature *s) {
}
break;
}
case DETECT_AL_APP_LAYER_EVENT:
s->mask |= SIG_MASK_REQUIRE_ENGINE_EVENT;
break;
case DETECT_ENGINE_EVENT:
s->mask |= SIG_MASK_REQUIRE_ENGINE_EVENT;
break;

Loading…
Cancel
Save