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,]+))?" \
69 static void DetectBytejumpRegisterTests(
void);
95 static inline bool DetectBytejumpValidateNbytesOnly(
const DetectBytejumpData *data, int32_t nbytes)
100 static bool DetectBytejumpValidateNbytes(
const DetectBytejumpData *data, int32_t nbytes)
102 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
118 "without \"string\"");
138 int32_t nbytes, int32_t
offset)
143 const uint8_t *ptr = NULL;
158 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
160 "seen in byte_jump - %d",
178 if (ptr == NULL || (nbytes &&
len <= 0)) {
184 if (ptr < payload || nbytes >
len) {
186 "pkt=%p, ptr=%p, len=%" PRIi32
", nbytes=%" PRIi32,
187 payload, ptr,
len, nbytes);
195 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
202 if (extbytes != nbytes) {
203 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
214 if ((val % 4) != 0) {
215 val += 4 - (val % 4);
221 const uint8_t *jumpptr;
224 jumpptr = payload + (int64_t)val;
225 SCLogDebug(
"NEWVAL: payload %p + %" PRIi64
" = %p", payload, (int64_t)val, jumpptr + val);
229 "NEWVAL: payload %p + %" PRIu32
" + %" PRIi64, payload,
payload_len, (int64_t)val);
231 jumpptr = ptr + (int64_t)val + extbytes;
232 SCLogDebug(
"NEWVAL: ptr %p + %" PRIi64
" = %p", ptr, val, jumpptr);
238 if (jumpptr < payload) {
240 SCLogDebug(
"jump location is before buffer start; resetting to buffer start");
242 SCLogDebug(
"Jump location (%" PRIu64
") is not within payload (%" PRIu32
")",
250 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x)", val, sptr, (
int)(sptr - payload));
273 pcre2_match_data *match = NULL;
275 memset(args, 0x00,
sizeof(args));
279 if (ret < 2 || ret > 10) {
280 SCLogError(
"parse error, ret %" PRId32
", string \"%s\"", ret, optstr);
289 pcre2len =
sizeof(
str);
290 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)
str, &pcre2len);
292 SCLogError(
"pcre2_substring_copy_bynumber failed "
303 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
309 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
311 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
314 strlcpy(args[1], str_ptr,
sizeof(args[1]));
318 for (i = 1; i < (ret - 1); i++) {
319 pcre2len =
sizeof(args[0]);
320 res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
322 SCLogError(
"pcre2_substring_copy_bynumber failed for arg %d", i + 1);
343 if (args[0][0] !=
'-' && isalpha((
unsigned char)args[0][0])) {
344 if (nbytes_str == NULL) {
346 "var name for nbytes. \"value\" argument supplied to "
347 "this function has to be non-NULL");
351 if (*nbytes_str == NULL)
356 SCLogError(
"Malformed number of bytes: %s", optstr);
362 if (args[1][0] !=
'-' && isalpha((
unsigned char)args[1][0])) {
365 "var name for offset. \"value\" argument supplied to "
366 "this function has to be non-NULL");
374 &data->
offset, 10, (uint16_t)strlen(args[1]), args[1], -65535, 65535) <= 0) {
382 for (i = 2; i < numargs; i++) {
383 if (strcmp(
"relative", args[i]) == 0) {
385 }
else if (strcasecmp(
"string", args[i]) == 0) {
387 }
else if (strcasecmp(
"dec", args[i]) == 0) {
389 }
else if (strcasecmp(
"hex", args[i]) == 0) {
391 }
else if (strcasecmp(
"oct", args[i]) == 0) {
393 }
else if (strcasecmp(
"big", args[i]) == 0) {
398 }
else if (strcasecmp(
"little", args[i]) == 0) {
400 }
else if (strcasecmp(
"from_beginning", args[i]) == 0) {
402 }
else if (strcasecmp(
"from_end", args[i]) == 0) {
404 }
else if (strcasecmp(
"align", args[i]) == 0) {
406 }
else if (strncasecmp(
"multiplier ", args[i], 11) == 0) {
408 args[i] + 11, 1, 65535) <= 0) {
409 SCLogError(
"Malformed multiplier: %s", optstr);
412 }
else if (strncasecmp(
"post_offset ", args[i], 12) == 0) {
414 args[i] + 12, -65535, 65535) <= 0) {
415 SCLogError(
"Malformed post_offset: %s", optstr);
419 }
else if (strcasecmp(
"dce", args[i]) == 0) {
422 SCLogError(
"Unknown option: \"%s\"", args[i]);
429 "cannot be used in the same byte_jump statement");
434 if (!DetectBytejumpValidateNbytes(data, nbytes)) {
439 data->
nbytes = (uint8_t)nbytes;
444 "without \"string\": %s",
450 pcre2_match_data_free(match);
458 if (nbytes_str != NULL && *nbytes_str != NULL) {
463 DetectBytejumpFree(
de_ctx, data);
465 pcre2_match_data_free(match);
478 data = DetectBytejumpParse(
de_ctx, optstr, &nbytes, &
offset);
498 if (prev_pm == NULL) {
517 if (prev_pm == NULL) {
539 "A byte_jump keyword with dce holds other invalid modifiers.");
544 if (nbytes != NULL) {
548 "seen in byte_jump - %s",
561 "seen in byte_jump - %s",
594 if (nbytes != NULL) {
600 DetectBytejumpFree(
de_ctx, data);
622 static int g_file_data_buffer_id = 0;
623 static int g_dce_stub_data_buffer_id = 0;
629 static int DetectBytejumpTestParse01(
void)
632 data = DetectBytejumpParse(NULL,
"4,0", NULL, NULL);
635 DetectBytejumpFree(NULL, data);
642 static int DetectBytejumpTestParse02(
void)
645 data = DetectBytejumpParse(NULL,
"4, 0", NULL, NULL);
654 DetectBytejumpFree(NULL, data);
661 static int DetectBytejumpTestParse03(
void)
664 data = DetectBytejumpParse(NULL,
665 " 4,0 , relative , little, string, "
666 "dec, align, from_beginning",
678 DetectBytejumpFree(NULL, data);
688 static int DetectBytejumpTestParse04(
void)
691 data = DetectBytejumpParse(NULL,
692 " 4,0 , relative , little, string, "
693 "dec, align, from_beginning , "
694 "multiplier 2 , post_offset -16 ",
706 DetectBytejumpFree(NULL, data);
713 static int DetectBytejumpTestParse05(
void)
716 data = DetectBytejumpParse(NULL,
717 " 4,0 , relative , little, dec, "
718 "align, from_beginning",
728 static int DetectBytejumpTestParse06(
void)
731 data = DetectBytejumpParse(NULL,
"9, 0", NULL, NULL);
740 static int DetectBytejumpTestParse07(
void)
743 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL, NULL);
752 static int DetectBytejumpTestParse08(
void)
755 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL, NULL);
764 static int DetectBytejumpTestParse09(
void)
772 "4,0, align, multiplier 2, "
773 "post_offset -16,dce") == 0);
775 "4,0, multiplier 2, "
776 "post_offset -16,dce") == 0);
777 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
778 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
779 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
780 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
781 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
782 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
783 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
784 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
785 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
786 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
799 static int DetectBytejumpTestParse10(
void)
806 "(msg:\"Testing bytejump_body\"; "
807 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
809 "content:\"one\"; distance:0; "
810 "byte_jump:4,0,align,multiplier 2, "
811 "post_offset -16,relative,dce; sid:1;)");
828 "(msg:\"Testing bytejump_body\"; "
829 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
831 "content:\"one\"; distance:0; "
832 "byte_jump:4,0,align,multiplier 2, "
833 "post_offset -16,relative,dce; sid:2;)");
851 "(msg:\"Testing bytejump_body\"; "
852 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
854 "content:\"one\"; distance:0; "
855 "byte_jump:4,0,align,multiplier 2, "
856 "post_offset -16,relative; sid:3;)");
880 static int DetectBytejumpTestParse11(
void)
890 "(msg:\"Testing bytejump_body\"; "
891 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
893 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
894 "post_offset -16,string,dce; sid:1;)");
898 "(msg:\"Testing bytejump_body\"; "
899 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
901 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
902 "post_offset -16,big,dce; sid:1;)");
906 "(msg:\"Testing bytejump_body\"; "
907 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
909 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
910 "post_offset -16,little,dce; sid:1;)");
914 "(msg:\"Testing bytejump_body\"; "
915 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
917 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
918 "post_offset -16,string,hex,dce; sid:1;)");
922 "(msg:\"Testing bytejump_body\"; "
923 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
925 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
926 "post_offset -16,string,dec,dce; sid:1;)");
930 "(msg:\"Testing bytejump_body\"; "
931 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
933 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
934 "post_offset -16,string,oct,dce; sid:1;)");
938 "(msg:\"Testing bytejump_body\"; "
939 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
941 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
942 "post_offset -16,from_beginning,dce; sid:1;)");
954 static int DetectBytejumpTestParse12(
void)
961 "(file_data; byte_jump:4,0,align,multiplier 2, "
962 "post_offset -16,relative; sid:1;)");
979 static int DetectBytejumpTestParse13(
void)
982 " 4,0 , relative , little, string, dec, "
988 DetectBytejumpFree(NULL, data);
993 static int DetectBytejumpTestParse14(
void)
996 " 4,0 , relative , little, string, dec, "
997 "align, from_beginning, from_end",
1010 static int DetectByteJumpTestPacket01 (
void)
1012 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1013 "User-Agent: Wget/1.11.4"
1015 "Host: www.google.com"
1016 "Connection: Keep-Alive"
1017 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1018 uint16_t buflen = strlen((
char *)buf);
1024 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1025 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1026 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1039 static int DetectByteJumpTestPacket02 (
void)
1041 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1042 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1043 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1044 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1045 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1046 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1048 uint16_t buflen =
sizeof(buf);
1054 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1055 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1056 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1064 static int DetectByteJumpTestPacket03(
void)
1066 uint8_t *buf = NULL;
1067 uint16_t buflen = 0;
1070 printf(
"malloc failed\n");
1073 memcpy(buf,
"boom", 4);
1081 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1082 "byte_jump:1,214748364; sid:1; rev:1;)";
1096 static int DetectByteJumpTestPacket04 (
void)
1098 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1099 uint16_t buflen = strlen((
char *)buf);
1105 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;)";
1116 static int DetectByteJumpTestPacket05 (
void)
1118 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1119 uint16_t buflen = strlen((
char *)buf);
1125 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;)";
1136 static int DetectByteJumpTestPacket06 (
void)
1138 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1139 uint16_t buflen = strlen((
char *)buf);
1145 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;)";
1156 static int DetectByteJumpTestPacket07 (
void)
1158 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1159 uint16_t buflen = strlen((
char *)buf);
1165 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;)";
1176 static int DetectByteJumpTestPacket08 (
void)
1178 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1179 uint16_t buflen = strlen((
char *)buf);
1184 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1185 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1197 static void DetectBytejumpRegisterTests(
void)
1202 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1203 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1204 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1205 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1206 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1207 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1208 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1209 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1210 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1211 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1212 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1213 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1214 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1215 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1217 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1218 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1219 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1220 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1221 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1222 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1223 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1224 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);