/src/suricata7/src/detect-quic-cyu-hash.c
Line | Count | Source |
1 | | /* Copyright (C) 2021-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 | | * |
20 | | * Implements the quic.cyu.hash sticky buffer |
21 | | */ |
22 | | |
23 | | #include "suricata-common.h" |
24 | | #include "detect.h" |
25 | | #include "detect-parse.h" |
26 | | #include "detect-content.h" |
27 | | |
28 | | #include "detect-engine.h" |
29 | | #include "detect-engine-mpm.h" |
30 | | #include "detect-engine-prefilter.h" |
31 | | #include "detect-engine-content-inspection.h" |
32 | | #include "detect-quic-cyu-hash.h" |
33 | | #include "detect-engine-build.h" |
34 | | #include "rust.h" |
35 | | #include "util-profiling.h" |
36 | | |
37 | | #ifdef UNITTESTS |
38 | | static void DetectQuicCyuHashRegisterTests(void); |
39 | | #endif |
40 | | |
41 | 73 | #define KEYWORD_NAME "quic.cyu.hash" |
42 | 73 | #define KEYWORD_DOC "quic-cyu.html#quic-cyu-hash" |
43 | 438 | #define BUFFER_NAME "quic.cyu.hash" |
44 | 73 | #define BUFFER_DESC "QUIC CYU Hash" |
45 | | static int g_buffer_id = 0; |
46 | | |
47 | | struct QuicHashGetDataArgs { |
48 | | uint32_t local_id; /**< used as index into thread inspect array */ |
49 | | void *txv; |
50 | | }; |
51 | | |
52 | | static int DetectQuicCyuHashSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) |
53 | 2.06k | { |
54 | 2.06k | if (DetectBufferSetActiveList(de_ctx, s, g_buffer_id) < 0) |
55 | 16 | return -1; |
56 | | |
57 | 2.04k | if (DetectSignatureSetAppProto(s, ALPROTO_QUIC) < 0) |
58 | 441 | return -1; |
59 | | |
60 | 1.60k | return 0; |
61 | 2.04k | } |
62 | | |
63 | | static InspectionBuffer *QuicHashGetData(DetectEngineThreadCtx *det_ctx, |
64 | | const DetectEngineTransforms *transforms, Flow *f, struct QuicHashGetDataArgs *cbdata, |
65 | | int list_id) |
66 | 1.69k | { |
67 | 1.69k | SCEnter(); |
68 | | |
69 | 1.69k | InspectionBuffer *buffer = |
70 | 1.69k | InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); |
71 | 1.69k | if (buffer == NULL) |
72 | 0 | return NULL; |
73 | 1.69k | if (buffer->initialized) |
74 | 304 | return buffer; |
75 | | |
76 | 1.39k | const uint8_t *data; |
77 | 1.39k | uint32_t data_len; |
78 | 1.39k | if (rs_quic_tx_get_cyu_hash(cbdata->txv, (uint16_t)cbdata->local_id, &data, &data_len) == 0) { |
79 | 1.08k | InspectionBufferSetupMultiEmpty(buffer); |
80 | 1.08k | return NULL; |
81 | 1.08k | } |
82 | | |
83 | 310 | InspectionBufferSetupMulti(buffer, transforms, data, data_len); |
84 | | |
85 | 310 | SCReturnPtr(buffer, "InspectionBuffer"); |
86 | 1.39k | } |
87 | | |
88 | | static uint8_t DetectEngineInspectQuicHash(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, |
89 | | const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, |
90 | | void *alstate, void *txv, uint64_t tx_id) |
91 | 304 | { |
92 | 304 | uint32_t local_id = 0; |
93 | | |
94 | 304 | const DetectEngineTransforms *transforms = NULL; |
95 | 304 | if (!engine->mpm) { |
96 | 0 | transforms = engine->v2.transforms; |
97 | 0 | } |
98 | | |
99 | 304 | while (1) { |
100 | 304 | struct QuicHashGetDataArgs cbdata = { |
101 | 304 | local_id, |
102 | 304 | txv, |
103 | 304 | }; |
104 | 304 | InspectionBuffer *buffer = |
105 | 304 | QuicHashGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); |
106 | 304 | if (buffer == NULL || buffer->inspect == NULL) |
107 | 0 | break; |
108 | | |
109 | 304 | det_ctx->buffer_offset = 0; |
110 | 304 | det_ctx->discontinue_matching = 0; |
111 | 304 | det_ctx->inspection_recursion_counter = 0; |
112 | | |
113 | 304 | const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, |
114 | 304 | (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, |
115 | 304 | DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); |
116 | 304 | if (match == 1) { |
117 | 304 | return DETECT_ENGINE_INSPECT_SIG_MATCH; |
118 | 304 | } |
119 | 0 | local_id++; |
120 | 0 | } |
121 | 0 | return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; |
122 | 304 | } |
123 | | |
124 | | typedef struct PrefilterMpmQuicHash { |
125 | | int list_id; |
126 | | const MpmCtx *mpm_ctx; |
127 | | const DetectEngineTransforms *transforms; |
128 | | } PrefilterMpmQuicHash; |
129 | | |
130 | | /** \brief QuicHash Mpm prefilter callback |
131 | | * |
132 | | * \param det_ctx detection engine thread ctx |
133 | | * \param p packet to inspect |
134 | | * \param f flow to inspect |
135 | | * \param txv tx to inspect |
136 | | * \param pectx inspection context |
137 | | */ |
138 | | static void PrefilterTxQuicHash(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, |
139 | | Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags) |
140 | 1.08k | { |
141 | 1.08k | SCEnter(); |
142 | | |
143 | 1.08k | const PrefilterMpmQuicHash *ctx = (const PrefilterMpmQuicHash *)pectx; |
144 | 1.08k | const MpmCtx *mpm_ctx = ctx->mpm_ctx; |
145 | 1.08k | const int list_id = ctx->list_id; |
146 | | |
147 | 1.08k | uint32_t local_id = 0; |
148 | 1.39k | while (1) { |
149 | | // loop until we get a NULL |
150 | | |
151 | 1.39k | struct QuicHashGetDataArgs cbdata = { local_id, txv }; |
152 | 1.39k | InspectionBuffer *buffer = QuicHashGetData(det_ctx, ctx->transforms, f, &cbdata, list_id); |
153 | 1.39k | if (buffer == NULL) |
154 | 1.08k | break; |
155 | | |
156 | 310 | if (buffer->inspect_len >= mpm_ctx->minlen) { |
157 | 310 | (void)mpm_table[mpm_ctx->mpm_type].Search( |
158 | 310 | mpm_ctx, &det_ctx->mtcu, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); |
159 | 310 | PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); |
160 | 310 | } |
161 | | |
162 | 310 | local_id++; |
163 | 310 | } |
164 | 1.08k | } |
165 | | |
166 | | static void PrefilterMpmQuicHashFree(void *ptr) |
167 | 42 | { |
168 | 42 | SCFree(ptr); |
169 | 42 | } |
170 | | |
171 | | static int PrefilterMpmQuicHashRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, |
172 | | const DetectBufferMpmRegistry *mpm_reg, int list_id) |
173 | 42 | { |
174 | 42 | PrefilterMpmQuicHash *pectx = SCCalloc(1, sizeof(*pectx)); |
175 | 42 | if (pectx == NULL) |
176 | 0 | return -1; |
177 | 42 | pectx->list_id = list_id; |
178 | 42 | pectx->mpm_ctx = mpm_ctx; |
179 | 42 | pectx->transforms = &mpm_reg->transforms; |
180 | | |
181 | 42 | return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxQuicHash, mpm_reg->app_v2.alproto, |
182 | 42 | mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmQuicHashFree, mpm_reg->pname); |
183 | 42 | } |
184 | | |
185 | | static bool DetectQuicHashValidateCallback(const Signature *s, const char **sigerror) |
186 | 235 | { |
187 | 634 | for (uint32_t x = 0; x < s->init_data->buffer_index; x++) { |
188 | 421 | if (s->init_data->buffers[x].id != (uint32_t)g_buffer_id) |
189 | 186 | continue; |
190 | 235 | const SigMatch *sm = s->init_data->buffers[x].head; |
191 | 448 | for (; sm != NULL; sm = sm->next) { |
192 | 235 | if (sm->type != DETECT_CONTENT) |
193 | 0 | continue; |
194 | | |
195 | 235 | const DetectContentData *cd = (DetectContentData *)sm->ctx; |
196 | | |
197 | 235 | if (cd->flags & DETECT_CONTENT_NOCASE) { |
198 | 0 | *sigerror = BUFFER_NAME " should not be used together with " |
199 | 0 | "nocase, since the rule is automatically " |
200 | 0 | "lowercased anyway which makes nocase redundant."; |
201 | 0 | SCLogWarning("rule %u: %s", s->id, *sigerror); |
202 | 0 | } |
203 | | |
204 | 235 | if (cd->content_len != 32) { |
205 | 17 | *sigerror = "Invalid length of the specified" BUFFER_NAME " (should " |
206 | 17 | "be 32 characters long). This rule will therefore " |
207 | 17 | "never match."; |
208 | 17 | SCLogWarning("rule %u: %s", s->id, *sigerror); |
209 | 17 | return false; |
210 | 17 | } |
211 | 7.04k | for (size_t i = 0; i < cd->content_len; ++i) { |
212 | 6.83k | if (!isxdigit(cd->content[i])) { |
213 | 5 | *sigerror = "Invalid " BUFFER_NAME |
214 | 5 | " string (should be string of hexadecimal characters)." |
215 | 5 | "This rule will therefore never match."; |
216 | 5 | SCLogWarning("rule %u: %s", s->id, *sigerror); |
217 | 5 | return false; |
218 | 5 | } |
219 | 6.83k | } |
220 | 218 | } |
221 | 235 | } |
222 | 213 | return true; |
223 | 235 | } |
224 | | |
225 | | void DetectQuicCyuHashRegister(void) |
226 | 73 | { |
227 | | /* quic.cyu.hash sticky buffer */ |
228 | 73 | sigmatch_table[DETECT_AL_QUIC_CYU_HASH].name = KEYWORD_NAME; |
229 | 73 | sigmatch_table[DETECT_AL_QUIC_CYU_HASH].desc = "sticky buffer to match on the QUIC CYU hash"; |
230 | 73 | sigmatch_table[DETECT_AL_QUIC_CYU_HASH].url = "/rules/" KEYWORD_DOC; |
231 | 73 | sigmatch_table[DETECT_AL_QUIC_CYU_HASH].Setup = DetectQuicCyuHashSetup; |
232 | 73 | sigmatch_table[DETECT_AL_QUIC_CYU_HASH].flags |= SIGMATCH_NOOPT; |
233 | | #ifdef UNITTESTS |
234 | | sigmatch_table[DETECT_AL_QUIC_CYU_HASH].RegisterTests = DetectQuicCyuHashRegisterTests; |
235 | | #endif |
236 | | |
237 | 73 | DetectAppLayerMpmRegister2( |
238 | 73 | BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterMpmQuicHashRegister, NULL, ALPROTO_QUIC, 1); |
239 | | |
240 | 73 | DetectAppLayerInspectEngineRegister2( |
241 | 73 | BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 0, DetectEngineInspectQuicHash, NULL); |
242 | | |
243 | 73 | DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC); |
244 | | |
245 | 73 | g_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME); |
246 | | |
247 | 73 | DetectBufferTypeRegisterValidateCallback(BUFFER_NAME, DetectQuicHashValidateCallback); |
248 | | |
249 | 73 | DetectBufferTypeSupportsMultiInstance(BUFFER_NAME); |
250 | 73 | } |
251 | | |
252 | | #ifdef UNITTESTS |
253 | | #include "app-layer-parser.h" |
254 | | #include "util-unittest.h" |
255 | | #include "util-unittest-helper.h" |
256 | | #include "flow-util.h" |
257 | | #include "detect-engine-alert.h" |
258 | | |
259 | | /** |
260 | | * \test DetectQuicCyuHashTest01 is a test for a valid quic packet, matching |
261 | | * on the cyu hash |
262 | | * |
263 | | * \retval 1 on success |
264 | | * \retval 0 on failure |
265 | | */ |
266 | | static int DetectQuicCyuHashTest01(void) |
267 | | { |
268 | | /* quic packet */ |
269 | | uint8_t buf[] = { 0xc3, 0x51, 0x30, 0x34, 0x36, 0x50, 0x76, 0xd8, 0x63, 0xb7, 0x54, 0xf7, 0xab, |
270 | | 0x32, 0x00, 0x00, 0x00, 0x01, 0x54, 0xfd, 0xf4, 0x79, 0x48, 0x76, 0xd0, 0x87, 0x58, 0x8d, |
271 | | 0x26, 0x8f, 0xa0, 0x01, 0x04, 0x00, 0x43, 0x48, 0x4c, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x50, |
272 | | 0x41, 0x44, 0x00, 0xe4, 0x02, 0x00, 0x00, 0x53, 0x4e, 0x49, 0x00, 0xf7, 0x02, 0x00, 0x00, |
273 | | 0x56, 0x45, 0x52, 0x00, 0xfb, 0x02, 0x00, 0x00, 0x43, 0x43, 0x53, 0x00, 0x0b, 0x03, 0x00, |
274 | | 0x00, 0x55, 0x41, 0x49, 0x44, 0x2c, 0x03, 0x00, 0x00, 0x54, 0x43, 0x49, 0x44, 0x30, 0x03, |
275 | | 0x00, 0x00, 0x50, 0x44, 0x4d, 0x44, 0x34, 0x03, 0x00, 0x00, 0x53, 0x4d, 0x48, 0x4c, 0x38, |
276 | | 0x03, 0x00, 0x00, 0x49, 0x43, 0x53, 0x4c, 0x3c, 0x03, 0x00, 0x00, 0x4e, 0x4f, 0x4e, 0x50, |
277 | | 0x5c, 0x03, 0x00, 0x00, 0x4d, 0x49, 0x44, 0x53, 0x60, 0x03, 0x00, 0x00, 0x53, 0x43, 0x4c, |
278 | | 0x53, 0x64, 0x03, 0x00, 0x00, 0x43, 0x53, 0x43, 0x54, 0x64, 0x03, 0x00, 0x00, 0x43, 0x4f, |
279 | | 0x50, 0x54, 0x64, 0x03, 0x00, 0x00, 0x49, 0x52, 0x54, 0x54, 0x68, 0x03, 0x00, 0x00, 0x43, |
280 | | 0x46, 0x43, 0x57, 0x6c, 0x03, 0x00, 0x00, 0x53, 0x46, 0x43, 0x57, 0x70, 0x03, 0x00, 0x00, |
281 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
282 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
283 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
284 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
285 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
286 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
287 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
288 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
289 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
290 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
291 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
292 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
293 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
294 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
295 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
296 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
297 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
298 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
299 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
300 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
301 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
302 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
303 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
304 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
305 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
306 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
307 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
308 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
309 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
310 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
311 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
312 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
313 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
314 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
315 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
316 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
317 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
318 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
319 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
320 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
321 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
322 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
323 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
324 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
325 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
326 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
327 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
328 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
329 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, |
330 | | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x31, 0x2e, 0x67, |
331 | | 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x51, 0x30, 0x34, 0x36, 0x01, 0xe8, |
332 | | 0x81, 0x60, 0x92, 0x92, 0x1a, 0xe8, 0x7e, 0xed, 0x80, 0x86, 0xa2, 0x15, 0x82, 0x91, 0x43, |
333 | | 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x2f, 0x37, 0x39, 0x2e, 0x30, 0x2e, 0x33, 0x39, 0x34, 0x35, |
334 | | 0x2e, 0x31, 0x31, 0x37, 0x20, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x78, 0x38, 0x36, 0x5f, |
335 | | 0x36, 0x34, 0x00, 0x00, 0x00, 0x00, 0x58, 0x35, 0x30, 0x39, 0x01, 0x00, 0x00, 0x00, 0x1e, |
336 | | 0x00, 0x00, 0x00, 0x82, 0x88, 0x09, 0x00, 0xfa, 0x0f, 0xde, 0xb7, 0x2e, 0x7e, 0x6c, 0x78, |
337 | | 0xcc, 0x09, 0x65, 0xab, 0x06, 0x0c, 0x31, 0x05, 0xfa, 0xd9, 0xa2, 0x0b, 0xdd, 0x74, 0x5c, |
338 | | 0x28, 0xdf, 0x7b, 0x74, 0x23, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x43, |
339 | | 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
340 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
341 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
342 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
343 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
344 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
345 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
346 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
347 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
348 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
349 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
350 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
351 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
352 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
353 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
354 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
355 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
356 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
357 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
358 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
359 | | 0x00, 0x00 }; |
360 | | |
361 | | Flow f; |
362 | | void *quic_state = NULL; |
363 | | Packet *p = NULL; |
364 | | Signature *s = NULL; |
365 | | ThreadVars tv; |
366 | | DetectEngineThreadCtx *det_ctx = NULL; |
367 | | AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); |
368 | | |
369 | | memset(&tv, 0, sizeof(ThreadVars)); |
370 | | memset(&f, 0, sizeof(Flow)); |
371 | | |
372 | | p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 443); |
373 | | |
374 | | FLOW_INITIALIZE(&f); |
375 | | f.flags |= FLOW_IPV4; |
376 | | f.proto = IPPROTO_UDP; |
377 | | f.protomap = FlowGetProtoMapping(f.proto); |
378 | | |
379 | | p->flow = &f; |
380 | | p->flags |= PKT_HAS_FLOW; |
381 | | p->flowflags |= FLOW_PKT_TOSERVER; |
382 | | f.alproto = ALPROTO_QUIC; |
383 | | |
384 | | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
385 | | FAIL_IF_NULL(de_ctx); |
386 | | de_ctx->mpm_matcher = mpm_default_matcher; |
387 | | de_ctx->flags |= DE_QUIET; |
388 | | |
389 | | s = DetectEngineAppendSig(de_ctx, |
390 | | "alert quic any any -> any any " |
391 | | "(msg:\"Test QUIC CYU hash\"; " |
392 | | "quic.cyu.hash; content:\"910a5e3a4d51593bd59a44611544f209\"; " |
393 | | "sid:1;)"); |
394 | | FAIL_IF_NULL(s); |
395 | | |
396 | | SigGroupBuild(de_ctx); |
397 | | DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); |
398 | | |
399 | | int r = AppLayerParserParse( |
400 | | NULL, alp_tctx, &f, ALPROTO_QUIC, STREAM_TOSERVER, buf, sizeof(buf)); |
401 | | if (r != 0) { |
402 | | printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); |
403 | | FAIL; |
404 | | } |
405 | | |
406 | | quic_state = f.alstate; |
407 | | FAIL_IF_NULL(quic_state); |
408 | | |
409 | | /* do detect */ |
410 | | SigMatchSignatures(&tv, de_ctx, det_ctx, p); |
411 | | |
412 | | if (!(PacketAlertCheck(p, 1))) { |
413 | | printf("sig 1 didn't alert, but it should have: "); |
414 | | FAIL; |
415 | | } |
416 | | |
417 | | if (alp_tctx != NULL) |
418 | | AppLayerParserThreadCtxFree(alp_tctx); |
419 | | if (det_ctx != NULL) |
420 | | DetectEngineThreadCtxDeinit(&tv, det_ctx); |
421 | | if (de_ctx != NULL) |
422 | | SigGroupCleanup(de_ctx); |
423 | | if (de_ctx != NULL) |
424 | | DetectEngineCtxFree(de_ctx); |
425 | | |
426 | | FLOW_DESTROY(&f); |
427 | | UTHFreePacket(p); |
428 | | PASS; |
429 | | } |
430 | | |
431 | | static void DetectQuicCyuHashRegisterTests(void) |
432 | | { |
433 | | UtRegisterTest("DetectQuicCyuHashTest01", DetectQuicCyuHashTest01); |
434 | | } |
435 | | |
436 | | #endif /* UNITTESTS */ |