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,]+))?" \
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",
179 if (ptr == NULL ||
len <= 0) {
189 if (ptr < payload || nbytes >
len) {
191 "pkt=%p, ptr=%p, len=%d, nbytes=%d",
192 payload, ptr,
len, nbytes);
200 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
207 if (extbytes != nbytes) {
208 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
218 if ((val % 4) != 0) {
219 val += 4 - (val % 4);
226 SCLogDebug(
"NEWVAL: payload %p + %" PRIu64, payload, val);
231 val += (ptr - payload) + extbytes;
232 SCLogDebug(
"NEWVAL: ptr %p + %" PRIu64, ptr, val);
239 SCLogDebug(
"Jump location (%" PRIu64
") is not within "
240 "payload (%" PRIu32
")",
248 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x)", val, sptr, (
int)(sptr - payload));
262 const uint8_t *ptr = NULL;
263 const uint8_t *jumpptr = NULL;
281 if (ptr == NULL ||
len == 0) {
295 if (ptr < p->payload || data->
nbytes >
len) {
297 "payload=%p, ptr=%p, len=%d, nbytes=%d",
305 data->
nbytes, (
const char *)ptr);
307 SCLogDebug(
"error extracting %d bytes of string data: %d",
315 if (extbytes != data->
nbytes) {
316 SCLogDebug(
"error extracting %d bytes of numeric data: %d",
327 if ((val % 4) != 0) {
328 val += 4 - (val % 4);
349 SCLogDebug(
"Jump location (%p) is not within "
358 SCLogDebug(
"jumping %" PRId64
" bytes from %p (%08x) to %p (%08x)",
359 val, sptr, (
int)(sptr - p->
payload),
360 jumpptr, (
int)(jumpptr - p->
payload));
382 pcre2_match_data *match = NULL;
384 memset(args, 0x00,
sizeof(args));
388 if (ret < 2 || ret > 10) {
389 SCLogError(
"parse error, ret %" PRId32
", string \"%s\"", ret, optstr);
398 pcre2len =
sizeof(
str);
399 res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)
str, &pcre2len);
401 SCLogError(
"pcre2_substring_copy_bynumber failed "
412 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
418 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
420 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
423 strlcpy(args[1], str_ptr,
sizeof(args[1]));
427 for (i = 1; i < (ret - 1); i++) {
428 pcre2len =
sizeof(args[0]);
429 res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
431 SCLogError(
"pcre2_substring_copy_bynumber failed for arg %d", i + 1);
452 if (args[0][0] !=
'-' && isalpha((
unsigned char)args[0][0])) {
453 if (nbytes_str == NULL) {
455 "var name for nbytes. \"value\" argument supplied to "
456 "this function has to be non-NULL");
460 if (*nbytes_str == NULL)
465 SCLogError(
"Malformed number of bytes: %s", optstr);
471 if (args[1][0] !=
'-' && isalpha((
unsigned char)args[1][0])) {
474 "var name for offset. \"value\" argument supplied to "
475 "this function has to be non-NULL");
490 for (i = 2; i < numargs; i++) {
491 if (strcmp(
"relative", args[i]) == 0) {
493 }
else if (strcasecmp(
"string", args[i]) == 0) {
495 }
else if (strcasecmp(
"dec", args[i]) == 0) {
497 }
else if (strcasecmp(
"hex", args[i]) == 0) {
499 }
else if (strcasecmp(
"oct", args[i]) == 0) {
501 }
else if (strcasecmp(
"big", args[i]) == 0) {
506 }
else if (strcasecmp(
"little", args[i]) == 0) {
508 }
else if (strcasecmp(
"from_beginning", args[i]) == 0) {
510 }
else if (strcasecmp(
"from_end", args[i]) == 0) {
512 }
else if (strcasecmp(
"align", args[i]) == 0) {
514 }
else if (strncasecmp(
"multiplier ", args[i], 11) == 0) {
516 args[i] + 11, 1, 65535) <= 0) {
517 SCLogError(
"Malformed multiplier: %s", optstr);
520 }
else if (strncasecmp(
"post_offset ", args[i], 12) == 0) {
522 args[i] + 12) <= 0) {
523 SCLogError(
"Malformed post_offset: %s", optstr);
526 }
else if (strcasecmp(
"dce", args[i]) == 0) {
529 SCLogError(
"Unknown option: \"%s\"", args[i]);
536 "cannot be used in the same byte_jump statement");
541 if (!DetectBytejumpValidateNbytes(data, nbytes)) {
546 data->
nbytes = (uint8_t)nbytes;
551 "without \"string\": %s",
557 pcre2_match_data_free(match);
565 if (nbytes_str != NULL && *nbytes_str != NULL) {
570 DetectBytejumpFree(
de_ctx, data);
572 pcre2_match_data_free(match);
586 data = DetectBytejumpParse(
de_ctx, optstr, &nbytes, &
offset);
606 if (prev_pm == NULL) {
625 if (prev_pm == NULL) {
647 "A byte_jump keyword with dce holds other invalid modifiers.");
652 if (nbytes != NULL) {
656 "seen in byte_jump - %s",
669 "seen in byte_jump - %s",
705 if (nbytes != NULL) {
711 DetectBytejumpFree(
de_ctx, data);
733 static int g_file_data_buffer_id = 0;
734 static int g_dce_stub_data_buffer_id = 0;
740 static int DetectBytejumpTestParse01(
void)
744 data = DetectBytejumpParse(NULL,
"4,0", NULL, NULL);
746 DetectBytejumpFree(NULL, data);
756 static int DetectBytejumpTestParse02(
void)
760 data = DetectBytejumpParse(NULL,
"4, 0", NULL, NULL);
766 && (data->
flags == 0)
771 DetectBytejumpFree(NULL, data);
780 static int DetectBytejumpTestParse03(
void)
784 data = DetectBytejumpParse(NULL,
785 " 4,0 , relative , little, string, "
786 "dec, align, from_beginning",
802 DetectBytejumpFree(NULL, data);
814 static int DetectBytejumpTestParse04(
void)
818 data = DetectBytejumpParse(NULL,
819 " 4,0 , relative , little, string, "
820 "dec, align, from_beginning , "
821 "multiplier 2 , post_offset -16 ",
837 DetectBytejumpFree(NULL, data);
846 static int DetectBytejumpTestParse05(
void)
850 data = DetectBytejumpParse(NULL,
851 " 4,0 , relative , little, dec, "
852 "align, from_beginning",
864 static int DetectBytejumpTestParse06(
void)
868 data = DetectBytejumpParse(NULL,
"9, 0", NULL, NULL);
879 static int DetectBytejumpTestParse07(
void)
883 data = DetectBytejumpParse(NULL,
"24, 0, string, dec", NULL, NULL);
894 static int DetectBytejumpTestParse08(
void)
898 data = DetectBytejumpParse(NULL,
"4, 0xffffffffffffffff", NULL, NULL);
909 static int DetectBytejumpTestParse09(
void)
917 "4,0, align, multiplier 2, "
918 "post_offset -16,dce") == 0);
920 "4,0, multiplier 2, "
921 "post_offset -16,dce") == 0);
922 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,post_offset -16,dce") == 0);
923 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
924 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0,dce") == 0);
925 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dce") == -1);
926 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, big, dce") == -1);
927 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, little, dce") == -1);
928 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, dec, dce") == -1);
929 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, oct, dce") == -1);
930 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, string, hex, dce") == -1);
931 FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
"4,0, from_beginning, dce") == -1);
944 static int DetectBytejumpTestParse10(
void)
951 "(msg:\"Testing bytejump_body\"; "
952 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
954 "content:\"one\"; distance:0; "
955 "byte_jump:4,0,align,multiplier 2, "
956 "post_offset -16,relative,dce; sid:1;)");
973 "(msg:\"Testing bytejump_body\"; "
974 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
976 "content:\"one\"; distance:0; "
977 "byte_jump:4,0,align,multiplier 2, "
978 "post_offset -16,relative,dce; sid:2;)");
996 "(msg:\"Testing bytejump_body\"; "
997 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
999 "content:\"one\"; distance:0; "
1000 "byte_jump:4,0,align,multiplier 2, "
1001 "post_offset -16,relative; sid:3;)");
1026 static int DetectBytejumpTestParse11(
void)
1038 "(msg:\"Testing bytejump_body\"; "
1039 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1041 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1042 "post_offset -16,string,dce; sid:1;)");
1049 "(msg:\"Testing bytejump_body\"; "
1050 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1052 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1053 "post_offset -16,big,dce; sid:1;)");
1060 "(msg:\"Testing bytejump_body\"; "
1061 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1063 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1064 "post_offset -16,little,dce; sid:1;)");
1071 "(msg:\"Testing bytejump_body\"; "
1072 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1074 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1075 "post_offset -16,string,hex,dce; sid:1;)");
1082 "(msg:\"Testing bytejump_body\"; "
1083 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1085 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1086 "post_offset -16,string,dec,dce; sid:1;)");
1093 "(msg:\"Testing bytejump_body\"; "
1094 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1096 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1097 "post_offset -16,string,oct,dce; sid:1;)");
1104 "(msg:\"Testing bytejump_body\"; "
1105 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1107 "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1108 "post_offset -16,from_beginning,dce; sid:1;)");
1125 static int DetectBytejumpTestParse12(
void)
1132 "(file_data; byte_jump:4,0,align,multiplier 2, "
1133 "post_offset -16,relative; sid:1;)");
1150 static int DetectBytejumpTestParse13(
void)
1153 " 4,0 , relative , little, string, dec, "
1159 DetectBytejumpFree(NULL, data);
1164 static int DetectBytejumpTestParse14(
void)
1167 " 4,0 , relative , little, string, dec, "
1168 "align, from_beginning, from_end",
1181 static int DetectByteJumpTestPacket01 (
void)
1184 uint8_t *buf = (uint8_t *)
"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1185 "User-Agent: Wget/1.11.4"
1187 "Host: www.google.com"
1188 "Connection: Keep-Alive"
1189 "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1190 uint16_t buflen = strlen((
char *)buf);
1197 char sig[] =
"alert tcp any any -> any any (msg:\"pcre + byte_test + "
1198 "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1199 "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1213 static int DetectByteJumpTestPacket02 (
void)
1216 uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1217 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1218 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1220 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1221 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1223 uint16_t buflen =
sizeof(buf);
1230 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1231 " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1232 "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1241 static int DetectByteJumpTestPacket03(
void)
1244 uint8_t *buf = NULL;
1245 uint16_t buflen = 0;
1248 printf(
"malloc failed\n");
1251 memcpy(buf,
"boom", 4);
1260 char sig[] =
"alert tcp any any -> any any (msg:\"byte_jump\"; "
1261 "byte_jump:1,214748364; sid:1; rev:1;)";
1276 static int DetectByteJumpTestPacket04 (
void)
1279 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1280 uint16_t buflen = strlen((
char *)buf);
1287 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;)";
1299 static int DetectByteJumpTestPacket05 (
void)
1302 uint8_t *buf = (uint8_t *)
"XYZ04abcdABCD";
1303 uint16_t buflen = strlen((
char *)buf);
1310 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;)";
1322 static int DetectByteJumpTestPacket06 (
void)
1325 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1326 uint16_t buflen = strlen((
char *)buf);
1333 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;)";
1345 static int DetectByteJumpTestPacket07 (
void)
1348 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1349 uint16_t buflen = strlen((
char *)buf);
1356 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;)";
1368 static int DetectByteJumpTestPacket08 (
void)
1370 uint8_t *buf = (uint8_t *)
"XX04abcdABCD";
1371 uint16_t buflen = strlen((
char *)buf);
1376 char sig[] =
"alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1377 "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1389 static void DetectBytejumpRegisterTests(
void)
1394 UtRegisterTest(
"DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1395 UtRegisterTest(
"DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1396 UtRegisterTest(
"DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1397 UtRegisterTest(
"DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1398 UtRegisterTest(
"DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1399 UtRegisterTest(
"DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1400 UtRegisterTest(
"DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1401 UtRegisterTest(
"DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1402 UtRegisterTest(
"DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1403 UtRegisterTest(
"DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1404 UtRegisterTest(
"DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1405 UtRegisterTest(
"DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1406 UtRegisterTest(
"DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1407 UtRegisterTest(
"DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1409 UtRegisterTest(
"DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1410 UtRegisterTest(
"DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1411 UtRegisterTest(
"DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1412 UtRegisterTest(
"DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1413 UtRegisterTest(
"DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1414 UtRegisterTest(
"DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1415 UtRegisterTest(
"DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1416 UtRegisterTest(
"DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);