49 #define PARSE_REGEX "^\\s*" \
50 "([^\\s,]+\\s*,\\s*[^\\s,]+)" \
51 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
52 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
53 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
54 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
55 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
56 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
57 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
58 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
59 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
70 static void DetectBytejumpRegisterTests(
void);
103 const uint8_t *ptr = NULL;
123 if (ptr == NULL ||
len <= 0) {
133 if (ptr < payload || data->nbytes >
len) {
135 "pkt=%p, ptr=%p, len=%d, nbytes=%d",
143 data->
nbytes, (
const char *)ptr);
145 SCLogDebug(
"error extracting %d bytes of string data: %d",
153 if (extbytes != data->
nbytes) {
154 SCLogDebug(
"error extracting %d bytes of numeric data: %d",
165 if ((val % 4) != 0) {
166 val += 4 - (val % 4);
173 SCLogDebug(
"NEWVAL: payload %p + %" PRIu64, payload, val);
178 val += (ptr - payload) + extbytes;
179 SCLogDebug(
"NEWVAL: ptr %p + %" PRIu64, ptr, val);
187 SCLogDebug(
"Jump location (%" PRIu64
") is not within "
188 "payload (%" PRIu32
")",
196 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x)", val, sptr, (
int)(sptr - payload));
210 const uint8_t *ptr = NULL;
211 const uint8_t *jumpptr = NULL;
229 if (ptr == NULL ||
len == 0) {
243 if (ptr < p->payload || data->
nbytes >
len) {
245 "payload=%p, ptr=%p, len=%d, nbytes=%d",
253 data->
nbytes, (
const char *)ptr);
255 SCLogDebug(
"error extracting %d bytes of string data: %d",
263 if (extbytes != data->
nbytes) {
264 SCLogDebug(
"error extracting %d bytes of numeric data: %d",
275 if ((val % 4) != 0) {
276 val += 4 - (val % 4);
297 SCLogDebug(
"Jump location (%p) is not within "
306 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x) to %p (%08x)",
307 val, sptr, (
int)(sptr - p->
payload),
308 jumpptr, (
int)(jumpptr - p->
payload));
322 int ret = 0, res = 0;
330 memset(args, 0x00,
sizeof(args));
334 if (ret < 2 || ret > 10) {
335 SCLogError(
"parse error, ret %" PRId32
", string \"%s\"", ret, optstr);
344 pcre2len =
sizeof(
str);
345 res = pcre2_substring_copy_bynumber(parse_regex.
match, 1, (PCRE2_UCHAR8 *)
str, &pcre2len);
347 SCLogError(
"pcre2_substring_copy_bynumber failed "
358 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
364 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
366 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
369 strlcpy(args[1], str_ptr,
sizeof(args[1]));
373 for (i = 1; i < (ret - 1); i++) {
374 pcre2len =
sizeof(args[0]);
375 res = pcre2_substring_copy_bynumber(
376 parse_regex.
match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
378 SCLogError(
"pcre2_substring_copy_bynumber failed for arg %d", i + 1);
400 SCLogError(
"Malformed number of bytes: %s", optstr);
405 if (args[1][0] !=
'-' && isalpha((
unsigned char)args[1][0])) {
408 "var name for offset. \"value\" argument supplied to "
409 "this function has to be non-NULL");
424 for (i = 2; i < numargs; i++) {
425 if (strcmp(
"relative", args[i]) == 0) {
427 }
else if (strcasecmp(
"string", args[i]) == 0) {
429 }
else if (strcasecmp(
"dec", args[i]) == 0) {
431 }
else if (strcasecmp(
"hex", args[i]) == 0) {
433 }
else if (strcasecmp(
"oct", args[i]) == 0) {
435 }
else if (strcasecmp(
"big", args[i]) == 0) {
440 }
else if (strcasecmp(
"little", args[i]) == 0) {
442 }
else if (strcasecmp(
"from_beginning", args[i]) == 0) {
444 }
else if (strcasecmp(
"from_end", args[i]) == 0) {
446 }
else if (strcasecmp(
"align", args[i]) == 0) {
448 }
else if (strncasecmp(
"multiplier ", args[i], 11) == 0) {
450 &data->
multiplier, 10, (uint16_t)strlen(args[i]) - 11, args[i] + 11) <= 0) {
451 SCLogError(
"Malformed multiplier: %s", optstr);
454 }
else if (strncasecmp(
"post_offset ", args[i], 12) == 0) {
456 args[i] + 12) <= 0) {
457 SCLogError(
"Malformed post_offset: %s", optstr);
460 }
else if (strcasecmp(
"dce", args[i]) == 0) {
463 SCLogError(
"Unknown option: \"%s\"", args[i]);
470 "cannot be used in the same byte_jump statement");
484 "with \"string\": %s",
491 "without \"string\": %s\n",
497 "without \"string\": %s",
504 data->
nbytes = (uint8_t)nbytes;
514 DetectBytejumpFree(
de_ctx, data);
546 if (prev_pm == NULL) {
565 if (prev_pm == NULL) {
587 "A byte_jump keyword with dce holds other invalid modifiers.");
596 "seen in byte_jump - %s",
634 DetectBytejumpFree(
de_ctx, data);
656 static int g_file_data_buffer_id = 0;
657 static int g_dce_stub_data_buffer_id = 0;
663 static int DetectBytejumpTestParse01(
void)
667 data = DetectBytejumpParse(NULL,
"4,0", NULL);
669 DetectBytejumpFree(NULL, data);
679 static int DetectBytejumpTestParse02(
void)
683 data = DetectBytejumpParse(NULL,
"4, 0", NULL);
689 && (data->
flags == 0)
694 DetectBytejumpFree(NULL, data);
703 static int DetectBytejumpTestParse03(
void)
707 data = DetectBytejumpParse(NULL,
" 4,0 , relative , little, string, "
708 "dec, align, from_beginning", NULL);
723 DetectBytejumpFree(NULL, data);
735 static int DetectBytejumpTestParse04(
void)
739 data = DetectBytejumpParse(NULL,
" 4,0 , relative , little, string, "
740 "dec, align, from_beginning , "
741 "multiplier 2 , post_offset -16 ", NULL);
756 DetectBytejumpFree(NULL, data);
765 static int DetectBytejumpTestParse05(
void)
769 data = DetectBytejumpParse(NULL,
" 4,0 , relative , little, dec, "
770 "align, from_beginning", NULL);
781 static int DetectBytejumpTestParse06(
void)
785 data = DetectBytejumpParse(NULL,
"9, 0", NULL);
796 static int DetectBytejumpTestParse07(
void)
800 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL);
811 static int DetectBytejumpTestParse08(
void)
815 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL);
826 static int DetectBytejumpTestParse09(
void)
839 result &= (DetectBytejumpSetup(NULL, s,
"4,0, align, multiplier 2, "
840 "post_offset -16,dce") == 0);
841 result &= (DetectBytejumpSetup(NULL, s,
"4,0, multiplier 2, "
842 "post_offset -16,dce") == 0);
843 result &= (DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
844 result &= (DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
845 result &= (DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
846 result &= (DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
847 result &= (DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
848 result &= (DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
849 result &= (DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
850 result &= (DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
851 result &= (DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
852 result &= (DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
853 result &= (s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[
DETECT_SM_LIST_PMATCH] != NULL);
862 static int DetectBytejumpTestParse10(
void)
875 "(msg:\"Testing bytejump_body\"; "
876 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
878 "content:\"one\"; distance:0; "
879 "byte_jump:4,0,align,multiplier 2, "
880 "post_offset -16,relative,dce; sid:1;)");
886 if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
890 result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type ==
DETECT_BYTEJUMP);
902 "(msg:\"Testing bytejump_body\"; "
903 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
905 "content:\"one\"; distance:0; "
906 "byte_jump:4,0,align,multiplier 2, "
907 "post_offset -16,relative,dce; sid:1;)");
908 if (s->
next == NULL) {
913 if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
917 result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type ==
DETECT_BYTEJUMP);
929 "(msg:\"Testing bytejump_body\"; "
930 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
932 "content:\"one\"; distance:0; "
933 "byte_jump:4,0,align,multiplier 2, "
934 "post_offset -16,relative; sid:1;)");
935 if (s->
next == NULL) {
940 if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
944 result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type ==
DETECT_BYTEJUMP);
966 static int DetectBytejumpTestParse11(
void)
978 "(msg:\"Testing bytejump_body\"; "
979 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
981 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
982 "post_offset -16,string,dce; sid:1;)");
989 "(msg:\"Testing bytejump_body\"; "
990 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
992 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
993 "post_offset -16,big,dce; sid:1;)");
1000 "(msg:\"Testing bytejump_body\"; "
1001 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1003 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1004 "post_offset -16,little,dce; sid:1;)");
1011 "(msg:\"Testing bytejump_body\"; "
1012 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1014 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1015 "post_offset -16,string,hex,dce; sid:1;)");
1022 "(msg:\"Testing bytejump_body\"; "
1023 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1025 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1026 "post_offset -16,string,dec,dce; sid:1;)");
1033 "(msg:\"Testing bytejump_body\"; "
1034 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1036 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1037 "post_offset -16,string,oct,dce; sid:1;)");
1044 "(msg:\"Testing bytejump_body\"; "
1045 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1047 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1048 "post_offset -16,from_beginning,dce; sid:1;)");
1065 static int DetectBytejumpTestParse12(
void)
1078 "(file_data; byte_jump:4,0,align,multiplier 2, "
1079 "post_offset -16,relative; sid:1;)");
1085 if (s->sm_lists_tail[g_file_data_buffer_id] == NULL) {
1089 if (s->sm_lists_tail[g_file_data_buffer_id]->type !=
DETECT_BYTEJUMP) {
1112 static int DetectBytejumpTestParse13(
void)
1115 " 4,0 , relative , little, string, dec, " "align, from_end", NULL);
1119 DetectBytejumpFree(NULL, data);
1124 static int DetectBytejumpTestParse14(
void)
1127 " 4,0 , relative , little, string, dec, "
1128 "align, from_beginning, from_end", NULL);
1140 static int DetectByteJumpTestPacket01 (
void)
1143 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1144 "User-Agent: Wget/1.11.4"
1146 "Host: www.google.com"
1147 "Connection: Keep-Alive"
1148 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1149 uint16_t buflen = strlen((
char *)buf);
1156 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1157 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1158 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1172 static int DetectByteJumpTestPacket02 (
void)
1175 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1176 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1177 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1179 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1180 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1182 uint16_t buflen =
sizeof(buf);
1189 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1190 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1191 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1200 static int DetectByteJumpTestPacket03(
void)
1203 uint8_t *buf = NULL;
1204 uint16_t buflen = 0;
1207 printf(
"malloc failed\n");
1210 memcpy(buf,
"boom", 4);
1219 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1220 "byte_jump:1,214748364; sid:1; rev:1;)";
1235 static int DetectByteJumpTestPacket04 (
void)
1238 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1239 uint16_t buflen = strlen((
char *)buf);
1246 char sig[] =
"alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"ABCD\"; distance:0; within:4; sid:1; rev:1;)";
1258 static int DetectByteJumpTestPacket05 (
void)
1261 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1262 uint16_t buflen = strlen((
char *)buf);
1269 char sig[] =
"alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"cdABCD\"; within:6; sid:1; rev:1;)";
1281 static int DetectByteJumpTestPacket06 (
void)
1284 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1285 uint16_t buflen = strlen((
char *)buf);
1292 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"ABCD\"; distance:4; within:4; sid:1; rev:1;)";
1304 static int DetectByteJumpTestPacket07 (
void)
1307 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1308 uint16_t buflen = strlen((
char *)buf);
1315 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"abcdABCD\"; distance:0; within:8; sid:1; rev:1;)";
1327 static int DetectByteJumpTestPacket08 (
void)
1329 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1330 uint16_t buflen = strlen((
char *)buf);
1335 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1336 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1348 static void DetectBytejumpRegisterTests(
void)
1353 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1354 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1355 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1356 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1357 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1358 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1359 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1360 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1361 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1362 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1363 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1364 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1365 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1366 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1368 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1369 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1370 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1371 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1372 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1373 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1374 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1375 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);