185
185
if(DETECT_ENCRYPTED && metadata->encrypted) {
186
186
cli_dbgmsg("RAR: Encrypted files found in archive.\n");
187
187
lseek(desc, 0, SEEK_SET);
188
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR);
188
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
189
189
if(ret != CL_VIRUS) {
190
190
*ctx->virname = "Heuristics.Encrypted.RAR";
227
227
cli_dbgmsg("RAR: Encrypted main header\n");
228
228
if(DETECT_ENCRYPTED) {
229
229
lseek(desc, 0, SEEK_SET);
230
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR);
230
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
231
231
if(ret != CL_VIRUS)
232
232
*ctx->virname = "Heuristics.Encrypted.RAR";
733
734
if(ctx->engine->maxscansize && ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize)
734
735
file->max_size = ctx->engine->maxscansize - ctx->scansize;
736
file->max_size = ctx->engine->maxfilesize;
737
file->max_size = ctx->engine->maxfilesize ? ctx->engine->maxfilesize : 0xffffffff;
738
739
cli_dbgmsg("CAB: Extracting file %s to %s, size %u, max_size: %u\n", file->name, tempname, file->length, (unsigned int) file->max_size);
739
740
file->written_size = 0;
740
741
if((ret = cab_extract(file, tempname))) {
741
742
cli_dbgmsg("CAB: Failed to extract file: %s\n", cl_strerror(ret));
743
if(file->length != file->written_size)
744
corrupted_input = ctx->corrupted_input;
745
if(file->length != file->written_size) {
744
746
cli_dbgmsg("CAB: Length from header %u but wrote %u bytes\n", (unsigned int) file->length, (unsigned int) file->written_size);
747
ctx->corrupted_input = 1;
746
749
ret = cli_scanfile(tempname, ctx);
750
ctx->corrupted_input = corrupted_input;
748
752
if(!ctx->engine->keeptmp) {
749
if (cli_unlink(tempname)) {
753
if (!access(tempname, R_OK) && cli_unlink(tempname)) {
751
755
ret = CL_EUNLINK;
976
980
snprintf(fullname, 1024, "%s"PATHSEP"nocomment.html", tempname);
977
981
fd = open(fullname, O_RDONLY|O_BINARY);
979
ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
983
ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
986
990
snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname);
987
991
fd = open(fullname, O_RDONLY|O_BINARY);
989
ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
993
ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
995
999
snprintf(fullname, 1024, "%s"PATHSEP"javascript", tempname);
996
1000
fd = open(fullname, O_RDONLY|O_BINARY);
998
ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
1002
ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
999
1003
if (ret == CL_CLEAN) {
1000
1004
lseek(fd, 0, SEEK_SET);
1001
ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR);
1005
ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL);
1023
1027
struct text_norm_state state;
1024
1028
char *tmpname = NULL;
1025
1029
int ofd = -1, ret;
1026
const struct cli_matcher *troot = ctx->engine->root[7];
1030
struct cli_matcher *troot = ctx->engine->root[7];
1027
1031
uint32_t maxpatlen = troot ? troot->maxpatlen : 0, offset = 0;
1028
1032
struct cli_matcher *groot = ctx->engine->root[0];
1029
1033
struct cli_ac_data gmdata, tmdata;
1096
1101
cli_dbgmsg("cli_scanscript: short read during normalizing\n");
1104
if(ctx->engine->keeptmp) {
1109
if(ret != CL_VIRUS) {
1110
ret = cli_lsig_eval(ctx, troot, &tmdata, NULL);
1112
ret = cli_lsig_eval(ctx, groot, &gmdata, NULL);
1099
1114
cli_ac_freedata(&tmdata);
1100
1115
cli_ac_freedata(&gmdata);
1101
if(ctx->engine->keeptmp) {
1619
1629
return CL_CLEAN;
1622
static int cli_scanembpe(int desc, cli_ctx *ctx)
1632
static int cli_scanembpe(cli_ctx *ctx, off_t offset)
1624
1634
int fd, bytes, ret = CL_CLEAN;
1625
unsigned long int size = 0;
1635
unsigned long int size = 0, todo;
1638
fmap_t *map = *ctx->fmap;
1629
1640
tmpname = cli_gentemp(ctx->engine->tmpdir);
1636
1647
return CL_ECREAT;
1639
while((bytes = read(desc, buff, sizeof(buff))) > 0) {
1650
todo = map->len - offset;
1652
bytes = MIN(todo, map->pgsz);
1656
if(!(buff = fmap_need_off_once(map, offset + size, bytes))) {
1658
if(!ctx->engine->keeptmp) {
1659
if (cli_unlink(tmpname)) {
1642
if(cli_checklimits("cli_scanembpe", ctx, size + sizeof(buff), 0, 0)!=CL_CLEAN)
1670
if(cli_checklimits("cli_scanembpe", ctx, size, 0, 0)!=CL_CLEAN)
1645
1673
if(cli_writen(fd, buff, bytes) != bytes) {
1704
1732
acmode |= AC_SCAN_FT;
1706
ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, refhash);
1734
ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, NULL, refhash);
1708
1736
if(ret >= CL_TYPENO) {
1709
1737
ctx->recursion++;
1712
if(type == CL_TYPE_TEXT_ASCII) {
1713
lseek(desc, 0, SEEK_SET);
1715
nret = cli_scandesc(desc, ctx, 0, ret, 1, NULL);
1716
if(nret == CL_VIRUS)
1717
cli_dbgmsg("%s found in descriptor %d when scanning file type %u\n", *ctx->virname, desc, ret);
1721
1738
if(nret != CL_VIRUS) {
1722
1739
lastzip = lastrar = 0xdeadbeef;
1723
1740
fpt = ftoffset;
1772
1789
ctx->container_type = CL_TYPE_AUTOIT;
1773
1790
ctx->container_size = map->len - fpt->offset; /* not precise */
1774
1791
cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int) fpt->offset);
1775
nret = cli_scanautoit(map->fd, ctx, fpt->offset + 23);
1792
nret = cli_scanautoit(ctx, fpt->offset + 23);
1802
1819
ctx->container_size = map->len - fpt->offset; /* not precise */
1803
1820
memset(&peinfo, 0, sizeof(struct cli_exe_info));
1804
1821
peinfo.offset = fpt->offset;
1805
lseek(map->fd, fpt->offset, SEEK_SET);
1806
1822
if(cli_peheader(map, &peinfo) == 0) {
1807
1823
cli_dbgmsg("*** Detected embedded PE file at %u ***\n", (unsigned int) fpt->offset);
1808
1824
if(peinfo.section)
1809
1825
free(peinfo.section);
1811
lseek(map->fd, fpt->offset, SEEK_SET);
1812
nret = cli_scanembpe(map->fd, ctx);
1827
nret = cli_scanembpe(ctx, fpt->offset);
1813
1828
break_loop = 1; /* we can stop here and other
1814
1829
* embedded executables will
1815
1830
* be found recursively
1884
1899
#define LINESTR(x) #x
1885
1900
#define LINESTR2(x) LINESTR(x)
1886
1901
#define __AT__ " at line "LINESTR2(__LINE__)
1887
#define ret_from_magicscan(retcode) do { \
1888
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
1902
#define ret_from_magicscan(retcode) do { \
1903
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
1904
if(ctx->engine->cb_post_scan) { \
1905
switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS && ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) { \
1907
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); \
1910
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n"); \
1912
*ctx->virname = "Detected.By.Callback"; \
1917
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n"); \
1892
int cli_magic_scandesc(int desc, cli_ctx *ctx)
1923
static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type)
1894
1925
int ret = CL_CLEAN;
1895
cli_file_t type, dettype = 0;
1926
cli_file_t dettype = 0;
1896
1927
struct stat sb;
1897
1928
uint8_t typercg = 1;
1898
1929
cli_file_t current_container_type = ctx->container_type;
1900
1931
unsigned char hash[16];
1901
1932
bitset_t *old_hook_lsig_matches;
1934
#ifdef HAVE__INTERNAL__SHA_COLLECT
1935
if(ctx->sha_collect>0) ctx->sha_collect = 0;
1903
1938
cli_dbgmsg("in cli_magic_scandesc (reclevel: %u/%u)\n", ctx->recursion, ctx->engine->maxreclevel);
1904
1939
if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
1905
1940
cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
1939
1974
ret_from_magicscan(CL_EMEM);
1977
if(ctx->engine->cb_pre_scan) {
1978
switch(ctx->engine->cb_pre_scan(desc, ctx->cb_ctx)) {
1980
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n");
1983
ret_from_magicscan(CL_CLEAN);
1985
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n");
1987
*ctx->virname = "Detected.By.Callback";
1990
ret_from_magicscan(CL_VIRUS);
1994
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n");
1942
1998
if(cache_check(hash, ctx) == CL_CLEAN) {
1943
1999
funmap(*ctx->fmap);
1955
2011
cli_dbgmsg("Raw mode: No support for special files\n");
1957
if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, hash)) == CL_VIRUS)
2013
if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS)
1958
2014
cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
1959
2015
else if(ret == CL_CLEAN) {
1960
2016
if(ctx->recursion != ctx->engine->maxreclevel)
1977
2034
ctx->hook_lsig_matches = old_hook_lsig_matches;
1978
2035
ret_from_magicscan(CL_EREAD);
2038
#ifdef HAVE__INTERNAL__SHA_COLLECT
2039
if(!ctx->sha_collect && type==CL_TYPE_MSEXE) ctx->sha_collect = 1;
1980
2041
lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
1982
2043
ctx->hook_lsig_matches = cli_bitset_init();
1983
2044
if (!ctx->hook_lsig_matches) {
1984
2045
ctx->hook_lsig_matches = old_hook_lsig_matches;
1985
2047
ret_from_magicscan(CL_EMEM);
2044
2106
ctx->container_type = CL_TYPE_AUTOIT;
2045
2107
ctx->container_size = sb.st_size;
2046
2108
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT))
2047
ret = cli_scanautoit(desc, ctx, 23);
2109
ret = cli_scanautoit(ctx, 23);
2050
2112
case CL_TYPE_MSSZDD:
2276
2338
ret = cli_scanscript(ctx);
2277
2339
if(ret != CL_VIRUS && ctx->container_type == CL_TYPE_MAIL) {
2278
2340
lseek(desc, 0, SEEK_SET);
2279
ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR);
2341
ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL);
2282
2344
/* Due to performance reasons all executables were first scanned
2377
int cli_magic_scandesc(int desc, cli_ctx *ctx)
2379
return magic_scandesc(desc, ctx, CL_TYPE_ANY);
2382
int cli_magic_scandesc_type(int desc, cli_ctx *ctx, cli_file_t type)
2384
return magic_scandesc(desc, ctx, type);
2387
int cli_scandesc_stats(int desc, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
2392
memset(&ctx, '\0', sizeof(cli_ctx));
2393
ctx.engine = engine;
2394
ctx.virname = virname;
2397
ctx.virsize = virsize;
2398
ctx.virhash = virhash;
2400
ctx.scanned = scanned;
2401
ctx.options = scanoptions;
2402
ctx.found_possibly_unwanted = 0;
2403
ctx.container_type = CL_TYPE_ANY;
2404
ctx.container_size = 0;
2405
ctx.dconf = (struct cli_dconf *) engine->dconf;
2406
ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2);
2409
if (!(ctx.hook_lsig_matches = cli_bitset_init())) {
2414
#ifdef HAVE__INTERNAL__SHA_COLLECT
2415
if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) {
2419
snprintf(link, sizeof(link), "/proc/self/fd/%u", desc);
2420
link[sizeof(link)-1]='\0';
2421
if((linksz=readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename)))==-1) {
2422
cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link);
2423
strcpy(ctx.entry_filename, "NO_IDEA");
2425
ctx.entry_filename[linksz]='\0';
2429
rc = cli_magic_scandesc(desc, &ctx);
2431
cli_bitset_free(ctx.hook_lsig_matches);
2433
if(rc == CL_CLEAN && ctx.found_possibly_unwanted)
2315
2438
int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
2440
return cli_scandesc_stats(desc, virname, NULL, NULL, scanned, engine, scanoptions);
2444
int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context)
2326
2455
ctx.container_type = CL_TYPE_ANY;
2327
2456
ctx.container_size = 0;
2328
2457
ctx.dconf = (struct cli_dconf *) engine->dconf;
2458
ctx.cb_ctx = context;
2329
2459
ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2);
2331
2461
return CL_EMEM;
2332
ctx.hook_lsig_matches = cli_bitset_init();
2462
if (!(ctx.hook_lsig_matches = cli_bitset_init())) {
2467
#ifdef HAVE__INTERNAL__SHA_COLLECT
2468
if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) {
2472
snprintf(link, sizeof(link), "/proc/self/fd/%u", desc);
2473
link[sizeof(link)-1]='\0';
2474
if((linksz=readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename)))==-1) {
2475
cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link);
2476
strcpy(ctx.entry_filename, "NO_IDEA");
2478
ctx.entry_filename[linksz]='\0';
2334
2482
rc = cli_magic_scandesc(desc, &ctx);
2540
int cli_scanfile_stats(const char *filename, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
2544
if((fd = safe_open(filename, O_RDONLY|O_BINARY)) == -1)
2547
ret = cli_scandesc_stats(fd, virname, virhash, virsize, scanned, engine, scanoptions);
2393
2554
Local Variables:
2394
2555
c-basic-offset: 4