suricata
detect-depth.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2019 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 Victor Julien <victor@inliniac.net>
22 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23 *
24 * Implements the depth keyword.
25 */
26
27#include "suricata-common.h"
28
29#include "decode.h"
30
31#include "detect.h"
32#include "detect-parse.h"
33#include "detect-content.h"
34#include "detect-uricontent.h"
35#include "detect-byte.h"
36#include "detect-byte-extract.h"
37#include "detect-depth.h"
38
39#include "flow-var.h"
40#include "app-layer.h"
41
42#include "util-byte.h"
43#include "util-debug.h"
44
45static int DetectDepthSetup (DetectEngineCtx *, Signature *, const char *);
46static int DetectStartsWithSetup (DetectEngineCtx *, Signature *, const char *);
47
49{
51 sigmatch_table[DETECT_DEPTH].desc = "designate how many bytes from the beginning of the payload will be checked";
52 sigmatch_table[DETECT_DEPTH].url = "/rules/payload-keywords.html#depth";
54 sigmatch_table[DETECT_DEPTH].Setup = DetectDepthSetup;
56
58 sigmatch_table[DETECT_STARTS_WITH].desc = "pattern must be at the start of a buffer (same as 'depth:<pattern len>')";
59 sigmatch_table[DETECT_STARTS_WITH].url = "/rules/payload-keywords.html#startswith";
60 sigmatch_table[DETECT_STARTS_WITH].Setup = DetectStartsWithSetup;
62}
63
64static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, const char *depthstr)
65{
66 const char *str = depthstr;
67 SigMatch *pm = NULL;
68 int ret = -1;
69
70 /* retrieve the sm to apply the depth against */
72 if (pm == NULL) {
73 SCLogError("depth needs "
74 "preceding content, uricontent option, http_client_body, "
75 "http_server_body, http_header option, http_raw_header option, "
76 "http_method option, http_cookie, http_raw_uri, "
77 "http_stat_msg, http_stat_code, http_user_agent, "
78 "http_host, http_raw_host or "
79 "file_data/dce_stub_data sticky buffer options.");
80 goto end;
81 }
82
83 /* verify other conditions. */
85
86 if (cd->flags & DETECT_CONTENT_DEPTH) {
87 SCLogError("can't use multiple depths for the same content.");
88 goto end;
89 }
90 if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) {
91 SCLogError("can't use a relative "
92 "keyword like within/distance with a absolute "
93 "relative keyword like depth/offset for the same "
94 "content.");
95 goto end;
96 }
97 if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) {
98 SCLogError("can't have a relative "
99 "negated keyword set along with 'fast_pattern'.");
100 goto end;
101 }
102 if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
103 SCLogError("can't have a relative "
104 "keyword set along with 'fast_pattern:only;'.");
105 goto end;
106 }
107 if (str[0] != '-' && isalpha((unsigned char)str[0])) {
109 if (!DetectByteRetrieveSMVar(str, s, -1, &index)) {
110 SCLogError("unknown byte_ keyword var "
111 "seen in depth - %s.",
112 str);
113 goto end;
114 }
115 cd->depth = index;
116 cd->flags |= DETECT_CONTENT_DEPTH_VAR;
117 } else {
118 if (StringParseUint16(&cd->depth, 0, 0, str) < 0)
119 {
120 SCLogError("invalid value for depth: %s.", str);
121 goto end;
122 }
123
124 if (cd->depth < cd->content_len) {
125 SCLogError("depth:%u smaller than "
126 "content of len %u.",
127 cd->depth, cd->content_len);
128 return -1;
129 }
130 /* Now update the real limit, as depth is relative to the offset */
131 cd->depth += cd->offset;
132 }
133 cd->flags |= DETECT_CONTENT_DEPTH;
134
135 ret = 0;
136 end:
137 return ret;
138}
139
140static int DetectStartsWithSetup (DetectEngineCtx *de_ctx, Signature *s, const char *unused)
141{
142 SigMatch *pm = NULL;
143 int ret = -1;
144
145 /* retrieve the sm to apply the depth against */
147 if (pm == NULL) {
148 SCLogError("startswith needs a "
149 "preceding content option.");
150 goto end;
151 }
152
153 /* verify other conditions. */
155
156 if (cd->flags & DETECT_CONTENT_DEPTH) {
157 SCLogError("can't use multiple "
158 "depth/startswith settings for the same content.");
159 goto end;
160 }
161 if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) {
162 SCLogError("can't use a relative "
163 "keyword like within/distance with a absolute "
164 "relative keyword like depth/offset for the same "
165 "content.");
166 goto end;
167 }
168 if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) {
169 SCLogError("can't have a relative "
170 "negated keyword set along with a 'fast_pattern'.");
171 goto end;
172 }
173 if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
174 SCLogError("can't have a relative "
175 "keyword set along with 'fast_pattern:only;'.");
176 goto end;
177 }
178 if (cd->flags & DETECT_CONTENT_OFFSET) {
179 SCLogError("can't mix offset "
180 "with startswith.");
181 goto end;
182 }
183
184 cd->depth = cd->content_len;
185 cd->flags |= DETECT_CONTENT_DEPTH;
186 cd->flags |= DETECT_CONTENT_STARTS_WITH;
187
188 ret = 0;
189 end:
190 return ret;
191}
bool DetectByteRetrieveSMVar(const char *arg, const Signature *s, int sm_list, DetectByteIndexType *index)
Used to retrieve args from BM.
Definition detect-byte.c:41
uint8_t DetectByteIndexType
Definition detect-byte.h:28
#define DETECT_CONTENT_STARTS_WITH
#define DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_FAST_PATTERN_ONLY
#define DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_FAST_PATTERN
#define DETECT_CONTENT_DEPTH_VAR
#define DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_NEGATED
void DetectDepthRegister(void)
@ DETECT_STARTS_WITH
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
SigTableElmt * sigmatch_table
#define SIGMATCH_NOOPT
Definition detect.h:1651
DetectEngineCtx * de_ctx
main detection engine ctx
Definition detect.h:932
a single match condition for a signature
Definition detect.h:356
SigMatchCtx * ctx
Definition detect.h:359
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
#define str(s)
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:337
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267