mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
bb11805 fix multiple results. Refactor false positive and heuristic precedence logic.
This commit is contained in:
parent
21ef08e3e6
commit
cbf5017a7d
22 changed files with 363 additions and 290 deletions
|
@ -116,7 +116,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
|
|||
|
||||
if (d == NULL)
|
||||
return;
|
||||
if (!(d->options & CL_SCAN_ALLMATCHES))
|
||||
if (!(d->options & CL_SCAN_ALLMATCHES) && !(d->options & CL_SCAN_HEURISTIC_PRECEDENCE))
|
||||
return;
|
||||
if (virname == NULL)
|
||||
return;
|
||||
|
@ -124,6 +124,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
|
|||
fname = (c && c->filename) ? c->filename : "(filename not set)";
|
||||
|
||||
if (virname) {
|
||||
d->infected++;
|
||||
conn_reply_virus(d->conn, fname, virname);
|
||||
if(c->virsize > 0 && optget(d->opts, "ExtendedDetectionInfo")->enabled)
|
||||
logg("~%s: %s(%s:%llu) FOUND\n", fname, virname, c->virhash, c->virsize);
|
||||
|
@ -274,19 +275,18 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
|
|||
}
|
||||
|
||||
if (ret == CL_VIRUS) {
|
||||
scandata->infected++;
|
||||
|
||||
if (scandata->options & CL_SCAN_ALLMATCHES) {
|
||||
if (scandata->options & CL_SCAN_ALLMATCHES || (scandata->infected && scandata->options & CL_SCAN_HEURISTIC_PRECEDENCE)) {
|
||||
if(optget(scandata->opts, "PreludeEnable")->enabled){
|
||||
prelude_logging(filename, virname, context.virhash, context.virsize);
|
||||
}
|
||||
virusaction(filename, virname, scandata->opts);
|
||||
} else {
|
||||
scandata->infected++;
|
||||
if (conn_reply_virus(scandata->conn, filename, virname) == -1) {
|
||||
free(filename);
|
||||
return CL_ETIMEOUT;
|
||||
}
|
||||
|
||||
if(optget(scandata->opts, "PreludeEnable")->enabled){
|
||||
prelude_logging(filename, virname, context.virhash, context.virsize);
|
||||
}
|
||||
|
|
|
@ -108,11 +108,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
|
|||
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
||||
if(res == SZ_ERROR_ENCRYPTED && DETECT_ENCRYPTED) {
|
||||
cli_dbgmsg("cli_7unz: Encrypted header found in archive.\n");
|
||||
cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
|
||||
viruses_found++;
|
||||
if(!SCAN_ALL) {
|
||||
found = CL_VIRUS;
|
||||
}
|
||||
found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
|
||||
} else if(res == SZ_OK) {
|
||||
UInt32 i, blockIndex = 0xFFFFFFFF;
|
||||
Byte *outBuffer = 0;
|
||||
|
@ -164,10 +160,12 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
|
|||
encrypted = 1;
|
||||
if(DETECT_ENCRYPTED) {
|
||||
cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n");
|
||||
cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
|
||||
found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
|
||||
if (found != CL_CLEAN) {
|
||||
if (found == CL_VIRUS) {
|
||||
if (SCAN_ALL)
|
||||
viruses_found++;
|
||||
if(!SCAN_ALL) {
|
||||
found = CL_VIRUS;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,6 +248,7 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
|
|||
int ret = CL_CLEAN, tmp = CL_CLEAN;
|
||||
off_t pos;
|
||||
uint32_t max_prtns = 0;
|
||||
int virus_found = 0;
|
||||
|
||||
prtn_intxn_list_init(&prtncheck);
|
||||
|
||||
|
@ -286,35 +287,30 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
|
|||
|
||||
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount);
|
||||
if (tmp != CL_CLEAN) {
|
||||
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
|
||||
if (tmp == CL_VIRUS) {
|
||||
apm_parsemsg("Name: %s\n", (char*)aptable.name);
|
||||
apm_parsemsg("Type: %s\n", (char*)aptable.type);
|
||||
|
||||
cli_dbgmsg("cli_scanapm: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
ret = tmp;
|
||||
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
if (ret == CL_VIRUS)
|
||||
virus_found = 1;
|
||||
if (SCAN_ALL || ret == CL_CLEAN)
|
||||
tmp = 0;
|
||||
}
|
||||
else if (tmp == CL_VIRUS) {
|
||||
apm_parsemsg("Name: %s\n", (char*)aptable.name);
|
||||
apm_parsemsg("Type: %s\n", (char*)aptable.type);
|
||||
|
||||
cli_dbgmsg("cli_scanapm: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
else {
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return tmp;
|
||||
else
|
||||
goto leave;
|
||||
} else {
|
||||
ret = tmp;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
pos += sectorsize;
|
||||
}
|
||||
|
||||
leave:
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
if (virus_found)
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2810,11 +2810,10 @@ int cli_bytecode_runlsig(cli_ctx *cctx, struct cli_target_info *tinfo,
|
|||
if (ctx.virname) {
|
||||
int rc;
|
||||
cli_dbgmsg("Bytecode found virus: %s\n", ctx.virname);
|
||||
cli_append_virus(cctx, ctx.virname);
|
||||
if (!strncmp(ctx.virname, "BC.Heuristics", 13))
|
||||
rc = cli_found_possibly_unwanted(cctx);
|
||||
rc = cli_append_possibly_unwanted(cctx, ctx.virname);
|
||||
else
|
||||
rc = CL_VIRUS;
|
||||
rc = cli_append_virus(cctx, ctx.virname);
|
||||
cli_bytecode_context_clear(&ctx);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ struct cl_fmap {
|
|||
HANDLE fh;
|
||||
HANDLE mh;
|
||||
#endif
|
||||
unsigned char maphash[16];
|
||||
uint32_t placeholder_for_bitmap;
|
||||
};
|
||||
|
||||
|
|
|
@ -604,6 +604,7 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
|
|||
off_t pos;
|
||||
size_t maplen;
|
||||
uint32_t max_prtns = 0;
|
||||
int virus_found = 0;
|
||||
|
||||
maplen = (*ctx->fmap)->real_len;
|
||||
|
||||
|
@ -647,23 +648,19 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
|
|||
else {
|
||||
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, gpe.firstLBA, gpe.lastLBA - gpe.firstLBA + 1);
|
||||
if (tmp != CL_CLEAN) {
|
||||
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
|
||||
if (tmp == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scangpt: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
ret = tmp;
|
||||
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
if (ret == CL_VIRUS)
|
||||
virus_found = 1;
|
||||
if (SCAN_ALL || ret == CL_CLEAN)
|
||||
tmp = 0;
|
||||
}
|
||||
else if (tmp == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scangpt: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
else {
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return tmp;
|
||||
else
|
||||
goto leave;
|
||||
} else {
|
||||
ret = tmp;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -672,6 +669,9 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
|
|||
pos += hdr.tableEntrySize;
|
||||
}
|
||||
|
||||
leave:
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
if (virus_found)
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ struct macho_fat_arch
|
|||
if(matcher) \
|
||||
return -1; \
|
||||
if(DETECT_BROKEN) { \
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable"); \
|
||||
if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Broken.Executable")) \
|
||||
return CL_VIRUS; \
|
||||
} \
|
||||
return CL_EFORMAT
|
||||
|
|
|
@ -738,19 +738,18 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
|
|||
newres->offset = adjbuffer+p_res.match[0];
|
||||
*res = newres;
|
||||
} else {
|
||||
if (ctx && SCAN_ALL) {
|
||||
ret = CL_CLEAN;
|
||||
viruses_found = 1;
|
||||
cli_append_virus(ctx, (const char *)pm->virname);
|
||||
}
|
||||
if (ctx)
|
||||
ret = cli_append_virus(ctx, (const char *)pm->virname);
|
||||
if (virname)
|
||||
*virname = pm->virname;
|
||||
if (!ctx || !SCAN_ALL) {
|
||||
ret = CL_VIRUS;
|
||||
if (!ctx || !SCAN_ALL)
|
||||
if (ret != CL_CLEAN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* move off to the end of the match for next match; offset is relative to adjbuffer
|
||||
* NOTE: misses matches starting within the last match; TODO: start from start of last match? */
|
||||
|
|
|
@ -157,7 +157,8 @@ static inline int matcher_run(const struct cli_matcher *root,
|
|||
if (SCAN_ALL)
|
||||
viruses_found = 1;
|
||||
else {
|
||||
cli_append_virus(ctx, *virname);
|
||||
ret = cli_append_virus(ctx, *virname);
|
||||
if (ret != CL_CLEAN)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +170,8 @@ static inline int matcher_run(const struct cli_matcher *root,
|
|||
if (SCAN_ALL)
|
||||
viruses_found = 1;
|
||||
else {
|
||||
cli_append_virus(ctx, *virname);
|
||||
ret = cli_append_virus(ctx, *virname);
|
||||
if (ret != CL_CLEAN)
|
||||
return ret;
|
||||
}
|
||||
} else if (ret > CL_TYPENO && acmode & AC_SCAN_VIR)
|
||||
|
@ -227,7 +229,7 @@ static inline int matcher_run(const struct cli_matcher *root,
|
|||
/* end experimental fragment */
|
||||
|
||||
if (ctx && !SCAN_ALL && ret == CL_VIRUS)
|
||||
cli_append_virus(ctx, *virname);
|
||||
return cli_append_virus(ctx, *virname);
|
||||
if (ctx && SCAN_ALL && viruses_found)
|
||||
return CL_VIRUS;
|
||||
|
||||
|
@ -500,6 +502,11 @@ void cli_targetinfo(struct cli_target_info *info, unsigned int target, fmap_t *m
|
|||
}
|
||||
|
||||
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
|
||||
{
|
||||
return cli_checkfp_virus(digest, size, ctx, NULL);
|
||||
}
|
||||
|
||||
int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const char * vname)
|
||||
{
|
||||
char md5[33];
|
||||
unsigned int i;
|
||||
|
@ -525,11 +532,11 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
|
|||
sprintf(md5 + i * 2, "%02x", digest[i]);
|
||||
md5[32] = 0;
|
||||
cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size,
|
||||
cli_get_last_virus(ctx) ? cli_get_last_virus(ctx) : "Name");
|
||||
vname ? vname : "Name");
|
||||
}
|
||||
|
||||
if(cli_get_last_virus(ctx))
|
||||
do_dsig_check = strncmp("W32S.", cli_get_last_virus(ctx), 5);
|
||||
if(vname)
|
||||
do_dsig_check = strncmp("W32S.", vname, 5);
|
||||
|
||||
map = *ctx->fmap;
|
||||
have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size)
|
||||
|
@ -586,7 +593,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
|
|||
for(i=0; i<SHA1_HASH_SIZE; i++)
|
||||
sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]);
|
||||
|
||||
cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, cli_get_last_virus(ctx), ctx->entry_filename);
|
||||
cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, vname?vname:"noname", ctx->entry_filename);
|
||||
} else
|
||||
cli_errmsg("can't compute sha\n!");
|
||||
|
||||
|
@ -614,10 +621,10 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
|
|||
}
|
||||
|
||||
if (ctx->engine->cb_hash)
|
||||
ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, cli_get_last_virus(ctx), ctx->cb_ctx);
|
||||
ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, vname?vname:"noname", ctx->cb_ctx);
|
||||
|
||||
if (ctx->engine->cb_stats_add_sample)
|
||||
ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, §ions, ctx->engine->stats_data);
|
||||
ctx->engine->cb_stats_add_sample(vname?vname:"noname", digest, size, §ions, ctx->engine->stats_data);
|
||||
|
||||
if (sections.sections)
|
||||
free(sections.sections);
|
||||
|
@ -768,8 +775,9 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
|
|||
return CL_CLEAN;
|
||||
if(matchicon(ctx, &target_info->exeinfo, ac_lsig->tdb.icongrp1, ac_lsig->tdb.icongrp2) == CL_VIRUS) {
|
||||
if(!ac_lsig->bc_idx) {
|
||||
cli_append_virus(ctx, ac_lsig->virname);
|
||||
return CL_VIRUS;
|
||||
rc = cli_append_virus(ctx, ac_lsig->virname);
|
||||
if (rc != CL_CLEAN)
|
||||
return rc;
|
||||
} else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) {
|
||||
return CL_VIRUS;
|
||||
}
|
||||
|
@ -777,8 +785,9 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
|
|||
return CL_CLEAN;
|
||||
}
|
||||
if(!ac_lsig->bc_idx) {
|
||||
cli_append_virus(ctx, ac_lsig->virname);
|
||||
return CL_VIRUS;
|
||||
rc = cli_append_virus(ctx, ac_lsig->virname);
|
||||
if (rc != CL_CLEAN)
|
||||
return rc;
|
||||
}
|
||||
if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) {
|
||||
return CL_VIRUS;
|
||||
|
@ -808,7 +817,7 @@ static int yara_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
|
|||
if (ac_lsig->flag & CLI_LSIG_FLAG_PRIVATE) {
|
||||
rc = CL_CLEAN;
|
||||
} else {
|
||||
cli_append_virus(ctx, ac_lsig->virname);
|
||||
rc = cli_append_virus(ctx, ac_lsig->virname);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
@ -1172,17 +1181,16 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
|
|||
/* If matched size-based hash ... */
|
||||
if (found % 2) {
|
||||
viruses_found = 1;
|
||||
cli_append_virus(ctx, virname);
|
||||
if (!SCAN_ALL)
|
||||
ret = cli_append_virus(ctx, virname);
|
||||
if (!SCAN_ALL || ret != CL_CLEAN)
|
||||
break;
|
||||
virname = NULL;
|
||||
}
|
||||
/* If matched size-agnostic hash ... */
|
||||
if (found > 1) {
|
||||
viruses_found = 1;
|
||||
cli_append_virus(ctx, virname_w);
|
||||
|
||||
if (!SCAN_ALL)
|
||||
ret = cli_append_virus(ctx, virname_w);
|
||||
if (!SCAN_ALL || ret != CL_CLEAN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1228,6 +1236,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
|
|||
{
|
||||
const struct cli_cdb *cdb;
|
||||
unsigned int viruses_found = 0;
|
||||
int ret = CL_CLEAN;
|
||||
|
||||
cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n",
|
||||
cli_ftname(cli_get_container_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer,
|
||||
|
@ -1237,10 +1246,10 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
|
|||
if (ctx->engine->cb_meta(cli_ftname(cli_get_container_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) {
|
||||
cli_dbgmsg("inner file blacklisted by callback: %s\n", fname);
|
||||
|
||||
cli_append_virus(ctx, "Detected.By.Callback");
|
||||
ret = cli_append_virus(ctx, "Detected.By.Callback");
|
||||
viruses_found++;
|
||||
if(!SCAN_ALL)
|
||||
return CL_VIRUS;
|
||||
if(!SCAN_ALL || ret != CL_CLEAN)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(!ctx->engine || !(cdb = ctx->engine->cdb))
|
||||
|
@ -1273,10 +1282,10 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
|
|||
if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH))
|
||||
continue;
|
||||
|
||||
cli_append_virus(ctx, cdb->virname);
|
||||
ret = cli_append_virus(ctx, cdb->virname);
|
||||
viruses_found++;
|
||||
if(!SCAN_ALL)
|
||||
return CL_VIRUS;
|
||||
if(!SCAN_ALL || ret != CL_CLEAN)
|
||||
return ret;
|
||||
|
||||
} while((cdb = cdb->next));
|
||||
|
||||
|
|
|
@ -208,6 +208,7 @@ int cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acd
|
|||
int cli_caloff(const char *offstr, const struct cli_target_info *info, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
|
||||
|
||||
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx);
|
||||
int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const char * vname);
|
||||
|
||||
int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2);
|
||||
|
||||
|
|
|
@ -590,9 +590,8 @@ cli_parse_mbox(const char *dir, cli_ctx *ctx)
|
|||
|
||||
if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted &&
|
||||
(*ctx->virname == NULL || SCAN_ALL)) {
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.Email");
|
||||
retcode = cli_append_virus(ctx, "Heuristics.Phishing.Email");
|
||||
ctx->found_possibly_unwanted = 0;
|
||||
retcode = CL_VIRUS;
|
||||
}
|
||||
|
||||
cli_dbgmsg("cli_mbox returning %d\n", retcode);
|
||||
|
|
|
@ -502,23 +502,17 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size
|
|||
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, mbr.entries[i].firstLBA,
|
||||
mbr.entries[i].numLBA);
|
||||
if (tmp != CL_CLEAN) {
|
||||
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
|
||||
if (tmp == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
ret = tmp;
|
||||
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
if (SCAN_ALL || ret == CL_CLEAN)
|
||||
tmp = 0;
|
||||
}
|
||||
else if (tmp == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
else {
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return tmp;
|
||||
else
|
||||
goto leave;
|
||||
} else {
|
||||
ret = tmp;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,6 +541,7 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size
|
|||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return ret;
|
||||
}
|
||||
|
@ -559,6 +554,7 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
|
|||
unsigned i, pitxn;
|
||||
int ret = CL_CLEAN, tmp = CL_CLEAN, mbr_base = 0;
|
||||
off_t pos = 0, logiclba = 0;
|
||||
int virus_found = 0;
|
||||
|
||||
mbr_base = sectorsize - sizeof(struct mbr_boot_record);
|
||||
|
||||
|
@ -585,23 +581,19 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
|
|||
/* assume that logical record is first and extended is second */
|
||||
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, logiclba, ebr.entries[0].numLBA);
|
||||
if (tmp != CL_CLEAN) {
|
||||
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
|
||||
if (tmp == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scanebr: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
ret = tmp;
|
||||
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
if (ret == CL_VIRUS)
|
||||
virus_found = 1;
|
||||
if (SCAN_ALL || ret == CL_CLEAN)
|
||||
tmp = 0;
|
||||
}
|
||||
else if (tmp == CL_VIRUS) {
|
||||
cli_dbgmsg("cli_scanebr: detected intersection with partitions "
|
||||
"[%u, %u]\n", pitxn, i);
|
||||
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
else {
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
return tmp;
|
||||
else
|
||||
goto leave;
|
||||
} else {
|
||||
ret = tmp;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -616,6 +608,9 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
|
|||
++i;
|
||||
} while (logiclba != 0 && (*prtncount) < ctx->engine->maxpartitions);
|
||||
|
||||
leave:
|
||||
prtn_intxn_list_free(&prtncheck);
|
||||
if (virus_found)
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1088,16 +1088,40 @@ int cli_unlink(const char *pathname)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void cli_append_virus(cli_ctx * ctx, const char * virname)
|
||||
void cli_virus_found_cb(cli_ctx * ctx)
|
||||
{
|
||||
if (ctx->virname == NULL)
|
||||
return;
|
||||
if (ctx->limit_exceeded == 0 || SCAN_ALL) {
|
||||
if (ctx->engine->cb_virus_found)
|
||||
ctx->engine->cb_virus_found(fmap_fd(*ctx->fmap), virname, ctx->cb_ctx);
|
||||
ctx->engine->cb_virus_found(fmap_fd(*ctx->fmap), (const char *)*ctx->virname, ctx->cb_ctx);
|
||||
}
|
||||
|
||||
int cli_append_possibly_unwanted(cli_ctx * ctx, const char * virname)
|
||||
{
|
||||
if (SCAN_ALL)
|
||||
return cli_append_virus(ctx, virname);
|
||||
else if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE)
|
||||
return cli_append_virus(ctx, virname);
|
||||
else if (ctx->num_viruses == 0 && ctx->virname != NULL && *ctx->virname == NULL) {
|
||||
ctx->found_possibly_unwanted = 1;
|
||||
ctx->num_viruses++;
|
||||
*ctx->virname = virname;
|
||||
}
|
||||
return CL_CLEAN;
|
||||
}
|
||||
|
||||
int cli_append_virus(cli_ctx * ctx, const char * virname)
|
||||
{
|
||||
if (ctx->virname == NULL)
|
||||
return CL_CLEAN;
|
||||
if (ctx->fmap != NULL && (*ctx->fmap) != NULL && CL_VIRUS != cli_checkfp_virus((*ctx->fmap)->maphash, (*ctx->fmap)->len, ctx, virname))
|
||||
return CL_CLEAN;
|
||||
if (!SCAN_ALL && ctx->num_viruses != 0)
|
||||
if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE)
|
||||
return CL_CLEAN;
|
||||
if (ctx->limit_exceeded == 0 || SCAN_ALL) {
|
||||
ctx->num_viruses++;
|
||||
*ctx->virname = virname;
|
||||
cli_virus_found_cb(ctx);
|
||||
}
|
||||
#if HAVE_JSON
|
||||
if (SCAN_PROPERTIES && ctx->wrkproperty) {
|
||||
json_object *arrobj, *virobj;
|
||||
|
@ -1105,17 +1129,18 @@ void cli_append_virus(cli_ctx * ctx, const char * virname)
|
|||
arrobj = json_object_new_array();
|
||||
if (NULL == arrobj) {
|
||||
cli_errmsg("cli_append_virus: no memory for json virus array\n");
|
||||
return;
|
||||
return CL_EMEM;
|
||||
}
|
||||
json_object_object_add(ctx->wrkproperty, "Viruses", arrobj);
|
||||
}
|
||||
virobj = json_object_new_string(virname);
|
||||
if (NULL == virobj) {
|
||||
cli_errmsg("cli_append_virus: no memory for json virus name object\n");
|
||||
return;
|
||||
return CL_EMEM;
|
||||
}
|
||||
json_object_array_add(arrobj, virobj);
|
||||
}
|
||||
return CL_VIRUS;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -601,9 +601,10 @@ static inline void cli_writeint32(void *offset, uint32_t value)
|
|||
}
|
||||
#endif
|
||||
|
||||
void cli_append_virus(cli_ctx *ctx, const char *virname);
|
||||
int cli_append_virus(cli_ctx *ctx, const char *virname);
|
||||
const char *cli_get_last_virus(const cli_ctx *ctx);
|
||||
const char *cli_get_last_virus_str(const cli_ctx *ctx);
|
||||
void cli_virus_found_cb(cli_ctx *ctx);
|
||||
|
||||
void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size);
|
||||
cli_file_t cli_get_container_type(cli_ctx *ctx, int index);
|
||||
|
|
|
@ -2458,10 +2458,10 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
|||
|
||||
pdf_parseobj(&pdf, obj);
|
||||
if (SCAN_ALGO && obj->numfilters > PDF_FILTER_DTRIGGER) {
|
||||
cli_append_virus(ctx, "Heuristic.PDF.TooManyFilters");
|
||||
rc = cli_append_virus(ctx, "Heuristic.PDF.TooManyFilters");
|
||||
alerts++;
|
||||
if (!SCAN_ALL)
|
||||
rc = CL_VIRUS;
|
||||
if (SCAN_ALL && rc == CL_VIRUS)
|
||||
rc = CL_CLEAN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2479,8 +2479,8 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
|||
* a password to decrypt */
|
||||
cli_append_virus(ctx, "Heuristics.Encrypted.PDF");
|
||||
alerts++;
|
||||
if (!SCAN_ALL)
|
||||
rc = CL_VIRUS;
|
||||
if (SCAN_ALL && rc == CL_VIRUS)
|
||||
rc = CL_CLEAN;
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
|
@ -2547,8 +2547,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
|||
if (!rc && SCAN_ALGO && (ctx->dconf->other & OTHER_CONF_PDFNAMEOBJ)) {
|
||||
if (pdf.flags & (1 << ESCAPED_COMMON_PDFNAME)) {
|
||||
/* for example /Fl#61te#44#65#63#6f#64#65 instead of /FlateDecode */
|
||||
cli_append_virus(ctx, "Heuristics.PDF.ObfuscatedNameObject");
|
||||
rc = cli_found_possibly_unwanted(ctx);
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.PDF.ObfuscatedNameObject");
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
|
|
192
libclamav/pe.c
192
libclamav/pe.c
|
@ -555,7 +555,7 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section)
|
|||
if (cli_debug_flag) {
|
||||
md5 = hashset[CLI_HASH_MD5];
|
||||
if (md5) {
|
||||
cli_dbgmsg("MDB: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
cli_dbgmsg("MDB hashset: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
exe_section->rsz, md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7],
|
||||
md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);
|
||||
} else if (cli_always_gen_section_hash) {
|
||||
|
@ -589,16 +589,20 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section)
|
|||
/* Do scans */
|
||||
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
|
||||
if(foundsize[type] && cli_hm_scan(hashset[type], exe_section->rsz, &virname, mdb_sect, type) == CL_VIRUS) {
|
||||
cli_append_virus(ctx, virname);
|
||||
ret = CL_VIRUS;
|
||||
if (!SCAN_ALL) {
|
||||
ret = cli_append_virus(ctx, virname);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret != CL_VIRUS)
|
||||
break;
|
||||
else if (!SCAN_ALL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(foundwild[type] && cli_hm_scan_wild(hashset[type], &virname, mdb_sect, type) == CL_VIRUS) {
|
||||
cli_append_virus(ctx, virname);
|
||||
ret = CL_VIRUS;
|
||||
if (!SCAN_ALL) {
|
||||
ret = cli_append_virus(ctx, virname);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret != CL_VIRUS)
|
||||
break;
|
||||
else if (!SCAN_ALL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2209,10 +2213,10 @@ static int validate_impname(const char *name, uint32_t length, int dll)
|
|||
|
||||
static inline int hash_impfns(cli_ctx *ctx, void **hashctx, uint32_t *impsz, struct pe_image_import_descriptor *image, const char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first)
|
||||
{
|
||||
uint32_t thuoff, offset;
|
||||
uint32_t thuoff = 0, offset;
|
||||
fmap_t *map = *ctx->fmap;
|
||||
size_t dlllen = 0, fsize = map->len;
|
||||
int i, j, err, num_fns = 0, ret = CL_SUCCESS;
|
||||
int i, j, err = 0, num_fns = 0, ret = CL_SUCCESS;
|
||||
const char *buffer;
|
||||
enum CLI_HASH_TYPE type;
|
||||
#if HAVE_JSON
|
||||
|
@ -2557,16 +2561,22 @@ static int scan_pe_imp(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_
|
|||
/* Do scans */
|
||||
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
|
||||
if(cli_hm_scan(hashset[type], impsz, &virname, imp, type) == CL_VIRUS) {
|
||||
cli_append_virus(ctx, virname);
|
||||
ret = CL_VIRUS;
|
||||
if(!SCAN_ALL)
|
||||
ret = cli_append_virus(ctx, virname);
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret != CL_VIRUS)
|
||||
break;
|
||||
else if (!SCAN_ALL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cli_hm_scan_wild(hashset[type], &virname, imp, type) == CL_VIRUS) {
|
||||
cli_append_virus(ctx, virname);
|
||||
ret = CL_VIRUS;
|
||||
if(!SCAN_ALL)
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret != CL_VIRUS)
|
||||
break;
|
||||
else if (!SCAN_ALL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2759,8 +2769,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
cli_dbgmsg("Can't read new header address\n");
|
||||
/* truncated header? */
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -2775,7 +2785,7 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
|
||||
if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
|
||||
/* bad information in e_lfanew - probably not a PE file */
|
||||
cli_dbgmsg("Can't read file header\n");
|
||||
cli_dbgmsg("cli_scanpe: Can't read file header\n");
|
||||
return CL_CLEAN;
|
||||
}
|
||||
|
||||
|
@ -2908,8 +2918,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
pe_add_heuristic_property(ctx, "BadNumberOfSections");
|
||||
#endif
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(!ctx->corrupted_input) {
|
||||
|
@ -2945,8 +2955,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
#endif
|
||||
cli_dbgmsg("SizeOfOptionalHeader too small\n");
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -2956,8 +2966,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
|
||||
cli_dbgmsg("Can't read optional file header\n");
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -2974,8 +2984,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
|
||||
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -3044,8 +3054,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
|
||||
cli_dbgmsg("Can't read optional file header\n");
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -3168,14 +3178,14 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
|
||||
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) {
|
||||
cli_dbgmsg("Bad virtual alignment\n");
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) {
|
||||
cli_dbgmsg("Bad file alignment\n");
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
fsize = map->len;
|
||||
|
@ -3206,8 +3216,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
free(exe_sections);
|
||||
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -3251,8 +3261,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
free(exe_sections);
|
||||
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN; /* no ninjas to see here! move along! */
|
||||
|
@ -3324,10 +3334,10 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */
|
||||
cli_dbgmsg("VirtualAddress is misaligned\n");
|
||||
cli_dbgmsg("------------------------------------\n");
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
free(section_hdr);
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
|
||||
|
@ -3355,8 +3365,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
free(section_hdr);
|
||||
free(exe_sections);
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -3365,10 +3375,10 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
if(!i) {
|
||||
if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */
|
||||
cli_dbgmsg("First section is in the wrong place\n");
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
free(section_hdr);
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
min = exe_sections[i].rva;
|
||||
|
@ -3376,10 +3386,10 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
} else {
|
||||
if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
|
||||
cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
|
||||
cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
|
||||
free(section_hdr);
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(exe_sections[i].rva < min)
|
||||
|
@ -3398,8 +3408,8 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
cli_dbgmsg("EntryPoint out of file\n");
|
||||
free(exe_sections);
|
||||
if(DETECT_BROKEN_PE) {
|
||||
cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return CL_VIRUS;
|
||||
ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
|
@ -3517,13 +3527,20 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
if(pt) {
|
||||
pt += 15;
|
||||
if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
|
||||
cli_append_virus(ctx,"Heuristics.W32.Parite.B");
|
||||
ret = cli_append_virus(ctx,"Heuristics.W32.Parite.B");
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALL) {
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
else
|
||||
viruses_found++;
|
||||
} else {
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3635,15 +3652,21 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
break;
|
||||
case KZSLOOP:
|
||||
if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
|
||||
cli_append_virus(ctx,"Heuristics.W32.Kriz");
|
||||
ret = cli_append_virus(ctx,"Heuristics.W32.Kriz");
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALL) {
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
else
|
||||
viruses_found++;
|
||||
} else {
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
|
||||
kzstate++;
|
||||
}
|
||||
|
@ -3667,13 +3690,20 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
|
||||
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
|
||||
if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
|
||||
cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
|
||||
ret = cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALL) {
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
else
|
||||
viruses_found++;
|
||||
} else {
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
|
||||
|
@ -3682,13 +3712,20 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
|
||||
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
|
||||
if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
|
||||
cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
|
||||
ret = cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALL) {
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
else
|
||||
viruses_found++;
|
||||
} else {
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3752,14 +3789,22 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
continue;
|
||||
|
||||
if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
|
||||
cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
|
||||
ret = cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
|
||||
if (ret != CL_CLEAN) {
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALL) {
|
||||
free(jumps);
|
||||
free(exe_sections);
|
||||
return CL_VIRUS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
else
|
||||
viruses_found++;
|
||||
} else {
|
||||
free(jumps);
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3775,21 +3820,28 @@ int cli_scanpe(cli_ctx *ctx)
|
|||
ret = CL_CLEAN;
|
||||
|
||||
if (!stats) {
|
||||
ret = CL_EMEM;
|
||||
free(exe_sections);
|
||||
return CL_EMEM;
|
||||
} else {
|
||||
cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
|
||||
if ((ret = cli_detect_swizz(stats)) == CL_VIRUS)
|
||||
cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
|
||||
|
||||
free(stats);
|
||||
}
|
||||
if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) {
|
||||
ret = cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
|
||||
if (ret != CL_CLEAN) {
|
||||
if (!(ret == CL_VIRUS && SCAN_ALL)) {
|
||||
if (ret == CL_VIRUS) {
|
||||
if (!SCAN_ALL) {
|
||||
free(stats);
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
|
||||
else
|
||||
viruses_found++;
|
||||
} else {
|
||||
free(stats);
|
||||
free(exe_sections);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4982,7 +5034,7 @@ int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo)
|
|||
|
||||
if(fmap_readn(map, &file_hdr, peinfo->offset + e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
|
||||
/* bad information in e_lfanew - probably not a PE file */
|
||||
cli_dbgmsg("Can't read file header\n");
|
||||
cli_dbgmsg("cli_peheader: Can't read file header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -814,32 +814,31 @@ int phishingScan(cli_ctx* ctx,tag_arguments_t* hrefs)
|
|||
case CL_PHISH_CLEAN:
|
||||
continue;
|
||||
case CL_PHISH_NUMERIC_IP:
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP");
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP");
|
||||
break;
|
||||
case CL_PHISH_CLOAKED_NULL:
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/
|
||||
break;
|
||||
case CL_PHISH_SSL_SPOOF:
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.Email.SSL-Spoof");
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.SSL-Spoof");
|
||||
break;
|
||||
case CL_PHISH_CLOAKED_UIU:
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/
|
||||
break;
|
||||
case CL_PHISH_HASH0:
|
||||
cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net");
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net");
|
||||
break;
|
||||
case CL_PHISH_HASH1:
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.URL.Blacklisted");
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.URL.Blacklisted");
|
||||
break;
|
||||
case CL_PHISH_HASH2:
|
||||
cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net");
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net");
|
||||
break;
|
||||
case CL_PHISH_NOMATCH:
|
||||
default:
|
||||
cli_append_virus(ctx, "Heuristics.Phishing.Email.SpoofedDomain");
|
||||
cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.SpoofedDomain");
|
||||
break;
|
||||
}
|
||||
return cli_found_possibly_unwanted(ctx);
|
||||
}
|
||||
return CL_CLEAN;
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx
|
|||
cli_dbgmsg("RAR: Encrypted files found in archive.\n");
|
||||
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
|
||||
if(ret != CL_VIRUS) {
|
||||
cli_append_virus(ctx, "Heuristics.Encrypted.RAR");
|
||||
if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR"))
|
||||
return CL_VIRUS;
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
|
|||
}
|
||||
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
|
||||
if(ret != CL_VIRUS)
|
||||
cli_append_virus(ctx, "Heuristics.Encrypted.RAR");
|
||||
if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR"))
|
||||
return CL_VIRUS;
|
||||
}
|
||||
return CL_CLEAN;
|
||||
|
@ -1179,8 +1179,8 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
|
|||
cli_jsonbool(ctx->wrkproperty, "HasMacros", 1);
|
||||
#endif
|
||||
if(BLOCK_MACROS && hasmacros) {
|
||||
cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros");
|
||||
ret = CL_VIRUS;
|
||||
ret = cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros");
|
||||
if (ret == CL_VIRUS)
|
||||
viruses_found++;
|
||||
}
|
||||
if (SCAN_ALL && viruses_found)
|
||||
|
@ -1611,10 +1611,8 @@ static int cli_scanriff(cli_ctx *ctx)
|
|||
{
|
||||
int ret = CL_CLEAN;
|
||||
|
||||
if(cli_check_riff_exploit(ctx) == 2) {
|
||||
ret = CL_VIRUS;
|
||||
cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002");
|
||||
}
|
||||
if (cli_check_riff_exploit(ctx) == 2)
|
||||
ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1623,10 +1621,8 @@ static int cli_scanjpeg(cli_ctx *ctx)
|
|||
{
|
||||
int ret = CL_CLEAN;
|
||||
|
||||
if(cli_check_jpeg_exploit(ctx, 0) == 1) {
|
||||
ret = CL_VIRUS;
|
||||
cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028");
|
||||
}
|
||||
if(cli_check_jpeg_exploit(ctx, 0) == 1)
|
||||
ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1872,7 +1868,7 @@ static int cli_scan_structured(cli_ctx *ctx)
|
|||
|
||||
if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) {
|
||||
cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count);
|
||||
cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber");
|
||||
if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber"))
|
||||
if (SCAN_ALL)
|
||||
viruses_found++;
|
||||
else
|
||||
|
@ -1881,7 +1877,7 @@ static int cli_scan_structured(cli_ctx *ctx)
|
|||
|
||||
if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) {
|
||||
cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count);
|
||||
cli_append_virus(ctx,"Heuristics.Structured.SSN");
|
||||
if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.SSN"))
|
||||
if (SCAN_ALL)
|
||||
viruses_found++;
|
||||
else
|
||||
|
@ -2161,32 +2157,32 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
|
|||
case CL_TYPE_MHTML:
|
||||
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) {
|
||||
cli_dbgmsg("MHTML signature found at %u\n", (unsigned int) fpt->offset);
|
||||
ret = cli_scanmail(ctx);
|
||||
nret = ret = cli_scanmail(ctx);
|
||||
}
|
||||
break;
|
||||
|
||||
case CL_TYPE_XDP:
|
||||
if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) {
|
||||
cli_dbgmsg("XDP signature found at %u\n", (unsigned int) fpt->offset);
|
||||
ret = cli_scanxdp(ctx);
|
||||
nret = ret = cli_scanxdp(ctx);
|
||||
}
|
||||
break;
|
||||
case CL_TYPE_XML_WORD:
|
||||
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) {
|
||||
cli_dbgmsg("XML-WORD signature found at %u\n", (unsigned int) fpt->offset);
|
||||
ret = cli_scanmsxml(ctx);
|
||||
nret = ret = cli_scanmsxml(ctx);
|
||||
}
|
||||
break;
|
||||
case CL_TYPE_XML_XL:
|
||||
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) {
|
||||
cli_dbgmsg("XML-XL signature found at %u\n", (unsigned int) fpt->offset);
|
||||
ret = cli_scanmsxml(ctx);
|
||||
nret = ret = cli_scanmsxml(ctx);
|
||||
}
|
||||
break;
|
||||
case CL_TYPE_XML_HWP:
|
||||
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) {
|
||||
cli_dbgmsg("XML-HWP signature found at %u\n", (unsigned int) fpt->offset);
|
||||
ret = cli_scanhwpml(ctx);
|
||||
nret = ret = cli_scanhwpml(ctx);
|
||||
}
|
||||
break;
|
||||
case CL_TYPE_RARSFX:
|
||||
|
@ -2441,10 +2437,16 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char *
|
|||
|
||||
UNUSEDPARAM(type);
|
||||
|
||||
if (retcode == CL_CLEAN && (ctx->found_possibly_unwanted || ctx->num_viruses != 0))
|
||||
if (retcode == CL_CLEAN && ctx->found_possibly_unwanted) {
|
||||
cli_virus_found_cb(ctx);
|
||||
cb_retcode = CL_VIRUS;
|
||||
}
|
||||
else {
|
||||
if (retcode == CL_CLEAN && ctx->num_viruses != 0)
|
||||
cb_retcode = CL_VIRUS;
|
||||
else
|
||||
cb_retcode = retcode;
|
||||
}
|
||||
|
||||
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__);
|
||||
if(ctx->engine->cb_post_scan) {
|
||||
|
@ -2689,6 +2691,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
|
|||
|
||||
perf_stop(ctx, PERFT_CACHE);
|
||||
hashed_size = (*ctx->fmap)->len;
|
||||
memcpy((*ctx->fmap)->maphash, hash, 16);
|
||||
ctx->hook_lsig_matches = NULL;
|
||||
|
||||
if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
|
||||
|
|
|
@ -90,8 +90,7 @@ int cli_check_mydoom_log(cli_ctx *ctx)
|
|||
if ((~check) != key)
|
||||
return CL_CLEAN;
|
||||
|
||||
cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log");
|
||||
return CL_VIRUS;
|
||||
return cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log");
|
||||
}
|
||||
|
||||
static int jpeg_check_photoshop_8bim(cli_ctx *ctx, off_t *off)
|
||||
|
|
|
@ -146,8 +146,7 @@ int cli_parsetiff(cli_ctx *ctx)
|
|||
if(entry.value + value_size > map->len) {
|
||||
cli_warnmsg("cli_parsetiff: TFD entry field %u exceeds bounds of TIFF file [%llu > %llu]\n",
|
||||
i, (long long unsigned)(entry.value + value_size), (long long unsigned)map->len);
|
||||
cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess");
|
||||
return CL_VIRUS;
|
||||
return cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -556,9 +556,8 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
|
|||
|
||||
if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) {
|
||||
cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n");
|
||||
cli_append_virus(ctx, "Heuristics.Encrypted.Zip");
|
||||
*ret = CL_VIRUS;
|
||||
if (!SCAN_ALL) {
|
||||
*ret = cli_append_virus(ctx, "Heuristics.Encrypted.Zip");
|
||||
if ((*ret == CL_VIRUS && !SCAN_ALL) || *ret != CL_CLEAN) {
|
||||
fmap_unneed_off(map, loff, SIZEOF_LH);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -461,27 +461,27 @@ static void do_phishing_test_allscan(const struct rtest *rtest)
|
|||
fail_unless(rc == CL_CLEAN,"phishingScan");
|
||||
switch(rtest->result) {
|
||||
case 0:
|
||||
fail_unless_fmt(ctx.found_possibly_unwanted,
|
||||
fail_unless_fmt(ctx.num_viruses,
|
||||
"this should be phishing, realURL: %s, displayURL: %s",
|
||||
rtest->realurl, rtest->displayurl);
|
||||
break;
|
||||
case 1:
|
||||
fail_unless_fmt(!ctx.found_possibly_unwanted,
|
||||
fail_unless_fmt(!ctx.num_viruses,
|
||||
"this should be whitelisted, realURL: %s, displayURL: %s",
|
||||
rtest->realurl, rtest->displayurl);
|
||||
break;
|
||||
case 2:
|
||||
fail_unless_fmt(!ctx.found_possibly_unwanted,
|
||||
fail_unless_fmt(!ctx.num_viruses,
|
||||
"this should be clean, realURL: %s, displayURL: %s",
|
||||
rtest->realurl, rtest->displayurl);
|
||||
break;
|
||||
case 3:
|
||||
if(!loaded_2)
|
||||
fail_unless_fmt(!ctx.found_possibly_unwanted,
|
||||
fail_unless_fmt(!ctx.num_viruses,
|
||||
"this should be clean, realURL: %s, displayURL: %s",
|
||||
rtest->realurl, rtest->displayurl);
|
||||
else {
|
||||
fail_unless_fmt(ctx.found_possibly_unwanted,
|
||||
fail_unless_fmt(ctx.num_viruses,
|
||||
"this should be blacklisted, realURL: %s, displayURL: %s",
|
||||
rtest->realurl, rtest->displayurl);
|
||||
if (*ctx.virname)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue