52 "([^\\s,]+\\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,]+))?" \
62 "(?:\\s*,\\s*((?:multiplier|post_offset|bitmask)\\s+[^\\s,]+|[^\\s,]+))?" \
72 static void DetectBytejumpRegisterTests(
void);
98 static inline bool DetectBytejumpValidateNbytesOnly(
const DetectBytejumpData *data, int32_t nbytes)
103 static bool DetectBytejumpValidateNbytes(
const DetectBytejumpData *data, int32_t nbytes)
105 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
121 "without \"string\"");
141 int32_t nbytes, int32_t
offset)
146 const uint8_t *ptr = NULL;
161 if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
163 "seen in byte_jump - %d",
181 if (ptr == NULL || (nbytes &&
len <= 0)) {
187 if (ptr < payload || nbytes >
len) {
189 "pkt=%p, ptr=%p, len=%" PRIi32
", nbytes=%" PRIi32,
190 payload, ptr,
len, nbytes);
198 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
205 if (extbytes != nbytes) {
206 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
217 SCLogDebug(
"[before bitmask] val: %" PRIi64
" bitmask_value: %" PRIx32, val,
223 SCLogDebug(
"[after bitmask] val: %" PRIi64
" bitmask_value: %" PRIx32, val,
230 if ((val % 4) != 0) {
231 val += 4 - (val % 4);
238 const uint8_t *jumpptr;
241 jumpptr = payload + (int64_t)val;
242 SCLogDebug(
"NEWVAL: payload %p + %" PRIi64
" = %p", payload, (int64_t)val, jumpptr + val);
246 "NEWVAL: payload %p + %" PRIu32
" + %" PRIi64, payload,
payload_len, (int64_t)val);
248 jumpptr = ptr + (int64_t)val + extbytes;
249 SCLogDebug(
"NEWVAL: ptr %p + %" PRIi64
" = %p", ptr, val, jumpptr);
255 if (jumpptr < payload) {
257 SCLogDebug(
"jump location is before buffer start; resetting to buffer start");
259 SCLogDebug(
"Jump location (%" PRIu64
") is not within payload (%" PRIu32
")",
267 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x)", val, sptr, (
int)(sptr - payload));
290 pcre2_match_data *match = NULL;
292 memset(args, 0x00,
sizeof(args));
296 if (ret < 2 || ret > 11) {
297 SCLogError(
"parse error, ret %" PRId32
", string \"%s\"", ret, optstr);
306 pcre2len =
sizeof(
str);
307 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)
str, &pcre2len);
309 SCLogError(
"pcre2_substring_copy_bynumber failed "
320 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
326 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
328 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
331 strlcpy(args[1], str_ptr,
sizeof(args[1]));
335 for (i = 1; i < (ret - 1); i++) {
336 pcre2len =
sizeof(args[0]);
337 res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
339 SCLogError(
"pcre2_substring_copy_bynumber failed for arg %d", i + 1);
360 if (args[0][0] !=
'-' && isalpha((
unsigned char)args[0][0])) {
361 if (nbytes_str == NULL) {
363 "var name for nbytes. \"value\" argument supplied to "
364 "this function has to be non-NULL");
368 if (*nbytes_str == NULL)
373 SCLogError(
"Malformed number of bytes: %s", optstr);
379 if (args[1][0] !=
'-' && isalpha((
unsigned char)args[1][0])) {
382 "var name for offset. \"value\" argument supplied to "
383 "this function has to be non-NULL");
391 &data->
offset, 10, (uint16_t)strlen(args[1]), args[1], -65535, 65535) <= 0) {
399 for (i = 2; i < numargs; i++) {
400 if (strcmp(
"relative", args[i]) == 0) {
402 }
else if (strcasecmp(
"string", args[i]) == 0) {
404 }
else if (strcasecmp(
"dec", args[i]) == 0) {
406 }
else if (strcasecmp(
"hex", args[i]) == 0) {
408 }
else if (strcasecmp(
"oct", args[i]) == 0) {
410 }
else if (strcasecmp(
"big", args[i]) == 0) {
415 }
else if (strcasecmp(
"little", args[i]) == 0) {
417 }
else if (strcasecmp(
"from_beginning", args[i]) == 0) {
419 }
else if (strcasecmp(
"from_end", args[i]) == 0) {
421 }
else if (strcasecmp(
"align", args[i]) == 0) {
423 }
else if (strncasecmp(
"multiplier ", args[i], 11) == 0) {
425 args[i] + 11, 1, 65535) <= 0) {
426 SCLogError(
"Malformed multiplier: %s", optstr);
429 }
else if (strncasecmp(
"post_offset ", args[i], 12) == 0) {
431 args[i] + 12, -65535, 65535) <= 0) {
432 SCLogError(
"Malformed post_offset: %s", optstr);
436 }
else if (strncasecmp(
"bitmask ", args[i], 8) == 0) {
447 }
else if (strcasecmp(
"dce", args[i]) == 0) {
450 SCLogError(
"Unknown option: \"%s\"", args[i]);
457 "cannot be used in the same byte_jump statement");
462 if (!DetectBytejumpValidateNbytes(data, nbytes)) {
467 data->
nbytes = (uint8_t)nbytes;
472 "without \"string\": %s",
481 while (!(bmask & 0x1)) {
489 pcre2_match_data_free(match);
497 if (nbytes_str != NULL && *nbytes_str != NULL) {
502 DetectBytejumpFree(
de_ctx, data);
504 pcre2_match_data_free(match);
517 data = DetectBytejumpParse(
de_ctx, optstr, &nbytes, &
offset);
535 if (prev_pm == NULL) {
552 if (prev_pm == NULL) {
574 "A byte_jump keyword with dce holds other invalid modifiers.");
579 if (nbytes != NULL) {
583 "seen in byte_jump - %s",
596 "seen in byte_jump - %s",
630 if (nbytes != NULL) {
636 DetectBytejumpFree(
de_ctx, data);
658 static int g_file_data_buffer_id = 0;
659 static int g_dce_stub_data_buffer_id = 0;
665 static int DetectBytejumpTestParse01(
void)
668 data = DetectBytejumpParse(NULL,
"4,0", NULL, NULL);
671 DetectBytejumpFree(NULL, data);
678 static int DetectBytejumpTestParse02(
void)
681 data = DetectBytejumpParse(NULL,
"4, 0", NULL, NULL);
690 DetectBytejumpFree(NULL, data);
697 static int DetectBytejumpTestParse03(
void)
700 data = DetectBytejumpParse(NULL,
701 " 4,0 , relative , little, string, "
702 "dec, align, from_beginning",
714 DetectBytejumpFree(NULL, data);
724 static int DetectBytejumpTestParse04(
void)
727 data = DetectBytejumpParse(NULL,
728 " 4,0 , relative , little, string, "
729 "dec, align, from_beginning , "
730 "multiplier 2 , post_offset -16 ",
742 DetectBytejumpFree(NULL, data);
749 static int DetectBytejumpTestParse05(
void)
752 data = DetectBytejumpParse(NULL,
753 " 4,0 , relative , little, dec, "
754 "align, from_beginning",
764 static int DetectBytejumpTestParse06(
void)
767 data = DetectBytejumpParse(NULL,
"9, 0", NULL, NULL);
776 static int DetectBytejumpTestParse07(
void)
779 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL, NULL);
788 static int DetectBytejumpTestParse08(
void)
791 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL, NULL);
800 static int DetectBytejumpTestParse09(
void)
808 "4,0, align, multiplier 2, "
809 "post_offset -16,dce") == 0);
811 "4,0, multiplier 2, "
812 "post_offset -16,dce") == 0);
813 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
814 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
815 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
816 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
817 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
818 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
819 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
820 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
821 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
822 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
835 static int DetectBytejumpTestParse10(
void)
842 "(msg:\"Testing bytejump_body\"; "
843 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
845 "content:\"one\"; distance:0; "
846 "byte_jump:4,0,align,multiplier 2, "
847 "post_offset -16,relative,dce; sid:1;)");
864 "(msg:\"Testing bytejump_body\"; "
865 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
867 "content:\"one\"; distance:0; "
868 "byte_jump:4,0,align,multiplier 2, "
869 "post_offset -16,relative,dce; sid:2;)");
887 "(msg:\"Testing bytejump_body\"; "
888 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
890 "content:\"one\"; distance:0; "
891 "byte_jump:4,0,align,multiplier 2, "
892 "post_offset -16,relative; sid:3;)");
916 static int DetectBytejumpTestParse11(
void)
926 "(msg:\"Testing bytejump_body\"; "
927 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
929 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
930 "post_offset -16,string,dce; sid:1;)");
934 "(msg:\"Testing bytejump_body\"; "
935 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
937 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
938 "post_offset -16,big,dce; sid:1;)");
942 "(msg:\"Testing bytejump_body\"; "
943 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
945 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
946 "post_offset -16,little,dce; sid:1;)");
950 "(msg:\"Testing bytejump_body\"; "
951 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
953 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
954 "post_offset -16,string,hex,dce; sid:1;)");
958 "(msg:\"Testing bytejump_body\"; "
959 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
961 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
962 "post_offset -16,string,dec,dce; sid:1;)");
966 "(msg:\"Testing bytejump_body\"; "
967 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
969 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
970 "post_offset -16,string,oct,dce; sid:1;)");
974 "(msg:\"Testing bytejump_body\"; "
975 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
977 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
978 "post_offset -16,from_beginning,dce; sid:1;)");
990 static int DetectBytejumpTestParse12(
void)
997 "(file_data; byte_jump:4,0,align,multiplier 2, "
998 "post_offset -16,relative; sid:1;)");
1015 static int DetectBytejumpTestParse13(
void)
1018 " 4,0 , relative , little, string, dec, "
1024 DetectBytejumpFree(NULL, data);
1029 static int DetectBytejumpTestParse14(
void)
1032 " 4,0 , relative , little, string, dec, "
1033 "align, from_beginning, from_end",
1041 static int DetectBytejumpTestParse15(
void)
1049 "(msg:\"Testing bytejump_body\"; "
1050 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1052 "content:\"one\"; distance:0; "
1053 "byte_jump:4,0,align,multiplier 2, "
1054 "post_offset -16,relative,bitmask 0x8f40,dce; sid:1;)");
1078 static int DetectBytejumpTestParse16(
void)
1086 "(msg:\"Testing bytejump_body\"; "
1087 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1089 "content:\"one\"; distance:0; "
1090 "byte_jump:4,0,align,multiplier 2, "
1091 "post_offset -16,relative,bitmask 5304,dce; sid:1;)");
1120 static int DetectByteJumpTestPacket01 (
void)
1122 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1123 "User-Agent: Wget/1.11.4"
1125 "Host: www.google.com"
1126 "Connection: Keep-Alive"
1127 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1128 uint16_t buflen = strlen((
char *)buf);
1134 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1135 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1136 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1149 static int DetectByteJumpTestPacket02 (
void)
1151 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1152 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1153 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1155 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1156 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1158 uint16_t buflen =
sizeof(buf);
1164 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1165 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1166 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1174 static int DetectByteJumpTestPacket03(
void)
1176 uint8_t *buf = NULL;
1177 uint16_t buflen = 0;
1180 printf(
"malloc failed\n");
1183 memcpy(buf,
"boom", 4);
1191 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1192 "byte_jump:1,214748364; sid:1; rev:1;)";
1206 static int DetectByteJumpTestPacket04 (
void)
1208 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1209 uint16_t buflen = strlen((
char *)buf);
1215 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;)";
1226 static int DetectByteJumpTestPacket05 (
void)
1228 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1229 uint16_t buflen = strlen((
char *)buf);
1235 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;)";
1246 static int DetectByteJumpTestPacket06 (
void)
1248 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1249 uint16_t buflen = strlen((
char *)buf);
1255 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;)";
1266 static int DetectByteJumpTestPacket07 (
void)
1268 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1269 uint16_t buflen = strlen((
char *)buf);
1275 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;)";
1286 static int DetectByteJumpTestPacket08 (
void)
1288 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1289 uint16_t buflen = strlen((
char *)buf);
1294 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1295 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1307 static void DetectBytejumpRegisterTests(
void)
1312 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1313 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1314 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1315 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1316 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1317 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1318 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1319 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1320 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1321 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1322 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1323 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1324 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1325 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1326 UtRegisterTest(
"DetectBytejumpTestParse15", DetectBytejumpTestParse15);
1327 UtRegisterTest(
"DetectBytejumpTestParse16", DetectBytejumpTestParse16);
1329 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1330 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1331 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1332 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1333 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1334 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1335 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1336 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);