suricata
detect-target.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 
28 #include "detect-parse.h"
29 #include "detect-engine.h"
30 
31 #include "detect-target.h"
32 
33 /**
34  * \brief Regex for parsing our keyword options
35  */
36 #define PARSE_REGEX "^\\s*(src_ip|dest_ip)\\s*$"
37 
38 static DetectParseRegex parse_regex;
39 
40 /* Prototypes of functions registered in DetectTargetRegister below */
41 static int DetectTargetSetup (DetectEngineCtx *, Signature *, const char *);
42 #ifdef UNITTESTS
43 static void DetectTargetRegisterTests (void);
44 #endif
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 = "/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 #ifdef UNITTESTS
67  sigmatch_table[DETECT_TARGET].RegisterTests = DetectTargetRegisterTests;
68 #endif
69  /* set up the PCRE for keyword parsing */
70  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
71 }
72 
73 /**
74  * \brief This function is used to parse target options passed via target: keyword
75  *
76  * \param targetstr Pointer to the user provided target options
77  *
78  * \retval 0 on Success
79  * \retval -1 on Failure
80  */
81 static int DetectTargetParse(Signature *s, const char *targetstr)
82 {
83  size_t pcre2len;
84  char value[10];
85 
86  pcre2_match_data *match = NULL;
87  int ret = DetectParsePcreExec(&parse_regex, &match, targetstr, 0, 0);
88  if (ret < 1) {
89  SCLogError("pcre_exec parse error, ret %" PRId32 ", string %s", ret, targetstr);
90  goto error;
91  }
92 
93  pcre2len = sizeof(value);
94  int res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)value, &pcre2len);
95  if (res < 0) {
96  SCLogError("pcre2_substring_copy_bynumber failed");
97  goto error;
98  }
99 
100  /* now check key value */
101  if (!strcmp(value, "src_ip")) {
102  if (s->flags & SIG_FLAG_DEST_IS_TARGET) {
103  SCLogError("Conflicting values of target keyword");
104  goto error;
105  }
107  } else if (!strcmp(value, "dest_ip")) {
108  if (s->flags & SIG_FLAG_SRC_IS_TARGET) {
109  SCLogError("Conflicting values of target keyword");
110  goto error;
111  }
113  } else {
114  SCLogError("only 'src_ip' and 'dest_ip' are supported as target value");
115  goto error;
116  }
117  pcre2_match_data_free(match);
118  return 0;
119 
120 error:
121  if (match) {
122  pcre2_match_data_free(match);
123  }
124  return -1;
125 }
126 
127 /**
128  * \brief parse the options from the 'target' keyword in the rule into
129  * the Signature data structure.
130  *
131  * \param de_ctx pointer to the Detection Engine Context
132  * \param s pointer to the Current Signature
133  * \param targetstr pointer to the user provided target options
134  *
135  * \retval 0 on Success
136  * \retval -1 on Failure
137  */
138 static int DetectTargetSetup(DetectEngineCtx *de_ctx, Signature *s, const char *targetstr)
139 {
140  int ret = DetectTargetParse(s, targetstr);
141  if (ret < 0)
142  return -1;
143 
144  return 0;
145 }
146 
147 #ifdef UNITTESTS
148 
149 static int DetectTargetSignatureTest01(void)
150 {
153 
154  Signature *sig = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (target: dest_ip; sid:1; rev:1;)");
155  FAIL_IF_NULL(sig);
156 
158  PASS;
159 }
160 
161 /**
162  * \brief this function registers unit tests for DetectTarget
163  */
164 static void DetectTargetRegisterTests(void)
165 {
166  UtRegisterTest("DetectTargetSignatureTest01",
167  DetectTargetSignatureTest01);
168 }
169 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1545
detect-target.h
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1544
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:78
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1529
DetectParseRegex
Definition: detect-parse.h:94
SigTableElmt_::name
const char * name
Definition: detect.h:1542
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
SIG_FLAG_DEST_IS_TARGET
#define SIG_FLAG_DEST_IS_TARGET
Definition: detect.h:288
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:995
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2912
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:4019
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3965
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1524
DetectTargetRegister
void DetectTargetRegister(void)
Registration function for target keyword.
Definition: detect-target.c:50
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:4145
PARSE_REGEX
#define PARSE_REGEX
Regex for parsing our keyword options.
Definition: detect-target.c:36
Signature_::flags
uint32_t flags
Definition: detect.h:693
DETECT_TARGET
@ DETECT_TARGET
Definition: detect-engine-register.h:276
SIG_FLAG_SRC_IS_TARGET
#define SIG_FLAG_SRC_IS_TARGET
Definition: detect.h:286
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1504
suricata-common.h
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
detect-parse.h
Signature_
Signature container.
Definition: detect.h:692
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2873
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1531