65 #define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>"
66 #define PARSE_REGEX "(?<!\\\\)/(.*(?<!(?<!\\\\)\\\\))/([^\"]*)"
68 #define SC_MATCH_LIMIT_DEFAULT 3500
69 #define SC_MATCH_LIMIT_RECURSION_DEFAULT 1500
71 static int pcre_match_limit = 0;
72 static int pcre_match_limit_recursion = 0;
78 static int pcre_use_jit = 1;
81 #ifdef PCRE_HAVE_JIT_EXEC
82 #define PCRE_JIT_MIN_STACK 32*1024
83 #define PCRE_JIT_MAX_STACK 512*1024
90 const char *
str,
const size_t strlen,
int start_offset,
int options,
int *ovector,
int ovector_size)
92 #ifdef PCRE_HAVE_JIT_EXEC
93 if (pd->thread_ctx_jit_stack_id != -1) {
94 pcre_jit_stack *jit_stack = (pcre_jit_stack *)
99 start_offset, options, ovector, ovector_size,
106 start_offset, options, ovector, ovector_size);
112 static void DetectPcreRegisterTests(
void);
132 SCLogDebug(
"Using PCRE match-limit setting of: %i", pcre_match_limit);
135 pcre_match_limit = val;
137 SCLogInfo(
"Using PCRE match-limit setting of: %i", pcre_match_limit);
139 SCLogDebug(
"Using PCRE match-limit setting of: %i", pcre_match_limit);
145 if (!
ConfGetInt(
"pcre.match-limit-recursion", &val)) {
147 SCLogDebug(
"Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
150 pcre_match_limit_recursion = val;
152 SCLogInfo(
"Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
154 SCLogDebug(
"Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
168 SCLogConfig(
"PCRE won't use JIT as OS doesn't allow RWX pages");
197 const uint8_t *ptr = NULL;
199 uint16_t capture_len = 0;
211 int start_offset = 0;
220 if (ret == PCRE_ERROR_NOMATCH) {
228 }
else if (ret >= 0) {
240 if (ret > 1 && pe->
idx != 0) {
242 for (x = 0; x < pe->
idx; x++) {
244 const char *str_ptr = NULL;
245 ret = pcre_get_substring((
char *)ptr, ov,
MAX_SUBSTRINGS, x+1, &str_ptr);
247 pcre_free_substring(str_ptr);
256 const char *str_ptr2 = NULL;
257 int ret2 = pcre_get_substring((
char *)ptr, ov,
MAX_SUBSTRINGS, x+2, &str_ptr2);
259 pcre_free_substring(str_ptr);
260 pcre_free_substring(str_ptr2);
264 uint16_t key_len = (ret < 0xff) ? (uint16_t)ret : 0xff;
265 capture_len = (ret2 < 0xffff) ? (uint16_t)ret2 : 0xffff;
268 (uint8_t *)str_ptr, key_len,
269 (uint8_t *)str_ptr2, capture_len,
274 capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
276 (uint8_t *)str_ptr, capture_len,
281 capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
283 (uint8_t *)str_ptr, capture_len,
303 static int DetectPcreSetList(
int list,
int set)
312 static int DetectPcreHasUpperCase(
const char *re)
314 size_t len = strlen(re);
315 bool is_meta =
false;
316 bool is_meta_hex =
false;
317 int meta_hex_cnt = 0;
319 for (
size_t i = 0; i <
len; i++) {
323 if (meta_hex_cnt == 2) {
327 }
else if (is_meta) {
334 else if (re[i] ==
'\\') {
337 else if (isupper((
unsigned char)re[i])) {
346 const char *regexstr,
int *sm_list,
char *capture_names,
347 size_t capture_names_size,
bool negate,
AppProto *alproto)
355 int ret = 0,
res = 0;
357 int check_host_header = 0;
358 char op_str[64] =
"";
361 char *fcap = strstr(regexstr,
"flow:");
362 char *pcap = strstr(regexstr,
"pkt:");
365 size_t slen = strlen(regexstr) + 1;
370 cut_capture = fcap - regexstr;
371 else if (pcap && !fcap)
372 cut_capture = pcap - regexstr;
374 cut_capture =
MIN((pcap - regexstr), (fcap - regexstr));
378 if (cut_capture > 1) {
379 int offset = cut_capture - 1;
382 if (regexstr[
offset] ==
',' || regexstr[
offset] ==
' ') {
389 if (cut_capture == (
offset + 1)) {
390 SCLogDebug(
"missing separators, assume it's part of the regex");
393 strlcpy(capture_names, regexstr+cut_capture, capture_names_size);
394 if (capture_names[strlen(capture_names)-1] ==
'"')
395 capture_names[strlen(capture_names)-1] =
'\0';
401 ret = pcre_exec(parse_regex.
regex, parse_regex.
study, regexstr,
417 2, op_str,
sizeof(op_str));
439 opts |= PCRE_ANCHORED;
442 opts |= PCRE_DOLLAR_ENDONLY;
445 opts |= PCRE_UNGREEDY;
449 opts |= PCRE_CASELESS;
453 opts |= PCRE_MULTILINE;
459 opts |= PCRE_EXTENDED;
485 *sm_list = DetectPcreSetList(*sm_list, list);
495 *sm_list = DetectPcreSetList(*sm_list, list);
505 *sm_list = DetectPcreSetList(*sm_list, list);
507 check_host_header = 1;
516 *sm_list = DetectPcreSetList(*sm_list, list);
526 *sm_list = DetectPcreSetList(*sm_list, list);
535 *sm_list = DetectPcreSetList(*sm_list, list);
541 *sm_list = DetectPcreSetList(*sm_list, list);
551 *sm_list = DetectPcreSetList(*sm_list, list);
561 *sm_list = DetectPcreSetList(*sm_list, list);
568 *sm_list = DetectPcreSetList(*sm_list, list);
575 *sm_list = DetectPcreSetList(*sm_list, list);
582 *sm_list = DetectPcreSetList(*sm_list, list);
589 *sm_list = DetectPcreSetList(*sm_list, list);
606 if (check_host_header) {
609 "specified along with \"i(caseless)\" modifier. "
610 "Since the hostname buffer we match against "
611 "is actually lowercase, having a "
612 "nocase is redundant.");
614 else if (DetectPcreHasUpperCase(re)) {
616 "specified has an uppercase char. "
617 "Since the hostname buffer we match against "
618 "is actually lowercase, please specify an "
619 "all lowercase based pcre.");
629 if (capture_names == NULL || strlen(capture_names) == 0)
630 opts |= PCRE_NO_AUTO_CAPTURE;
634 opts &= ~PCRE_NO_AUTO_CAPTURE;
640 "at offset %" PRId32
": %s", regexstr, eo, eb);
647 options |= PCRE_STUDY_JIT_COMPILE;
658 if (ret != 0 || jit != 1) {
662 SCLogDebug(
"PCRE JIT compiler does not support: %s. "
663 "Falling back to regular PCRE handling (%s:%d)",
674 if(pcre_match_limit >= -1) {
678 #ifndef NO_PCRE_MATCH_RLIMIT
679 if(pcre_match_limit_recursion >= -1) {
687 #ifndef NO_PCRE_MATCH_RLIMIT
698 DetectPcreFree(
de_ctx, pd);
708 int ret = 0,
res = 0;
710 memset(&ov, 0,
sizeof(ov));
711 char type_str[16] =
"";
712 const char *orig_right_edge = regexstr + strlen(regexstr);
718 SCLogDebug(
"regexstr %s, pd %p", regexstr, pd);
721 SCLogDebug(
"ret %d capture_cnt %d", ret, capture_cnt);
722 if (ret == 0 && capture_cnt && strlen(capture_names) > 0)
725 while ((name_array[name_idx] = strtok_r(name_idx == 0 ? capture_names : NULL,
" ,", &ptr))){
726 if (name_idx > (capture_cnt - 1)) {
728 "var capture names than capturing substrings");
731 SCLogDebug(
"name '%s'", name_array[name_idx]);
733 if (strcmp(name_array[name_idx],
"pkt:key") == 0) {
741 }
else if (key == 1 && strcmp(name_array[name_idx],
"pkt:value") == 0) {
746 }
else if (key == 0 && strcmp(name_array[name_idx],
"pkt:value") == 0) {
748 }
else if (key == 1) {
751 }
else if (strncmp(name_array[name_idx],
"flow:", 5) == 0) {
756 }
else if (strncmp(name_array[name_idx],
"pkt:", 4) == 0) {
764 "var capture names must start with 'pkt:' or 'flow:'");
776 size_t cap_buffer_len = strlen(regexstr) + 1;
777 char capture_str[cap_buffer_len];
778 memset(capture_str, 0x00, cap_buffer_len);
786 ret = pcre_exec(parse_capture_regex.
regex, parse_capture_regex.
study, regexstr,
792 res = pcre_copy_substring((
char *)regexstr, ov,
MAX_SUBSTRINGS, 1, type_str,
sizeof(type_str));
797 res = pcre_copy_substring((
char *)regexstr, ov,
MAX_SUBSTRINGS, 2, capture_str, cap_buffer_len);
802 if (strlen(capture_str) == 0 || strlen(type_str) == 0) {
815 if (strcmp(type_str,
"pkt") == 0) {
820 }
else if (strcmp(type_str,
"flow") == 0) {
829 if (regexstr >= orig_right_edge)
838 #ifdef PCRE_HAVE_JIT_EXEC
839 static void *DetectPcreThreadInit(
void *data )
841 pcre_jit_stack *jit_stack = pcre_jit_stack_alloc(PCRE_JIT_MIN_STACK, PCRE_JIT_MAX_STACK);
843 if (jit_stack == NULL) {
848 return (
void *)jit_stack;
851 static void DetectPcreThreadFree(
void *ctx)
855 pcre_jit_stack_free((pcre_jit_stack *)ctx);
865 char capture_names[1024] =
"";
868 pd = DetectPcreParse(
de_ctx, regexstr, &parsed_sm_list,
873 if (DetectPcreParseCapture(regexstr,
de_ctx, pd, capture_names) < 0)
876 #ifdef PCRE_HAVE_JIT_EXEC
880 DetectPcreThreadInit, (
void *)pd,
881 DetectPcreThreadFree, 1);
888 "Expression seen with a sticky buffer still set; either (1) reset sticky "
889 "buffer with pkt_data or (2) use a sticky buffer providing \"%s\".",
899 switch (parsed_sm_list) {
913 sm_list = parsed_sm_list;
925 sm->
ctx = (
void *)pd;
928 for (uint8_t x = 0; x < pd->
idx; x++) {
942 "preceding match in the same buffer");
945 }
else if (prev_pm == NULL) {
959 DetectPcreFree(
de_ctx, pd);
977 static int g_file_data_buffer_id = 0;
978 static int g_http_header_buffer_id = 0;
979 static int g_dce_stub_data_buffer_id = 0;
984 static int DetectPcreParseTest01 (
void)
988 const char *teststring =
"/blah/7";
994 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1004 static int DetectPcreParseTest02 (
void)
1008 const char *teststring =
"/blah/Ui$";
1014 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1025 static int DetectPcreParseTest03 (
void)
1029 const char *teststring =
"/blah/UNi";
1035 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1045 static int DetectPcreParseTest04 (
void)
1049 const char *teststring =
"/b\\\"lah/i";
1055 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1059 DetectPcreFree(NULL, pd);
1067 static int DetectPcreParseTest05 (
void)
1071 const char *teststring =
"/b(l|a)h/";
1077 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1081 DetectPcreFree(NULL, pd);
1089 static int DetectPcreParseTest06 (
void)
1093 const char *teststring =
"/b(l|a)h/smi";
1099 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1103 DetectPcreFree(NULL, pd);
1111 static int DetectPcreParseTest07 (
void)
1115 const char *teststring =
"/blah/Ui";
1121 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1125 DetectPcreFree(NULL, pd);
1133 static int DetectPcreParseTest08 (
void)
1137 const char *teststring =
"/b(l|a)h/O";
1143 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1147 DetectPcreFree(NULL, pd);
1156 static int DetectPcreParseTest09 (
void)
1159 const char *teststring =
"/lala\\\\/";
1165 pd = DetectPcreParse(
de_ctx, teststring, &list, NULL, 0,
false, &alproto);
1168 DetectPcreFree(NULL, pd);
1176 static int DetectPcreParseTest10(
void)
1205 static int DetectPcreParseTest11(
void)
1216 "(msg:\"Testing bytejump_body\"; "
1217 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1219 "pcre:/bamboo/R; sid:1;)");
1222 FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1224 data = (
DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1229 "(msg:\"Testing bytejump_body\"; "
1230 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1232 "pcre:/bamboo/R; sid:1;)");
1235 FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1237 data = (
DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1242 "(msg:\"Testing bytejump_body\"; "
1243 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1245 "pcre:/bamboo/RB; sid:1;)");
1248 FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1250 data = (
DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1255 "(msg:\"Testing bytejump_body\"; "
1256 "content:\"one\"; pcre:/bamboo/; sid:1;)");
1259 FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] != NULL);
1272 static int DetectPcreParseTest12(
void)
1283 "(file_data; pcre:/abc/R; sid:1;)");
1287 FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1291 data = (
DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1305 static int DetectPcreParseTest13(
void)
1316 "(file_data; content:\"abc\"; pcre:/def/R; sid:1;)");
1320 FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1324 data = (
DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1338 static int DetectPcreParseTest14(
void)
1349 "(file_data; pcre:/def/; sid:1;)");
1353 FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1357 data = (
DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1369 static int DetectPcreParseTest15(
void)
1377 "alert tcp any any -> any any "
1378 "(msg:\"Testing pcre relative http_method\"; "
1380 "http_method; pcre:\"/abc/RM\"; sid:1;)");
1392 static int DetectPcreParseTest16(
void)
1400 "alert tcp any any -> any any "
1401 "(msg:\"Testing pcre relative http_cookie\"; "
1402 "content:\"test\"; "
1403 "http_cookie; pcre:\"/abc/RC\"; sid:1;)");
1414 static int DetectPcreParseTest17(
void)
1422 "alert tcp any any -> any any "
1423 "(msg:\"Testing pcre relative http_raw_header\"; "
1424 "flow:to_server; content:\"test\"; "
1425 "http_raw_header; pcre:\"/abc/RD\"; sid:1;)");
1436 static int DetectPcreParseTest18(
void)
1444 "alert tcp any any -> any any "
1445 "(msg:\"Testing pcre relative http_header\"; "
1446 "content:\"test\"; "
1447 "http_header; pcre:\"/abc/RH\"; sid:1;)");
1458 static int DetectPcreParseTest19(
void)
1466 "alert tcp any any -> any any "
1467 "(msg:\"Testing pcre relative http_client_body\"; "
1468 "content:\"test\"; "
1469 "http_client_body; pcre:\"/abc/RP\"; sid:1;)");
1480 static int DetectPcreParseTest20(
void)
1488 "alert tcp any any -> any any "
1489 "(msg:\"Testing http_raw_uri\"; "
1490 "content:\"test\"; "
1491 "http_raw_uri; pcre:\"/abc/RI\"; sid:1;)");
1502 static int DetectPcreParseTest21(
void)
1510 "alert tcp any any -> any any "
1511 "(msg:\"Testing pcre relative uricontent\"; "
1512 "uricontent:\"test\"; "
1513 "pcre:\"/abc/RU\"; sid:1;)");
1524 static int DetectPcreParseTest22(
void)
1532 "alert tcp any any -> any any "
1533 "(msg:\"Testing pcre relative http_uri\"; "
1534 "content:\"test\"; "
1535 "http_uri; pcre:\"/abc/RU\"; sid:1;)");
1546 static int DetectPcreParseTest23(
void)
1554 "alert tcp any any -> any any "
1555 "(msg:\"Testing inconsistent pcre relative\"; "
1557 "http_cookie; pcre:\"/abc/RM\"; sid:1;)");
1568 static int DetectPcreParseTest24(
void)
1576 "alert tcp any any -> any any "
1577 "(msg:\"Testing inconsistent pcre modifiers\"; "
1578 "pcre:\"/abc/UI\"; sid:1;)");
1589 static int DetectPcreParseTest25(
void)
1597 "alert tcp any any -> any any "
1598 "(msg:\"Testing inconsistent pcre modifiers\"; "
1599 "pcre:\"/abc/DH\"; sid:1;)");
1610 static int DetectPcreParseTest26(
void)
1618 "alert http any any -> any any "
1619 "(msg:\"Testing inconsistent pcre modifiers\"; "
1620 "pcre:\"/abc/F\"; sid:1;)");
1631 static int DetectPcreParseTest27(
void)
1639 "(content:\"baduricontent\"; http_raw_uri; "
1640 "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)");
1651 static int DetectPcreParseTest28(
void)
1659 "(content:\"|2E|suricata\"; http_host; pcre:\"/\\x2Esuricata$/W\"; "
1667 static int DetectPcreTestSig01(
void)
1669 uint8_t *buf = (uint8_t *)
1670 "GET /one/ HTTP/1.1\r\n"
1671 "Host: one.example.org\r\n"
1673 "GET /two/ HTTP/1.1\r\n"
1674 "Host: two.example.org\r\n"
1676 uint16_t buflen = strlen((
char *)buf);
1682 memset(&th_v, 0,
sizeof(th_v));
1688 p->
tcph->th_seq = htonl(1000);
1691 f->
proto = IPPROTO_TCP;
1705 de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/^gEt/i\"; pcre:\"/\\/two\\//U\"; pcre:\"/GET \\/two\\//\"; pcre:\"/\\s+HTTP/R\"; sid:1;)");
1730 static int DetectPcreTestSig02(
void)
1732 uint8_t *buf = (uint8_t *)
1733 "GET /one/ HTTP/1.1\r\n"
1734 "Host: one.example.org\r\n"
1736 "GET /two/ HTTP/1.1\r\n"
1737 "Host: two.example.org\r\n"
1739 uint16_t buflen = strlen((
char *)buf);
1745 memset(&th_v, 0,
sizeof(th_v));
1746 memset(&f, 0,
sizeof(f));
1754 pcre_match_limit = 100;
1755 pcre_match_limit_recursion = 100;
1785 static int DetectPcreTestSig03(
void)
1787 uint8_t *buf = (uint8_t *)
1788 "GET /one/ HTTP/1.1\r\n"
1789 "Host: one.example.org\r\n"
1791 "GET /two/ HTTP/1.1\r\n"
1792 "Host: two.example.org\r\n"
1794 uint16_t buflen = strlen((
char *)buf);
1799 memset(&th_v, 0,
sizeof(th_v));
1829 static int DetectPcreModifPTest04(
void)
1831 uint8_t httpbuf1[] =
1832 "GET / HTTP/1.1\r\n"
1833 "Host: www.emergingthreats.net\r\n"
1834 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
1835 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
1836 "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
1837 "Accept-Encoding: gzip,deflate\r\n"
1838 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
1839 "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1840 "Server: Apache\r\n"
1841 "X-Powered-By: PHP/5.2.5\r\n"
1842 "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n"
1843 "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n"
1844 "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1845 "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
1846 "Pragma: no-cache\r\n"
1847 "Keep-Alive: timeout=15, max=100\r\n"
1848 "Connection: Keep-Alive\r\n"
1849 "Transfer-Encoding: chunked\r\n"
1850 "Content-Type: text/html; charset=utf-8\r\n"
1854 "<!DOCTYPE html PUBLIC\r\n"
1857 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
1866 memset(&th_v, 0,
sizeof(th_v));
1867 memset(&f, 0,
sizeof(f));
1868 memset(&ssn, 0,
sizeof(ssn));
1874 f.
proto = IPPROTO_TCP;
1891 "\"Pcre modifier P\"; pcre:\"/DOCTYPE/P\"; "
1896 "Pcre modifier P (no match)\"; pcre:\"/blah/P\"; sid:2;)");
1933 static int DetectPcreModifPTest05(
void)
1935 uint8_t httpbuf1[] =
1936 "GET / HTTP/1.1\r\n"
1937 "Host: www.emergingthreats.net\r\n"
1938 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
1939 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
1940 "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
1941 "Accept-Encoding: gzip,deflate\r\n"
1942 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
1943 "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1944 "Server: Apache\r\n"
1945 "X-Powered-By: PHP/5.2.5\r\n"
1946 "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n"
1947 "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n"
1948 "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1949 "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
1950 "Pragma: no-cache\r\n"
1951 "Keep-Alive: timeout=15, max=100\r\n"
1952 "Connection: Keep-Alive\r\n"
1953 "Transfer-Encoding: chunked\r\n"
1954 "Content-Type: text/html; charset=utf-8\r\n"
1960 uint8_t httpbuf2[] =
"<!DOCTYPE html PUBLIC\r\n0\r\n\r\n";
1962 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
1963 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
1973 memset(&th_v, 0,
sizeof(th_v));
1974 memset(&f, 0,
sizeof(f));
1975 memset(&ssn, 0,
sizeof(ssn));
1982 f.
proto = IPPROTO_TCP;
2003 "\"Pcre modifier P\"; pcre:\"/DOC/P\"; "
2008 "Pcre modifier P (no match)\"; pcre:\"/DOCTYPE/P\"; sid:2;)");
2055 static int DetectPcreTestSig06(
void)
2057 uint8_t *buf = (uint8_t *)
2058 "lalala lalala\\ lala\n";
2059 uint16_t buflen = strlen((
char *)buf);
2063 char sig[] =
"alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/ lalala\\\\/\"; sid:1;)";
2076 static int DetectPcreTestSig07(
void)
2078 uint8_t *buf = (uint8_t *)
2080 uint16_t buflen = strlen((
char *)buf);
2083 char sig[] =
"alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)";
2092 static int DetectPcreTestSig08(
void)
2095 uint8_t *buf = (uint8_t *)
2097 uint16_t buflen = strlen((
char *)buf);
2100 char sig[] =
"alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)";
2111 static int DetectPcreTestSig09(
void)
2114 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2115 "Cookie: dummy\r\n\r\n";
2116 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2125 memset(&th_v, 0,
sizeof(th_v));
2126 memset(&p, 0,
sizeof(p));
2127 memset(&f, 0,
sizeof(f));
2128 memset(&ssn, 0,
sizeof(ssn));
2134 f.
proto = IPPROTO_TCP;
2151 "\"HTTP cookie\"; pcre:\"/dummy/C\"; "
2174 if (det_ctx != NULL) {
2190 static int DetectPcreTestSig10(
void)
2193 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2194 "Cookie: dummoOOooooO\r\n\r\n";
2195 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2204 memset(&th_v, 0,
sizeof(th_v));
2205 memset(&p, 0,
sizeof(p));
2206 memset(&f, 0,
sizeof(f));
2207 memset(&ssn, 0,
sizeof(ssn));
2213 f.
proto = IPPROTO_TCP;
2230 "\"HTTP cookie\"; pcre:!\"/dummy/C\"; "
2253 if (det_ctx != NULL) {
2269 static int DetectPcreTestSig11(
void)
2272 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2273 "Cookie: dummy\r\n\r\n";
2274 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2283 memset(&th_v, 0,
sizeof(th_v));
2284 memset(&p, 0,
sizeof(p));
2285 memset(&f, 0,
sizeof(f));
2286 memset(&ssn, 0,
sizeof(ssn));
2292 f.
proto = IPPROTO_TCP;
2309 "\"HTTP method\"; pcre:\"/POST/M\"; "
2332 if (det_ctx != NULL) {
2348 static int DetectPcreTestSig12(
void)
2351 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2352 "Cookie: dummoOOooooO\r\n\r\n";
2353 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2362 memset(&th_v, 0,
sizeof(th_v));
2363 memset(&p, 0,
sizeof(p));
2364 memset(&f, 0,
sizeof(f));
2365 memset(&ssn, 0,
sizeof(ssn));
2371 f.
proto = IPPROTO_TCP;
2388 "\"HTTP method\"; pcre:!\"/POST/M\"; "
2411 if (det_ctx != NULL) {
2427 static int DetectPcreTestSig13(
void)
2430 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2431 "Cookie: dummy\r\n\r\n";
2432 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2441 memset(&th_v, 0,
sizeof(th_v));
2442 memset(&p, 0,
sizeof(p));
2443 memset(&f, 0,
sizeof(f));
2444 memset(&ssn, 0,
sizeof(ssn));
2450 f.
proto = IPPROTO_TCP;
2467 "\"HTTP header\"; pcre:\"/User[-_]Agent[:]?\\sMozilla/H\"; "
2490 if (det_ctx != NULL) {
2506 static int DetectPcreTestSig14(
void)
2509 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nUser-Agent: IEXPLORER/1.0\r\n"
2510 "Cookie: dummoOOooooO\r\n\r\n";
2511 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2520 memset(&th_v, 0,
sizeof(th_v));
2521 memset(&p, 0,
sizeof(p));
2522 memset(&f, 0,
sizeof(f));
2523 memset(&ssn, 0,
sizeof(ssn));
2529 f.
proto = IPPROTO_TCP;
2546 "\"HTTP header\"; pcre:!\"/User-Agent[:]?\\s+Mozilla/H\"; "
2569 if (det_ctx != NULL) {
2585 static int DetectPcreTestSig15(
void)
2588 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2589 "Cookie: dummy 1234\r\n\r\n";
2590 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2599 memset(&th_v, 0,
sizeof(th_v));
2600 memset(&p, 0,
sizeof(p));
2601 memset(&f, 0,
sizeof(f));
2602 memset(&ssn, 0,
sizeof(ssn));
2608 f.
proto = IPPROTO_TCP;
2625 "\"pcre relative HTTP cookie\"; content:\"dummy\";"
2626 " http_cookie; pcre:\"/1234/RC\"; "
2649 if (det_ctx != NULL) {
2665 static int DetectPcreTestSig16(
void)
2668 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2669 "Cookie: dummy 1234\r\n\r\n";
2670 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2679 memset(&th_v, 0,
sizeof(th_v));
2680 memset(&p, 0,
sizeof(p));
2681 memset(&f, 0,
sizeof(f));
2682 memset(&ssn, 0,
sizeof(ssn));
2688 f.
proto = IPPROTO_TCP;
2705 "\"pcre relative HTTP method\"; content:\"PO\";"
2706 " http_method; pcre:\"/ST/RM\"; "
2729 if (det_ctx != NULL) {
2744 static int DetectPcreTxBodyChunksTest01(
void)
2749 uint8_t httpbuf1[] =
"GET / HTTP/1.1\r\n";
2750 uint8_t httpbuf2[] =
"User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2751 uint8_t httpbuf3[] =
"Cookie: dummy\r\n\r\n";
2752 uint8_t httpbuf4[] =
"Body one!!";
2753 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2754 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
2755 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
2756 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
2757 uint8_t httpbuf5[] =
"GET /?var=val HTTP/1.1\r\n";
2758 uint8_t httpbuf6[] =
"User-Agent: Firefox/1.0\r\n";
2759 uint8_t httpbuf7[] =
"Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2760 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
2761 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
2762 uint32_t httplen7 =
sizeof(httpbuf7) - 1;
2765 memset(&f, 0,
sizeof(f));
2766 memset(&ssn, 0,
sizeof(ssn));
2772 f.
proto = IPPROTO_TCP;
2845 static int DetectPcreTxBodyChunksTest02(
void)
2853 uint8_t httpbuf1[] =
"POST / HTTP/1.1\r\n";
2854 uint8_t httpbuf2[] =
"User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2855 uint8_t httpbuf3[] =
"Cookie: dummy\r\n\r\n";
2856 uint8_t httpbuf4[] =
"Body one!!";
2857 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2858 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
2859 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
2860 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
2861 uint8_t httpbuf5[] =
"GET /?var=val HTTP/1.1\r\n";
2862 uint8_t httpbuf6[] =
"User-Agent: Firefox/1.0\r\n";
2863 uint8_t httpbuf7[] =
"Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2864 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
2865 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
2866 uint32_t httplen7 =
sizeof(httpbuf7) - 1;
2869 memset(&th_v, 0,
sizeof(th_v));
2870 memset(&f, 0,
sizeof(f));
2871 memset(&ssn, 0,
sizeof(ssn));
2877 f.
proto = IPPROTO_TCP;
2893 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;)");
2895 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;)");
2999 if (det_ctx != NULL) {
3014 static int DetectPcreTxBodyChunksTest03(
void)
3022 uint8_t httpbuf1[] =
"POST / HTTP/1.1\r\n";
3023 uint8_t httpbuf2[] =
"User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
3024 uint8_t httpbuf3[] =
"Cookie: dummy\r\n\r\n";
3025 uint8_t httpbuf4[] =
"Body one!!";
3026 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3027 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3028 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3029 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3030 uint8_t httpbuf5[] =
"GET /?var=val HTTP/1.1\r\n";
3031 uint8_t httpbuf6[] =
"User-Agent: Firefox/1.0\r\n";
3032 uint8_t httpbuf7[] =
"Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
3033 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3034 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3035 uint32_t httplen7 =
sizeof(httpbuf7) - 1;
3038 memset(&th_v, 0,
sizeof(th_v));
3039 memset(&f, 0,
sizeof(f));
3040 memset(&ssn, 0,
sizeof(ssn));
3046 f.
proto = IPPROTO_TCP;
3062 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;)");
3064 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;)");
3150 if (det_ctx != NULL) {
3167 static int DetectPcreFlowvarCapture01(
void)
3170 "Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13";
3171 uint32_t ualen1 =
sizeof(uabuf1) - 1;
3172 uint8_t httpbuf1[] =
3173 "GET / HTTP/1.1\r\n"
3174 "Host: www.emergingthreats.net\r\n"
3175 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
3176 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3177 "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3178 "Accept-Encoding: gzip,deflate\r\n"
3179 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3180 "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3181 "Server: Apache\r\n"
3183 "<!DOCTYPE html PUBLIC\r\n\r\n";
3184 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3193 memset(&th_v, 0,
sizeof(th_v));
3194 memset(&f, 0,
sizeof(f));
3195 memset(&ssn, 0,
sizeof(ssn));
3201 f.
proto = IPPROTO_TCP;
3216 s =
DetectEngineAppendSig(
de_ctx,
"alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; sid:1;)");
3219 FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3220 s->sm_lists[g_http_header_buffer_id]->
next == NULL ||
3250 printf(
"buffer mismatch: ");
3268 static int DetectPcreFlowvarCapture02(
void)
3272 uint32_t ualen1 =
sizeof(uabuf1) - 1;
3273 uint8_t httpbuf1[] =
3274 "GET / HTTP/1.1\r\n"
3275 "Host: www.emergingthreats.net\r\n"
3276 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
3277 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3278 "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3279 "Accept-Encoding: gzip,deflate\r\n"
3280 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3281 "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3282 "Server: Apache\r\n"
3284 "<!DOCTYPE html PUBLIC\r\n\r\n";
3285 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3294 memset(&th_v, 0,
sizeof(th_v));
3295 memset(&f, 0,
sizeof(f));
3296 memset(&ssn, 0,
sizeof(ssn));
3302 f.
proto = IPPROTO_TCP;
3317 s =
DetectEngineAppendSig(
de_ctx,
"alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; priority:1; sid:1;)");
3320 FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3321 s->sm_lists[g_http_header_buffer_id]->
next == NULL ||
3325 s =
DetectEngineAppendSig(
de_ctx,
"alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; priority:3; sid:2;)");
3328 FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3329 s->sm_lists[g_http_header_buffer_id]->
next == NULL ||
3369 printf(
"buffer mismatch: ");
3387 static int DetectPcreFlowvarCapture03(
void)
3389 uint8_t httpbuf1[] =
3390 "GET / HTTP/1.1\r\n"
3391 "Host: www.emergingthreats.net\r\n"
3392 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
3393 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3394 "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3395 "Accept-Encoding: gzip,deflate\r\n"
3396 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3397 "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3398 "Server: Apache\r\n"
3400 "<!DOCTYPE html PUBLIC\r\n\r\n";
3401 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3410 memset(&th_v, 0,
sizeof(th_v));
3411 memset(&f, 0,
sizeof(f));
3412 memset(&ssn, 0,
sizeof(ssn));
3418 f.
proto = IPPROTO_TCP;
3433 s =
DetectEngineAppendSig(
de_ctx,
"alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:1; sid:1;)");
3436 FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3437 s->sm_lists[g_http_header_buffer_id]->
next == NULL ||
3441 s =
DetectEngineAppendSig(
de_ctx,
"alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:3; sid:2;)");
3444 FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3445 s->sm_lists[g_http_header_buffer_id]->
next == NULL ||
3485 static int DetectPcreParseHttpHost(
void)
3493 DetectPcreData *pd = DetectPcreParse(
de_ctx,
"/domain\\.com/W", &list, NULL, 0,
false, &alproto);
3495 DetectPcreFree(NULL, pd);
3498 pd = DetectPcreParse(
de_ctx,
"/dOmain\\.com/W", &list, NULL, 0,
false, &alproto);
3503 pd = DetectPcreParse(
de_ctx,
"/domain\\D+\\.com/W", &list, NULL, 0,
false, &alproto);
3505 DetectPcreFree(NULL, pd);
3510 pd = DetectPcreParse(
de_ctx,
"/\\\\Ddomain\\.com/W", &list, NULL, 0,
false, &alproto);
3520 static int DetectPcreParseCaptureTest(
void)
3526 "(content:\"Server: \"; http_header; pcre:\"/(.*)\\r\\n/HR, flow:somecapture\"; content:\"xyz\"; http_header; sid:1;)");
3529 "(content:\"Server: \"; http_header; pcre:\"/(flow:.*)\\r\\n/HR\"; content:\"xyz\"; http_header; sid:2;)");
3532 "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)([0-9]+)\\r\\n/HR, flow:somecapture, pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
3535 "alert http any any -> any any "
3536 "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)\\r\\n/HR, flow:somecapture, "
3537 "pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
3554 static void DetectPcreRegisterTests(
void)
3589 UtRegisterTest(
"DetectPcreTestSig01 -- pcre test", DetectPcreTestSig01);
3590 UtRegisterTest(
"DetectPcreTestSig02 -- pcre test", DetectPcreTestSig02);
3592 DetectPcreTestSig03);
3595 DetectPcreModifPTest04);
3596 UtRegisterTest(
"DetectPcreModifPTest05 -- Modifier P fragmented",
3597 DetectPcreModifPTest05);
3600 DetectPcreTestSig07);
3602 DetectPcreTestSig08);
3604 DetectPcreTestSig09);
3606 DetectPcreTestSig10);
3608 DetectPcreTestSig11);
3610 DetectPcreTestSig12);
3612 DetectPcreTestSig13);
3614 DetectPcreTestSig14);
3615 UtRegisterTest(
"DetectPcreTestSig15 -- relative Cookie modifier",
3616 DetectPcreTestSig15);
3617 UtRegisterTest(
"DetectPcreTestSig16 -- relative Method modifier",
3618 DetectPcreTestSig16);
3621 DetectPcreTxBodyChunksTest01);
3622 UtRegisterTest(
"DetectPcreTxBodyChunksTest02 -- modifier P, body chunks per tx",
3623 DetectPcreTxBodyChunksTest02);
3624 UtRegisterTest(
"DetectPcreTxBodyChunksTest03 -- modifier P, body chunks per tx",
3625 DetectPcreTxBodyChunksTest03);
3627 UtRegisterTest(
"DetectPcreFlowvarCapture01 -- capture for http_header",
3628 DetectPcreFlowvarCapture01);
3629 UtRegisterTest(
"DetectPcreFlowvarCapture02 -- capture for http_header",
3630 DetectPcreFlowvarCapture02);
3631 UtRegisterTest(
"DetectPcreFlowvarCapture03 -- capture for http_header",
3632 DetectPcreFlowvarCapture03);
3634 UtRegisterTest(
"DetectPcreParseHttpHost", DetectPcreParseHttpHost);
3635 UtRegisterTest(
"DetectPcreParseCaptureTest", DetectPcreParseCaptureTest);