51 "([^\\s,]+\\s*,\\s*[^\\s,]+)" \
52 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
53 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
54 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
55 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
56 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
57 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
58 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
59 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
60 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
61 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
71 static void DetectBytejumpRegisterTests(
void);
97 static inline bool DetectBytejumpValidateNbytesOnly(
const DetectBytejumpData *data, int32_t nbytes)
102 static bool DetectBytejumpValidateNbytes(
const DetectBytejumpData *data, int32_t nbytes)
104 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
120 "without \"string\"");
140 int32_t nbytes, int32_t
offset)
145 const uint8_t *ptr = NULL;
160 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
162 "seen in byte_jump - %d",
180 if (ptr == NULL || (nbytes &&
len <= 0)) {
186 if (ptr < payload || nbytes >
len) {
188 "pkt=%p, ptr=%p, len=%" PRIi32
", nbytes=%" PRIi32,
189 payload, ptr,
len, nbytes);
197 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
204 if (extbytes != nbytes) {
205 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
216 SCLogDebug(
"[before bitmask] val: %" PRIi64
" bitmask_value: %" PRIx32, val,
222 SCLogDebug(
"[after bitmask] val: %" PRIi64
" bitmask_value: %" PRIx32, val,
229 if ((val % 4) != 0) {
230 val += 4 - (val % 4);
237 const uint8_t *jumpptr;
240 jumpptr = payload + (int64_t)val;
241 SCLogDebug(
"NEWVAL: payload %p + %" PRIi64
" = %p", payload, (int64_t)val, jumpptr + val);
245 "NEWVAL: payload %p + %" PRIu32
" + %" PRIi64, payload,
payload_len, (int64_t)val);
247 jumpptr = ptr + (int64_t)val + extbytes;
248 SCLogDebug(
"NEWVAL: ptr %p + %" PRIi64
" = %p", ptr, val, jumpptr);
254 if (jumpptr < payload) {
256 SCLogDebug(
"jump location is before buffer start; resetting to buffer start");
258 SCLogDebug(
"Jump location (%" PRIu64
") is not within payload (%" PRIu32
")",
266 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x)", val, sptr, (
int)(sptr - payload));
289 pcre2_match_data *match = NULL;
291 memset(args, 0x00,
sizeof(args));
295 if (ret < 2 || ret > 11) {
296 SCLogError(
"parse error, ret %" PRId32
", string \"%s\"", ret, optstr);
305 pcre2len =
sizeof(
str);
306 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)
str, &pcre2len);
308 SCLogError(
"pcre2_substring_copy_bynumber failed "
319 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
325 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
327 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
330 strlcpy(args[1], str_ptr,
sizeof(args[1]));
334 for (i = 1; i < (ret - 1); i++) {
335 pcre2len =
sizeof(args[0]);
336 res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
338 SCLogError(
"pcre2_substring_copy_bynumber failed for arg %d", i + 1);
359 if (args[0][0] !=
'-' && isalpha((
unsigned char)args[0][0])) {
360 if (nbytes_str == NULL) {
362 "var name for nbytes. \"value\" argument supplied to "
363 "this function has to be non-NULL");
367 if (*nbytes_str == NULL)
372 SCLogError(
"Malformed number of bytes: %s", optstr);
378 if (args[1][0] !=
'-' && isalpha((
unsigned char)args[1][0])) {
381 "var name for offset. \"value\" argument supplied to "
382 "this function has to be non-NULL");
390 &data->
offset, 10, (uint16_t)strlen(args[1]), args[1], -65535, 65535) <= 0) {
398 for (i = 2; i < numargs; i++) {
399 if (strcmp(
"relative", args[i]) == 0) {
401 }
else if (strcasecmp(
"string", args[i]) == 0) {
403 }
else if (strcasecmp(
"dec", args[i]) == 0) {
405 }
else if (strcasecmp(
"hex", args[i]) == 0) {
407 }
else if (strcasecmp(
"oct", args[i]) == 0) {
409 }
else if (strcasecmp(
"big", args[i]) == 0) {
414 }
else if (strcasecmp(
"little", args[i]) == 0) {
416 }
else if (strcasecmp(
"from_beginning", args[i]) == 0) {
418 }
else if (strcasecmp(
"from_end", args[i]) == 0) {
420 }
else if (strcasecmp(
"align", args[i]) == 0) {
422 }
else if (strncasecmp(
"multiplier ", args[i], 11) == 0) {
424 args[i] + 11, 1, 65535) <= 0) {
425 SCLogError(
"Malformed multiplier: %s", optstr);
428 }
else if (strncasecmp(
"post_offset ", args[i], 12) == 0) {
430 args[i] + 12, -65535, 65535) <= 0) {
431 SCLogError(
"Malformed post_offset: %s", optstr);
435 }
else if (strncasecmp(
"bitmask ", args[i], 8) == 0) {
446 }
else if (strcasecmp(
"dce", args[i]) == 0) {
449 SCLogError(
"Unknown option: \"%s\"", args[i]);
456 "cannot be used in the same byte_jump statement");
461 if (!DetectBytejumpValidateNbytes(data, nbytes)) {
466 data->
nbytes = (uint8_t)nbytes;
471 "without \"string\": %s",
480 while (!(bmask & 0x1)) {
488 pcre2_match_data_free(match);
496 if (nbytes_str != NULL && *nbytes_str != NULL) {
501 DetectBytejumpFree(
de_ctx, data);
503 pcre2_match_data_free(match);
516 data = DetectBytejumpParse(
de_ctx, optstr, &nbytes, &
offset);
534 if (prev_pm == NULL) {
551 if (prev_pm == NULL) {
573 "A byte_jump keyword with dce holds other invalid modifiers.");
578 if (nbytes != NULL) {
582 "seen in byte_jump - %s",
595 "seen in byte_jump - %s",
629 if (nbytes != NULL) {
635 DetectBytejumpFree(
de_ctx, data);
657 static int g_file_data_buffer_id = 0;
658 static int g_dce_stub_data_buffer_id = 0;
664 static int DetectBytejumpTestParse01(
void)
667 data = DetectBytejumpParse(NULL,
"4,0", NULL, NULL);
670 DetectBytejumpFree(NULL, data);
677 static int DetectBytejumpTestParse02(
void)
680 data = DetectBytejumpParse(NULL,
"4, 0", NULL, NULL);
689 DetectBytejumpFree(NULL, data);
696 static int DetectBytejumpTestParse03(
void)
699 data = DetectBytejumpParse(NULL,
700 " 4,0 , relative , little, string, "
701 "dec, align, from_beginning",
713 DetectBytejumpFree(NULL, data);
723 static int DetectBytejumpTestParse04(
void)
726 data = DetectBytejumpParse(NULL,
727 " 4,0 , relative , little, string, "
728 "dec, align, from_beginning , "
729 "multiplier 2 , post_offset -16 ",
741 DetectBytejumpFree(NULL, data);
748 static int DetectBytejumpTestParse05(
void)
751 data = DetectBytejumpParse(NULL,
752 " 4,0 , relative , little, dec, "
753 "align, from_beginning",
763 static int DetectBytejumpTestParse06(
void)
766 data = DetectBytejumpParse(NULL,
"9, 0", NULL, NULL);
775 static int DetectBytejumpTestParse07(
void)
778 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL, NULL);
787 static int DetectBytejumpTestParse08(
void)
790 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL, NULL);
799 static int DetectBytejumpTestParse09(
void)
807 "4,0, align, multiplier 2, "
808 "post_offset -16,dce") == 0);
810 "4,0, multiplier 2, "
811 "post_offset -16,dce") == 0);
812 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
813 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
814 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
815 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
816 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
817 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
818 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
819 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
820 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
821 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
834 static int DetectBytejumpTestParse10(
void)
841 "(msg:\"Testing bytejump_body\"; "
842 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
844 "content:\"one\"; distance:0; "
845 "byte_jump:4,0,align,multiplier 2, "
846 "post_offset -16,relative,dce; sid:1;)");
863 "(msg:\"Testing bytejump_body\"; "
864 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
866 "content:\"one\"; distance:0; "
867 "byte_jump:4,0,align,multiplier 2, "
868 "post_offset -16,relative,dce; sid:2;)");
886 "(msg:\"Testing bytejump_body\"; "
887 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
889 "content:\"one\"; distance:0; "
890 "byte_jump:4,0,align,multiplier 2, "
891 "post_offset -16,relative; sid:3;)");
915 static int DetectBytejumpTestParse11(
void)
925 "(msg:\"Testing bytejump_body\"; "
926 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
928 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
929 "post_offset -16,string,dce; sid:1;)");
933 "(msg:\"Testing bytejump_body\"; "
934 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
936 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
937 "post_offset -16,big,dce; sid:1;)");
941 "(msg:\"Testing bytejump_body\"; "
942 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
944 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
945 "post_offset -16,little,dce; sid:1;)");
949 "(msg:\"Testing bytejump_body\"; "
950 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
952 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
953 "post_offset -16,string,hex,dce; sid:1;)");
957 "(msg:\"Testing bytejump_body\"; "
958 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
960 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
961 "post_offset -16,string,dec,dce; sid:1;)");
965 "(msg:\"Testing bytejump_body\"; "
966 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
968 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
969 "post_offset -16,string,oct,dce; sid:1;)");
973 "(msg:\"Testing bytejump_body\"; "
974 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
976 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
977 "post_offset -16,from_beginning,dce; sid:1;)");
989 static int DetectBytejumpTestParse12(
void)
996 "(file_data; byte_jump:4,0,align,multiplier 2, "
997 "post_offset -16,relative; sid:1;)");
1014 static int DetectBytejumpTestParse13(
void)
1017 " 4,0 , relative , little, string, dec, "
1023 DetectBytejumpFree(NULL, data);
1028 static int DetectBytejumpTestParse14(
void)
1031 " 4,0 , relative , little, string, dec, "
1032 "align, from_beginning, from_end",
1040 static int DetectBytejumpTestParse15(
void)
1048 "(msg:\"Testing bytejump_body\"; "
1049 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1051 "content:\"one\"; distance:0; "
1052 "byte_jump:4,0,align,multiplier 2, "
1053 "post_offset -16,relative,bitmask 0x8f40,dce; sid:1;)");
1077 static int DetectBytejumpTestParse16(
void)
1085 "(msg:\"Testing bytejump_body\"; "
1086 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1088 "content:\"one\"; distance:0; "
1089 "byte_jump:4,0,align,multiplier 2, "
1090 "post_offset -16,relative,bitmask 5304,dce; sid:1;)");
1119 static int DetectByteJumpTestPacket01 (
void)
1121 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1122 "User-Agent: Wget/1.11.4"
1124 "Host: www.google.com"
1125 "Connection: Keep-Alive"
1126 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1127 uint16_t buflen = strlen((
char *)buf);
1133 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1134 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1135 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1148 static int DetectByteJumpTestPacket02 (
void)
1150 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1151 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1152 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1154 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1155 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1157 uint16_t buflen =
sizeof(buf);
1163 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1164 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1165 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1173 static int DetectByteJumpTestPacket03(
void)
1175 uint8_t *buf = NULL;
1176 uint16_t buflen = 0;
1179 printf(
"malloc failed\n");
1182 memcpy(buf,
"boom", 4);
1190 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1191 "byte_jump:1,214748364; sid:1; rev:1;)";
1205 static int DetectByteJumpTestPacket04 (
void)
1207 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1208 uint16_t buflen = strlen((
char *)buf);
1214 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;)";
1225 static int DetectByteJumpTestPacket05 (
void)
1227 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1228 uint16_t buflen = strlen((
char *)buf);
1234 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;)";
1245 static int DetectByteJumpTestPacket06 (
void)
1247 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1248 uint16_t buflen = strlen((
char *)buf);
1254 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;)";
1265 static int DetectByteJumpTestPacket07 (
void)
1267 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1268 uint16_t buflen = strlen((
char *)buf);
1274 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;)";
1285 static int DetectByteJumpTestPacket08 (
void)
1287 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1288 uint16_t buflen = strlen((
char *)buf);
1293 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1294 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1306 static void DetectBytejumpRegisterTests(
void)
1311 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1312 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1313 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1314 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1315 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1316 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1317 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1318 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1319 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1320 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1321 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1322 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1323 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1324 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1325 UtRegisterTest(
"DetectBytejumpTestParse15", DetectBytejumpTestParse15);
1326 UtRegisterTest(
"DetectBytejumpTestParse16", DetectBytejumpTestParse16);
1328 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1329 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1330 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1331 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1332 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1333 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1334 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1335 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);