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",
596 if (nbytes != NULL) {
602 DetectBytejumpFree(
de_ctx, data);
624 static int g_file_data_buffer_id = 0;
625 static int g_dce_stub_data_buffer_id = 0;
631 static int DetectBytejumpTestParse01(
void)
634 data = DetectBytejumpParse(NULL,
"4,0", NULL, NULL);
637 DetectBytejumpFree(NULL, data);
644 static int DetectBytejumpTestParse02(
void)
647 data = DetectBytejumpParse(NULL,
"4, 0", NULL, NULL);
656 DetectBytejumpFree(NULL, data);
663 static int DetectBytejumpTestParse03(
void)
666 data = DetectBytejumpParse(NULL,
667 " 4,0 , relative , little, string, "
668 "dec, align, from_beginning",
680 DetectBytejumpFree(NULL, data);
690 static int DetectBytejumpTestParse04(
void)
693 data = DetectBytejumpParse(NULL,
694 " 4,0 , relative , little, string, "
695 "dec, align, from_beginning , "
696 "multiplier 2 , post_offset -16 ",
708 DetectBytejumpFree(NULL, data);
715 static int DetectBytejumpTestParse05(
void)
718 data = DetectBytejumpParse(NULL,
719 " 4,0 , relative , little, dec, "
720 "align, from_beginning",
730 static int DetectBytejumpTestParse06(
void)
733 data = DetectBytejumpParse(NULL,
"9, 0", NULL, NULL);
742 static int DetectBytejumpTestParse07(
void)
745 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL, NULL);
754 static int DetectBytejumpTestParse08(
void)
757 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL, NULL);
766 static int DetectBytejumpTestParse09(
void)
774 "4,0, align, multiplier 2, "
775 "post_offset -16,dce") == 0);
777 "4,0, multiplier 2, "
778 "post_offset -16,dce") == 0);
779 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
780 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
781 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
782 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
783 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
784 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
785 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
786 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
787 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
788 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
801 static int DetectBytejumpTestParse10(
void)
808 "(msg:\"Testing bytejump_body\"; "
809 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
811 "content:\"one\"; distance:0; "
812 "byte_jump:4,0,align,multiplier 2, "
813 "post_offset -16,relative,dce; sid:1;)");
830 "(msg:\"Testing bytejump_body\"; "
831 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
833 "content:\"one\"; distance:0; "
834 "byte_jump:4,0,align,multiplier 2, "
835 "post_offset -16,relative,dce; sid:2;)");
853 "(msg:\"Testing bytejump_body\"; "
854 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
856 "content:\"one\"; distance:0; "
857 "byte_jump:4,0,align,multiplier 2, "
858 "post_offset -16,relative; sid:3;)");
882 static int DetectBytejumpTestParse11(
void)
892 "(msg:\"Testing bytejump_body\"; "
893 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
895 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
896 "post_offset -16,string,dce; sid:1;)");
900 "(msg:\"Testing bytejump_body\"; "
901 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
903 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
904 "post_offset -16,big,dce; sid:1;)");
908 "(msg:\"Testing bytejump_body\"; "
909 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
911 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
912 "post_offset -16,little,dce; sid:1;)");
916 "(msg:\"Testing bytejump_body\"; "
917 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
919 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
920 "post_offset -16,string,hex,dce; sid:1;)");
924 "(msg:\"Testing bytejump_body\"; "
925 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
927 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
928 "post_offset -16,string,dec,dce; sid:1;)");
932 "(msg:\"Testing bytejump_body\"; "
933 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
935 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
936 "post_offset -16,string,oct,dce; sid:1;)");
940 "(msg:\"Testing bytejump_body\"; "
941 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
943 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
944 "post_offset -16,from_beginning,dce; sid:1;)");
956 static int DetectBytejumpTestParse12(
void)
963 "(file_data; byte_jump:4,0,align,multiplier 2, "
964 "post_offset -16,relative; sid:1;)");
981 static int DetectBytejumpTestParse13(
void)
984 " 4,0 , relative , little, string, dec, "
990 DetectBytejumpFree(NULL, data);
995 static int DetectBytejumpTestParse14(
void)
998 " 4,0 , relative , little, string, dec, "
999 "align, from_beginning, from_end",
1012 static int DetectByteJumpTestPacket01 (
void)
1014 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1015 "User-Agent: Wget/1.11.4"
1017 "Host: www.google.com"
1018 "Connection: Keep-Alive"
1019 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1020 uint16_t buflen = strlen((
char *)buf);
1026 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1027 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1028 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1041 static int DetectByteJumpTestPacket02 (
void)
1043 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1044 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1045 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1046 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1047 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1048 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1050 uint16_t buflen =
sizeof(buf);
1056 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1057 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1058 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1066 static int DetectByteJumpTestPacket03(
void)
1068 uint8_t *buf = NULL;
1069 uint16_t buflen = 0;
1072 printf(
"malloc failed\n");
1075 memcpy(buf,
"boom", 4);
1083 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1084 "byte_jump:1,214748364; sid:1; rev:1;)";
1098 static int DetectByteJumpTestPacket04 (
void)
1100 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1101 uint16_t buflen = strlen((
char *)buf);
1107 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;)";
1118 static int DetectByteJumpTestPacket05 (
void)
1120 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1121 uint16_t buflen = strlen((
char *)buf);
1127 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;)";
1138 static int DetectByteJumpTestPacket06 (
void)
1140 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1141 uint16_t buflen = strlen((
char *)buf);
1147 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;)";
1158 static int DetectByteJumpTestPacket07 (
void)
1160 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1161 uint16_t buflen = strlen((
char *)buf);
1167 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;)";
1178 static int DetectByteJumpTestPacket08 (
void)
1180 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1181 uint16_t buflen = strlen((
char *)buf);
1186 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1187 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1199 static void DetectBytejumpRegisterTests(
void)
1204 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1205 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1206 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1207 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1208 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1209 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1210 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1211 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1212 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1213 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1214 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1215 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1216 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1217 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1219 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1220 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1221 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1222 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1223 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1224 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1225 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1226 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);