56 #define VALID_KW "relative|big|little|string|oct|dec|hex|dce|bitmask"
57 #define PARSE_REGEX "^\\s*" \
58 "([^\\s,]+)\\s*,\\s*" \
59 "(\\!?\\s*[^\\s,]*)" \
60 "\\s*,\\s*([^\\s,]+\\s*,\\s*[^\\s,]+)" \
61 "(?:\\s*,\\s*((?:"VALID_KW")\\s+[^\\s,]+|["VALID_KW"]+))?" \
62 "(?:\\s*,\\s*((?:"VALID_KW")\\s+[^\\s,]+|["VALID_KW"]+))?" \
63 "(?:\\s*,\\s*((?:"VALID_KW")\\s+[^\\s,]+|["VALID_KW"]+))?" \
64 "(?:\\s*,\\s*((?:"VALID_KW")\\s+[^\\s,]+|["VALID_KW"]+))?" \
65 "(?:\\s*,\\s*((?:"VALID_KW")\\s+[^\\s,]+|["VALID_KW"]+))?" \
66 "(?:\\s*,\\s*((?:"VALID_KW")\\s+[^\\s,]+|["VALID_KW"]+))?" \
76 static void DetectBytetestRegisterTests(
void);
82 sigmatch_table[
DETECT_BYTETEST].
desc =
"extract <num of bytes> and perform an operation selected with <operator> against the value in <test value> at a particular <offset>";
102 static inline bool DetectBytetestValidateNbytesOnly(
const DetectBytetestData *data, int32_t nbytes)
107 static bool DetectBytetestValidateNbytes(
110 if (!DetectBytetestValidateNbytesOnly(data, nbytes)) {
120 SCLogError(
"Cannot test more than 23 bytes with \"string\": %s", optstr);
124 SCLogError(
"Cannot test more than 8 bytes without \"string\": %s", optstr);
127 SCLogError(
"Cannot use a base without \"string\": %s", optstr);
137 SCLogError(
"Cannot use a base without \"string\": %s", optstr);
159 int32_t
offset, int32_t nbytes, uint64_t value)
169 if (!DetectBytetestValidateNbytesOnly(data, nbytes)) {
170 SCLogDebug(
"Invalid byte_test nbytes seen in byte_test - %d", nbytes);
175 const uint8_t *ptr = NULL;
186 SCLogDebug(
"relative, working with det_ctx->buffer_offset %"PRIu32
", "
196 if (ptr == NULL ||
len <= 0) {
210 if (ptr < payload || nbytes >
len) {
211 SCLogDebug(
"Data not within payload pkt=%p, ptr=%p, len=%" PRIu32
", nbytes=%d", payload,
228 "bytes of string data: %d",
234 SCLogDebug(
"comparing base %d string 0x%" PRIx64
" %s%u 0x%" PRIx64,
235 data->
base, val, (neg ?
"!" :
""), data->
op, data->
value);
241 if (extbytes != nbytes) {
243 "of numeric data: %d",
248 SCLogDebug(
"comparing numeric 0x%" PRIx64
" %s%u 0x%" PRIx64,
249 val, (neg ?
"!" :
""), data->
op, data->
value);
306 if ((!neg && match) || (neg && !match)) {
307 SCLogDebug(
"MATCH [bt] extracted value is %"PRIu64, val);
324 const char *optstr,
char **value,
char **
offset,
char **nbytes_str)
328 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
331 char *test_value = NULL;
332 char *data_offset = NULL;
337 const char *str_ptr = NULL;
338 pcre2_match_data *match = NULL;
342 if (ret < 4 || ret > 9) {
343 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, optstr);
348 for (i = 0; i < (ret - 1); i++) {
349 res = pcre2_substring_get_bynumber(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
351 SCLogError(
"pcre2_substring_get_bynumber failed "
358 test_value = (
char *) str_ptr;
359 data_offset =
SCStrdup((
char *) str_ptr);
360 if (data_offset == NULL) {
364 args[i] = (
char *)str_ptr;
387 if (args[0][0] !=
'-' && isalpha((
unsigned char)args[0][0])) {
388 if (nbytes_str == NULL) {
390 "var name for nbytes. \"value\" argument supplied to "
391 "this function has to be non-NULL");
395 if (*nbytes_str == NULL)
400 SCLogError(
"Malformed number of bytes: %s", str_ptr);
407 if (args[1] != NULL) {
410 if (args[1][op_offset] ==
'!') {
412 op_ptr = &args[1][1];
413 while (isspace((
char)*op_ptr) || (*op_ptr ==
',')) op_ptr++;
414 op_offset = op_ptr - &args[1][0];
418 op_ptr = args[1] + op_offset;
419 if ((strcmp(
"=", op_ptr) == 0) || (data->
neg_op
420 && strcmp(
"", op_ptr) == 0)) {
422 }
else if (strcmp(
"<", op_ptr) == 0) {
424 }
else if (strcmp(
">", op_ptr) == 0) {
426 }
else if (strcmp(
"&", op_ptr) == 0) {
428 }
else if (strcmp(
"^", op_ptr) == 0) {
430 }
else if (strcmp(
">=", op_ptr) == 0) {
432 }
else if (strcmp(
"<=", op_ptr) == 0) {
446 char *end_ptr = test_value;
447 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
450 if (test_value[0] !=
'-' && isalpha((
unsigned char)test_value[0])) {
453 "var name for value. \"value\" argument supplied to "
454 "this function has to be non-NULL");
462 SCLogError(
"Malformed value: %s", test_value);
470 char *end_ptr = data_offset;
471 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
','))) end_ptr++;
473 while (isspace((
unsigned char)*str_ptr) || (*str_ptr ==
',')) str_ptr++;
474 end_ptr = (
char *)str_ptr;
475 while (!(isspace((
unsigned char)*end_ptr) || (*end_ptr ==
',')) && (*end_ptr !=
'\0'))
477 memmove(data_offset, str_ptr, end_ptr - str_ptr);
478 data_offset[end_ptr-str_ptr] =
'\0';
479 if (data_offset[0] !=
'-' && isalpha((
unsigned char)data_offset[0])) {
480 if (data_offset == NULL) {
482 "var name for offset. \"offset\" argument supplied to "
483 "this function has to be non-NULL");
491 SCLogError(
"Malformed offset: %s", data_offset);
499 int bitmask_index = -1;
500 for (i = 3; i < (ret - 1); i++) {
501 if (args[i] != NULL) {
502 if (strcmp(
"relative", args[i]) == 0) {
504 }
else if (strcasecmp(
"string", args[i]) == 0) {
506 }
else if (strcasecmp(
"dec", args[i]) == 0) {
508 }
else if (strcasecmp(
"hex", args[i]) == 0) {
510 }
else if (strcasecmp(
"oct", args[i]) == 0) {
512 }
else if (strcasecmp(
"big", args[i]) == 0) {
517 }
else if (strcasecmp(
"little", args[i]) == 0) {
519 }
else if (strcasecmp(
"dce", args[i]) == 0) {
521 }
else if (strncasecmp(
"bitmask", args[i], strlen(
"bitmask")) == 0) {
532 if (!DetectBytetestValidateNbytes(data, nbytes, optstr)) {
537 data->
nbytes = (uint8_t)nbytes;
542 SCLogError(
"Malformed bitmask value: %s", args[bitmask_index] + strlen(
"bitmask"));
550 uint32_t bmask = data->
bitmask;
551 while (!(bmask & 0x1)){
558 for (i = 0; i < (ret - 1); i++){
560 pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
562 if (data_offset)
SCFree(data_offset);
564 pcre2_substring_free((PCRE2_UCHAR8 *)test_value);
565 pcre2_match_data_free(match);
569 for (i = 0; i < (ret - 1); i++){
571 pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
573 if (data_offset)
SCFree(data_offset);
575 pcre2_substring_free((PCRE2_UCHAR8 *)test_value);
578 pcre2_match_data_free(match);
613 if (prev_pm == NULL) {
632 if (prev_pm == NULL) {
652 "A byte_test keyword with dce holds other invalid modifiers.");
661 "seen in byte_test - %s",
675 "seen in byte_test - %s",
685 if (nbytes != NULL) {
689 "seen in byte_test - %s",
729 DetectBytetestFree(
de_ctx, data);
753 static int g_file_data_buffer_id = 0;
754 static int g_dce_stub_data_buffer_id = 0;
760 static int DetectBytetestTestParse01(
void)
764 data = DetectBytetestParse(
"4, =, 1 , 0", NULL, NULL, NULL);
766 DetectBytetestFree(NULL, data);
776 static int DetectBytetestTestParse02(
void)
780 data = DetectBytetestParse(
"4, !=, 1, 0", NULL, NULL, NULL);
784 && (data->
value == 1)
791 DetectBytetestFree(NULL, data);
800 static int DetectBytetestTestParse03(
void)
804 data = DetectBytetestParse(
"4, !=, 1, 0, relative", NULL, NULL, NULL);
808 && (data->
value == 1)
816 DetectBytetestFree(NULL, data);
825 static int DetectBytetestTestParse04(
void)
829 data = DetectBytetestParse(
"4, !=, 1, 0, string, oct", NULL, NULL, NULL);
833 && (data->
value == 1)
841 DetectBytetestFree(NULL, data);
850 static int DetectBytetestTestParse05(
void)
854 data = DetectBytetestParse(
"4, =, 1, 0, string, dec", NULL, NULL, NULL);
858 && (data->
value == 1)
865 DetectBytetestFree(NULL, data);
874 static int DetectBytetestTestParse06(
void)
878 data = DetectBytetestParse(
"4, >, 1, 0, string, hex", NULL, NULL, NULL);
882 && (data->
value == 1)
889 DetectBytetestFree(NULL, data);
898 static int DetectBytetestTestParse07(
void)
902 data = DetectBytetestParse(
"4, <, 5, 0, big", NULL, NULL, NULL);
906 && (data->
value == 5)
913 DetectBytetestFree(NULL, data);
922 static int DetectBytetestTestParse08(
void)
926 data = DetectBytetestParse(
"4, <, 5, 0, little", NULL, NULL, NULL);
930 && (data->
value == 5)
937 DetectBytetestFree(NULL, data);
946 static int DetectBytetestTestParse09(
void)
950 data = DetectBytetestParse(
"4, !, 5, 0", NULL, NULL, NULL);
954 && (data->
value == 5)
961 DetectBytetestFree(NULL, data);
970 static int DetectBytetestTestParse10(
void)
974 data = DetectBytetestParse(
" 4 , ! &, 5 , 0 , little ", NULL, NULL, NULL);
978 && (data->
value == 5)
986 DetectBytetestFree(NULL, data);
995 static int DetectBytetestTestParse11(
void)
999 data = DetectBytetestParse(
"4,!^,5,0,little,string,relative,hex", NULL, NULL, NULL);
1003 && (data->
value == 5)
1013 DetectBytetestFree(NULL, data);
1022 static int DetectBytetestTestParse12(
void)
1026 data = DetectBytetestParse(
"4, =, 1, 0, hex", NULL, NULL, NULL);
1037 static int DetectBytetestTestParse13(
void)
1041 data = DetectBytetestParse(
"9, =, 1, 0", NULL, NULL, NULL);
1052 static int DetectBytetestTestParse14(
void)
1056 data = DetectBytetestParse(
"23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL, NULL);
1060 && (data->
value == 0xffffffffffffffffULL)
1067 DetectBytetestFree(NULL, data);
1076 static int DetectBytetestTestParse15(
void)
1080 data = DetectBytetestParse(
"24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL, NULL);
1091 static int DetectBytetestTestParse16(
void)
1095 data = DetectBytetestParse(
"4,=,0,0xffffffffffffffffULL", NULL, NULL, NULL);
1106 static int DetectBytetestTestParse17(
void)
1110 data = DetectBytetestParse(
"4, <, 5, 0, dce", NULL, NULL, NULL);
1114 (data->
value == 5) &&
1119 DetectBytetestFree(NULL, data);
1128 static int DetectBytetestTestParse18(
void)
1132 data = DetectBytetestParse(
"4, <, 5, 0", NULL, NULL, NULL);
1136 (data->
value == 5) &&
1141 DetectBytetestFree(NULL, data);
1150 static int DetectBytetestTestParse19(
void)
1163 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,dce") == 0);
1164 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,string,dce") == -1);
1165 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,big,dce") == -1);
1166 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,little,dce") == -1);
1167 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,hex,dce") == -1);
1168 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,oct,dce") == -1);
1169 result &= (DetectBytetestSetup(NULL, s,
"1,=,1,6,dec,dce") == -1);
1178 static int DetectBytetestTestParse20(
void)
1191 "(msg:\"Testing bytetest_body\"; "
1192 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1194 "content:\"one\"; distance:0; "
1195 "byte_test:1,=,1,6,relative,dce; sid:1;)");
1219 "(msg:\"Testing bytetest_body\"; "
1220 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1222 "content:\"one\"; distance:0; "
1223 "byte_test:1,=,1,6,relative,dce; sid:1;)");
1224 if (s->
next == NULL) {
1246 "(msg:\"Testing bytetest_body\"; "
1247 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1249 "content:\"one\"; distance:0; "
1250 "byte_test:1,=,1,6,relative; sid:1;)");
1251 if (s->
next == NULL) {
1282 static int DetectBytetestTestParse21(
void)
1294 "(msg:\"Testing bytetest_body\"; "
1295 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1296 "content:\"one\"; byte_test:1,=,1,6,string,dce; sid:1;)");
1303 "(msg:\"Testing bytetest_body\"; "
1304 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1305 "content:\"one\"; byte_test:1,=,1,6,big,dce; sid:1;)");
1312 "(msg:\"Testing bytetest_body\"; "
1313 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1314 "content:\"one\"; byte_test:1,=,1,6,little,dce; sid:1;)");
1321 "(msg:\"Testing bytetest_body\"; "
1322 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1323 "content:\"one\"; byte_test:1,=,1,6,hex,dce; sid:1;)");
1330 "(msg:\"Testing bytetest_body\"; "
1331 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1332 "content:\"one\"; byte_test:1,=,1,6,dec,dce; sid:1;)");
1339 "(msg:\"Testing bytetest_body\"; "
1340 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1341 "content:\"one\"; byte_test:1,=,1,6,oct,dce; sid:1;)");
1348 "(msg:\"Testing bytetest_body\"; "
1349 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1350 "content:\"one\"; byte_test:1,=,1,6,string,hex,dce; sid:1;)");
1357 "(msg:\"Testing bytetest_body\"; "
1358 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1359 "content:\"one\"; byte_test:1,=,1,6,big,string,hex,dce; sid:1;)");
1366 "(msg:\"Testing bytetest_body\"; "
1367 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1368 "content:\"one\"; byte_test:1,=,1,6,big,string,oct,dce; sid:1;)");
1375 "(msg:\"Testing bytetest_body\"; "
1376 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1377 "content:\"one\"; byte_test:1,=,1,6,little,string,hex,dce; sid:1;)");
1384 "(msg:\"Testing bytetest_body\"; "
1385 "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1386 "content:\"one\"; byte_test:1,=,1,6,big,string,dec,dce; sid:1;)");
1403 static int DetectBytetestTestParse22(
void)
1416 "(file_data; byte_test:1,=,1,6,relative; sid:1;)");
1418 printf(
"sig parse failed: ");
1433 printf(
"wrong flags: ");
1449 static int DetectBytetestTestParse23(
void)
1452 data = DetectBytetestParse(
"4, <, 5, 0, bitmask 0xf8", NULL, NULL, NULL);
1463 DetectBytetestFree(NULL, data);
1471 static int DetectBytetestTestParse24(
void)
1474 data = DetectBytetestParse(
1475 "4, !<, 5, 0, relative,string,hex, big, bitmask 0xf8", NULL, NULL, NULL);
1489 DetectBytetestFree(NULL, data);
1497 static void DetectBytetestRegisterTests(
void)
1502 UtRegisterTest(
"DetectBytetestTestParse01", DetectBytetestTestParse01);
1503 UtRegisterTest(
"DetectBytetestTestParse02", DetectBytetestTestParse02);
1504 UtRegisterTest(
"DetectBytetestTestParse03", DetectBytetestTestParse03);
1505 UtRegisterTest(
"DetectBytetestTestParse04", DetectBytetestTestParse04);
1506 UtRegisterTest(
"DetectBytetestTestParse05", DetectBytetestTestParse05);
1507 UtRegisterTest(
"DetectBytetestTestParse06", DetectBytetestTestParse06);
1508 UtRegisterTest(
"DetectBytetestTestParse07", DetectBytetestTestParse07);
1509 UtRegisterTest(
"DetectBytetestTestParse08", DetectBytetestTestParse08);
1510 UtRegisterTest(
"DetectBytetestTestParse09", DetectBytetestTestParse09);
1511 UtRegisterTest(
"DetectBytetestTestParse10", DetectBytetestTestParse10);
1512 UtRegisterTest(
"DetectBytetestTestParse11", DetectBytetestTestParse11);
1513 UtRegisterTest(
"DetectBytetestTestParse12", DetectBytetestTestParse12);
1514 UtRegisterTest(
"DetectBytetestTestParse13", DetectBytetestTestParse13);
1515 UtRegisterTest(
"DetectBytetestTestParse14", DetectBytetestTestParse14);
1516 UtRegisterTest(
"DetectBytetestTestParse15", DetectBytetestTestParse15);
1517 UtRegisterTest(
"DetectBytetestTestParse16", DetectBytetestTestParse16);
1518 UtRegisterTest(
"DetectBytetestTestParse17", DetectBytetestTestParse17);
1519 UtRegisterTest(
"DetectBytetestTestParse18", DetectBytetestTestParse18);
1520 UtRegisterTest(
"DetectBytetestTestParse19", DetectBytetestTestParse19);
1521 UtRegisterTest(
"DetectBytetestTestParse20", DetectBytetestTestParse20);
1522 UtRegisterTest(
"DetectBytetestTestParse21", DetectBytetestTestParse21);
1523 UtRegisterTest(
"DetectBytetestTestParse22", DetectBytetestTestParse22);
1524 UtRegisterTest(
"DetectBytetestTestParse23", DetectBytetestTestParse23);
1525 UtRegisterTest(
"DetectBytetestTestParse24", DetectBytetestTestParse24);