66 #define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>"
67 #define PARSE_REGEX "(?<!\\\\)/(.*(?<!(?<!\\\\)\\\\))/([^\"]*)"
69 static int pcre_match_limit = 0;
70 static int pcre_match_limit_recursion = 0;
76 static int pcre2_use_jit = 1;
84 const char *
str,
const size_t strlen,
int start_offset,
int options,
85 pcre2_match_data *match)
94 static void DetectPcreRegisterTests(
void);
114 SCLogDebug(
"Using PCRE match-limit setting of: %i", pcre_match_limit);
116 pcre_match_limit = (int)val;
118 SCLogInfo(
"Using PCRE match-limit setting of: %i", pcre_match_limit);
120 SCLogDebug(
"Using PCRE match-limit setting of: %i", pcre_match_limit);
126 if (!
SCConfGetInt(
"pcre.match-limit-recursion", &val)) {
128 SCLogDebug(
"Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
130 pcre_match_limit_recursion = (int)val;
132 SCLogInfo(
"Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
134 SCLogDebug(
"Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
139 if (parse_regex == NULL) {
140 FatalError(
"pcre2 compile failed for parse_regex");
146 if (parse_capture_regex == NULL) {
147 FatalError(
"pcre2 compile failed for parse_capture_regex");
150 #ifdef PCRE2_HAVE_JIT
152 SCLogConfig(
"PCRE2 won't use JIT as OS doesn't allow RWX pages");
178 const uint8_t *ptr = NULL;
180 PCRE2_SIZE capture_len = 0;
192 int start_offset = 0;
198 pcre2_match_data *match =
201 ret = DetectPcreExec(det_ctx, pe, (
char *)ptr,
len, start_offset, 0, match);
204 if (ret == PCRE2_ERROR_NOMATCH) {
212 }
else if (ret >= 0) {
224 if (ret > 1 && pe->
idx != 0) {
226 for (x = 0; x < pe->
idx; x++) {
228 const char *pcre2_str_ptr = NULL;
229 ret = pcre2_substring_get_bynumber(
230 match, x + 1, (PCRE2_UCHAR8 **)&pcre2_str_ptr, &capture_len);
232 pcre2_substring_free((PCRE2_UCHAR8 *)pcre2_str_ptr);
236 capture_len = (capture_len < 0xffff) ? (uint16_t)capture_len : 0xffff;
237 uint8_t *str_ptr =
SCMalloc(capture_len);
239 pcre2_substring_free((PCRE2_UCHAR8 *)pcre2_str_ptr);
242 memcpy(str_ptr, pcre2_str_ptr, capture_len);
243 pcre2_substring_free((PCRE2_UCHAR8 *)pcre2_str_ptr);
250 const char *pcre2_str_ptr2 = NULL;
252 uint16_t key_len = (capture_len < 0xff) ? (uint16_t)capture_len : 0xff;
253 int ret2 = pcre2_substring_get_bynumber(
254 match, x + 2, (PCRE2_UCHAR8 **)&pcre2_str_ptr2, &capture_len);
258 pcre2_substring_free((PCRE2_UCHAR8 *)pcre2_str_ptr2);
261 capture_len = (capture_len < 0xffff) ? (uint16_t)capture_len : 0xffff;
262 uint8_t *str_ptr2 =
SCMalloc(capture_len);
265 pcre2_substring_free((PCRE2_UCHAR8 *)pcre2_str_ptr2);
268 memcpy(str_ptr2, pcre2_str_ptr2, capture_len);
269 pcre2_substring_free((PCRE2_UCHAR8 *)pcre2_str_ptr2);
272 (uint8_t *)str_ptr2, (uint16_t)capture_len,
289 PCRE2_SIZE *ov = pcre2_get_ovector_pointer(match);
291 det_ctx->
buffer_offset = (uint32_t)((ptr + ov[1]) - payload);
304 static int DetectPcreSetList(
int list,
int set)
307 SCLogError(
"only one pcre option to specify a buffer type is allowed");
313 static int DetectPcreHasUpperCase(
const char *re)
315 size_t len = strlen(re);
316 bool is_meta =
false;
317 bool is_meta_hex =
false;
318 int meta_hex_cnt = 0;
320 for (
size_t i = 0; i <
len; i++) {
324 if (meta_hex_cnt == 2) {
328 }
else if (is_meta) {
335 else if (re[i] ==
'\\') {
338 else if (isupper((
unsigned char)re[i])) {
347 const char *regexstr,
int *sm_list,
char *capture_names,
348 size_t capture_names_size,
bool negate,
AppProto *alproto)
350 pcre2_match_data *match = NULL;
356 int ret = 0, res = 0;
357 int check_host_header = 0;
358 char op_str[64] =
"";
360 bool apply_match_limit =
false;
363 char *fcap = strstr(regexstr,
"flow:");
364 char *pcap = strstr(regexstr,
"pkt:");
367 size_t slen = strlen(regexstr) + 1;
372 cut_capture = (int)(fcap - regexstr);
373 else if (pcap && !fcap)
374 cut_capture = (int)(pcap - regexstr);
378 cut_capture = (int)
MIN((pcap - regexstr), (fcap - regexstr));
383 if (cut_capture > 1) {
384 int offset = cut_capture - 1;
387 if (regexstr[
offset] ==
',' || regexstr[
offset] ==
' ') {
394 if (cut_capture == (
offset + 1)) {
395 SCLogDebug(
"missing separators, assume it's part of the regex");
398 strlcpy(capture_names, regexstr+cut_capture, capture_names_size);
399 if (capture_names[strlen(capture_names)-1] ==
'"')
400 capture_names[strlen(capture_names)-1] =
'\0';
407 match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
412 ret = pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)regexstr, slen, 0, 0, match, NULL);
418 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)re, &slen);
420 SCLogError(
"pcre2_substring_copy_bynumber failed");
421 pcre2_match_data_free(match);
426 size_t copylen =
sizeof(op_str);
427 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)op_str, ©len);
429 SCLogError(
"pcre2_substring_copy_bynumber failed");
430 pcre2_match_data_free(match);
450 opts |= PCRE2_ANCHORED;
453 opts |= PCRE2_DOLLAR_ENDONLY;
456 opts |= PCRE2_UNGREEDY;
460 opts |= PCRE2_CASELESS;
464 opts |= PCRE2_MULTILINE;
467 opts |= PCRE2_DOTALL;
470 opts |= PCRE2_EXTENDED;
474 apply_match_limit =
true;
479 SCLogError(
"regex modifier 'B' inconsistent with chosen buffer");
492 SCLogError(
"regex modifier 'U' inconsistent with 'B'");
496 *sm_list = DetectPcreSetList(*sm_list, list);
502 SCLogError(
"regex modifier 'V' inconsistent with 'B'");
506 *sm_list = DetectPcreSetList(*sm_list, list);
512 SCLogError(
"regex modifier 'W' inconsistent with 'B'");
516 *sm_list = DetectPcreSetList(*sm_list, list);
518 check_host_header = 1;
523 SCLogError(
"regex modifier 'Z' inconsistent with 'B'");
527 *sm_list = DetectPcreSetList(*sm_list, list);
533 SCLogError(
"regex modifier 'H' inconsistent with 'B'");
537 *sm_list = DetectPcreSetList(*sm_list, list);
542 SCLogError(
"regex modifier 'I' inconsistent with 'B'");
546 *sm_list = DetectPcreSetList(*sm_list, list);
552 *sm_list = DetectPcreSetList(*sm_list, list);
558 SCLogError(
"regex modifier 'M' inconsistent with 'B'");
562 *sm_list = DetectPcreSetList(*sm_list, list);
568 SCLogError(
"regex modifier 'C' inconsistent with 'B'");
572 *sm_list = DetectPcreSetList(*sm_list, list);
579 *sm_list = DetectPcreSetList(*sm_list, list);
586 *sm_list = DetectPcreSetList(*sm_list, list);
593 *sm_list = DetectPcreSetList(*sm_list, list);
600 *sm_list = DetectPcreSetList(*sm_list, list);
605 SCLogError(
"unknown regex modifier '%c'", *op);
617 if (check_host_header) {
620 "specified along with \"i(caseless)\" modifier. "
621 "Since the hostname buffer we match against "
622 "is actually lowercase, having a "
623 "nocase is redundant.");
625 else if (DetectPcreHasUpperCase(re)) {
627 "specified has an uppercase char. "
628 "Since the hostname buffer we match against "
629 "is actually lowercase, please specify an "
630 "all lowercase based pcre.");
640 if (capture_names == NULL || strlen(capture_names) == 0)
641 opts |= PCRE2_NO_AUTO_CAPTURE;
644 pcre2_compile((PCRE2_SPTR8)re, PCRE2_ZERO_TERMINATED, opts, &en, &eo2, NULL);
646 opts &= ~PCRE2_NO_AUTO_CAPTURE;
648 pcre2_compile((PCRE2_SPTR8)re, PCRE2_ZERO_TERMINATED, opts, &en, &eo2, NULL);
651 PCRE2_UCHAR errbuffer[256];
652 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
653 SCLogError(
"pcre2 compile of \"%s\" failed at "
655 regexstr, (
int)eo2, errbuffer);
659 #ifdef PCRE2_HAVE_JIT
666 SCLogDebug(
"PCRE2 JIT compiler does not support: %s. "
667 "Falling back to regular PCRE2 handling (%s:%d)",
675 SCLogError(
"pcre2 could not create match context");
679 if (apply_match_limit) {
680 if (pcre_match_limit >= -1) {
683 if (pcre_match_limit_recursion >= -1) {
692 pcre2_match_data_free(match);
696 pcre2_match_data_free(match);
697 DetectPcreFree(
de_ctx, pd);
707 int ret = 0, res = 0;
708 char type_str[16] =
"";
709 const char *orig_right_edge = regexstr + strlen(regexstr);
715 pcre2_match_data *match = NULL;
717 SCLogDebug(
"regexstr %s, pd %p", regexstr, pd);
719 ret = pcre2_pattern_info(pd->
parse_regex.
regex, PCRE2_INFO_CAPTURECOUNT, &capture_cnt);
720 SCLogDebug(
"ret %d capture_cnt %d", ret, capture_cnt);
721 if (ret == 0 && capture_cnt && strlen(capture_names) > 0)
724 while ((name_array[name_idx] = strtok_r(name_idx == 0 ? capture_names : NULL,
" ,", &ptr))){
725 if (name_idx > (capture_cnt - 1)) {
727 "var capture names than capturing substrings");
730 SCLogDebug(
"name '%s'", name_array[name_idx]);
732 if (strcmp(name_array[name_idx],
"pkt:key") == 0) {
740 }
else if (key == 1 && strcmp(name_array[name_idx],
"pkt:value") == 0) {
745 }
else if (key == 0 && strcmp(name_array[name_idx],
"pkt:value") == 0) {
747 }
else if (key == 1) {
750 }
else if (strncmp(name_array[name_idx],
"flow:", 5) == 0) {
756 }
else if (strncmp(name_array[name_idx],
"pkt:", 4) == 0) {
765 "var capture names must start with 'pkt:' or 'flow:'");
777 size_t cap_buffer_len = strlen(regexstr) + 1;
778 char capture_str[cap_buffer_len];
779 memset(capture_str, 0x00, cap_buffer_len);
789 pcre2_match_data_free(match);
792 copylen =
sizeof(type_str);
793 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)type_str, ©len);
795 SCLogError(
"pcre2_substring_copy_bynumber failed");
798 cap_buffer_len = strlen(regexstr) + 1;
799 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)capture_str, &cap_buffer_len);
801 SCLogError(
"pcre2_substring_copy_bynumber failed");
804 if (strlen(capture_str) == 0 || strlen(type_str) == 0) {
812 SCLogError(
"rule can have maximally %d pkt/flow "
815 pcre2_match_data_free(match);
819 if (strcmp(type_str,
"pkt") == 0) {
824 }
else if (strcmp(type_str,
"flow") == 0) {
831 PCRE2_SIZE *ov = pcre2_get_ovector_pointer(match);
834 pcre2_match_data_free(match);
837 if (regexstr >= orig_right_edge)
843 pcre2_match_data_free(match);
847 static void *DetectPcreThreadInit(
void *data)
850 pcre2_match_data *match = pcre2_match_data_create_from_pattern(pd->
parse_regex.
regex, NULL);
854 static void DetectPcreThreadFree(
void *
ctx)
857 pcre2_match_data *match = (pcre2_match_data *)
ctx;
858 pcre2_match_data_free(match);
867 char capture_names[1024] =
"";
870 pd = DetectPcreParse(
de_ctx, regexstr, &parsed_sm_list,
875 if (DetectPcreParseCapture(regexstr,
de_ctx, pd, capture_names) < 0)
879 de_ctx,
"pcre", DetectPcreThreadInit, (
void *)pd, DetectPcreThreadFree, 0);
886 SCLogError(
"Expression seen with a sticky buffer still set; either (1) reset sticky "
887 "buffer with pkt_data or (2) use a sticky buffer providing \"%s\".",
896 switch (parsed_sm_list) {
910 sm_list = parsed_sm_list;
923 for (uint8_t x = 0; x < pd->
idx; x++) {
937 "preceding match in the same buffer");
940 }
else if (prev_pm == NULL) {
954 DetectPcreFree(
de_ctx, pd);
968 for (uint8_t i = 0; i < pd->
idx; i++) {
976 static int g_file_data_buffer_id = 0;
977 static int g_http_header_buffer_id = 0;
978 static int g_dce_stub_data_buffer_id = 0;
983 static int DetectPcreParseTest01 (
void)
987 const char *teststring =
"/blah/7";
993 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1003 static int DetectPcreParseTest02 (
void)
1007 const char *teststring =
"/blah/Ui$";
1013 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1024 static int DetectPcreParseTest03 (
void)
1028 const char *teststring =
"/blah/UNi";
1034 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1044 static int DetectPcreParseTest04 (
void)
1048 const char *teststring =
"/b\\\"lah/i";
1054 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1058 DetectPcreFree(
de_ctx, pd);
1066 static int DetectPcreParseTest05 (
void)
1070 const char *teststring =
"/b(l|a)h/";
1076 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1080 DetectPcreFree(
de_ctx, pd);
1088 static int DetectPcreParseTest06 (
void)
1092 const char *teststring =
"/b(l|a)h/smi";
1098 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1102 DetectPcreFree(
de_ctx, pd);
1110 static int DetectPcreParseTest07 (
void)
1114 const char *teststring =
"/blah/Ui";
1120 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1124 DetectPcreFree(
de_ctx, pd);
1132 static int DetectPcreParseTest08 (
void)
1136 const char *teststring =
"/b(l|a)h/O";
1142 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1146 DetectPcreFree(
de_ctx, pd);
1155 static int DetectPcreParseTest09 (
void)
1158 const char *teststring =
"/lala\\\\/";
1164 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1167 DetectPcreFree(
de_ctx, pd);
1175 static int DetectPcreParseTest10(
void)
1204 static int DetectPcreParseTest15(
void)
1212 "alert tcp any any -> any any "
1213 "(msg:\"Testing pcre relative http_method\"; "
1215 "http_method; pcre:\"/abc/RM\"; sid:1;)");
1227 static int DetectPcreParseTest16(
void)
1235 "alert tcp any any -> any any "
1236 "(msg:\"Testing pcre relative http_cookie\"; "
1237 "content:\"test\"; "
1238 "http_cookie; pcre:\"/abc/RC\"; sid:1;)");
1249 static int DetectPcreParseTest17(
void)
1257 "alert tcp any any -> any any "
1258 "(msg:\"Testing pcre relative http_raw_header\"; "
1259 "flow:to_server; content:\"test\"; "
1260 "http_raw_header; pcre:\"/abc/RD\"; sid:1;)");
1271 static int DetectPcreParseTest18(
void)
1279 "alert tcp any any -> any any "
1280 "(msg:\"Testing pcre relative http_header\"; "
1281 "content:\"test\"; "
1282 "http_header; pcre:\"/abc/RH\"; sid:1;)");
1293 static int DetectPcreParseTest19(
void)
1301 "alert tcp any any -> any any "
1302 "(msg:\"Testing pcre relative http_client_body\"; "
1303 "content:\"test\"; "
1304 "http_client_body; pcre:\"/abc/RP\"; sid:1;)");
1315 static int DetectPcreParseTest20(
void)
1323 "alert tcp any any -> any any "
1324 "(msg:\"Testing http_raw_uri\"; "
1325 "content:\"test\"; "
1326 "http_raw_uri; pcre:\"/abc/RI\"; sid:1;)");
1337 static int DetectPcreParseTest21(
void)
1345 "alert tcp any any -> any any "
1346 "(msg:\"Testing pcre relative uricontent\"; "
1347 "uricontent:\"test\"; "
1348 "pcre:\"/abc/RU\"; sid:1;)");
1359 static int DetectPcreParseTest22(
void)
1367 "alert tcp any any -> any any "
1368 "(msg:\"Testing pcre relative http_uri\"; "
1369 "content:\"test\"; "
1370 "http_uri; pcre:\"/abc/RU\"; sid:1;)");
1381 static int DetectPcreParseTest23(
void)
1389 "alert tcp any any -> any any "
1390 "(msg:\"Testing inconsistent pcre relative\"; "
1392 "http_cookie; pcre:\"/abc/RM\"; sid:1;)");
1403 static int DetectPcreParseTest24(
void)
1411 "alert tcp any any -> any any "
1412 "(msg:\"Testing inconsistent pcre modifiers\"; "
1413 "pcre:\"/abc/UI\"; sid:1;)");
1424 static int DetectPcreParseTest25(
void)
1432 "alert tcp any any -> any any "
1433 "(msg:\"Testing inconsistent pcre modifiers\"; "
1434 "pcre:\"/abc/DH\"; sid:1;)");
1445 static int DetectPcreParseTest26(
void)
1453 "alert http any any -> any any "
1454 "(msg:\"Testing inconsistent pcre modifiers\"; "
1455 "pcre:\"/abc/F\"; sid:1;)");
1466 static int DetectPcreParseTest27(
void)
1474 "(content:\"baduricontent\"; http_raw_uri; "
1475 "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)");
1486 static int DetectPcreParseTest28(
void)
1494 "(content:\"|2E|suricata\"; http_host; pcre:\"/\\x2Esuricata$/W\"; "
1502 static int DetectPcreTestSig01(
void)
1504 uint8_t *buf = (uint8_t *)
"lalala lalala\\ lala\n";
1505 uint16_t buflen = strlen((
char *)buf);
1509 char sig[] =
"alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/ "
1510 "lalala\\\\/\"; sid:1;)";
1523 static int DetectPcreTestSig02(
void)
1525 uint8_t *buf = (uint8_t *)
"lalala\n";
1526 uint16_t buflen = strlen((
char *)buf);
1529 char sig[] =
"alert tcp any any -> any any (msg:\"pcre with an ending slash\"; "
1530 "pcre:\"/^(la)+$/\"; sid:1;)";
1539 static int DetectPcreTestSig03(
void)
1542 uint8_t *buf = (uint8_t *)
"lalala";
1543 uint16_t buflen = strlen((
char *)buf);
1546 char sig[] =
"alert tcp any any -> any any (msg:\"pcre with an ending slash\"; "
1547 "pcre:\"/^(la)+$/\"; sid:1;)";
1557 static int DetectPcreTxBodyChunksTest01(
void)
1562 uint8_t httpbuf1[] =
"GET / HTTP/1.1\r\n";
1563 uint8_t httpbuf2[] =
"User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1564 uint8_t httpbuf3[] =
"Cookie: dummy\r\n\r\n";
1565 uint8_t httpbuf4[] =
"Body one!!";
1566 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
1567 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
1568 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
1569 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
1570 uint8_t httpbuf5[] =
"GET /?var=val HTTP/1.1\r\n";
1571 uint8_t httpbuf6[] =
"User-Agent: Firefox/1.0\r\n";
1572 uint8_t httpbuf7[] =
"Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1573 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
1574 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
1575 uint32_t httplen7 =
sizeof(httpbuf7) - 1;
1578 memset(&f, 0,
sizeof(f));
1579 memset(&ssn, 0,
sizeof(ssn));
1585 f.
proto = IPPROTO_TCP;
1656 static int DetectPcreTxBodyChunksTest02(
void)
1664 uint8_t httpbuf1[] =
"POST / HTTP/1.1\r\n";
1665 uint8_t httpbuf2[] =
"User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1666 uint8_t httpbuf3[] =
"Cookie: dummy\r\n\r\n";
1667 uint8_t httpbuf4[] =
"Body one!!";
1668 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
1669 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
1670 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
1671 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
1672 uint8_t httpbuf5[] =
"GET /?var=val HTTP/1.1\r\n";
1673 uint8_t httpbuf6[] =
"User-Agent: Firefox/1.0\r\n";
1674 uint8_t httpbuf7[] =
"Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1675 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
1676 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
1677 uint32_t httplen7 =
sizeof(httpbuf7) - 1;
1680 memset(&th_v, 0,
sizeof(th_v));
1681 memset(&f, 0,
sizeof(f));
1682 memset(&ssn, 0,
sizeof(ssn));
1688 f.
proto = IPPROTO_TCP;
1704 s =
DetectEngineAppendSig(
de_ctx,
"alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)");
1706 s =
DetectEngineAppendSig(
de_ctx,
"alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)");
1796 if (det_ctx != NULL) {
1811 static int DetectPcreTxBodyChunksTest03(
void)
1819 uint8_t httpbuf1[] =
"POST / HTTP/1.1\r\n";
1820 uint8_t httpbuf2[] =
"User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1821 uint8_t httpbuf3[] =
"Cookie: dummy\r\n\r\n";
1822 uint8_t httpbuf4[] =
"Body one!!";
1823 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
1824 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
1825 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
1826 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
1827 uint8_t httpbuf5[] =
"GET /?var=val HTTP/1.1\r\n";
1828 uint8_t httpbuf6[] =
"User-Agent: Firefox/1.0\r\n";
1829 uint8_t httpbuf7[] =
"Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1830 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
1831 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
1832 uint32_t httplen7 =
sizeof(httpbuf7) - 1;
1835 memset(&th_v, 0,
sizeof(th_v));
1836 memset(&f, 0,
sizeof(f));
1837 memset(&ssn, 0,
sizeof(ssn));
1843 f.
proto = IPPROTO_TCP;
1859 s =
DetectEngineAppendSig(
de_ctx,
"alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)");
1861 s =
DetectEngineAppendSig(
de_ctx,
"alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)");
1933 if (det_ctx != NULL) {
1950 static int DetectPcreParseHttpHost(
void)
1958 DetectPcreData *pd = DetectPcreParse(
de_ctx,
"/domain\\.com/W", &list, NULL, 0,
false, &alproto);
1960 DetectPcreFree(
de_ctx, pd);
1963 pd = DetectPcreParse(
de_ctx,
"/dOmain\\.com/W", &list, NULL, 0,
false, &alproto);
1968 pd = DetectPcreParse(
de_ctx,
"/domain\\D+\\.com/W", &list, NULL, 0,
false, &alproto);
1970 DetectPcreFree(
de_ctx, pd);
1975 pd = DetectPcreParse(
de_ctx,
"/\\\\Ddomain\\.com/W", &list, NULL, 0,
false, &alproto);
1985 static int DetectPcreParseCaptureTest(
void)
1991 "(content:\"Server: \"; http_header; pcre:\"/(.*)\\r\\n/HR, flow:somecapture\"; content:\"xyz\"; http_header; sid:1;)");
1994 "(content:\"Server: \"; http_header; pcre:\"/(flow:.*)\\r\\n/HR\"; content:\"xyz\"; http_header; sid:2;)");
1997 "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)([0-9]+)\\r\\n/HR, flow:somecapture, pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
2000 "alert http any any -> any any "
2001 "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)\\r\\n/HR, flow:somecapture, "
2002 "pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
2020 static void DetectPcreRegisterTests(
void)
2052 UtRegisterTest(
"DetectPcreTestSig02 -- anchored pcre", DetectPcreTestSig02);
2053 UtRegisterTest(
"DetectPcreTestSig03 -- anchored pcre", DetectPcreTestSig03);
2056 DetectPcreTxBodyChunksTest01);
2057 UtRegisterTest(
"DetectPcreTxBodyChunksTest02 -- modifier P, body chunks per tx",
2058 DetectPcreTxBodyChunksTest02);
2059 UtRegisterTest(
"DetectPcreTxBodyChunksTest03 -- modifier P, body chunks per tx",
2060 DetectPcreTxBodyChunksTest03);
2062 UtRegisterTest(
"DetectPcreParseHttpHost", DetectPcreParseHttpHost);
2063 UtRegisterTest(
"DetectPcreParseCaptureTest", DetectPcreParseCaptureTest);