suricata
detect-bypass.c
Go to the documentation of this file.
1 /* Copyright (C) 2016 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Giuseppe Longo <glongo@stamus-networks.com>
22  *
23  */
24 
25 #include "suricata-common.h"
26 #include "threads.h"
27 #include "app-layer.h"
28 #include "app-layer-parser.h"
29 #include "debug.h"
30 #include "decode.h"
31 
32 #include "detect.h"
33 #include "detect-parse.h"
34 
35 #include "detect-engine.h"
36 #include "detect-engine-mpm.h"
37 #include "detect-engine-state.h"
38 #include "detect-engine-sigorder.h"
39 #include "detect-bypass.h"
40 
41 #include "flow.h"
42 #include "flow-var.h"
43 #include "flow-util.h"
44 
45 #include "stream-tcp.h"
46 
47 #include "util-debug.h"
48 #include "util-spm-bm.h"
49 #include "util-unittest.h"
50 #include "util-unittest-helper.h"
51 #include "util-device.h"
52 
53 static int DetectBypassMatch(DetectEngineThreadCtx *, Packet *,
54  const Signature *, const SigMatchCtx *);
55 static int DetectBypassSetup(DetectEngineCtx *, Signature *, const char *);
56 #ifdef UNITTESTS
57 static void DetectBypassRegisterTests(void);
58 #endif
59 
60 /**
61  * \brief Registration function for keyword: bypass
62  */
64 {
65  sigmatch_table[DETECT_BYPASS].name = "bypass";
66  sigmatch_table[DETECT_BYPASS].desc = "call the bypass callback when the match of a sig is complete";
67  sigmatch_table[DETECT_BYPASS].url = "/rules/bypass-keyword.html";
68  sigmatch_table[DETECT_BYPASS].Match = DetectBypassMatch;
69  sigmatch_table[DETECT_BYPASS].Setup = DetectBypassSetup;
71 #ifdef UNITTESTS
72  sigmatch_table[DETECT_BYPASS].RegisterTests = DetectBypassRegisterTests;
73 #endif
75 }
76 
77 static int DetectBypassSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
78 {
79  SigMatch *sm = NULL;
80 
81  if (s->flags & SIG_FLAG_FILESTORE) {
83  "bypass can't work with filestore keyword");
84  return -1;
85  }
86  s->flags |= SIG_FLAG_BYPASS;
87 
88  sm = SigMatchAlloc();
89  if (sm == NULL)
90  return -1;
91 
92  sm->type = DETECT_BYPASS;
93  sm->ctx = NULL;
95 
96  return 0;
97 }
98 
99 static int DetectBypassMatch(DetectEngineThreadCtx *det_ctx, Packet *p,
100  const Signature *s, const SigMatchCtx *ctx)
101 {
103 
104  return 1;
105 }
106 
107 #ifdef UNITTESTS
108 #include "app-layer-htp.h"
109 
110 static int callback_var = 0;
111 
112 static int BypassCallback(Packet *p)
113 {
114  callback_var = 1;
115  return 1;
116 }
117 
118 static void ResetCallbackVar(void)
119 {
120  callback_var = 0;
121 }
122 
123 static int DetectBypassTestSig01(void)
124 {
125  TcpSession ssn;
126  Packet *p1 = NULL;
127  Packet *p2 = NULL;
128  ThreadVars th_v;
129  DetectEngineCtx *de_ctx = NULL;
130  DetectEngineThreadCtx *det_ctx = NULL;
131  HtpState *http_state = NULL;
132  Flow f;
133  uint8_t http_buf1[] =
134  "GET /index.html HTTP/1.0\r\n"
135  "Host: This is dummy message body\r\n"
136  "User-Agent: www.openinfosecfoundation.org\r\n"
137  "Content-Type: text/html\r\n"
138  "\r\n";
139  uint32_t http_len1 = sizeof(http_buf1) - 1;
140  uint8_t http_buf2[] =
141  "HTTP/1.0 200 ok\r\n"
142  "Content-Type: text/html\r\n"
143  "Content-Length: 7\r\n"
144  "\r\n"
145  "message";
146  uint32_t http_len2 = sizeof(http_buf2) - 1;
148  LiveDevice *livedev = SCMalloc(sizeof(LiveDevice));
149  FAIL_IF(livedev == NULL);
150 
151  memset(&th_v, 0, sizeof(th_v));
152  memset(&f, 0, sizeof(f));
153  memset(&ssn, 0, sizeof(ssn));
154 
155  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
156  FAIL_IF(p1 == NULL);
157  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
158  FAIL_IF(p2 == NULL);
159 
160  p1->BypassPacketsFlow = BypassCallback;
161  p2->BypassPacketsFlow = BypassCallback;
162 
163  FLOW_INITIALIZE(&f);
164  f.protoctx = (void *)&ssn;
165  f.proto = IPPROTO_TCP;
166  f.flags |= FLOW_IPV4;
167 
168  p1->flow = &f;
172  p1->livedev = livedev;
173  p2->flow = &f;
177  p2->livedev = livedev;
178  f.alproto = ALPROTO_HTTP;
179 
181 
183  FAIL_IF(de_ctx == NULL);
184 
185  de_ctx->flags |= DE_QUIET;
186 
187  const char *sigs[3];
188  sigs[0] = "alert tcp any any -> any any (bypass; content:\"GET \"; sid:1;)";
189  sigs[1] = "alert http any any -> any any "
190  "(bypass; content:\"message\"; http_server_body; "
191  "sid:2;)";
192  sigs[2] = "alert http any any -> any any "
193  "(bypass; content:\"message\"; http_host; "
194  "sid:3;)";
195  FAIL_IF(UTHAppendSigs(de_ctx, sigs, 3) == 0);
196 
200 
202  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
203 
204  FLOWLOCK_WRLOCK(&f);
205  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
206  STREAM_TOSERVER, http_buf1, http_len1);
207  FAIL_IF(r != 0);
208  FLOWLOCK_UNLOCK(&f);
209 
210  http_state = f.alstate;
211  FAIL_IF(http_state == NULL);
212 
213  /* do detect */
214  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
215 
216  FAIL_IF(PacketAlertCheck(p1, 1));
217 
218  FLOWLOCK_WRLOCK(&f);
220  http_buf2, http_len2);
221  FAIL_IF(r != 0);
222  FLOWLOCK_UNLOCK(&f);
223  /* do detect */
224  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
225 
226  FAIL_IF(!(PacketAlertCheck(p2, 2)));
227  FAIL_IF(!(PacketAlertCheck(p1, 3)));
228 
229  FAIL_IF(callback_var == 0);
230 
232  FLOW_DESTROY(&f);
233  UTHFreePacket(p1);
234  UTHFreePacket(p2);
235  ResetCallbackVar();
236  SCFree(livedev);
237  PASS;
238 }
239 
240 static void DetectBypassRegisterTests(void)
241 {
242  UtRegisterTest("DetectBypassTestSig01", DetectBypassTestSig01);
243 }
244 #endif /* UNITTESTS */
DETECT_BYPASS
@ DETECT_BYPASS
Definition: detect-engine-register.h:288
SigTableElmt_::url
const char * url
Definition: detect.h:1214
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1213
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1109
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1201
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1211
PacketBypassCallback
void PacketBypassCallback(Packet *p)
Definition: decode.c:408
stream-tcp.h
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Flow_::proto
uint8_t proto
Definition: flow.h:365
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:138
Packet_::flags
uint32_t flags
Definition: decode.h:449
threads.h
Flow_
Flow data structure.
Definition: flow.h:347
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1205
LiveDevice_
Definition: util-device.h:40
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:767
SCSigSignatureOrderingModuleCleanup
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
Definition: detect-engine-sigorder.c:808
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:219
DE_QUIET
#define DE_QUIET
Definition: detect.h:294
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:445
Packet_::BypassPacketsFlow
int(* BypassPacketsFlow)(struct Packet_ *)
Definition: decode.h:496
Flow_::protoctx
void * protoctx
Definition: flow.h:441
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1196
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:95
util-unittest.h
HtpState_
Definition: app-layer-htp.h:243
util-unittest-helper.h
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:264
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:98
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
app-layer-htp.h
decode.h
util-device.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1010
SCSigOrderSignatures
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
Definition: detect-engine-sigorder.c:728
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
SIG_FLAG_BYPASS
#define SIG_FLAG_BYPASS
Definition: detect.h:241
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:19
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:261
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SCSigRegisterSignatureOrderingFuncs
void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
Lets you register the Signature ordering functions. The order in which the functions are registered,...
Definition: detect-engine-sigorder.c:788
app-layer-parser.h
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:323
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1688
Signature_::flags
uint32_t flags
Definition: detect.h:529
Packet_
Definition: decode.h:414
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
Packet_::livedev
struct LiveDevice_ * livedev
Definition: decode.h:562
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1179
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:220
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1888
SigMatch_::type
uint8_t type
Definition: detect.h:321
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:252
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:315
detect-bypass.h
DetectBypassRegister
void DetectBypassRegister(void)
Registration function for keyword: bypass.
Definition: detect-bypass.c:63
Packet_::flow
struct Flow_ * flow
Definition: decode.h:451
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2797
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1203
suricata-common.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
util-spm-bm.h
detect-engine-sigorder.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:273
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:485
Flow_::alstate
void * alstate
Definition: flow.h:476
Flow_::flags
uint32_t flags
Definition: flow.h:421
detect-parse.h
Signature_
Signature container.
Definition: detect.h:528
SigMatch_
a single match condition for a signature
Definition: detect.h:320
ALPROTO_HTTP
@ ALPROTO_HTTP
Definition: app-layer-protos.h:30
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:221
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2048
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1380
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:768
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:87
UTHAppendSigs
int UTHAppendSigs(DetectEngineCtx *de_ctx, const char *sigs[], int numsigs)
UTHAppendSigs: Add sigs to the detection_engine checking for errors.
Definition: util-unittest-helper.c:681
TcpSession_
Definition: stream-tcp-private.h:260
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
flow-var.h
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:130
SIG_FLAG_FILESTORE
#define SIG_FLAG_FILESTORE
Definition: detect.h:234
debug.h
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1107
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1203
app-layer.h
SC_ERR_CONFLICTING_RULE_KEYWORDS
@ SC_ERR_CONFLICTING_RULE_KEYWORDS
Definition: util-error.h:171