suricata
detect-target.c
Go to the documentation of this file.
1 /* Copyright (C) 2017 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 Eric Leblond <eric@regit.org>
22  *
23  * target keyword allow rules writer to specify information about target of the attack
24  */
25 
26 #include "suricata-common.h"
27 #include "util-unittest.h"
28 
29 #include "detect-parse.h"
30 #include "detect-engine.h"
31 
32 #include "detect-target.h"
33 
34 /**
35  * \brief Regex for parsing our keyword options
36  */
37 #define PARSE_REGEX "^\\s*(src_ip|dest_ip)\\s*$"
38 
39 static pcre *parse_regex;
40 static pcre_extra *parse_regex_study;
41 
42 /* Prototypes of functions registered in DetectTargetRegister below */
43 static int DetectTargetSetup (DetectEngineCtx *, Signature *, const char *);
44 static void DetectTargetRegisterTests (void);
45 
46 /**
47  * \brief Registration function for target keyword
48  *
49  */
51  /* keyword name: this is how the keyword is used in a rule */
52  sigmatch_table[DETECT_TARGET].name = "target";
53  /* description: listed in "suricata --list-keywords=all" */
54  sigmatch_table[DETECT_TARGET].desc = "indicate to output module which side is the target of the attack";
55  /* link to further documentation of the keyword. Normally on the Suricata redmine/wiki */
56  sigmatch_table[DETECT_TARGET].url = DOC_URL DOC_VERSION "/rules/meta.html#target";
57  /* match function is called when the signature is inspected on a packet */
59  /* setup function is called during signature parsing, when the target
60  * keyword is encountered in the rule */
61  sigmatch_table[DETECT_TARGET].Setup = DetectTargetSetup;
62  /* free function is called when the detect engine is freed. Normally at
63  * shutdown, but also during rule reloads. */
65  /* registers unittests into the system */
66  sigmatch_table[DETECT_TARGET].RegisterTests = DetectTargetRegisterTests;
67 
68  /* set up the PCRE for keyword parsing */
69  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
70 }
71 
72 /**
73  * \brief This function is used to parse target options passed via target: keyword
74  *
75  * \param targetstr Pointer to the user provided target options
76  *
77  * \retval targetd pointer to DetectTargetData on success
78  * \retval NULL on failure
79  */
80 static int DetectTargetParse(Signature *s, const char *targetstr)
81 {
82 #define MAX_SUBSTRINGS 30
83  int ret = 0, res = 0;
84  int ov[MAX_SUBSTRINGS];
85  char value[10];
86 
87  ret = pcre_exec(parse_regex, parse_regex_study,
88  targetstr, strlen(targetstr), 0, 0, ov, MAX_SUBSTRINGS);
89  if (ret < 1) {
90  SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, targetstr);
91  return -1;
92  }
93 
94  res = pcre_copy_substring(targetstr, ov, MAX_SUBSTRINGS, 1,
95  value, sizeof(value));
96  if (res < 0) {
97  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
98  return -1;
99  }
100 
101  /* now check key value */
102  if (!strcmp(value, "src_ip")) {
103  if (s->flags & SIG_FLAG_DEST_IS_TARGET) {
105  "Conflicting values of target keyword");
106  return -1;
107  }
109  } else if (!strcmp(value, "dest_ip")) {
110  if (s->flags & SIG_FLAG_SRC_IS_TARGET) {
112  "Conflicting values of target keyword");
113  return -1;
114  }
116  } else {
117  SCLogError(SC_ERR_INVALID_VALUE, "only 'src_ip' and 'dest_ip' are supported as target value");
118  return -1;
119  }
120  return 0;
121 }
122 
123 /**
124  * \brief parse the options from the 'target' keyword in the rule into
125  * the Signature data structure.
126  *
127  * \param de_ctx pointer to the Detection Engine Context
128  * \param s pointer to the Current Signature
129  * \param targetstr pointer to the user provided target options
130  *
131  * \retval 0 on Success
132  * \retval -1 on Failure
133  */
134 static int DetectTargetSetup(DetectEngineCtx *de_ctx, Signature *s, const char *targetstr)
135 {
136  int ret = DetectTargetParse(s, targetstr);
137  if (ret < 0)
138  return -1;
139 
140  return 0;
141 }
142 
143 #ifdef UNITTESTS
144 
145 static int DetectTargetSignatureTest01(void)
146 {
148  FAIL_IF_NULL(de_ctx);
149 
150  Signature *sig = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (target: dest_ip; sid:1; rev:1;)");
151  FAIL_IF_NULL(sig);
152 
153  DetectEngineCtxFree(de_ctx);
154  PASS;
155 }
156 
157 #endif /* UNITTESTS */
158 
159 /**
160  * \brief this function registers unit tests for DetectTarget
161  */
162 void DetectTargetRegisterTests(void) {
163 #ifdef UNITTESTS
164  UtRegisterTest("DetectTargetSignatureTest01",
165  DetectTargetSignatureTest01);
166 #endif /* UNITTESTS */
167 }
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1439
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1179
uint32_t flags
Definition: detect.h:518
#define PASS
Pass the test.
void DetectTargetRegister(void)
Registration function for target keyword.
Definition: detect-target.c:50
const char * name
Definition: detect.h:1193
#define SIG_FLAG_DEST_IS_TARGET
Definition: detect.h:247
Signature container.
Definition: detect.h:517
#define SIG_FLAG_SRC_IS_TARGET
Definition: detect.h:245
main detection engine ctx
Definition: detect.h:756
void(* Free)(void *)
Definition: detect.h:1184
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1163
#define PARSE_REGEX
Regex for parsing our keyword options.
Definition: detect-target.c:37
const char * desc
Definition: detect.h:1195
PoolThreadReserved res
const char * url
Definition: detect.h:1196
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define DOC_URL
Definition: suricata.h:86
#define MAX_SUBSTRINGS
#define DOC_VERSION
Definition: suricata.h:91
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void(* RegisterTests)(void)
Definition: detect.h:1185
DetectEngineCtx * DetectEngineCtxInit(void)