238
239
if(mdata->maxdepth && ctx->recursion > mdata->maxdepth)
241
/* TODO add support for regex */
242
/*if(mdata->filename && !strstr(zdirent.d_name, mdata->filename))*/
243
if(mdata->filename && strcmp((char *) metadata->filename, mdata->filename))
242
if(mdata->filename && !cli_matchregex(metadata->filename, mdata->filename))
246
245
break; /* matched */
293
292
if(!cli_leavetemps_flag)
296
if(ret == UNRAR_EMEM)
295
if(ret == UNRAR_PASSWD) {
296
cli_dbgmsg("RAR: Encrypted main header\n");
297
if(DETECT_ENCRYPTED) {
298
lseek(desc, 0, SEEK_SET);
299
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR);
301
*ctx->virname = "Encrypted.RAR";
305
} if(ret == UNRAR_EMEM) {
331
341
rc = cli_magic_scandesc(rar_state.ofd,ctx);
332
342
close(rar_state.ofd);
333
343
if(!cli_leavetemps_flag)
334
unlink(rar_state.filename);
344
if (cli_unlink(rar_state.filename)) ret = CL_EIO;
335
345
if(rc == CL_VIRUS ) {
336
346
cli_dbgmsg("RAR: infected with %s\n",*ctx->virname);
487
500
if(cli_writen(fd, buff, bytes) != bytes) {
488
501
cli_dbgmsg("GZip: Can't write to file.\n");
490
if(!cli_leavetemps_flag)
503
if(!cli_leavetemps_flag) {
504
if (cli_unlink(tmpname)) {
502
521
if(ret == CL_VIRUS) {
504
523
if(!cli_leavetemps_flag)
524
if (cli_unlink(tmpname)) ret = CL_EIO;
510
if(fsync(fd) == -1) {
511
cli_dbgmsg("GZip: Can't synchronise descriptor %d\n", fd);
513
if(!cli_leavetemps_flag)
519
529
lseek(fd, 0, SEEK_SET);
520
530
if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) {
521
531
cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname);
523
if(!cli_leavetemps_flag)
533
if(!cli_leavetemps_flag) {
534
if (cli_unlink(tmpname)) {
529
543
if(!cli_leavetemps_flag)
544
if (cli_unlink(tmpname)) ret = CL_EIO;
552
static int cli_scanbzip(int desc, cli_ctx *ctx) {
553
cli_warnmsg("cli_scanbzip: bzip2 support not compiled in\n");
538
559
#ifdef NOBZ2PREFIX
539
560
#define BZ2_bzReadOpen bzReadOpen
577
598
if(!(buff = (char *) cli_malloc(FILEBUFF))) {
578
599
cli_dbgmsg("Bzip: Unable to malloc %u bytes.\n", FILEBUFF);
580
if(!cli_leavetemps_flag)
601
if(!cli_leavetemps_flag) {
602
if (cli_unlink(tmpname)) {
605
BZ2_bzReadClose(&bzerror, bfd);
584
611
BZ2_bzReadClose(&bzerror, bfd);
595
622
cli_dbgmsg("Bzip: Can't write to file.\n");
596
623
BZ2_bzReadClose(&bzerror, bfd);
598
if(!cli_leavetemps_flag)
625
if(!cli_leavetemps_flag) {
626
if (cli_unlink(tmpname)) {
610
643
if(ret == CL_VIRUS) {
612
645
if(!cli_leavetemps_flag)
646
if (cli_unlink(tmpname)) ret = CL_EIO;
619
if(fsync(fd) == -1) {
620
cli_dbgmsg("Bzip: Synchronisation failed for descriptor %d\n", fd);
622
if(!cli_leavetemps_flag)
629
652
lseek(fd, 0, SEEK_SET);
630
653
if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) {
631
654
cli_dbgmsg("Bzip: Infected with %s\n", *ctx->virname);
634
657
if(!cli_leavetemps_flag)
658
if (cli_unlink(tmpname)) ret = CL_EIO;
719
747
static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
721
int ret = CL_CLEAN, i, j, fd, ofd, data_len;
749
int ret = CL_CLEAN, i, j, fd, data_len;
722
750
vba_project_t *vba_project;
724
752
struct dirent *dent;
740
769
if(!(vba_project = (vba_project_t *)cli_vba_readdir(dirname, U, hashcnt))) continue;
742
771
for(i = 0; i < vba_project->count; i++) {
743
for(j = 0; j < vba_project->colls[i]; j++) {
744
snprintf(vbaname, 1024, "%s/%u_%u", vba_project->dir, vba_project->name[i], j);
772
for(j = 0; (unsigned int)j < vba_project->colls[i]; j++) {
773
snprintf(vbaname, 1024, "%s/%s_%u", vba_project->dir, vba_project->name[i], j);
745
774
vbaname[sizeof(vbaname)-1] = '\0';
746
775
fd = open(vbaname, O_RDONLY|O_BINARY);
747
776
if(fd == -1) continue;
748
cli_dbgmsg("VBADir: Decompress VBA project '%u_%u'\n", vba_project->name[i], j);
777
cli_dbgmsg("VBADir: Decompress VBA project '%s_%u'\n", vba_project->name[i], j);
749
778
data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len);
753
cli_dbgmsg("VBADir: WARNING: VBA project '%u_%u' decompressed to NULL\n", vba_project->name[i], j);
782
cli_dbgmsg("VBADir: WARNING: VBA project '%s_%u' decompressed to NULL\n", vba_project->name[i], j);
755
784
/* cli_dbgmsg("Project content:\n%s", data); */
776
805
if(ret == CL_CLEAN && (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
777
806
while(hashcnt--) {
778
snprintf(vbaname, 1024, "%s/%u_%u", dirname, hash, hashcnt);
807
snprintf(vbaname, 1024, "%s/%s_%u", dirname, hash, hashcnt);
779
808
vbaname[sizeof(vbaname)-1] = '\0';
780
809
fd = open(vbaname, O_RDONLY|O_BINARY);
781
810
if (fd == -1) continue;
794
823
if (ret == CL_CLEAN && (hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
795
824
while(hashcnt--) {
796
snprintf(vbaname, sizeof(vbaname), "%s/%u_%u", dirname, hash, hashcnt);
825
snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
797
826
vbaname[sizeof(vbaname)-1] = '\0';
798
827
fd = open(vbaname, O_RDONLY|O_BINARY);
799
828
if (fd == -1) continue;
840
869
/* Check directory for embedded OLE objects */
841
870
hashcnt = uniq_get(U, "_1_ole10native", 14, &hash);
842
871
while(hashcnt--) {
843
snprintf(vbaname, sizeof(vbaname), "%s/%u_%u", dirname, hash, hashcnt);
872
snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
844
873
vbaname[sizeof(vbaname)-1] = '\0';
846
875
fd = open(vbaname, O_RDONLY|O_BINARY);
984
if(ret == CL_CLEAN) {
985
snprintf(fullname, 1024, "%s/javascript", tempname);
986
fd = open(fullname, O_RDONLY|O_BINARY);
988
ret = cli_scandesc(fd, ctx, CL_TYPE_SCRIPT, 0, NULL, AC_SCAN_VIR);
955
993
if (ret == CL_CLEAN) {
956
994
snprintf(fullname, 1024, "%s/rfc2397", tempname);
957
995
ret = cli_scandir(fullname, ctx, 0);
1075
1112
lseek(fd, 0, SEEK_SET);
1076
1113
ret = cli_scanhtml(fd, ctx);
1079
if(!cli_leavetemps_flag)
1116
if(!cli_leavetemps_flag) {
1117
if (cli_unlink(tempname)) ret = CL_EIO;
1082
1119
cli_dbgmsg("cli_scanhtml_utf16: Decoded HTML data saved in %s\n", tempname);
1083
1120
free(tempname);
1369
if(fsync(ndesc) == -1) {
1370
cli_errmsg("CryptFF: Can't fsync descriptor %d\n", ndesc);
1376
1406
lseek(ndesc, 0, SEEK_SET);
1378
1408
cli_dbgmsg("CryptFF: Scanning decrypted data\n");
1536
static int cli_scan_structured(int desc, cli_ctx *ctx)
1540
unsigned int cc_count = 0;
1541
unsigned int ssn_count = 0;
1543
const struct cl_limits *lim = NULL;
1544
int (*ccfunc)(const unsigned char *buffer, int length);
1545
int (*ssnfunc)(const unsigned char *buffer, int length);
1548
if(ctx == NULL || ctx->limits == NULL)
1553
if(lim->min_cc_count == 1)
1554
ccfunc = dlp_has_cc;
1556
ccfunc = dlp_get_cc_count;
1558
switch((ctx->options & CL_SCAN_STRUCTURED_SSN_NORMAL) | (ctx->options & CL_SCAN_STRUCTURED_SSN_STRIPPED)) {
1560
case (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED):
1561
if(lim->min_ssn_count == 1)
1562
ssnfunc = dlp_has_ssn;
1564
ssnfunc = dlp_get_ssn_count;
1567
case CL_SCAN_STRUCTURED_SSN_NORMAL:
1568
if(lim->min_ssn_count == 1)
1569
ssnfunc = dlp_has_normal_ssn;
1571
ssnfunc = dlp_get_normal_ssn_count;
1574
case CL_SCAN_STRUCTURED_SSN_STRIPPED:
1575
if(lim->min_ssn_count == 1)
1576
ssnfunc = dlp_has_stripped_ssn;
1578
ssnfunc = dlp_get_stripped_ssn_count;
1585
while(!done && ((result = cli_readn(desc, buf, 8191)) > 0)) {
1586
if((cc_count += ccfunc((const unsigned char *)buf, result)) >= lim->min_cc_count)
1589
if(ssnfunc && ((ssn_count += ssnfunc((const unsigned char *)buf, result)) >= lim->min_ssn_count))
1593
if(cc_count != 0 && cc_count >= lim->min_cc_count) {
1594
cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count);
1595
*ctx->virname = "Structured.CreditCardNumber";
1599
if(ssn_count != 0 && ssn_count >= lim->min_ssn_count) {
1600
cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count);
1601
*ctx->virname = "Structured.SSN";
1506
1608
static int cli_scanembpe(int desc, cli_ctx *ctx)
1508
1610
int fd, bytes, ret = CL_CLEAN;
1530
1632
if(cli_writen(fd, buff, bytes) != bytes) {
1531
1633
cli_dbgmsg("cli_scanembpe: Can't write to temporary file\n");
1533
if(!cli_leavetemps_flag)
1635
if(!cli_leavetemps_flag) {
1636
if (cli_unlink(tmpname)) {
1540
if(fsync(fd) == -1) {
1541
cli_dbgmsg("cli_scanembpe: Can't synchronise descriptor %d\n", fd);
1543
if(!cli_leavetemps_flag)
1549
1646
ctx->recursion++;
1550
1647
lseek(fd, 0, SEEK_SET);
1551
1648
if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) {
1552
1649
cli_dbgmsg("cli_scanembpe: Infected with %s\n", *ctx->virname);
1554
if(!cli_leavetemps_flag)
1651
if(!cli_leavetemps_flag) {
1652
if (cli_unlink(tmpname)) {
1557
1658
return CL_VIRUS;
1559
1660
ctx->recursion--;
1562
if(!cli_leavetemps_flag)
1663
if(!cli_leavetemps_flag) {
1664
if (cli_unlink(tmpname)) {
1566
1671
/* intentionally ignore possible errors from cli_magic_scandesc */
1934
2037
ret = cli_check_mydoom_log(desc, ctx->virname);
2040
case CL_TYPE_TEXT_ASCII:
2041
if(SCAN_STRUCTURED && (DCONF_OTHER & OTHER_CONF_DLP))
2042
/* TODO: consider calling this from cli_scanscript() for
2045
ret = cli_scan_structured(desc, ctx);
1941
2051
ctx->recursion--;
1943
2056
if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
1944
2057
if(sb.st_size > 1048576) {
1945
2058
cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > 1 MB)\n");
1950
2063
/* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */
1951
if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && ret != CL_VIRUS && !ctx->engine->sdb) {
2064
if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && !ctx->engine->sdb) {
1952
2065
if(cli_scanraw(desc, ctx, type, typercg, &dettype) == CL_VIRUS)
1953
2066
return CL_VIRUS;
1957
2070
lseek(desc, 0, SEEK_SET);
1959
2072
case CL_TYPE_TEXT_ASCII:
2073
case CL_TYPE_TEXT_UTF16BE:
2074
case CL_TYPE_TEXT_UTF16LE:
2075
case CL_TYPE_TEXT_UTF8:
1960
2076
if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML)
1961
2077
ret = cli_scanscript(desc, ctx);
2130
int cli_found_possibly_unwanted(cli_ctx* ctx)
2133
cli_dbgmsg("found Possibly Unwanted: %s\n",*ctx->virname);
2134
if(ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) {
2135
/* we found a heuristic match, don't scan further,
2136
* but consider it a virus. */
2137
cli_dbgmsg("cli_found_possibly_unwanted: CL_VIRUS\n");
2140
/* heuristic scan isn't taking precedence, keep scanning.
2141
* If this is part of an archive, and
2142
* we find a real malware we report that instead of the
2143
* heuristic match */
2144
ctx->found_possibly_unwanted = 1;
2146
cli_warnmsg("cli_found_possibly_unwanted called, but virname is not set\n");
2014
2151
static int cli_scanfile(const char *filename, cli_ctx *ctx)