50 #define PARSE_REGEX "^\\s*" \
51 "([^\\s,]+\\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,]+))?" \
60 "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
70 static void DetectBytejumpRegisterTests(
void);
96 static inline bool DetectBytejumpValidateNbytesOnly(
const DetectBytejumpData *data, int32_t nbytes)
101 static bool DetectBytejumpValidateNbytes(
const DetectBytejumpData *data, int32_t nbytes)
103 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
119 "without \"string\"");
139 int32_t nbytes, int32_t
offset)
144 const uint8_t *ptr = NULL;
159 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
161 "seen in byte_jump - %d",
179 if (ptr == NULL || (nbytes &&
len <= 0)) {
185 if (ptr < payload || nbytes >
len) {
187 "pkt=%p, ptr=%p, len=%" PRIi32
", nbytes=%" PRIi32,
188 payload, ptr,
len, nbytes);
196 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
203 if (extbytes != nbytes) {
204 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
215 if ((val % 4) != 0) {
216 val += 4 - (val % 4);
222 const uint8_t *jumpptr;
225 jumpptr = payload + (int64_t)val;
226 SCLogDebug(
"NEWVAL: payload %p + %" PRIi64
" = %p", payload, (int64_t)val, jumpptr + val);
230 "NEWVAL: payload %p + %" PRIu32
" + %" PRIi64, payload,
payload_len, (int64_t)val);
232 jumpptr = ptr + (int64_t)val + extbytes;
233 SCLogDebug(
"NEWVAL: ptr %p + %" PRIi64
" = %p", ptr, val, jumpptr);
239 if (jumpptr < payload) {
241 SCLogDebug(
"jump location is before buffer start; resetting to buffer start");
243 SCLogDebug(
"Jump location (%" PRIu64
") is not within payload (%" PRIu32
")",
251 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x)", val, sptr, (
int)(sptr - payload));
274 pcre2_match_data *match = NULL;
276 memset(args, 0x00,
sizeof(args));
280 if (ret < 2 || ret > 10) {
281 SCLogError(
"parse error, ret %" PRId32
", string \"%s\"", ret, optstr);
290 pcre2len =
sizeof(
str);
291 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)
str, &pcre2len);
293 SCLogError(
"pcre2_substring_copy_bynumber failed "
304 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
310 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
312 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
315 strlcpy(args[1], str_ptr,
sizeof(args[1]));
319 for (i = 1; i < (ret - 1); i++) {
320 pcre2len =
sizeof(args[0]);
321 res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
323 SCLogError(
"pcre2_substring_copy_bynumber failed for arg %d", i + 1);
344 if (args[0][0] !=
'-' && isalpha((
unsigned char)args[0][0])) {
345 if (nbytes_str == NULL) {
347 "var name for nbytes. \"value\" argument supplied to "
348 "this function has to be non-NULL");
352 if (*nbytes_str == NULL)
357 SCLogError(
"Malformed number of bytes: %s", optstr);
363 if (args[1][0] !=
'-' && isalpha((
unsigned char)args[1][0])) {
366 "var name for offset. \"value\" argument supplied to "
367 "this function has to be non-NULL");
375 &data->
offset, 10, (uint16_t)strlen(args[1]), args[1], -65535, 65535) <= 0) {
383 for (i = 2; i < numargs; i++) {
384 if (strcmp(
"relative", args[i]) == 0) {
386 }
else if (strcasecmp(
"string", args[i]) == 0) {
388 }
else if (strcasecmp(
"dec", args[i]) == 0) {
390 }
else if (strcasecmp(
"hex", args[i]) == 0) {
392 }
else if (strcasecmp(
"oct", args[i]) == 0) {
394 }
else if (strcasecmp(
"big", args[i]) == 0) {
399 }
else if (strcasecmp(
"little", args[i]) == 0) {
401 }
else if (strcasecmp(
"from_beginning", args[i]) == 0) {
403 }
else if (strcasecmp(
"from_end", args[i]) == 0) {
405 }
else if (strcasecmp(
"align", args[i]) == 0) {
407 }
else if (strncasecmp(
"multiplier ", args[i], 11) == 0) {
409 args[i] + 11, 1, 65535) <= 0) {
410 SCLogError(
"Malformed multiplier: %s", optstr);
413 }
else if (strncasecmp(
"post_offset ", args[i], 12) == 0) {
415 args[i] + 12, -65535, 65535) <= 0) {
416 SCLogError(
"Malformed post_offset: %s", optstr);
420 }
else if (strcasecmp(
"dce", args[i]) == 0) {
423 SCLogError(
"Unknown option: \"%s\"", args[i]);
430 "cannot be used in the same byte_jump statement");
435 if (!DetectBytejumpValidateNbytes(data, nbytes)) {
440 data->
nbytes = (uint8_t)nbytes;
445 "without \"string\": %s",
451 pcre2_match_data_free(match);
459 if (nbytes_str != NULL && *nbytes_str != NULL) {
464 DetectBytejumpFree(
de_ctx, data);
466 pcre2_match_data_free(match);
479 data = DetectBytejumpParse(
de_ctx, optstr, &nbytes, &
offset);
499 if (prev_pm == NULL) {
518 if (prev_pm == NULL) {
540 "A byte_jump keyword with dce holds other invalid modifiers.");
545 if (nbytes != NULL) {
549 "seen in byte_jump - %s",
562 "seen in byte_jump - %s",
595 if (nbytes != NULL) {
601 DetectBytejumpFree(
de_ctx, data);
623 static int g_file_data_buffer_id = 0;
624 static int g_dce_stub_data_buffer_id = 0;
630 static int DetectBytejumpTestParse01(
void)
633 data = DetectBytejumpParse(NULL,
"4,0", NULL, NULL);
636 DetectBytejumpFree(NULL, data);
643 static int DetectBytejumpTestParse02(
void)
646 data = DetectBytejumpParse(NULL,
"4, 0", NULL, NULL);
655 DetectBytejumpFree(NULL, data);
662 static int DetectBytejumpTestParse03(
void)
665 data = DetectBytejumpParse(NULL,
666 " 4,0 , relative , little, string, "
667 "dec, align, from_beginning",
679 DetectBytejumpFree(NULL, data);
689 static int DetectBytejumpTestParse04(
void)
692 data = DetectBytejumpParse(NULL,
693 " 4,0 , relative , little, string, "
694 "dec, align, from_beginning , "
695 "multiplier 2 , post_offset -16 ",
707 DetectBytejumpFree(NULL, data);
714 static int DetectBytejumpTestParse05(
void)
717 data = DetectBytejumpParse(NULL,
718 " 4,0 , relative , little, dec, "
719 "align, from_beginning",
729 static int DetectBytejumpTestParse06(
void)
732 data = DetectBytejumpParse(NULL,
"9, 0", NULL, NULL);
741 static int DetectBytejumpTestParse07(
void)
744 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL, NULL);
753 static int DetectBytejumpTestParse08(
void)
756 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL, NULL);
765 static int DetectBytejumpTestParse09(
void)
773 "4,0, align, multiplier 2, "
774 "post_offset -16,dce") == 0);
776 "4,0, multiplier 2, "
777 "post_offset -16,dce") == 0);
778 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
779 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
780 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
781 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
782 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
783 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
784 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
785 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
786 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
787 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
800 static int DetectBytejumpTestParse10(
void)
807 "(msg:\"Testing bytejump_body\"; "
808 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
810 "content:\"one\"; distance:0; "
811 "byte_jump:4,0,align,multiplier 2, "
812 "post_offset -16,relative,dce; sid:1;)");
829 "(msg:\"Testing bytejump_body\"; "
830 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
832 "content:\"one\"; distance:0; "
833 "byte_jump:4,0,align,multiplier 2, "
834 "post_offset -16,relative,dce; sid:2;)");
852 "(msg:\"Testing bytejump_body\"; "
853 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
855 "content:\"one\"; distance:0; "
856 "byte_jump:4,0,align,multiplier 2, "
857 "post_offset -16,relative; sid:3;)");
881 static int DetectBytejumpTestParse11(
void)
891 "(msg:\"Testing bytejump_body\"; "
892 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
894 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
895 "post_offset -16,string,dce; sid:1;)");
899 "(msg:\"Testing bytejump_body\"; "
900 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
902 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
903 "post_offset -16,big,dce; sid:1;)");
907 "(msg:\"Testing bytejump_body\"; "
908 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
910 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
911 "post_offset -16,little,dce; sid:1;)");
915 "(msg:\"Testing bytejump_body\"; "
916 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
918 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
919 "post_offset -16,string,hex,dce; sid:1;)");
923 "(msg:\"Testing bytejump_body\"; "
924 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
926 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
927 "post_offset -16,string,dec,dce; sid:1;)");
931 "(msg:\"Testing bytejump_body\"; "
932 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
934 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
935 "post_offset -16,string,oct,dce; sid:1;)");
939 "(msg:\"Testing bytejump_body\"; "
940 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
942 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
943 "post_offset -16,from_beginning,dce; sid:1;)");
955 static int DetectBytejumpTestParse12(
void)
962 "(file_data; byte_jump:4,0,align,multiplier 2, "
963 "post_offset -16,relative; sid:1;)");
980 static int DetectBytejumpTestParse13(
void)
983 " 4,0 , relative , little, string, dec, "
989 DetectBytejumpFree(NULL, data);
994 static int DetectBytejumpTestParse14(
void)
997 " 4,0 , relative , little, string, dec, "
998 "align, from_beginning, from_end",
1011 static int DetectByteJumpTestPacket01 (
void)
1013 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1014 "User-Agent: Wget/1.11.4"
1016 "Host: www.google.com"
1017 "Connection: Keep-Alive"
1018 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1019 uint16_t buflen = strlen((
char *)buf);
1025 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1026 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1027 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1040 static int DetectByteJumpTestPacket02 (
void)
1042 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1043 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1044 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1046 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1047 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1049 uint16_t buflen =
sizeof(buf);
1055 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1056 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1057 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1065 static int DetectByteJumpTestPacket03(
void)
1067 uint8_t *buf = NULL;
1068 uint16_t buflen = 0;
1071 printf(
"malloc failed\n");
1074 memcpy(buf,
"boom", 4);
1082 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1083 "byte_jump:1,214748364; sid:1; rev:1;)";
1097 static int DetectByteJumpTestPacket04 (
void)
1099 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1100 uint16_t buflen = strlen((
char *)buf);
1106 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;)";
1117 static int DetectByteJumpTestPacket05 (
void)
1119 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1120 uint16_t buflen = strlen((
char *)buf);
1126 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;)";
1137 static int DetectByteJumpTestPacket06 (
void)
1139 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1140 uint16_t buflen = strlen((
char *)buf);
1146 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;)";
1157 static int DetectByteJumpTestPacket07 (
void)
1159 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1160 uint16_t buflen = strlen((
char *)buf);
1166 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;)";
1177 static int DetectByteJumpTestPacket08 (
void)
1179 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1180 uint16_t buflen = strlen((
char *)buf);
1185 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1186 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1198 static void DetectBytejumpRegisterTests(
void)
1203 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1204 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1205 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1206 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1207 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1208 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1209 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1210 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1211 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1212 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1213 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1214 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1215 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1216 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1218 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1219 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1220 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1221 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1222 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1223 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1224 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1225 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);