suricata
detect-http-client-body.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2021 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 * \ingroup httplayer
20 *
21 * @{
22 */
23
24
25/** \file
26 *
27 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28 * \author Victor Julien <victor@inliniac.net>
29 *
30 * \brief Handle HTTP request body match corresponding to http_client_body
31 * keyword.
32 *
33 */
34
35#include "../suricata-common.h"
36#include "../suricata.h"
37#include "../decode.h"
38
39#include "detect.h"
40#include "detect-engine.h"
41#include "detect-engine-mpm.h"
42#include "detect-parse.h"
43#include "detect-engine-state.h"
46#include "detect-isdataat.h"
48#include "detect-engine-build.h"
49
50#include "flow-util.h"
51#include "util-debug.h"
52#include "util-print.h"
53#include "flow.h"
54
55#include "app-layer-parser.h"
56
57#include "stream-tcp.h"
58
59#include "util-unittest.h"
61#include "app-layer.h"
62#include "app-layer-htp.h"
63#include "app-layer-protos.h"
64
65#include "conf.h"
66#include "conf-yaml-loader.h"
67
68#include "util-validate.h"
69
70#ifdef UNITTESTS
71
72/**
73 * \test Test parser accepting valid rules and rejecting invalid rules
74 */
75static int DetectHttpClientBodyParserTest01(void)
76{
77 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; http_client_body; sid:1;)", true));
78 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; nocase; http_client_body; sid:1;)", true));
79 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; endswith; http_client_body; sid:1;)", true));
80 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; http_client_body; sid:1;)", true));
81 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; endswith; http_client_body; sid:1;)", true));
82
83 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; rawbytes; http_client_body; sid:1;)", false));
84 FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http_client_body; sid:1;)", false));
85 FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; content:\"abc\"; http_client_body; sid:1;)", false));
86 PASS;
87}
88
89/**
90 * \test Test parser accepting valid rules and rejecting invalid rules
91 */
92static int DetectHttpClientBodyParserTest02(void)
93{
94 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; sid:1;)", true));
95 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; nocase; sid:1;)", true));
96 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; endswith; sid:1;)", true));
97 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; startswith; sid:1;)", true));
98 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; startswith; endswith; sid:1;)", true));
99 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; bsize:10; sid:1;)", true));
100
101 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; rawbytes; sid:1;)", false));
102 FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http.request_body; sid:1;)", false));
103 FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; http.request_body; content:\"abc\"; sid:1;)", false));
104 PASS;
105}
106
107struct TestSteps {
108 const uint8_t *input;
109 size_t input_size; /**< if 0 strlen will be used */
110 int direction; /**< STREAM_TOSERVER, STREAM_TOCLIENT */
112};
113
114static int RunTest (struct TestSteps *steps, const char *sig, const char *yaml)
115{
116 TcpSession ssn;
117 Flow f;
118 ThreadVars th_v;
119 DetectEngineThreadCtx *det_ctx = NULL;
122
123 memset(&th_v, 0, sizeof(th_v));
124 memset(&f, 0, sizeof(f));
125 memset(&ssn, 0, sizeof(ssn));
126
127 if (yaml) {
129 SCConfInit();
131
132 SCConfYamlLoadString(yaml, strlen(yaml));
133 HTPConfigure();
134 }
135
137
141
142 FLOW_INITIALIZE(&f);
143 f.protoctx = (void *)&ssn;
144 f.proto = IPPROTO_TCP;
145 f.flags |= FLOW_IPV4;
147
148 SCLogDebug("sig %s", sig);
149 Signature *s = DetectEngineAppendSig(de_ctx, (char *)sig);
150 FAIL_IF_NULL(s);
151
153 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
154 FAIL_IF_NULL(det_ctx);
155
156 struct TestSteps *b = steps;
157 int i = 0;
158 while (b->input != NULL) {
159 SCLogDebug("chunk %p %d", b, i);
160 (void)i;
161 Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
162 FAIL_IF_NULL(p);
163 p->flow = &f;
164 p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT;
167
169 (uint8_t *)b->input,
170 b->input_size ? b->input_size : strlen((const char *)b->input));
171 FAIL_IF_NOT(r == 0);
172
173 /* do detect */
174 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
175
176 int match = PacketAlertCheck(p, 1);
177 FAIL_IF_NOT (b->expect == match);
178
179 UTHFreePackets(&p, 1);
180 b++;
181 i++;
182 }
183
184 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
187
189 FLOW_DESTROY(&f);
190
191 if (yaml) {
194 }
195 PASS;
196}
197
198static int DetectEngineHttpClientBodyTest01(void)
199{
200 struct TestSteps steps[] = {
201 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
202 "Host: www.openinfosecfoundation.org\r\n"
203 "Content-Type: text/html\r\n"
204 "Content-Length: 46\r\n"
205 "\r\n"
206 "This is dummy body1",
207 0, STREAM_TOSERVER, 0 },
208 { (const uint8_t *)"This is dummy message body2",
209 0, STREAM_TOSERVER, 1 },
210 { NULL, 0, 0, 0 },
211 };
212
213 const char *sig = "alert http any any -> any any (content:\"body1This\"; http_client_body; sid:1;)";
214 return RunTest(steps, sig, NULL);
215}
216
217static int DetectEngineHttpClientBodyTest02(void)
218{
219 struct TestSteps steps[] = {
220 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
221 "Host: www.openinfosecfoundation.org\r\n"
222 "Content-Type: text/html\r\n"
223 "Content-Length: 19\r\n"
224 "\r\n"
225 "This is dummy body1",
226 0, STREAM_TOSERVER, 1 },
227 { NULL, 0, 0, 0 },
228 };
229
230 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:5; sid:1;)";
231 return RunTest(steps, sig, NULL);
232}
233
234static int DetectEngineHttpClientBodyTest03(void)
235{
236 struct TestSteps steps[] = {
237 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
238 "Host: www.openinfosecfoundation.org\r\n"
239 "Content-Type: text/html\r\n"
240 "Content-Length: 46\r\n"
241 "\r\n"
242 "This is dummy body1",
243 0, STREAM_TOSERVER, 0 },
244 { (const uint8_t *)"This is dummy message body2",
245 0, STREAM_TOSERVER, 0 },
246 { NULL, 0, 0, 0 },
247 };
248
249 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:16; sid:1;)";
250 return RunTest(steps, sig, NULL);
251}
252
253static int DetectEngineHttpClientBodyTest04(void)
254{
255 struct TestSteps steps[] = {
256 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
257 "Host: www.openinfosecfoundation.org\r\n"
258 "Content-Type: text/html\r\n"
259 "Content-Length: 46\r\n"
260 "\r\n"
261 "This is dummy body1",
262 0, STREAM_TOSERVER, 0 },
263 { (const uint8_t *)"This is dummy message body2",
264 0, STREAM_TOSERVER, 1 },
265 { NULL, 0, 0, 0 },
266 };
267
268 const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; offset:16; sid:1;)";
269 return RunTest(steps, sig, NULL);
270}
271
272static int DetectEngineHttpClientBodyTest05(void)
273{
274 struct TestSteps steps[] = {
275 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
276 "Host: www.openinfosecfoundation.org\r\n"
277 "Content-Type: text/html\r\n"
278 "Content-Length: 46\r\n"
279 "\r\n"
280 "This is dummy body1",
281 0, STREAM_TOSERVER, 0 },
282 { (const uint8_t *)"This is dummy message body2",
283 0, STREAM_TOSERVER, 1 },
284 { NULL, 0, 0, 0 },
285 };
286
287 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; depth:25; sid:1;)";
288 return RunTest(steps, sig, NULL);
289}
290
291static int DetectEngineHttpClientBodyTest06(void)
292{
293 struct TestSteps steps[] = {
294 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
295 "Host: www.openinfosecfoundation.org\r\n"
296 "Content-Type: text/html\r\n"
297 "Content-Length: 46\r\n"
298 "\r\n"
299 "This is dummy body1",
300 0, STREAM_TOSERVER, 0 },
301 { (const uint8_t *)"This is dummy message body2",
302 0, STREAM_TOSERVER, 0 },
303 { NULL, 0, 0, 0 },
304 };
305
306 const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:25; sid:1;)";
307 return RunTest(steps, sig, NULL);
308}
309
310static int DetectEngineHttpClientBodyTest07(void)
311{
312 struct TestSteps steps[] = {
313 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
314 "Host: www.openinfosecfoundation.org\r\n"
315 "Content-Type: text/html\r\n"
316 "Content-Length: 46\r\n"
317 "\r\n"
318 "This is dummy body1",
319 0, STREAM_TOSERVER, 0 },
320 { (const uint8_t *)"This is dummy message body2",
321 0, STREAM_TOSERVER, 1 },
322 { NULL, 0, 0, 0 },
323 };
324
325 const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:15; sid:1;)";
326 return RunTest(steps, sig, NULL);
327}
328
329static int DetectEngineHttpClientBodyTest08(void)
330{
331 struct TestSteps steps[] = {
332 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
333 "Host: www.openinfosecfoundation.org\r\n"
334 "Content-Type: text/html\r\n"
335 "Content-Length: 46\r\n"
336 "\r\n"
337 "This is dummy body1",
338 0, STREAM_TOSERVER, 0 },
339 { (const uint8_t *)"This is dummy message body2",
340 0, STREAM_TOSERVER, 1 },
341 { NULL, 0, 0, 0 },
342 };
343
344 const char *sig = "alert http any any -> any any (content:\"This is dummy body1This is dummy message body2\"; http_client_body; sid:1;)";
345 return RunTest(steps, sig, NULL);
346}
347
348static int DetectEngineHttpClientBodyTest09(void)
349{
350 struct TestSteps steps[] = {
351 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
352 "Host: www.openinfosecfoundation.org\r\n"
353 "Content-Type: text/html\r\n"
354 "Content-Length: 46\r\n"
355 "\r\n"
356 "This is dummy body1",
357 0, STREAM_TOSERVER, 0 },
358 { (const uint8_t *)"This is dummy message body2",
359 0, STREAM_TOSERVER, 1 },
360 { NULL, 0, 0, 0 },
361 };
362
363 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"This\"; http_client_body; within:5; sid:1;)";
364 return RunTest(steps, sig, NULL);
365}
366
367static int DetectEngineHttpClientBodyTest10(void)
368{
369 struct TestSteps steps[] = {
370 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
371 "Host: www.openinfosecfoundation.org\r\n"
372 "Content-Type: text/html\r\n"
373 "Content-Length: 46\r\n"
374 "\r\n"
375 "This is dummy body1",
376 0, STREAM_TOSERVER, 0 },
377 { (const uint8_t *)"This is dummy message body2",
378 0, STREAM_TOSERVER, 1 },
379 { NULL, 0, 0, 0 },
380 };
381
382 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"boom\"; http_client_body; within:5; sid:1;)";
383 return RunTest(steps, sig, NULL);
384}
385
386static int DetectEngineHttpClientBodyTest11(void)
387{
388 struct TestSteps steps[] = {
389 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
390 "Host: www.openinfosecfoundation.org\r\n"
391 "Content-Type: text/html\r\n"
392 "Content-Length: 46\r\n"
393 "\r\n"
394 "This is dummy body1",
395 0, STREAM_TOSERVER, 0 },
396 { (const uint8_t *)"This is dummy message body2",
397 0, STREAM_TOSERVER, 0 },
398 { NULL, 0, 0, 0 },
399 };
400
401 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"boom\"; http_client_body; within:5; sid:1;)";
402 return RunTest(steps, sig, NULL);
403}
404
405static int DetectEngineHttpClientBodyTest12(void)
406{
407 struct TestSteps steps[] = {
408 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
409 "Host: www.openinfosecfoundation.org\r\n"
410 "Content-Type: text/html\r\n"
411 "Content-Length: 46\r\n"
412 "\r\n"
413 "This is dummy body1",
414 0, STREAM_TOSERVER, 0 },
415 { (const uint8_t *)"This is dummy message body2",
416 0, STREAM_TOSERVER, 0 },
417 { NULL, 0, 0, 0 },
418 };
419
420 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"This\"; http_client_body; within:5; sid:1;)";
421 return RunTest(steps, sig, NULL);
422}
423
424static int DetectEngineHttpClientBodyTest13(void)
425{
426 struct TestSteps steps[] = {
427 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
428 "Host: www.openinfosecfoundation.org\r\n"
429 "Content-Type: text/html\r\n"
430 "Content-Length: 46\r\n"
431 "\r\n"
432 "This is dummy body1",
433 0, STREAM_TOSERVER, 0 },
434 { (const uint8_t *)"This is dummy message body2",
435 0, STREAM_TOSERVER, 1 },
436 { NULL, 0, 0, 0 },
437 };
438
439 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:5; sid:1;)";
440 return RunTest(steps, sig, NULL);
441}
442
443static int DetectEngineHttpClientBodyTest14(void)
444{
445 struct TestSteps steps[] = {
446 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
447 "Host: www.openinfosecfoundation.org\r\n"
448 "Content-Type: text/html\r\n"
449 "Content-Length: 46\r\n"
450 "\r\n"
451 "This is dummy body1",
452 0, STREAM_TOSERVER, 0 },
453 { (const uint8_t *)"This is dummy message body2",
454 0, STREAM_TOSERVER, 1 },
455 { NULL, 0, 0, 0 },
456 };
457
458 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:10; sid:1;)";
459 return RunTest(steps, sig, NULL);
460}
461
462static int DetectEngineHttpClientBodyTest15(void)
463{
464 struct TestSteps steps[] = {
465 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
466 "Host: www.openinfosecfoundation.org\r\n"
467 "Content-Type: text/html\r\n"
468 "Content-Length: 46\r\n"
469 "\r\n"
470 "This is dummy body1",
471 0, STREAM_TOSERVER, 0 },
472 { (const uint8_t *)"This is dummy message body2",
473 0, STREAM_TOSERVER, 0 },
474 { NULL, 0, 0, 0 },
475 };
476
477 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:10; sid:1;)";
478 return RunTest(steps, sig, NULL);
479}
480
481static int DetectEngineHttpClientBodyTest16(void)
482{
483 struct TestSteps steps[] = {
484 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
485 "Host: www.openinfosecfoundation.org\r\n"
486 "Content-Type: text/html\r\n"
487 "Content-Length: 46\r\n"
488 "\r\n"
489 "This is dummy body1",
490 0, STREAM_TOSERVER, 0 },
491 { (const uint8_t *)"This is dummy message body2",
492 0, STREAM_TOSERVER, 0 },
493 { NULL, 0, 0, 0 },
494 };
495
496 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:5; sid:1;)";
497 return RunTest(steps, sig, NULL);
498}
499
500static int DetectEngineHttpClientBodyTest17(void)
501{
502 struct TestSteps steps[] = {
503 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
504 "Host: www.openinfosecfoundation.org\r\n"
505 "Content-Type: text/html\r\n"
506 "Content-Length: 19\r\n"
507 "\r\n"
508 "This is dummy body1",
509 0, STREAM_TOSERVER, 0 },
510 { NULL, 0, 0, 0 },
511 };
512
513 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; sid:1;)";
514 return RunTest(steps, sig, NULL);
515}
516
517static int DetectEngineHttpClientBodyTest18(void)
518{
519 struct TestSteps steps[] = {
520 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
521 "Host: www.openinfosecfoundation.org\r\n"
522 "Content-Type: text/html\r\n"
523 "Content-Length: 19\r\n"
524 "\r\n"
525 "This is dummy body1",
526 0, STREAM_TOSERVER, 0 },
527 { NULL, 0, 0, 0 },
528 };
529
530 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; fast_pattern; sid:1;)";
531 return RunTest(steps, sig, NULL);
532}
533
534static int DetectEngineHttpClientBodyTest19(void)
535{
536 struct TestSteps steps[] = {
537 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
538 "Host: www.openinfosecfoundation.org\r\n"
539 "Content-Type: text/html\r\n"
540 "Content-Length: 19\r\n"
541 "\r\n"
542 "This is dummy body1",
543 0, STREAM_TOSERVER, 0 },
544 { NULL, 0, 0, 0 },
545 };
546
547 const char *sig = "alert http any any -> any any (content:\"bambu\"; http_client_body; content:\"is\"; http_client_body; sid:1;)";
548 return RunTest(steps, sig, NULL);
549}
550
551static int DetectEngineHttpClientBodyTest20(void)
552{
553 struct TestSteps steps[] = {
554 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
555 "Host: www.openinfosecfoundation.org\r\n"
556 "Content-Type: text/html\r\n"
557 "Content-Length: 19\r\n"
558 "\r\n"
559 "This is dummy body1",
560 0, STREAM_TOSERVER, 1 },
561 { NULL, 0, 0, 0 },
562 };
563
564 const char *sig = "alert http any any -> any any (content:\"is\"; http_client_body; fast_pattern; sid:1;)";
565 return RunTest(steps, sig, NULL);
566}
567
568static int DetectEngineHttpClientBodyTest21(void)
569{
570 struct TestSteps steps[] = {
571 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
572 "Host: www.openinfosecfoundation.org\r\n"
573 "Content-Type: text/html\r\n"
574 "Content-Length: 46\r\n"
575 "\r\n"
576 "This is dummy body1",
577 0, STREAM_TOSERVER, 0 },
578 { (const uint8_t *)"This is dummy message body2",
579 0, STREAM_TOSERVER, 1 },
580 { NULL, 0, 0, 0 },
581 };
582
583 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; http_client_body; within:7; sid:1;)";
584 return RunTest(steps, sig, NULL);
585}
586
587static int DetectEngineHttpClientBodyTest22(void)
588{
589 struct TestSteps steps[] = {
590 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
591 "Host: www.openinfosecfoundation.org\r\n"
592 "Content-Type: text/html\r\n"
593 "Content-Length: 46\r\n"
594 "\r\n"
595 "This is dummy body1",
596 0, STREAM_TOSERVER, 0 },
597 { (const uint8_t *)"This is dummy message body2",
598 0, STREAM_TOSERVER, 1 },
599 { NULL, 0, 0, 0 },
600 };
601
602 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; within:7; http_client_body; sid:1;)";
603 return RunTest(steps, sig, NULL);
604}
605
606static int DetectEngineHttpClientBodyTest23(void)
607{
608 struct TestSteps steps[] = {
609 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
610 "Host: www.openinfosecfoundation.org\r\n"
611 "Content-Type: text/html\r\n"
612 "Content-Length: 46\r\n"
613 "\r\n"
614 "This is dummy body1",
615 0, STREAM_TOSERVER, 0 },
616 { (const uint8_t *)"This is dummy message body2",
617 0, STREAM_TOSERVER, 0 },
618 { NULL, 0, 0, 0 },
619 };
620
621 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:3; http_client_body; sid:1;)";
622 return RunTest(steps, sig, NULL);
623}
624
625static int DetectEngineHttpClientBodyTest24(void)
626{
627 struct TestSteps steps[] = {
628 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
629 "Host: www.openinfosecfoundation.org\r\n"
630 "Content-Type: text/html\r\n"
631 "Content-Length: 46\r\n"
632 "\r\n"
633 "This is dummy body1",
634 0, STREAM_TOSERVER, 0 },
635 { (const uint8_t *)"This is dummy message body2",
636 0, STREAM_TOSERVER, 1 },
637 { NULL, 0, 0, 0 },
638 };
639
640 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:13; http_client_body; sid:1;)";
641 return RunTest(steps, sig, NULL);
642}
643
644static int DetectEngineHttpClientBodyTest25(void)
645{
646 struct TestSteps steps[] = {
647 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
648 "Host: www.openinfosecfoundation.org\r\n"
649 "Content-Type: text/html\r\n"
650 "Content-Length: 46\r\n"
651 "\r\n"
652 "This is dummy body1",
653 0, STREAM_TOSERVER, 0 },
654 { (const uint8_t *)"This is dummy message body2",
655 0, STREAM_TOSERVER, 1 },
656 { NULL, 0, 0, 0 },
657 };
658
659 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:15; http_client_body; sid:1;)";
660 return RunTest(steps, sig, NULL);
661}
662
663static int DetectEngineHttpClientBodyTest26(void)
664{
665 struct TestSteps steps[] = {
666 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
667 "Host: www.openinfosecfoundation.org\r\n"
668 "Content-Type: text/html\r\n"
669 "Content-Length: 46\r\n"
670 "\r\n"
671 "This is dummy body1",
672 0, STREAM_TOSERVER, 0 },
673 { (const uint8_t *)"This is dummy message body2",
674 0, STREAM_TOSERVER, 0 },
675 { NULL, 0, 0, 0 },
676 };
677
678 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:10; http_client_body; sid:1;)";
679 return RunTest(steps, sig, NULL);
680}
681
682static int DetectEngineHttpClientBodyTest27(void)
683{
684 struct TestSteps steps[] = {
685 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
686 "Host: www.openinfosecfoundation.org\r\n"
687 "Content-Type: text/html\r\n"
688 "Content-Length: 46\r\n"
689 "\r\n"
690 "This is dummy body1",
691 0, STREAM_TOSERVER, 0 },
692 { (const uint8_t *)"This is dummy message body2",
693 0, STREAM_TOSERVER, 1 },
694 { NULL, 0, 0, 0 },
695 };
696
697 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:8; http_client_body; sid:1;)";
698 return RunTest(steps, sig, NULL);
699}
700
701static int DetectEngineHttpClientBodyTest28(void)
702{
703 struct TestSteps steps[] = {
704 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
705 "Host: www.openinfosecfoundation.org\r\n"
706 "Content-Type: text/html\r\n"
707 "Content-Length: 46\r\n"
708 "\r\n"
709 "This is dummy body1",
710 0, STREAM_TOSERVER, 0 },
711 { (const uint8_t *)"This is dummy message body2",
712 0, STREAM_TOSERVER, 0 },
713 { NULL, 0, 0, 0 },
714 };
715
716 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:14; http_client_body; sid:1;)";
717 return RunTest(steps, sig, NULL);
718}
719
720static int DetectEngineHttpClientBodyTest29(void)
721{
722 const char *request_buffer = "GET /one HTTP/1.0\r\n"
723 "Host: localhost\r\n\r\n";
724#define TOTAL_REQUESTS 45
725 uint8_t *http_buf = SCMalloc(TOTAL_REQUESTS * strlen(request_buffer));
726 if (unlikely(http_buf == NULL))
727 return 0;
728 for (int i = 0; i < TOTAL_REQUESTS; i++) {
729 memcpy(http_buf + i * strlen(request_buffer), request_buffer,
730 strlen(request_buffer));
731 }
732 uint32_t http_buf_len = TOTAL_REQUESTS * strlen(request_buffer);
733#undef TOTAL_REQUESTS
734
735 struct TestSteps steps[] = {
736 { (const uint8_t *)http_buf,
737 (size_t)http_buf_len, STREAM_TOSERVER, 0 },
738
739 { (const uint8_t *)"HTTP/1.0 200 ok\r\n"
740 "Content-Type: text/html\r\n"
741 "Content-Length: 5\r\n"
742 "\r\n"
743 "dummy",
744 0, STREAM_TOCLIENT, 0 },
745
746 { NULL, 0, 0, 0 },
747 };
748
749 const char *sig = "alert http any any -> any any (content:\"dummyone\"; fast_pattern:0,3; http_server_body; sid:1;)";
750 int result = RunTest(steps, sig, NULL);
751 SCFree(http_buf);
752 return result;
753}
754
755static int DetectEngineHttpClientBodyTest30(void)
756{
757 const char yaml[] = "\
758%YAML 1.1\n\
759---\n\
760libhtp:\n\
761\n\
762 default-config:\n\
763 personality: IDS\n\
764 request-body-limit: 0\n\
765 response-body-limit: 0\n\
766\n\
767 request-body-inspect-window: 0\n\
768 response-body-inspect-window: 0\n\
769 request-body-minimal-inspect-size: 0\n\
770 response-body-minimal-inspect-size: 0\n\
771";
772 struct TestSteps steps[] = {
773 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
774 "Host: www.openinfosecfoundation.org\r\n"
775 "Content-Type: text/html\r\n"
776 "Content-Length: 46\r\n"
777 "\r\n"
778 "This is dummy body1",
779 0, STREAM_TOSERVER, 0 },
780 { (const uint8_t *)"This is dummy message body2",
781 0, STREAM_TOSERVER, 0 },
782 { NULL, 0, 0, 0 },
783 };
784
785 const char *sig = "alert http any any -> any any (content:\"bags\"; within:4; http_client_body; sid:1;)";
786 return RunTest(steps, sig, yaml);
787}
788
789static int DetectEngineHttpClientBodyTest31(void)
790{
791 const char yaml[] = "\
792%YAML 1.1\n\
793---\n\
794libhtp:\n\
795\n\
796 default-config:\n\
797 personality: IDS\n\
798 request-body-limit: 0\n\
799 response-body-limit: 0\n\
800\n\
801 request-body-inspect-window: 0\n\
802 response-body-inspect-window: 0\n\
803 request-body-minimal-inspect-size: 0\n\
804 response-body-minimal-inspect-size: 0\n\
805";
806
807 struct TestSteps steps[] = {
808 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
809 "Host: www.openinfosecfoundation.org\r\n"
810 "Content-Type: text/html\r\n"
811 "Content-Length: 46\r\n"
812 "\r\n"
813 "This is dummy body1",
814 0, STREAM_TOSERVER, 0 },
815 { (const uint8_t *)"This is dummy message body2",
816 0, STREAM_TOSERVER, 0 },
817 { NULL, 0, 0, 0 },
818 };
819
820 const char *sig = "alert http any any -> any any (content:\"bags\"; depth:4; http_client_body; sid:1;)";
821 return RunTest(steps, sig, yaml);
822}
823
824/**
825 * \test Test that a signature containing a http_client_body is correctly parsed
826 * and the keyword is registered.
827 */
828static int DetectHttpClientBodyTest01(void)
829{
833
834 Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
835 "(msg:\"Testing http_client_body\"; "
836 "content:\"one\"; http_client_body; sid:1;)");
837 FAIL_IF_NULL(s);
838
841
843 PASS;
844}
845
846/**
847 * \test Test that a signature containing an valid http_client_body entry is
848 * parsed.
849 * \todo error in sig 'http_client_body:;'
850 */
851static int DetectHttpClientBodyTest02(void)
852{
856
857 Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
858 "(msg:\"Testing http_client_body\"; "
859 "content:\"one\"; http_client_body:; sid:1;)");
860 FAIL_IF_NULL(s);
861
863 PASS;
864}
865
866/**
867 * \test Test invalid signatures
868 */
869static int DetectHttpClientBodyTest03(void)
870{
874
875 const char *sigs[] = {
876 "alert tcp any any -> any any (http_client_body; sid:1;)",
877 "alert tcp any any -> any any "
878 "(msg:\"Testing http_client_body\"; "
879 "content:\"one\"; rawbytes; http_client_body; sid:2;)",
880 NULL,
881 };
882
883 for (uint32_t i = 0; sigs[i] != NULL; i++) {
886 }
888 PASS;
889}
890
891/**
892 * \test Test that an invalid signature containing a rawbytes along with a
893 * http_client_body is invalidated.
894 */
895static int DetectHttpClientBodyTest05(void)
896{
900
901 const char *sigs[] = {
902 "alert tcp any any -> any any (content:\"one\"; http_client_body; nocase; sid:1;)",
903 NULL,
904 };
905
906 for (uint32_t i = 0; sigs[i] != NULL; i++) {
908 FAIL_IF_NULL(s);
909 }
911 PASS;
912}
913
914/**
915 *\test Test that the http_client_body content matches against a http request
916 * which holds the content.
917 */
918static int DetectHttpClientBodyTest06(void)
919{
920 TcpSession ssn;
921 Packet *p = NULL;
922 ThreadVars th_v;
923 DetectEngineCtx *de_ctx = NULL;
924 DetectEngineThreadCtx *det_ctx = NULL;
925 HtpState *http_state = NULL;
926 Flow f;
927 uint8_t http_buf[] =
928 "GET /index.html HTTP/1.0\r\n"
929 "Host: www.openinfosecfoundation.org\r\n"
930 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
931 "Content-Type: text/html\r\n"
932 "Content-Length: 26\r\n"
933 "\r\n"
934 "This is dummy message body";
935 uint32_t http_len = sizeof(http_buf) - 1;
936 int result = 0;
938
939 memset(&th_v, 0, sizeof(th_v));
940 memset(&f, 0, sizeof(f));
941 memset(&ssn, 0, sizeof(ssn));
942
943 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
944
945 FLOW_INITIALIZE(&f);
946 f.protoctx = (void *)&ssn;
947 f.proto = IPPROTO_TCP;
948 f.flags |= FLOW_IPV4;
949
950 p->flow = &f;
955
957
959 if (de_ctx == NULL)
960 goto end;
961
963
964 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
965 "(msg:\"http client body test\"; "
966 "content:\"message\"; http_client_body; "
967 "sid:1;)");
968 FAIL_IF_NULL(s);
969
971 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
972
973 int r = AppLayerParserParse(
974 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
975 if (r != 0) {
976 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
977 result = 0;
978 goto end;
979 }
980
981 http_state = f.alstate;
982 if (http_state == NULL) {
983 printf("no http state: \n");
984 result = 0;
985 goto end;
986 }
987
988 /* do detect */
989 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
990
991 if (!(PacketAlertCheck(p, 1))) {
992 printf("sid 1 didn't match but should have\n");
993 goto end;
994 }
995
996 result = 1;
997end:
998 if (alp_tctx != NULL)
1000 if (de_ctx != NULL)
1002
1003 StreamTcpFreeConfig(true);
1004 FLOW_DESTROY(&f);
1005 UTHFreePackets(&p, 1);
1006 return result;
1007}
1008
1009/**
1010 *\test Test that the http_client_body content matches against a http request
1011 * which holds the content.
1012 */
1013static int DetectHttpClientBodyTest07(void)
1014{
1015 TcpSession ssn;
1016 Packet *p1 = NULL;
1017 Packet *p2 = NULL;
1018 ThreadVars th_v;
1019 DetectEngineCtx *de_ctx = NULL;
1020 DetectEngineThreadCtx *det_ctx = NULL;
1021 HtpState *http_state = NULL;
1022 Flow f;
1023 uint8_t http1_buf[] =
1024 "GET /index.html HTTP/1.0\r\n"
1025 "Host: www.openinfosecfoundation.org\r\n"
1026 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1027 "Content-Type: text/html\r\n"
1028 "Content-Length: 54\r\n"
1029 "\r\n"
1030 "This is dummy message body1";
1031 uint8_t http2_buf[] =
1032 "This is dummy message body2";
1033 uint32_t http1_len = sizeof(http1_buf) - 1;
1034 uint32_t http2_len = sizeof(http2_buf) - 1;
1035 int result = 0;
1037
1038 memset(&th_v, 0, sizeof(th_v));
1039 memset(&f, 0, sizeof(f));
1040 memset(&ssn, 0, sizeof(ssn));
1041
1042 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1043 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1044
1045 FLOW_INITIALIZE(&f);
1046 f.protoctx = (void *)&ssn;
1047 f.proto = IPPROTO_TCP;
1048 f.flags |= FLOW_IPV4;
1049
1050 p1->flow = &f;
1054 p2->flow = &f;
1059
1060 StreamTcpInitConfig(true);
1061
1063 if (de_ctx == NULL)
1064 goto end;
1065
1066 de_ctx->flags |= DE_QUIET;
1067
1068 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1069 "(msg:\"http client body test\"; "
1070 "content:\"message\"; http_client_body; "
1071 "sid:1;)");
1072 FAIL_IF_NULL(s);
1073
1075 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1076
1077 int r = AppLayerParserParse(
1078 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1079 if (r != 0) {
1080 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1081 result = 0;
1082 goto end;
1083 }
1084
1085 http_state = f.alstate;
1086 if (http_state == NULL) {
1087 printf("no http state: ");
1088 goto end;
1089 }
1090
1091 /* do detect */
1092 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1093
1094 if (PacketAlertCheck(p1, 1)) {
1095 printf("sid 1 matched on p1 but shouldn't have: ");
1096 goto end;
1097 }
1098
1100 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1101 if (r != 0) {
1102 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1103 goto end;
1104 }
1105
1106 /* do detect */
1107 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1108 if (!(PacketAlertCheck(p2, 1))) {
1109 printf("sid 1 didn't match on p2 but should have: ");
1110 goto end;
1111 }
1112
1113 result = 1;
1114end:
1115 if (alp_tctx != NULL)
1117 if (de_ctx != NULL)
1119
1120 StreamTcpFreeConfig(true);
1121 FLOW_DESTROY(&f);
1122 UTHFreePackets(&p1, 1);
1123 UTHFreePackets(&p2, 1);
1124 return result;
1125}
1126
1127/**
1128 *\test Test that the http_client_body content matches against a http request
1129 * which holds the content.
1130 */
1131static int DetectHttpClientBodyTest08(void)
1132{
1133 TcpSession ssn;
1134 Packet *p1 = NULL;
1135 Packet *p2 = NULL;
1136 ThreadVars th_v;
1137 DetectEngineCtx *de_ctx = NULL;
1138 DetectEngineThreadCtx *det_ctx = NULL;
1139 HtpState *http_state = NULL;
1140 Flow f;
1141 uint8_t http1_buf[] =
1142 "GET /index.html HTTP/1.0\r\n"
1143 "Host: www.openinfosecfoundation.org\r\n"
1144 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1145 "Content-Type: text/html\r\n"
1146 "Content-Length: 46\r\n"
1147 "\r\n"
1148 "This is dummy body1";
1149 uint8_t http2_buf[] =
1150 "This is dummy message body2";
1151 uint32_t http1_len = sizeof(http1_buf) - 1;
1152 uint32_t http2_len = sizeof(http2_buf) - 1;
1153 int result = 0;
1155
1156 memset(&th_v, 0, sizeof(th_v));
1157 memset(&f, 0, sizeof(f));
1158 memset(&ssn, 0, sizeof(ssn));
1159
1160 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1161 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1162
1163 FLOW_INITIALIZE(&f);
1164 f.protoctx = (void *)&ssn;
1165 f.proto = IPPROTO_TCP;
1166 f.flags |= FLOW_IPV4;
1167
1168 p1->flow = &f;
1172 p2->flow = &f;
1177
1178 StreamTcpInitConfig(true);
1179
1181 if (de_ctx == NULL)
1182 goto end;
1183
1184 de_ctx->flags |= DE_QUIET;
1185
1186 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1187 "(msg:\"http client body test\"; "
1188 "content:\"message\"; http_client_body; "
1189 "sid:1;)");
1190 FAIL_IF_NULL(s);
1191
1193 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1194
1195 int r = AppLayerParserParse(
1196 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1197 if (r != 0) {
1198 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1199 result = 0;
1200 goto end;
1201 }
1202
1203 http_state = f.alstate;
1204 if (http_state == NULL) {
1205 printf("no http state: ");
1206 result = 0;
1207 goto end;
1208 }
1209
1210 /* do detect */
1211 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1212
1213 if ((PacketAlertCheck(p1, 1))) {
1214 printf("sid 1 didn't match but should have");
1215 goto end;
1216 }
1217
1219 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1220 if (r != 0) {
1221 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1222 result = 0;
1223 goto end;
1224 }
1225
1226 /* do detect */
1227 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1228
1229 if (!(PacketAlertCheck(p2, 1))) {
1230 printf("sid 1 didn't match but should have");
1231 goto end;
1232 }
1233
1234 result = 1;
1235end:
1236 if (alp_tctx != NULL)
1238 if (de_ctx != NULL)
1240
1241 StreamTcpFreeConfig(true);
1242 FLOW_DESTROY(&f);
1243 UTHFreePackets(&p1, 1);
1244 UTHFreePackets(&p2, 1);
1245 return result;
1246}
1247
1248/**
1249 *\test Test that the http_client_body content matches against a http request
1250 * which holds the content, against a cross boundary present pattern.
1251 */
1252static int DetectHttpClientBodyTest09(void)
1253{
1254 TcpSession ssn;
1255 Packet *p1 = NULL;
1256 Packet *p2 = NULL;
1257 ThreadVars th_v;
1258 DetectEngineCtx *de_ctx = NULL;
1259 DetectEngineThreadCtx *det_ctx = NULL;
1260 HtpState *http_state = NULL;
1261 Flow f;
1262 uint8_t http1_buf[] =
1263 "GET /index.html HTTP/1.0\r\n"
1264 "Host: www.openinfosecfoundation.org\r\n"
1265 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1266 "Content-Type: text/html\r\n"
1267 "Content-Length: 46\r\n"
1268 "\r\n"
1269 "This is dummy body1";
1270 uint8_t http2_buf[] =
1271 "This is dummy message body2";
1272 uint32_t http1_len = sizeof(http1_buf) - 1;
1273 uint32_t http2_len = sizeof(http2_buf) - 1;
1274 int result = 0;
1276
1277 memset(&th_v, 0, sizeof(th_v));
1278 memset(&f, 0, sizeof(f));
1279 memset(&ssn, 0, sizeof(ssn));
1280
1281 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1282 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1283
1284 FLOW_INITIALIZE(&f);
1285 f.protoctx = (void *)&ssn;
1286 f.proto = IPPROTO_TCP;
1287 f.flags |= FLOW_IPV4;
1288
1289 p1->flow = &f;
1293 p2->flow = &f;
1298
1299 StreamTcpInitConfig(true);
1300
1302 if (de_ctx == NULL)
1303 goto end;
1304
1305 de_ctx->flags |= DE_QUIET;
1306
1307 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1308 "(msg:\"http client body test\"; "
1309 "content:\"body1This\"; http_client_body; "
1310 "sid:1;)");
1311 FAIL_IF_NULL(s);
1312
1314 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1315
1316 int r = AppLayerParserParse(
1317 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1318 if (r != 0) {
1319 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1320 result = 0;
1321 goto end;
1322 }
1323
1324 http_state = f.alstate;
1325 if (http_state == NULL) {
1326 printf("no http state: ");
1327 result = 0;
1328 goto end;
1329 }
1330
1331 /* do detect */
1332 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1333
1334 if ((PacketAlertCheck(p1, 1))) {
1335 printf("sid 1 didn't match but should have");
1336 goto end;
1337 }
1338
1340 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1341 if (r != 0) {
1342 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1343 result = 0;
1344 goto end;
1345 }
1346
1347 /* do detect */
1348 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1349
1350 if (!(PacketAlertCheck(p2, 1))) {
1351 printf("sid 1 didn't match but should have");
1352 goto end;
1353 }
1354
1355 result = 1;
1356end:
1357 if (alp_tctx != NULL)
1359 if (de_ctx != NULL)
1361
1362 StreamTcpFreeConfig(true);
1363 FLOW_DESTROY(&f);
1364 UTHFreePackets(&p1, 1);
1365 UTHFreePackets(&p2, 1);
1366 return result;
1367}
1368
1369/**
1370 *\test Test that the http_client_body content matches against a http request
1371 * against a case insensitive pattern.
1372 */
1373static int DetectHttpClientBodyTest10(void)
1374{
1375 TcpSession ssn;
1376 Packet *p1 = NULL;
1377 Packet *p2 = NULL;
1378 ThreadVars th_v;
1379 DetectEngineCtx *de_ctx = NULL;
1380 DetectEngineThreadCtx *det_ctx = NULL;
1381 HtpState *http_state = NULL;
1382 Flow f;
1383 uint8_t http1_buf[] =
1384 "GET /index.html HTTP/1.0\r\n"
1385 "Host: www.openinfosecfoundation.org\r\n"
1386 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1387 "Content-Type: text/html\r\n"
1388 "Content-Length: 46\r\n"
1389 "\r\n"
1390 "This is dummy bodY1";
1391 uint8_t http2_buf[] =
1392 "This is dummy message body2";
1393 uint32_t http1_len = sizeof(http1_buf) - 1;
1394 uint32_t http2_len = sizeof(http2_buf) - 1;
1395 int result = 0;
1397
1398 memset(&th_v, 0, sizeof(th_v));
1399 memset(&f, 0, sizeof(f));
1400 memset(&ssn, 0, sizeof(ssn));
1401
1402 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1403 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1404
1405 FLOW_INITIALIZE(&f);
1406 f.protoctx = (void *)&ssn;
1407 f.proto = IPPROTO_TCP;
1408 f.flags |= FLOW_IPV4;
1409
1410 p1->flow = &f;
1414 p2->flow = &f;
1419
1420 StreamTcpInitConfig(true);
1421
1423 if (de_ctx == NULL)
1424 goto end;
1425
1426 de_ctx->flags |= DE_QUIET;
1427
1428 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1429 "(msg:\"http client body test\"; "
1430 "content:\"body1This\"; http_client_body; nocase;"
1431 "sid:1;)");
1432 FAIL_IF_NULL(s);
1433
1435 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1436
1437 int r = AppLayerParserParse(
1438 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1439 if (r != 0) {
1440 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1441 result = 0;
1442 goto end;
1443 }
1444
1445 http_state = f.alstate;
1446 if (http_state == NULL) {
1447 printf("no http state: \n");
1448 result = 0;
1449 goto end;
1450 }
1451
1452 /* do detect */
1453 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1454
1455 if ((PacketAlertCheck(p1, 1))) {
1456 printf("sid 1 didn't match but should have\n");
1457 goto end;
1458 }
1459
1461 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1462 if (r != 0) {
1463 printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1464 result = 0;
1465 goto end;
1466 }
1467
1468 /* do detect */
1469 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1470
1471 if (!(PacketAlertCheck(p2, 1))) {
1472 printf("sid 1 didn't match but should have");
1473 goto end;
1474 }
1475
1476 result = 1;
1477end:
1478 if (alp_tctx != NULL)
1480 if (de_ctx != NULL)
1482
1483 StreamTcpFreeConfig(true);
1484 FLOW_DESTROY(&f);
1485 UTHFreePackets(&p1, 1);
1486 UTHFreePackets(&p2, 1);
1487 return result;
1488}
1489
1490/**
1491 *\test Test that the negated http_client_body content matches against a
1492 * http request which doesn't hold the content.
1493 */
1494static int DetectHttpClientBodyTest11(void)
1495{
1496 TcpSession ssn;
1497 Packet *p = NULL;
1498 ThreadVars th_v;
1499 DetectEngineCtx *de_ctx = NULL;
1500 DetectEngineThreadCtx *det_ctx = NULL;
1501 HtpState *http_state = NULL;
1502 Flow f;
1503 uint8_t http_buf[] =
1504 "GET /index.html HTTP/1.0\r\n"
1505 "Host: www.openinfosecfoundation.org\r\n"
1506 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1507 "Content-Type: text/html\r\n"
1508 "Content-Length: 26\r\n"
1509 "\r\n"
1510 "This is dummy message body";
1511 uint32_t http_len = sizeof(http_buf) - 1;
1512 int result = 0;
1514
1515 memset(&th_v, 0, sizeof(th_v));
1516 memset(&f, 0, sizeof(f));
1517 memset(&ssn, 0, sizeof(ssn));
1518
1519 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1520
1521 FLOW_INITIALIZE(&f);
1522 f.protoctx = (void *)&ssn;
1523 f.proto = IPPROTO_TCP;
1524 f.flags |= FLOW_IPV4;
1525
1526 p->flow = &f;
1531
1532 StreamTcpInitConfig(true);
1533
1535 if (de_ctx == NULL)
1536 goto end;
1537
1538 de_ctx->flags |= DE_QUIET;
1539
1540 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1541 "(msg:\"http client body test\"; "
1542 "content:!\"message1\"; http_client_body; "
1543 "sid:1;)");
1544 FAIL_IF_NULL(s);
1545
1547 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1548
1549 int r = AppLayerParserParse(
1550 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1551 if (r != 0) {
1552 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1553 result = 0;
1554 goto end;
1555 }
1556
1557 http_state = f.alstate;
1558 if (http_state == NULL) {
1559 printf("no http state: ");
1560 result = 0;
1561 goto end;
1562 }
1563
1564 /* do detect */
1565 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1566
1567 if (!(PacketAlertCheck(p, 1))) {
1568 printf("sid 1 didn't match but should have");
1569 goto end;
1570 }
1571
1572 result = 1;
1573end:
1574 if (alp_tctx != NULL)
1576 if (de_ctx != NULL)
1578
1579 StreamTcpFreeConfig(true);
1580 FLOW_DESTROY(&f);
1581 UTHFreePackets(&p, 1);
1582 return result;
1583}
1584
1585/**
1586 *\test Negative test that the negated http_client_body content matches against a
1587 * http request which holds hold the content.
1588 */
1589static int DetectHttpClientBodyTest12(void)
1590{
1591 TcpSession ssn;
1592 Packet *p = NULL;
1593 ThreadVars th_v;
1594 DetectEngineCtx *de_ctx = NULL;
1595 DetectEngineThreadCtx *det_ctx = NULL;
1596 HtpState *http_state = NULL;
1597 Flow f;
1598 uint8_t http_buf[] =
1599 "GET /index.html HTTP/1.0\r\n"
1600 "Host: www.openinfosecfoundation.org\r\n"
1601 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1602 "Content-Type: text/html\r\n"
1603 "Content-Length: 26\r\n"
1604 "\r\n"
1605 "This is dummy message body";
1606 uint32_t http_len = sizeof(http_buf) - 1;
1607 int result = 0;
1609
1610 memset(&th_v, 0, sizeof(th_v));
1611 memset(&f, 0, sizeof(f));
1612 memset(&ssn, 0, sizeof(ssn));
1613
1614 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1615
1616 FLOW_INITIALIZE(&f);
1617 f.protoctx = (void *)&ssn;
1618 f.proto = IPPROTO_TCP;
1619 f.flags |= FLOW_IPV4;
1620
1621 p->flow = &f;
1626
1627 StreamTcpInitConfig(true);
1628
1630 if (de_ctx == NULL)
1631 goto end;
1632
1633 de_ctx->flags |= DE_QUIET;
1634
1635 Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1636 "(msg:\"http client body test\"; "
1637 "content:!\"message\"; http_client_body; "
1638 "sid:1;)");
1639 FAIL_IF_NULL(s);
1640
1642 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1643
1644 int r = AppLayerParserParse(
1645 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1646 if (r != 0) {
1647 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1648 result = 0;
1649 goto end;
1650 }
1651
1652 http_state = f.alstate;
1653 if (http_state == NULL) {
1654 printf("no http state: ");
1655 result = 0;
1656 goto end;
1657 }
1658
1659 /* do detect */
1660 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1661
1662 if ((PacketAlertCheck(p, 1))) {
1663 printf("sid 1 didn't match but should have");
1664 goto end;
1665 }
1666
1667 result = 1;
1668end:
1669 if (alp_tctx != NULL)
1671 if (de_ctx != NULL)
1673
1674 StreamTcpFreeConfig(true);
1675 FLOW_DESTROY(&f);
1676 UTHFreePackets(&p, 1);
1677 return result;
1678}
1679
1680/**
1681 *\test Test that the http_client_body content matches against a http request
1682 * which holds the content.
1683 */
1684static int DetectHttpClientBodyTest13(void)
1685{
1686 TcpSession ssn;
1687 Packet *p = NULL;
1688 ThreadVars th_v;
1689 DetectEngineCtx *de_ctx = NULL;
1690 DetectEngineThreadCtx *det_ctx = NULL;
1691 HtpState *http_state = NULL;
1692 Flow f;
1693 uint8_t http_buf[] =
1694 "GET /index.html HTTP/1.0\r\n"
1695 "Host: www.openinfosecfoundation.org\r\n"
1696 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1697 "Content-Type: text/html\r\n"
1698 "Content-Length: 55\r\n"
1699 "\r\n"
1700 "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend";
1701 uint32_t http_len = sizeof(http_buf) - 1;
1702 int result = 0;
1704
1705 memset(&th_v, 0, sizeof(th_v));
1706 memset(&f, 0, sizeof(f));
1707 memset(&ssn, 0, sizeof(ssn));
1708
1709 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1710
1711 FLOW_INITIALIZE(&f);
1712 f.protoctx = (void *)&ssn;
1713 f.proto = IPPROTO_TCP;
1714 f.flags |= FLOW_IPV4;
1715
1716 p->flow = &f;
1721
1722 StreamTcpInitConfig(true);
1723
1725 if (de_ctx == NULL)
1726 goto end;
1727
1728 de_ctx->flags |= DE_QUIET;
1729
1731 "alert http any any -> any any "
1732 "(msg:\"http client body test\"; "
1733 "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_client_body; "
1734 "sid:1;)");
1735 FAIL_IF_NULL(s);
1736
1738 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1739
1740 int r = AppLayerParserParse(
1741 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1742 if (r != 0) {
1743 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1744 result = 0;
1745 goto end;
1746 }
1747
1748 http_state = f.alstate;
1749 if (http_state == NULL) {
1750 printf("no http state: ");
1751 result = 0;
1752 goto end;
1753 }
1754
1755 /* do detect */
1756 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1757
1758 if (!(PacketAlertCheck(p, 1))) {
1759 printf("sid 1 didn't match but should have");
1760 goto end;
1761 }
1762
1763 result = 1;
1764end:
1765 if (alp_tctx != NULL)
1767 if (de_ctx != NULL)
1769
1770 StreamTcpFreeConfig(true);
1771 FLOW_DESTROY(&f);
1772 UTHFreePackets(&p, 1);
1773 return result;
1774}
1775
1776/** \test multiple http transactions and body chunks of request handling */
1777static int DetectHttpClientBodyTest14(void)
1778{
1779 int result = 0;
1780 Signature *s = NULL;
1781 DetectEngineThreadCtx *det_ctx = NULL;
1782 ThreadVars th_v;
1783 Flow f;
1784 TcpSession ssn;
1785 Packet *p = NULL;
1786 uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1787 uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1788 uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1789 uint8_t httpbuf4[] = "Body one!!";
1790 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1791 uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1792 uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1793 uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1794 uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1795 uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1796 uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1797 uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1798 uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1799 uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1801
1802 memset(&th_v, 0, sizeof(th_v));
1803 memset(&f, 0, sizeof(f));
1804 memset(&ssn, 0, sizeof(ssn));
1805
1806 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1807
1808 FLOW_INITIALIZE(&f);
1809 f.protoctx = (void *)&ssn;
1810 f.proto = IPPROTO_TCP;
1811 f.flags |= FLOW_IPV4;
1812
1813 p->flow = &f;
1818
1819 StreamTcpInitConfig(true);
1820
1822 if (de_ctx == NULL) {
1823 goto end;
1824 }
1825
1826 de_ctx->flags |= DE_QUIET;
1827
1828 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)");
1829 if (s == NULL) {
1830 printf("sig parse failed: ");
1831 goto end;
1832 }
1833 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)");
1834 if (s == NULL) {
1835 printf("sig2 parse failed: ");
1836 goto end;
1837 }
1838
1840 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1841
1842 int r = AppLayerParserParse(
1843 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1844 if (r != 0) {
1845 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1846 goto end;
1847 }
1848
1849 /* do detect */
1850 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1851 if (PacketAlertCheck(p, 1)) {
1852 printf("sig 1 alerted: ");
1853 goto end;
1854 }
1855 p->alerts.cnt = 0;
1856
1857 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1858 if (r != 0) {
1859 printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
1860 goto end;
1861 }
1862
1863 /* do detect */
1864 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1865 if (PacketAlertCheck(p, 1)) {
1866 printf("sig 1 alerted (2): ");
1867 goto end;
1868 }
1869 p->alerts.cnt = 0;
1870
1871 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1872 if (r != 0) {
1873 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1874 goto end;
1875 }
1876
1877 /* do detect */
1878 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1879 if (PacketAlertCheck(p, 1)) {
1880 printf("signature matched, but shouldn't have: ");
1881 goto end;
1882 }
1883 p->alerts.cnt = 0;
1884
1885 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
1886 if (r != 0) {
1887 printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
1888 result = 0;
1889 goto end;
1890 }
1891
1892 /* do detect */
1893 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1894 if (!(PacketAlertCheck(p, 1))) {
1895 printf("sig 1 didn't alert: ");
1896 goto end;
1897 }
1898 p->alerts.cnt = 0;
1899
1900 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
1901 if (r != 0) {
1902 printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
1903 goto end;
1904 }
1905
1906 /* do detect */
1907 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1908 if (PacketAlertCheck(p, 1)) {
1909 printf("sig 1 alerted (5): ");
1910 goto end;
1911 }
1912 p->alerts.cnt = 0;
1913
1914 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
1915 if (r != 0) {
1916 printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
1917 goto end;
1918 }
1919
1920 /* do detect */
1921 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1922 if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
1923 printf("sig 1 alerted (request 2, chunk 6): ");
1924 goto end;
1925 }
1926 p->alerts.cnt = 0;
1927
1928 SCLogDebug("sending data chunk 7");
1929
1930 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
1931 if (r != 0) {
1932 printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
1933 goto end;
1934 }
1935
1936 /* do detect */
1937 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1938 if (!(PacketAlertCheck(p, 2))) {
1939 printf("signature 2 didn't match, but should have: ");
1940 goto end;
1941 }
1942 p->alerts.cnt = 0;
1943
1944 HtpState *htp_state = f.alstate;
1945 if (htp_state == NULL) {
1946 printf("no http state: ");
1947 result = 0;
1948 goto end;
1949 }
1950
1951 if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
1952 printf("The http app layer doesn't have 2 transactions, but it should: ");
1953 goto end;
1954 }
1955
1956 result = 1;
1957end:
1958 if (alp_tctx != NULL)
1960 if (det_ctx != NULL) {
1961 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1962 }
1963 if (de_ctx != NULL) {
1965 }
1966
1967 StreamTcpFreeConfig(true);
1968 FLOW_DESTROY(&f);
1969 UTHFreePacket(p);
1970 return result;
1971}
1972
1973/** \test multiple http transactions and body chunks of request handling */
1974static int DetectHttpClientBodyTest15(void)
1975{
1976 int result = 0;
1977 Signature *s = NULL;
1978 DetectEngineThreadCtx *det_ctx = NULL;
1979 ThreadVars th_v;
1980 Flow f;
1981 TcpSession ssn;
1982 Packet *p = NULL;
1983 uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1984 uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1985 uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1986 uint8_t httpbuf4[] = "Body one!!";
1987 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1988 uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1989 uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1990 uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1991 uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1992 uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1993 uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1994 uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1995 uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1996 uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1998
1999 memset(&th_v, 0, sizeof(th_v));
2000 memset(&f, 0, sizeof(f));
2001 memset(&ssn, 0, sizeof(ssn));
2002
2003 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2004
2005 FLOW_INITIALIZE(&f);
2006 f.protoctx = (void *)&ssn;
2007 f.proto = IPPROTO_TCP;
2008 f.flags |= FLOW_IPV4;
2009
2010 p->flow = &f;
2015
2016 StreamTcpInitConfig(true);
2017
2019 if (de_ctx == NULL) {
2020 goto end;
2021 }
2022
2023 de_ctx->flags |= DE_QUIET;
2024
2025 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)");
2026 if (s == NULL) {
2027 printf("sig parse failed: ");
2028 goto end;
2029 }
2030 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)");
2031 if (s == NULL) {
2032 printf("sig2 parse failed: ");
2033 goto end;
2034 }
2035
2037 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2038
2039 int r = AppLayerParserParse(
2040 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2041 if (r != 0) {
2042 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2043 goto end;
2044 }
2045
2046 /* do detect */
2047 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2048 if (PacketAlertCheck(p, 1)) {
2049 printf("sig 1 alerted: ");
2050 goto end;
2051 }
2052 p->alerts.cnt = 0;
2053
2054 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2055 if (r != 0) {
2056 printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
2057 goto end;
2058 }
2059
2060 /* do detect */
2061 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2062 if (PacketAlertCheck(p, 1)) {
2063 printf("sig 1 alerted (2): ");
2064 goto end;
2065 }
2066 p->alerts.cnt = 0;
2067
2068 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
2069 if (r != 0) {
2070 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
2071 goto end;
2072 }
2073
2074 /* do detect */
2075 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2076 if (PacketAlertCheck(p, 1)) {
2077 printf("signature matched, but shouldn't have: ");
2078 goto end;
2079 }
2080 p->alerts.cnt = 0;
2081
2082 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
2083 if (r != 0) {
2084 printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
2085 result = 0;
2086 goto end;
2087 }
2088
2089 /* do detect */
2090 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2091 if (!(PacketAlertCheck(p, 1))) {
2092 printf("sig 1 didn't alert: ");
2093 goto end;
2094 }
2095 p->alerts.cnt = 0;
2096
2097 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
2098 if (r != 0) {
2099 printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2100 goto end;
2101 }
2102
2103 /* do detect */
2104 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2105 if (PacketAlertCheck(p, 1)) {
2106 printf("sig 1 alerted (5): ");
2107 goto end;
2108 }
2109 p->alerts.cnt = 0;
2110
2111 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
2112 if (r != 0) {
2113 printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2114 goto end;
2115 }
2116
2117 /* do detect */
2118 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2119 if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2120 printf("sig 1 alerted (request 2, chunk 6): ");
2121 goto end;
2122 }
2123 p->alerts.cnt = 0;
2124
2125 SCLogDebug("sending data chunk 7");
2126
2127 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
2128 if (r != 0) {
2129 printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2130 goto end;
2131 }
2132
2133 /* do detect */
2134 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2135 if (!(PacketAlertCheck(p, 2))) {
2136 printf("signature 2 didn't match, but should have: ");
2137 goto end;
2138 }
2139 p->alerts.cnt = 0;
2140
2141 HtpState *htp_state = f.alstate;
2142 if (htp_state == NULL) {
2143 printf("no http state: ");
2144 result = 0;
2145 goto end;
2146 }
2147
2148 /* hardcoded check of the transactions and it's client body chunks */
2149 if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2150 printf("The http app layer doesn't have 2 transactions, but it should: ");
2151 goto end;
2152 }
2153
2154 htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 0);
2155 htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 1);
2156
2157 HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2158
2159 HtpBodyChunk *cur = htud->request_body.first;
2160 if (htud->request_body.first == NULL) {
2161 SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2162 goto end;
2163 }
2164
2166 (uint8_t *)"Body one!!", 10) != 1)
2167 {
2168 SCLogDebug("Body data in t1 is not correctly set: ");
2169 goto end;
2170 }
2171
2172 htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2173
2174 cur = htud->request_body.first;
2175 if (htud->request_body.first == NULL) {
2176 SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2177 goto end;
2178 }
2179
2181 (uint8_t *)"Body two!!", 10) != 1)
2182 {
2183 SCLogDebug("Body data in t1 is not correctly set: ");
2184 goto end;
2185 }
2186
2187 result = 1;
2188end:
2189 if (alp_tctx != NULL)
2191 if (det_ctx != NULL) {
2192 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2193 }
2194 if (de_ctx != NULL) {
2196 }
2197
2198 StreamTcpFreeConfig(true);
2199 FLOW_DESTROY(&f);
2200 UTHFreePacket(p);
2201 return result;
2202}
2203
2204static int DetectHttpClientBodyTest22(void)
2205{
2208 de_ctx->flags |= DE_QUIET;
2210 "alert icmp any any -> any any "
2211 "(content:\"one\"; content:\"two\"; http_client_body; "
2212 "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2213 FAIL_IF_NULL(s);
2215 FAIL_IF(DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL);
2216 SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id);
2217 FAIL_IF_NULL(sm);
2218
2219 DetectContentData *cd1 =
2221 DetectContentData *cd2 =
2223 DetectContentData *hcbd1 =
2224 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2225 ->prev->ctx;
2226 DetectContentData *hcbd2 =
2227 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2228 FAIL_IF(cd1->flags != 0);
2229 FAIL_IF(memcmp(cd1->content, "one", cd1->content_len) != 0);
2230 FAIL_IF(cd2->flags != 0);
2231 FAIL_IF(memcmp(cd2->content, "four", cd2->content_len) != 0);
2233 FAIL_IF(memcmp(hcbd1->content, "two", hcbd1->content_len) != 0);
2235 FAIL_IF(memcmp(hcbd2->content, "three", hcbd1->content_len) != 0);
2236
2241
2243 PASS;
2244}
2245
2246static int DetectHttpClientBodyTest23(void)
2247{
2250 de_ctx->flags |= DE_QUIET;
2251
2253 "alert icmp any any -> any any "
2254 "(content:\"one\"; http_client_body; pcre:/two/; "
2255 "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2256 FAIL_IF_NULL(s);
2258 FAIL_IF_NULL(DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id));
2259
2260 DetectPcreData *pd1 =
2262 ->prev->ctx;
2263 DetectContentData *cd2 =
2265 ->ctx;
2266 DetectContentData *hcbd1 =
2267 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2268 ->prev->ctx;
2269 DetectContentData *hcbd2 =
2270 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2271 FAIL_IF(pd1->flags != 0);
2272 FAIL_IF(cd2->flags != 0);
2273 FAIL_IF(memcmp(cd2->content, "four", cd2->content_len) != 0);
2275 FAIL_IF(memcmp(hcbd1->content, "one", hcbd1->content_len) != 0);
2277 FAIL_IF(memcmp(hcbd2->content, "three", hcbd1->content_len) != 0);
2281
2283 PASS;
2284}
2285
2286static int DetectHttpClientBodyTest24(void)
2287{
2290 de_ctx->flags |= DE_QUIET;
2291 Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2292 "(content:\"one\"; http_client_body; pcre:/two/; "
2293 "content:\"three\"; distance:10; within:15; "
2294 "http_client_body; content:\"four\"; sid:1;)");
2295 FAIL_IF_NULL(s);
2296
2298 FAIL_IF_NULL(DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id));
2299
2300 DetectPcreData *pd1 =
2302 ->prev->ctx;
2303 DetectContentData *cd2 =
2305 ->ctx;
2306 DetectContentData *hcbd1 =
2307 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2308 ->prev->ctx;
2309 DetectContentData *hcbd2 =
2310 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2311 FAIL_IF(pd1->flags != 0);
2312 FAIL_IF(cd2->flags != 0);
2313 FAIL_IF(memcmp(cd2->content, "four", cd2->content_len) != 0);
2315 FAIL_IF(memcmp(hcbd1->content, "one", hcbd1->content_len) != 0);
2317 FAIL_IF(memcmp(hcbd2->content, "three", hcbd1->content_len) != 0);
2318
2322
2324 PASS;
2325}
2326
2327static int DetectHttpClientBodyTest25(void)
2328{
2331 de_ctx->flags |= DE_QUIET;
2332 Signature *s =
2333 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2334 "(content:\"one\"; http_client_body; pcre:/two/; "
2335 "content:\"three\"; distance:10; http_client_body; "
2336 "content:\"four\"; distance:10; sid:1;)");
2337 FAIL_IF_NULL(s);
2339 FAIL_IF_NULL(DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id));
2340
2341 DetectPcreData *pd1 =
2343 ->prev->ctx;
2344 DetectContentData *cd2 =
2346 ->ctx;
2347 DetectContentData *hcbd1 =
2348 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2349 ->prev->ctx;
2350 DetectContentData *hcbd2 =
2351 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2352 FAIL_IF(pd1->flags != DETECT_PCRE_RELATIVE_NEXT);
2353 FAIL_IF(cd2->flags != DETECT_CONTENT_DISTANCE);
2354 FAIL_IF(memcmp(cd2->content, "four", cd2->content_len) != 0);
2356 FAIL_IF(memcmp(hcbd1->content, "one", hcbd1->content_len) != 0);
2358 FAIL_IF(memcmp(hcbd2->content, "three", hcbd1->content_len) != 0);
2359
2363
2365 PASS;
2366}
2367
2368static int DetectHttpClientBodyTest26(void)
2369{
2370 DetectEngineCtx *de_ctx = NULL;
2371 int result = 0;
2372
2373 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2374 goto end;
2375
2376 de_ctx->flags |= DE_QUIET;
2378 "alert icmp any any -> any any "
2379 "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2380 "content:\"three\"; distance:10; http_client_body; within:10; "
2381 "content:\"four\"; distance:10; sid:1;)");
2382 if (de_ctx->sig_list == NULL) {
2383 printf("de_ctx->sig_list == NULL\n");
2384 goto end;
2385 }
2386
2388 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL\n");
2389 goto end;
2390 }
2391
2392 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2393 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2394 goto end;
2395 }
2396
2397 DetectPcreData *pd1 =
2399 ->prev->ctx;
2400 DetectContentData *cd2 =
2402 ->ctx;
2403 DetectContentData *hcbd1 =
2404 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2405 ->prev->ctx;
2406 DetectContentData *hcbd2 =
2407 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2408 if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || cd2->flags != DETECT_CONTENT_DISTANCE ||
2409 memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2411 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2412 hcbd2->flags !=
2414 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2415 printf ("failed: http_client_body incorrect flags");
2416 goto end;
2417 }
2418
2419 if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2420 DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2421 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2422 goto end;
2423 }
2424
2425 result = 1;
2426
2427 end:
2429 return result;
2430}
2431
2432static int DetectHttpClientBodyTest27(void)
2433{
2434 DetectEngineCtx *de_ctx = NULL;
2435 int result = 0;
2436
2437 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2438 goto end;
2439
2440 de_ctx->flags |= DE_QUIET;
2442 "alert icmp any any -> any any "
2443 "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2444 "content:\"three\"; distance:10; http_client_body; within:10; "
2445 "content:\"four\"; distance:10; sid:1;)");
2446 FAIL_IF_NULL(s);
2447
2448 result = 1;
2449
2450 end:
2452 return result;
2453}
2454
2455static int DetectHttpClientBodyTest28(void)
2456{
2457 DetectEngineCtx *de_ctx = NULL;
2458 int result = 0;
2459
2460 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2461 goto end;
2462
2463 de_ctx->flags |= DE_QUIET;
2464 Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2465 "(content:\"one\"; http_client_body; pcre:/two/; "
2466 "content:\"three\"; http_client_body; depth:10; "
2467 "content:\"four\"; distance:10; sid:1;)");
2468 if (de_ctx->sig_list == NULL) {
2469 printf("de_ctx->sig_list == NULL\n");
2470 goto end;
2471 }
2472
2474 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL\n");
2475 goto end;
2476 }
2477
2478 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2479 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2480 goto end;
2481 }
2482
2483 DetectPcreData *pd1 =
2485 ->prev->ctx;
2486 DetectContentData *cd2 =
2488 ->ctx;
2489 DetectContentData *hcbd1 =
2490 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2491 ->prev->ctx;
2492 DetectContentData *hcbd2 =
2493 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2494 if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || cd2->flags != DETECT_CONTENT_DISTANCE ||
2495 memcmp(cd2->content, "four", cd2->content_len) != 0 || hcbd1->flags != 0 ||
2496 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2498 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2499 goto end;
2500 }
2501
2502 if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2503 !DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2504 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2505 goto end;
2506 }
2507
2508 result = 1;
2509
2510 end:
2512 return result;
2513}
2514
2515static int DetectHttpClientBodyTest29(void)
2516{
2517 DetectEngineCtx *de_ctx = NULL;
2518 int result = 0;
2519
2520 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2521 goto end;
2522
2523 de_ctx->flags |= DE_QUIET;
2524 Signature *s =
2525 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2526 "(content:\"one\"; http_client_body; "
2527 "content:\"two\"; distance:0; http_client_body; sid:1;)");
2528 if (de_ctx->sig_list == NULL) {
2529 printf("de_ctx->sig_list == NULL\n");
2530 goto end;
2531 }
2532
2534 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2535 goto end;
2536 }
2537
2538 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2539 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2540 goto end;
2541 }
2542
2543 DetectContentData *hcbd1 =
2544 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2545 ->prev->ctx;
2546 DetectContentData *hcbd2 =
2547 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2549 FAIL_IF(memcmp(hcbd1->content, "one", hcbd1->content_len) != 0);
2551 FAIL_IF(memcmp(hcbd2->content, "two", hcbd1->content_len) != 0);
2552
2553 result = 1;
2554
2555 end:
2557 return result;
2558}
2559
2560static int DetectHttpClientBodyTest30(void)
2561{
2562 DetectEngineCtx *de_ctx = NULL;
2563 int result = 0;
2564
2565 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2566 goto end;
2567
2568 de_ctx->flags |= DE_QUIET;
2569 Signature *s =
2570 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2571 "(content:\"one\"; http_client_body; "
2572 "content:\"two\"; within:5; http_client_body; sid:1;)");
2573 if (de_ctx->sig_list == NULL) {
2574 printf("de_ctx->sig_list == NULL\n");
2575 goto end;
2576 }
2577
2579 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2580 goto end;
2581 }
2582
2583 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2584 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2585 goto end;
2586 }
2587
2588 DetectContentData *hcbd1 =
2589 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2590 ->prev->ctx;
2591 DetectContentData *hcbd2 =
2592 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2594 FAIL_IF(memcmp(hcbd1->content, "one", hcbd1->content_len) != 0);
2596 FAIL_IF(memcmp(hcbd2->content, "two", hcbd1->content_len) != 0);
2597
2598 result = 1;
2599
2600 end:
2602 return result;
2603}
2604
2605static int DetectHttpClientBodyTest31(void)
2606{
2607 DetectEngineCtx *de_ctx = NULL;
2608 int result = 0;
2609
2610 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2611 goto end;
2612
2613 de_ctx->flags |= DE_QUIET;
2614 Signature *s =
2615 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2616 "(content:\"one\"; within:5; http_client_body; sid:1;)");
2617 FAIL_IF_NULL(s);
2618
2619 result = 1;
2620
2621 end:
2623 return result;
2624}
2625
2626static int DetectHttpClientBodyTest32(void)
2627{
2628 DetectEngineCtx *de_ctx = NULL;
2629 int result = 0;
2630
2631 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2632 goto end;
2633
2634 de_ctx->flags |= DE_QUIET;
2635 Signature *s =
2636 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2637 "(content:\"one\"; http_client_body; within:5; sid:1;)");
2638 FAIL_IF_NULL(s);
2639
2640 result = 1;
2641
2642 end:
2644 return result;
2645}
2646
2647static int DetectHttpClientBodyTest33(void)
2648{
2649 DetectEngineCtx *de_ctx = NULL;
2650 int result = 0;
2651
2652 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2653 goto end;
2654
2655 de_ctx->flags |= DE_QUIET;
2656 Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2657 "(content:\"one\"; within:5; sid:1;)");
2658 FAIL_IF_NULL(s);
2659
2660 result = 1;
2661
2662 end:
2664 return result;
2665}
2666
2667static int DetectHttpClientBodyTest34(void)
2668{
2669 DetectEngineCtx *de_ctx = NULL;
2670 int result = 0;
2671
2672 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2673 goto end;
2674
2675 de_ctx->flags |= DE_QUIET;
2676 Signature *s =
2677 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2678 "(pcre:/one/P; "
2679 "content:\"two\"; within:5; http_client_body; sid:1;)");
2680 if (de_ctx->sig_list == NULL) {
2681 printf("de_ctx->sig_list == NULL\n");
2682 goto end;
2683 }
2684
2686 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2687 goto end;
2688 }
2689
2690 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2691 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2692 goto end;
2693 }
2694
2695 if (DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id) == NULL ||
2696 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->type != DETECT_CONTENT ||
2697 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev == NULL ||
2698 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev->type !=
2699 DETECT_PCRE) {
2700
2701 goto end;
2702 }
2703
2704 DetectPcreData *pd1 =
2705 (DetectPcreData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2706 ->prev->ctx;
2707 DetectContentData *hcbd2 =
2708 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2711 FAIL_IF(memcmp(hcbd2->content, "two", hcbd2->content_len) != 0);
2712
2713 result = 1;
2714
2715 end:
2717 return result;
2718}
2719
2720static int DetectHttpClientBodyTest35(void)
2721{
2722 DetectEngineCtx *de_ctx = NULL;
2723 int result = 0;
2724
2725 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2726 goto end;
2727
2728 de_ctx->flags |= DE_QUIET;
2729 Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2730 "(content:\"two\"; http_client_body; "
2731 "pcre:/one/PR; sid:1;)");
2732 if (de_ctx->sig_list == NULL) {
2733 printf("de_ctx->sig_list == NULL\n");
2734 goto end;
2735 }
2736
2738 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2739 goto end;
2740 }
2741
2742 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2743 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2744 goto end;
2745 }
2746
2747 if (DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id) == NULL ||
2748 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->type != DETECT_PCRE ||
2749 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev == NULL ||
2750 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev->type !=
2752
2753 goto end;
2754 }
2755
2756 DetectContentData *hcbd1 =
2757 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2758 ->prev->ctx;
2759 DetectPcreData *pd2 =
2760 (DetectPcreData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2763 FAIL_IF(memcmp(hcbd1->content, "two", hcbd1->content_len) != 0);
2764
2765 result = 1;
2766
2767 end:
2769 return result;
2770}
2771
2772static int DetectHttpClientBodyTest36(void)
2773{
2774 DetectEngineCtx *de_ctx = NULL;
2775 int result = 0;
2776
2777 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2778 goto end;
2779
2780 de_ctx->flags |= DE_QUIET;
2781 Signature *s =
2782 DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2783 "(pcre:/one/P; "
2784 "content:\"two\"; distance:5; http_client_body; sid:1;)");
2785 if (de_ctx->sig_list == NULL) {
2786 printf("de_ctx->sig_list == NULL\n");
2787 goto end;
2788 }
2789
2791 printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2792 goto end;
2793 }
2794
2795 if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2796 printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2797 goto end;
2798 }
2799
2800 if (DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id) == NULL ||
2801 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->type != DETECT_CONTENT ||
2802 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev == NULL ||
2803 DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev->type !=
2804 DETECT_PCRE) {
2805
2806 goto end;
2807 }
2808
2809 DetectPcreData *pd1 =
2810 (DetectPcreData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2811 ->prev->ctx;
2812 DetectContentData *hcbd2 =
2813 (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2816 FAIL_IF(memcmp(hcbd2->content, "two", hcbd2->content_len) != 0);
2817
2818 result = 1;
2819
2820 end:
2822 return result;
2823}
2824
2825static int DetectHttpClientBodyIsdataatParseTest(void)
2826{
2829 de_ctx->flags |= DE_QUIET;
2830
2832 "alert tcp any any -> any any ("
2833 "content:\"one\"; http_client_body; "
2834 "isdataat:!4,relative; sid:1;)");
2835 FAIL_IF_NULL(s);
2836
2837 SigMatch *sm = DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id);
2838 FAIL_IF_NULL(sm);
2840
2842 FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
2843 FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
2844 FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
2845
2847 PASS;
2848}
2849
2850void DetectHttpClientBodyRegisterTests(void)
2851{
2852 UtRegisterTest("DetectHttpClientBodyParserTest01", DetectHttpClientBodyParserTest01);
2853 UtRegisterTest("DetectHttpClientBodyParserTest02", DetectHttpClientBodyParserTest02);
2854 UtRegisterTest("DetectHttpClientBodyTest01", DetectHttpClientBodyTest01);
2855 UtRegisterTest("DetectHttpClientBodyTest02", DetectHttpClientBodyTest02);
2856 UtRegisterTest("DetectHttpClientBodyTest03", DetectHttpClientBodyTest03);
2857 UtRegisterTest("DetectHttpClientBodyTest05", DetectHttpClientBodyTest05);
2858 UtRegisterTest("DetectHttpClientBodyTest06", DetectHttpClientBodyTest06);
2859 UtRegisterTest("DetectHttpClientBodyTest07", DetectHttpClientBodyTest07);
2860 UtRegisterTest("DetectHttpClientBodyTest08", DetectHttpClientBodyTest08);
2861 UtRegisterTest("DetectHttpClientBodyTest09", DetectHttpClientBodyTest09);
2862 UtRegisterTest("DetectHttpClientBodyTest10", DetectHttpClientBodyTest10);
2863 UtRegisterTest("DetectHttpClientBodyTest11", DetectHttpClientBodyTest11);
2864 UtRegisterTest("DetectHttpClientBodyTest12", DetectHttpClientBodyTest12);
2865 UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13);
2866 UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14);
2867 UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15);
2868
2869 UtRegisterTest("DetectHttpClientBodyTest22", DetectHttpClientBodyTest22);
2870 UtRegisterTest("DetectHttpClientBodyTest23", DetectHttpClientBodyTest23);
2871 UtRegisterTest("DetectHttpClientBodyTest24", DetectHttpClientBodyTest24);
2872 UtRegisterTest("DetectHttpClientBodyTest25", DetectHttpClientBodyTest25);
2873 UtRegisterTest("DetectHttpClientBodyTest26", DetectHttpClientBodyTest26);
2874 UtRegisterTest("DetectHttpClientBodyTest27", DetectHttpClientBodyTest27);
2875 UtRegisterTest("DetectHttpClientBodyTest28", DetectHttpClientBodyTest28);
2876 UtRegisterTest("DetectHttpClientBodyTest29", DetectHttpClientBodyTest29);
2877 UtRegisterTest("DetectHttpClientBodyTest30", DetectHttpClientBodyTest30);
2878 UtRegisterTest("DetectHttpClientBodyTest31", DetectHttpClientBodyTest31);
2879 UtRegisterTest("DetectHttpClientBodyTest32", DetectHttpClientBodyTest32);
2880 UtRegisterTest("DetectHttpClientBodyTest33", DetectHttpClientBodyTest33);
2881 UtRegisterTest("DetectHttpClientBodyTest34", DetectHttpClientBodyTest34);
2882 UtRegisterTest("DetectHttpClientBodyTest35", DetectHttpClientBodyTest35);
2883 UtRegisterTest("DetectHttpClientBodyTest36", DetectHttpClientBodyTest36);
2884
2885 UtRegisterTest("DetectHttpClientBodyIsdataatParseTest",
2886 DetectHttpClientBodyIsdataatParseTest);
2887
2888 UtRegisterTest("DetectEngineHttpClientBodyTest01",
2889 DetectEngineHttpClientBodyTest01);
2890 UtRegisterTest("DetectEngineHttpClientBodyTest02",
2891 DetectEngineHttpClientBodyTest02);
2892 UtRegisterTest("DetectEngineHttpClientBodyTest03",
2893 DetectEngineHttpClientBodyTest03);
2894 UtRegisterTest("DetectEngineHttpClientBodyTest04",
2895 DetectEngineHttpClientBodyTest04);
2896 UtRegisterTest("DetectEngineHttpClientBodyTest05",
2897 DetectEngineHttpClientBodyTest05);
2898 UtRegisterTest("DetectEngineHttpClientBodyTest06",
2899 DetectEngineHttpClientBodyTest06);
2900 UtRegisterTest("DetectEngineHttpClientBodyTest07",
2901 DetectEngineHttpClientBodyTest07);
2902 UtRegisterTest("DetectEngineHttpClientBodyTest08",
2903 DetectEngineHttpClientBodyTest08);
2904 UtRegisterTest("DetectEngineHttpClientBodyTest09",
2905 DetectEngineHttpClientBodyTest09);
2906 UtRegisterTest("DetectEngineHttpClientBodyTest10",
2907 DetectEngineHttpClientBodyTest10);
2908 UtRegisterTest("DetectEngineHttpClientBodyTest11",
2909 DetectEngineHttpClientBodyTest11);
2910 UtRegisterTest("DetectEngineHttpClientBodyTest12",
2911 DetectEngineHttpClientBodyTest12);
2912 UtRegisterTest("DetectEngineHttpClientBodyTest13",
2913 DetectEngineHttpClientBodyTest13);
2914 UtRegisterTest("DetectEngineHttpClientBodyTest14",
2915 DetectEngineHttpClientBodyTest14);
2916 UtRegisterTest("DetectEngineHttpClientBodyTest15",
2917 DetectEngineHttpClientBodyTest15);
2918 UtRegisterTest("DetectEngineHttpClientBodyTest16",
2919 DetectEngineHttpClientBodyTest16);
2920 UtRegisterTest("DetectEngineHttpClientBodyTest17",
2921 DetectEngineHttpClientBodyTest17);
2922 UtRegisterTest("DetectEngineHttpClientBodyTest18",
2923 DetectEngineHttpClientBodyTest18);
2924 UtRegisterTest("DetectEngineHttpClientBodyTest19",
2925 DetectEngineHttpClientBodyTest19);
2926 UtRegisterTest("DetectEngineHttpClientBodyTest20",
2927 DetectEngineHttpClientBodyTest20);
2928 UtRegisterTest("DetectEngineHttpClientBodyTest21",
2929 DetectEngineHttpClientBodyTest21);
2930 UtRegisterTest("DetectEngineHttpClientBodyTest22",
2931 DetectEngineHttpClientBodyTest22);
2932 UtRegisterTest("DetectEngineHttpClientBodyTest23",
2933 DetectEngineHttpClientBodyTest23);
2934 UtRegisterTest("DetectEngineHttpClientBodyTest24",
2935 DetectEngineHttpClientBodyTest24);
2936 UtRegisterTest("DetectEngineHttpClientBodyTest25",
2937 DetectEngineHttpClientBodyTest25);
2938 UtRegisterTest("DetectEngineHttpClientBodyTest26",
2939 DetectEngineHttpClientBodyTest26);
2940 UtRegisterTest("DetectEngineHttpClientBodyTest27",
2941 DetectEngineHttpClientBodyTest27);
2942 UtRegisterTest("DetectEngineHttpClientBodyTest28",
2943 DetectEngineHttpClientBodyTest28);
2944 UtRegisterTest("DetectEngineHttpClientBodyTest29",
2945 DetectEngineHttpClientBodyTest29);
2946
2947 UtRegisterTest("DetectEngineHttpClientBodyTest30",
2948 DetectEngineHttpClientBodyTest30);
2949 UtRegisterTest("DetectEngineHttpClientBodyTest31",
2950 DetectEngineHttpClientBodyTest31);
2951}
2952
2953#endif
2954
2955/**
2956 * @}
2957 */
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
@ ALPROTO_HTTP1
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
void SCConfInit(void)
Initialize the configuration system.
Definition conf.c:120
void SCConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition conf.c:684
void SCConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition conf.c:694
uint16_t type
#define PKT_HAS_FLOW
Definition decode.h:1266
#define PKT_STREAM_EST
Definition decode.h:1262
#define DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_MPM
#define DETECT_CONTENT_IS_SINGLE(c)
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
SigMatch * DetectBufferGetLastSigMatch(const Signature *s, const uint32_t buf_id)
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
@ DETECT_ISDATAAT
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.
Data structures and function prototypes for keeping state for the detection engine.
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
#define ISDATAAT_RELATIVE
#define ISDATAAT_NEGATED
#define ISDATAAT_RAWBYTES
#define DETECT_PCRE_RELATIVE_NEXT
Definition detect-pcre.h:34
#define DETECT_PCRE_RELATIVE
Definition detect-pcre.h:29
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition detect.c:2420
#define DE_QUIET
Definition detect.h:330
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
@ DETECT_SM_LIST_PMATCH
Definition detect.h:119
#define FLOW_INITIALIZE(f)
Definition flow-util.h:38
#define FLOW_DESTROY(f)
Definition flow-util.h:119
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_PKT_ESTABLISHED
Definition flow.h:235
#define FLOW_IPV4
Definition flow.h:100
#define FLOW_PKT_TOCLIENT
Definition flow.h:234
AppLayerParserThreadCtx * alp_tctx
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 FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
void HtpConfigRestoreBackup(void)
void HtpConfigCreateBackup(void)
void HTPConfigure(void)
void StreamTcpFreeConfig(bool quiet)
Definition stream-tcp.c:859
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition stream-tcp.c:488
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
Signature * sig_list
Definition detect.h:941
Flow data structure.
Definition flow.h:356
uint8_t proto
Definition flow.h:378
uint32_t flags
Definition flow.h:421
AppProto alproto
application level protocol
Definition flow.h:450
void * alstate
Definition flow.h:479
void * protoctx
Definition flow.h:441
StreamingBufferSegment sbseg
HtpBodyChunk * first
StreamingBuffer * sb
uint16_t cnt
Definition decode.h:287
uint8_t flowflags
Definition decode.h:532
PacketAlerts alerts
Definition decode.h:620
struct Flow_ * flow
Definition decode.h:546
uint32_t flags
Definition decode.h:544
a single match condition for a signature
Definition detect.h:356
uint16_t type
Definition detect.h:357
struct SigMatch_ * prev
Definition detect.h:361
SigMatchCtx * ctx
Definition detect.h:359
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition detect.h:642
struct SigMatch_ * smlists_tail[DETECT_SM_LIST_MAX]
Definition detect.h:644
Signature container.
Definition detect.h:668
SignatureInitData * init_data
Definition detect.h:747
const uint8_t * input
Per thread variable structure.
Definition threadvars.h:58
#define TOTAL_REQUESTS
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
int UTHParseSignature(const char *str, bool expect)
parser a sig and see if the expected result is correct