/src/suricata8/src/detect-dce-iface.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2022 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 Anoop Saldanha <anoopsaldanha@gmail.com> |
22 | | * |
23 | | * Implements dce_iface keyword. |
24 | | */ |
25 | | |
26 | | #include "suricata-common.h" |
27 | | |
28 | | #include "detect.h" |
29 | | #include "detect-parse.h" |
30 | | |
31 | | #include "detect-engine.h" |
32 | | #include "detect-engine-mpm.h" |
33 | | #include "detect-engine-state.h" |
34 | | #include "detect-engine-build.h" |
35 | | #include "detect-dce-iface.h" |
36 | | |
37 | | #include "flow.h" |
38 | | #include "flow-var.h" |
39 | | #include "flow-util.h" |
40 | | |
41 | | #include "app-layer.h" |
42 | | #include "queue.h" |
43 | | #include "stream-tcp-reassemble.h" |
44 | | |
45 | | #include "util-debug.h" |
46 | | #include "util-unittest.h" |
47 | | #include "util-unittest-helper.h" |
48 | | #include "stream-tcp.h" |
49 | | |
50 | | #include "rust.h" |
51 | | |
52 | 39 | #define PARSE_REGEX "^\\s*([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12})(?:\\s*,\\s*(<|>|=|!)([0-9]{1,5}))?(?:\\s*,\\s*(any_frag))?\\s*$" |
53 | | |
54 | | static DetectParseRegex parse_regex; |
55 | | |
56 | | static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx, |
57 | | Flow *f, uint8_t flags, void *state, void *txv, |
58 | | const Signature *s, const SigMatchCtx *m); |
59 | | static int DetectDceIfaceSetup(DetectEngineCtx *, Signature *, const char *); |
60 | | static void DetectDceIfaceFree(DetectEngineCtx *, void *); |
61 | | static int g_dce_generic_list_id = 0; |
62 | | |
63 | | /** |
64 | | * \brief Registers the keyword handlers for the "dce_iface" keyword. |
65 | | */ |
66 | | void DetectDceIfaceRegister(void) |
67 | 39 | { |
68 | 39 | sigmatch_table[DETECT_DCE_IFACE].name = "dcerpc.iface"; |
69 | 39 | sigmatch_table[DETECT_DCE_IFACE].alias = "dce_iface"; |
70 | 39 | sigmatch_table[DETECT_DCE_IFACE].AppLayerTxMatch = DetectDceIfaceMatchRust; |
71 | 39 | sigmatch_table[DETECT_DCE_IFACE].Setup = DetectDceIfaceSetup; |
72 | 39 | sigmatch_table[DETECT_DCE_IFACE].Free = DetectDceIfaceFree; |
73 | 39 | sigmatch_table[DETECT_DCE_IFACE].desc = |
74 | 39 | "match on the value of the interface UUID in a DCERPC header"; |
75 | 39 | sigmatch_table[DETECT_DCE_IFACE].url = "/rules/dcerpc-keywords.html#dcerpc-iface"; |
76 | 39 | DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); |
77 | | |
78 | 39 | g_dce_generic_list_id = DetectBufferTypeRegister("dce_generic"); |
79 | | |
80 | 39 | DetectAppLayerInspectEngineRegister("dce_generic", ALPROTO_DCERPC, SIG_FLAG_TOSERVER, 0, |
81 | 39 | DetectEngineInspectGenericList, NULL); |
82 | 39 | DetectAppLayerInspectEngineRegister( |
83 | 39 | "dce_generic", ALPROTO_SMB, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); |
84 | | |
85 | 39 | DetectAppLayerInspectEngineRegister("dce_generic", ALPROTO_DCERPC, SIG_FLAG_TOCLIENT, 0, |
86 | 39 | DetectEngineInspectGenericList, NULL); |
87 | 39 | DetectAppLayerInspectEngineRegister( |
88 | 39 | "dce_generic", ALPROTO_SMB, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); |
89 | 39 | } |
90 | | |
91 | | /** |
92 | | * \brief App layer match function for the "dce_iface" keyword. |
93 | | * |
94 | | * \param t Pointer to the ThreadVars instance. |
95 | | * \param det_ctx Pointer to the DetectEngineThreadCtx. |
96 | | * \param f Pointer to the flow. |
97 | | * \param flags Pointer to the flags indicating the flow direction. |
98 | | * \param state Pointer to the app layer state data. |
99 | | * \param s Pointer to the Signature instance. |
100 | | * \param m Pointer to the SigMatch. |
101 | | * |
102 | | * \retval 1 On Match. |
103 | | * \retval 0 On no match. |
104 | | */ |
105 | | static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx, |
106 | | Flow *f, uint8_t flags, void *state, void *txv, |
107 | | const Signature *s, const SigMatchCtx *m) |
108 | 0 | { |
109 | 0 | SCEnter(); |
110 | |
|
111 | 0 | if (f->alproto == ALPROTO_DCERPC) { |
112 | | // TODO check if state is NULL |
113 | 0 | return SCDcerpcIfaceMatch(txv, state, (void *)m); |
114 | 0 | } |
115 | | |
116 | 0 | int ret = 0; |
117 | |
|
118 | 0 | if (SCSmbTxGetDceIface(f->alstate, txv, (void *)m) != 1) { |
119 | 0 | SCLogDebug("SCSmbTxGetDceIface: didn't match"); |
120 | 0 | } else { |
121 | 0 | SCLogDebug("SCSmbTxGetDceIface: matched!"); |
122 | 0 | ret = 1; |
123 | | // TODO validate frag |
124 | 0 | } |
125 | 0 | SCReturnInt(ret); |
126 | 0 | } |
127 | | |
128 | | /** |
129 | | * \brief Creates a SigMatch for the "dce_iface" keyword being sent as argument, |
130 | | * and appends it to the Signature(s). |
131 | | * |
132 | | * \param de_ctx Pointer to the detection engine context. |
133 | | * \param s Pointer to signature for the current Signature being parsed |
134 | | * from the rules. |
135 | | * \param arg Pointer to the string holding the keyword value. |
136 | | * |
137 | | * \retval 0 on success, -1 on failure. |
138 | | */ |
139 | | |
140 | | static int DetectDceIfaceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) |
141 | 1.69k | { |
142 | 1.69k | SCEnter(); |
143 | | |
144 | 1.69k | if (SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) < 0) |
145 | 6 | return -1; |
146 | | |
147 | 1.68k | void *did = SCDcerpcIfaceParse(arg); |
148 | 1.68k | if (did == NULL) { |
149 | 356 | SCLogError("Error parsing dce_iface option in " |
150 | 356 | "signature"); |
151 | 356 | return -1; |
152 | 356 | } |
153 | | |
154 | 1.32k | if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_DCE_IFACE, did, g_dce_generic_list_id) == NULL) { |
155 | 0 | DetectDceIfaceFree(de_ctx, did); |
156 | 0 | return -1; |
157 | 0 | } |
158 | 1.32k | return 0; |
159 | 1.32k | } |
160 | | |
161 | | static void DetectDceIfaceFree(DetectEngineCtx *de_ctx, void *ptr) |
162 | 1.32k | { |
163 | 1.32k | SCEnter(); |
164 | 1.32k | if (ptr != NULL) { |
165 | 1.32k | SCDcerpcIfaceFree(ptr); |
166 | 1.32k | } |
167 | 1.32k | SCReturn; |
168 | 1.32k | } |