... | ... |
@@ -3188,6 +3188,109 @@ static void ytable_delete(struct cli_ytable *ytable) |
3188 | 3188 |
} |
3189 | 3189 |
} |
3190 | 3190 |
|
3191 |
+static int yara_subhex_verify(const char *hexstr) |
|
3192 |
+{ |
|
3193 |
+ size_t max_sublen = 0; |
|
3194 |
+ const char *track = hexstr; |
|
3195 |
+ int in = 0; |
|
3196 |
+ |
|
3197 |
+ /* REQUIRES - subpatterns must be at least length 2 */ |
|
3198 |
+ while (*track != '\0' && max_sublen < 4) { |
|
3199 |
+ switch(*track) { |
|
3200 |
+ case '*': |
|
3201 |
+ case '?': |
|
3202 |
+ max_sublen = 0; |
|
3203 |
+ break; |
|
3204 |
+ case '[': |
|
3205 |
+ case '{': |
|
3206 |
+ if (in) { |
|
3207 |
+ cli_warnmsg("load_oneyara[verify]: string has invalid nesting\n"); |
|
3208 |
+ return CL_EMALFDB; |
|
3209 |
+ } |
|
3210 |
+ in = 1; |
|
3211 |
+ break; |
|
3212 |
+ case ']': |
|
3213 |
+ case '}': |
|
3214 |
+ if (!in) { |
|
3215 |
+ cli_warnmsg("load_oneyara[verify]: string has invalid sequence close\n"); |
|
3216 |
+ return CL_EMALFDB; |
|
3217 |
+ } |
|
3218 |
+ in = 0; |
|
3219 |
+ break; |
|
3220 |
+ default: |
|
3221 |
+ max_sublen++; |
|
3222 |
+ break; |
|
3223 |
+ } |
|
3224 |
+ |
|
3225 |
+ track++; |
|
3226 |
+ } |
|
3227 |
+ if (in) { |
|
3228 |
+ cli_warnmsg("load_oneyara[verify]: string has unterminated sequence\n"); |
|
3229 |
+ return CL_EMALFDB; |
|
3230 |
+ } |
|
3231 |
+ if (max_sublen < 4) { |
|
3232 |
+ cli_warnmsg("load_oneyara[verify]: cannot find a static subpattern of length 2\n"); |
|
3233 |
+ return CL_EMALFDB; |
|
3234 |
+ } |
|
3235 |
+ |
|
3236 |
+ return CL_SUCCESS; |
|
3237 |
+} |
|
3238 |
+ |
|
3239 |
+static int yara_altstr_verify(const char *hexstr) |
|
3240 |
+{ |
|
3241 |
+ cli_warnmsg("load_oneyara[verify]: string has alternating sequence\n"); |
|
3242 |
+ return 1; |
|
3243 |
+} |
|
3244 |
+ |
|
3245 |
+/* should only operate on HEX STRINGS */ |
|
3246 |
+static int yara_hexstr_verify(YR_STRING *string, const char *hexstr) |
|
3247 |
+{ |
|
3248 |
+ int ret = CL_SUCCESS; |
|
3249 |
+ char *hexcpy, *track, *alt; |
|
3250 |
+ |
|
3251 |
+ |
|
3252 |
+ /* Quick Check 1: NULL String */ |
|
3253 |
+ if (!hexstr || !string) { |
|
3254 |
+ cli_warnmsg("load_oneyara[verify]: string is empty\n"); |
|
3255 |
+ return CL_ENULLARG; |
|
3256 |
+ } |
|
3257 |
+ |
|
3258 |
+ /* Quick Check 2: String Too Short */ |
|
3259 |
+ if (strlen(hexstr)/2 < CLI_DEFAULT_AC_MINDEPTH) { |
|
3260 |
+ cli_warnmsg("load_oneyara[verify]: string is too short %s\n", string->identifier); |
|
3261 |
+ return CL_EMALFDB; |
|
3262 |
+ } |
|
3263 |
+ |
|
3264 |
+ /* Long Check: No Alternating Strings, Subhex must be Length 2 */ |
|
3265 |
+ hexcpy = cli_strdup(hexstr); |
|
3266 |
+ track = hexcpy; |
|
3267 |
+ while ((alt = strchr(track, '('))) { |
|
3268 |
+ char *start = alt+1; |
|
3269 |
+ *alt = '\0'; |
|
3270 |
+ |
|
3271 |
+ alt = strchr(start, ')'); |
|
3272 |
+ *alt = '\0'; |
|
3273 |
+ |
|
3274 |
+ ret = yara_subhex_verify(track); |
|
3275 |
+ if (ret != CL_SUCCESS) { |
|
3276 |
+ free(hexcpy); |
|
3277 |
+ return ret; |
|
3278 |
+ } |
|
3279 |
+ |
|
3280 |
+ ret = yara_altstr_verify(start); |
|
3281 |
+ if (ret != CL_SUCCESS) { |
|
3282 |
+ free(hexcpy); |
|
3283 |
+ return ret; |
|
3284 |
+ } |
|
3285 |
+ |
|
3286 |
+ track = alt+1; |
|
3287 |
+ } |
|
3288 |
+ ret = yara_subhex_verify(track); |
|
3289 |
+ free(hexcpy); |
|
3290 |
+ |
|
3291 |
+ return ret; |
|
3292 |
+} |
|
3293 |
+ |
|
3191 | 3294 |
static unsigned int yara_total, yara_loaded, yara_malform, yara_empty, yara_complex; |
3192 | 3295 |
#define YARATARGET0 "Target:0" |
3193 | 3296 |
#define YARATARGET1 "Target:1" |
... | ... |
@@ -3311,11 +3414,14 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op |
3311 | 3311 |
break; |
3312 | 3312 |
} |
3313 | 3313 |
|
3314 |
- if (strlen(substr)/2 < CLI_DEFAULT_AC_MINDEPTH) { |
|
3315 |
- cli_warnmsg("load_oneyara: string is too short %s\n", string->identifier); |
|
3314 |
+ /* handle lack of hexstr support here in order to suppress */ |
|
3315 |
+ ret = yara_hexstr_verify(string, substr); |
|
3316 |
+ if (ret != CL_SUCCESS) { |
|
3316 | 3317 |
str_error++; |
3317 | 3318 |
free(substr); |
3318 |
- continue; |
|
3319 |
+ /* suppress the error */ |
|
3320 |
+ ret = CL_SUCCESS; |
|
3321 |
+ break; |
|
3319 | 3322 |
} |
3320 | 3323 |
|
3321 | 3324 |
cli_yaramsg("load_oneyara: hex string: [%.*s] => [%s]\n", string->length, string->string, substr); |
... | ... |
@@ -3384,7 +3490,7 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op |
3384 | 3384 |
if (STRING_IS_NO_CASE(string)) { |
3385 | 3385 |
cli_yaramsg("STRING_IS_NO_CASE %s\n", STRING_IS_SINGLE_MATCH(string) ? "yes" : "no"); |
3386 | 3386 |
if ((ret = ytable_add_attrib(&ytable, NULL, "i", 1)) != CL_SUCCESS) { |
3387 |
- cli_yaramsg("load_oneyara: failed to add 'nocase' sigopt\n"); |
|
3387 |
+ cli_warnmsg("load_oneyara: failed to add 'nocase' sigopt\n"); |
|
3388 | 3388 |
str_error++; |
3389 | 3389 |
break; |
3390 | 3390 |
} |
... | ... |
@@ -3392,15 +3498,21 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op |
3392 | 3392 |
if (STRING_IS_ASCII(string)) { |
3393 | 3393 |
cli_yaramsg("STRING_IS_ASCII %s\n", STRING_IS_SINGLE_MATCH(string) ? "yes" : "no"); |
3394 | 3394 |
if ((ret = ytable_add_attrib(&ytable, NULL, "a", 1)) != CL_SUCCESS) { |
3395 |
- cli_yaramsg("load_oneyara: failed to add 'ascii' sigopt\n"); |
|
3395 |
+ cli_warnmsg("load_oneyara: failed to add 'ascii' sigopt\n"); |
|
3396 | 3396 |
str_error++; |
3397 | 3397 |
break; |
3398 | 3398 |
} |
3399 | 3399 |
} |
3400 | 3400 |
if (STRING_IS_WIDE(string)) { |
3401 | 3401 |
cli_yaramsg("STRING_IS_WIDE %s\n", STRING_IS_SINGLE_MATCH(string) ? "yes" : "no"); |
3402 |
+ /* handle lack of 'wide' support for regex here in order to suppress */ |
|
3403 |
+ if (STRING_IS_REGEXP(string)) { |
|
3404 |
+ cli_warnmsg("load_oneyara[verify]: wide modifier [w] is not supported for regex subsigs\n"); |
|
3405 |
+ str_error++; |
|
3406 |
+ break; |
|
3407 |
+ } |
|
3402 | 3408 |
if ((ret = ytable_add_attrib(&ytable, NULL, "w", 1)) != CL_SUCCESS) { |
3403 |
- cli_yaramsg("load_oneyara: failed to add 'wide' sigopt\n"); |
|
3409 |
+ cli_warnmsg("load_oneyara: failed to add 'wide' sigopt\n"); |
|
3404 | 3410 |
str_error++; |
3405 | 3411 |
break; |
3406 | 3412 |
} |
... | ... |
@@ -3408,7 +3520,7 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op |
3408 | 3408 |
if (STRING_IS_FULL_WORD(string)) { |
3409 | 3409 |
cli_yaramsg("STRING_IS_FULL_WORD %s\n", STRING_IS_SINGLE_MATCH(string) ? "yes" : "no"); |
3410 | 3410 |
if ((ret = ytable_add_attrib(&ytable, NULL, "f", 1)) != CL_SUCCESS) { |
3411 |
- cli_yaramsg("load_oneyara: failed to add 'fullword' sigopt\n"); |
|
3411 |
+ cli_warnmsg("load_oneyara: failed to add 'fullword' sigopt\n"); |
|
3412 | 3412 |
str_error++; |
3413 | 3413 |
break; |
3414 | 3414 |
} |