suricata
detect-krb5-msgtype.c
Go to the documentation of this file.
1/* Copyright (C) 2018-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 Pierre Chifflier <chifflier@wzdftpd.net>
22 */
23
24#include "suricata-common.h"
25#include "util-unittest.h"
26#include "util-byte.h"
27
28#include "detect-parse.h"
29#include "detect-engine.h"
30
31#include "detect-krb5-msgtype.h"
32
33#include "rust.h"
34
35/**
36 * \brief Regex for parsing our keyword options
37 */
38#define PARSE_REGEX "^\\s*([A-z0-9\\.]+|\"[A-z0-9_\\.]+\")\\s*$"
39static DetectParseRegex parse_regex;
40
41/* Prototypes of functions registered in DetectKrb5MsgTypeRegister below */
42static int DetectKrb5MsgTypeMatch (DetectEngineThreadCtx *, Flow *,
43 uint8_t, void *, void *, const Signature *,
44 const SigMatchCtx *);
45static int DetectKrb5MsgTypeSetup (DetectEngineCtx *, Signature *, const char *);
46static void DetectKrb5MsgTypeFree (DetectEngineCtx *, void *);
47#ifdef UNITTESTS
48static void DetectKrb5MsgTypeRegisterTests (void);
49#endif
50
51static int g_krb5_msg_type_list_id = 0;
52
53/**
54 * \brief Registration function for krb5_msg_type: keyword
55 *
56 * This function is called once in the 'lifetime' of the engine.
57 */
59{
60 sigmatch_table[DETECT_KRB5_MSGTYPE].name = "krb5_msg_type";
61 sigmatch_table[DETECT_KRB5_MSGTYPE].desc = "match Kerberos 5 message type";
62 sigmatch_table[DETECT_KRB5_MSGTYPE].url = "/rules/kerberos-keywords.html#krb5-msg-type";
64 sigmatch_table[DETECT_KRB5_MSGTYPE].AppLayerTxMatch = DetectKrb5MsgTypeMatch;
65 sigmatch_table[DETECT_KRB5_MSGTYPE].Setup = DetectKrb5MsgTypeSetup;
66 sigmatch_table[DETECT_KRB5_MSGTYPE].Free = DetectKrb5MsgTypeFree;
67#ifdef UNITTESTS
68 sigmatch_table[DETECT_KRB5_MSGTYPE].RegisterTests = DetectKrb5MsgTypeRegisterTests;
69#endif
70
73
76
77 /* set up the PCRE for keyword parsing */
79
80 g_krb5_msg_type_list_id = DetectBufferTypeRegister("krb5_msg_type");
81 SCLogDebug("g_krb5_msg_type_list_id %d", g_krb5_msg_type_list_id);
82}
83
84/**
85 * \brief This function is used to match KRB5 rule option on a packet
86 *
87 * \param t pointer to thread vars
88 * \param det_ctx pointer to the pattern matcher thread
89 * \param p pointer to the current packet
90 * \param m pointer to the sigmatch with context that we will cast into DetectKrb5Data
91 *
92 * \retval 0 no match
93 * \retval 1 match
94 */
95static int DetectKrb5MsgTypeMatch (DetectEngineThreadCtx *det_ctx,
96 Flow *f, uint8_t flags, void *state,
97 void *txv, const Signature *s,
98 const SigMatchCtx *ctx)
99{
100 uint32_t msg_type;
102
103 SCEnter();
104
105 SCKrb5TxGetMsgType(txv, &msg_type);
106
107 if (dd->msg_type == msg_type)
108 SCReturnInt(1);
109
110 SCReturnInt(0);
111}
112
113/**
114 * \brief This function is used to parse options passed via krb5_msgtype: keyword
115 *
116 * \param krb5str Pointer to the user provided krb5_msg_type options
117 *
118 * \retval krb5d pointer to DetectKrb5Data on success
119 * \retval NULL on failure
120 */
121static DetectKrb5MsgTypeData *DetectKrb5MsgTypeParse (const char *krb5str)
122{
123 DetectKrb5MsgTypeData *krb5d = NULL;
124 char arg1[4] = "";
125 int res = 0;
126 size_t pcre2len;
127
128 pcre2_match_data *match = NULL;
129 int ret = DetectParsePcreExec(&parse_regex, &match, krb5str, 0, 0);
130 if (ret != 2) {
131 SCLogError("parse error, ret %" PRId32 "", ret);
132 goto error;
133 }
134
135 pcre2len = sizeof(arg1);
136 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)arg1, &pcre2len);
137 if (res < 0) {
138 SCLogError("pcre2_substring_copy_bynumber failed");
139 goto error;
140 }
141
142 krb5d = SCMalloc(sizeof (DetectKrb5MsgTypeData));
143 if (unlikely(krb5d == NULL))
144 goto error;
145 if (StringParseUint8(&krb5d->msg_type, 10, 0,
146 (const char *)arg1) < 0) {
147 goto error;
148 }
149 pcre2_match_data_free(match);
150 return krb5d;
151
152error:
153 if (match) {
154 pcre2_match_data_free(match);
155 }
156 if (krb5d)
157 SCFree(krb5d);
158 return NULL;
159}
160
161/**
162 * \brief parse the options from the 'krb5_msg_type' keyword in the rule into
163 * the Signature data structure.
164 *
165 * \param de_ctx pointer to the Detection Engine Context
166 * \param s pointer to the Current Signature
167 * \param krb5str pointer to the user provided options
168 *
169 * \retval 0 on Success
170 * \retval -1 on Failure
171 */
172static int DetectKrb5MsgTypeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *krb5str)
173{
174 DetectKrb5MsgTypeData *krb5d = NULL;
175
177 return -1;
178
179 krb5d = DetectKrb5MsgTypeParse(krb5str);
180 if (krb5d == NULL)
181 goto error;
182
184 g_krb5_msg_type_list_id) == NULL) {
185 goto error;
186 }
187
188 return 0;
189
190error:
191 if (krb5d != NULL)
192 DetectKrb5MsgTypeFree(de_ctx, krb5d);
193 return -1;
194}
195
196/**
197 * \brief this function will free memory associated with DetectKrb5Data
198 *
199 * \param ptr pointer to DetectKrb5Data
200 */
201static void DetectKrb5MsgTypeFree(DetectEngineCtx *de_ctx, void *ptr) {
203
204 SCFree(krb5d);
205}
206
207#ifdef UNITTESTS
208
209/**
210 * \test description of the test
211 */
212
213static int DetectKrb5MsgTypeParseTest01 (void)
214{
215 DetectKrb5MsgTypeData *krb5d = DetectKrb5MsgTypeParse("10");
216 FAIL_IF_NULL(krb5d);
217 FAIL_IF(!(krb5d->msg_type == 10));
218 DetectKrb5MsgTypeFree(NULL, krb5d);
219 PASS;
220}
221
222static int DetectKrb5MsgTypeSignatureTest01 (void)
223{
226
227 Signature *sig = DetectEngineAppendSig(de_ctx, "alert krb5 any any -> any any (krb5_msg_type:10; sid:1; rev:1;)");
228 FAIL_IF_NULL(sig);
229
231 PASS;
232}
233
234/**
235 * \brief this function registers unit tests for DetectKrb5MsgType
236 */
237static void DetectKrb5MsgTypeRegisterTests(void)
238{
239 UtRegisterTest("DetectKrb5MsgTypeParseTest01", DetectKrb5MsgTypeParseTest01);
240 UtRegisterTest("DetectKrb5MsgTypeSignatureTest01",
241 DetectKrb5MsgTypeSignatureTest01);
242}
243#endif /* UNITTESTS */
@ ALPROTO_KRB5
uint8_t flags
Definition decode-gre.h:0
@ DETECT_KRB5_MSGTYPE
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
int DetectBufferTypeRegister(const char *name)
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
void DetectKrb5MsgTypeRegister(void)
Registration function for krb5_msg_type: keyword.
#define PARSE_REGEX
Regex for parsing our keyword options.
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define SIG_FLAG_TOCLIENT
Definition detect.h:272
#define SIG_FLAG_TOSERVER
Definition detect.h:271
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
struct Thresholds ctx
main detection engine ctx
Definition detect.h:932
Flow data structure.
Definition flow.h:356
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
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
const char * desc
Definition detect.h:1461
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition detect.h:1424
void(* RegisterTests)(void)
Definition detect.h:1448
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
int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
Definition util-byte.c:361
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)