Browse code

Detect encrypted archives

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@370 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2004/03/04 11:27:37
Showing 14 changed files
... ...
@@ -97,6 +97,7 @@ Vijay Sarvepalli <vssarvep*office.uncg.edu>
97 97
 Matt Sullivan <matt*sullivan.gen.nz>
98 98
 Joe Talbott <josepht*cstone.net>
99 99
 Gernot Tenchio <g.tenchio*telco-tech.de>
100
+Michael L Torrie <torriem*chem.byu.edu>
100 101
 Laurent Wacrenier <lwa*teaser.fr>
101 102
 David Woakes <david*mitredata.co.uk>
102 103
 Leonid Zeitlin <lz*europe.com>
... ...
@@ -1,3 +1,10 @@
1
+Thu Mar  4 03:29:07 CET 2004 (tk)
2
+---------------------------------
3
+  * libclamav: CL_ENCRYPTED: mark encrypted Zip archives as a virus type
4
+	       "Encrypted.Zip" (Michael L Torrie <torriem*chem.byu.edu>)
5
+  * clamscan: --detect-encrypted
6
+  * clamd: ArchiveDetectEncrypted
7
+
1 8
 Wed Mar  3 11:36:17 CET 2004 (tk)
2 9
 ---------------------------------
3 10
   * libclamav: mbox wrapper: scan Qmail bounces
... ...
@@ -59,6 +59,7 @@ struct cfgstruct *parsecfg(const char *cfgfile)
59 59
 	    {"ArchiveMaxFiles", OPT_NUM},
60 60
 	    {"ArchiveMaxCompressionRatio", OPT_NUM},
61 61
 	    {"ArchiveLimitMemoryUsage", OPT_NOARG},
62
+	    {"ArchiveDetectEncrypted", OPT_NOARG},
62 63
 	    {"DataDirectory", OPT_STR}, /* obsolete */
63 64
 	    {"DatabaseDirectory", OPT_STR}, /* clamd + freshclam */
64 65
 	    {"TCPAddr", OPT_STR},
... ...
@@ -275,6 +275,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
275 275
 	} else {
276 276
 	    limits.archivememlim = 0;
277 277
 	}
278
+
278 279
     }
279 280
 
280 281
     if(cfgopt(copt, "ScanArchive")) {
... ...
@@ -287,6 +288,12 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
287 287
 	    logg("RAR support disabled.\n");
288 288
 	    options |= CL_DISABLERAR;
289 289
 	}
290
+
291
+	if(cfgopt(copt, "ArchiveDetectEncrypted")) {
292
+	    logg("Blocking encrypted archives.\n");
293
+	    options |= CL_ENCRYPTED;
294
+	}
295
+
290 296
     } else {
291 297
 	logg("Archive support disabled.\n");
292 298
     }
... ...
@@ -213,6 +213,7 @@ void help(void)
213 213
     mprintf("\n");
214 214
     mprintf("    --no-ole2                            Disable OLE2 support\n");
215 215
     mprintf("    --no-archive                         Disable libclamav archive support\n");
216
+    mprintf("    --detect-encrypted                   Detect encrypted archives.\n");
216 217
     mprintf("    --max-space=#n                       Extract first #n kilobytes only\n");
217 218
     mprintf("    --max-files=#n                       Extract first #n files only\n");
218 219
     mprintf("    --max-recursion=#n                   Maximal recursion level\n");
... ...
@@ -355,6 +355,9 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us
355 355
     else
356 356
 	options |= CL_ARCHIVE;
357 357
 
358
+    if(optl(opt, "detect-encrypted"))
359
+	options |= CL_ENCRYPTED;
360
+
358 361
     if(optl(opt, "no-ole2"))
359 362
 	options &= ~CL_OLE2;
360 363
     else
... ...
@@ -77,6 +77,7 @@ int main(int argc, char **argv)
77 77
 	    {"max-recursion", 1, 0, 0},
78 78
 	    {"disable-archive", 0, 0, 0},
79 79
 	    {"no-archive", 0, 0, 0},
80
+	    {"detect-encrypted", 0, 0, 0},
80 81
 	    {"no-ole2", 0, 0, 0},
81 82
 	    {"mbox", 0, 0, 'm'},
82 83
 	    {"stdout", 0, 0, 0},
... ...
@@ -186,6 +186,10 @@ ArchiveMaxCompressionRatio 200
186 186
 # affects bzip2 decompressor only.
187 187
 #ArchiveLimitMemoryUsage
188 188
 
189
+# Mark encrypted archives as viruses (currently only works with Zip archives)
190
+#ArchiveDetectEncrypted
191
+
192
+
189 193
 ##
190 194
 ## Clamuko settings
191 195
 ## WARNING: This is experimental software. It is very likely it will hang
... ...
@@ -68,6 +68,7 @@ extern "C"
68 68
 #define CL_MAIL		2
69 69
 #define CL_DISABLERAR	4
70 70
 #define CL_OLE2		8
71
+#define CL_ENCRYPTED    16
71 72
 
72 73
 struct cli_patt {
73 74
     short int *pattern;
... ...
@@ -52,11 +52,11 @@ int cli_scanrar_inuse = 0;
52 52
 #include <bzlib.h>
53 53
 #endif
54 54
 
55
-#define SCAN_ARCHIVE	(options & CL_ARCHIVE)
56
-#define SCAN_MAIL	(options & CL_MAIL)
57
-#define SCAN_OLE2	(options & CL_OLE2)
58
-#define DISABLE_RAR	(options & CL_DISABLERAR)
59
-
55
+#define SCAN_ARCHIVE	    (options & CL_ARCHIVE)
56
+#define SCAN_MAIL	    (options & CL_MAIL)
57
+#define SCAN_OLE2	    (options & CL_OLE2)
58
+#define DISABLE_RAR	    (options & CL_DISABLERAR)
59
+#define DETECT_ENCRYPTED    (options & CL_ENCRYPTED)
60 60
 
61 61
 typedef enum {
62 62
     CL_UNKNOWN_TYPE = 0,
... ...
@@ -326,7 +326,7 @@ int cli_scanzip(int desc, char **virname, long int *scanned, const struct cl_nod
326 326
 	    break;
327 327
 	}
328 328
 
329
-	cli_dbgmsg("Zip -> %s, compressed: %d, normal: %d.\n", zdirent.d_name, zdirent.d_csize, zdirent.st_size);
329
+	cli_dbgmsg("Zip -> %s, compressed: %d, normal: %d, encrypted flag: %d\n", zdirent.d_name, zdirent.d_csize, zdirent.st_size, zdirent.d_flags);
330 330
 
331 331
 	if(limits && limits->maxratio > 0 && source.st_size && (zdirent.st_size / source.st_size) >= limits->maxratio) {
332 332
 	    *virname = "Oversized.Zip";
... ...
@@ -350,6 +350,14 @@ int cli_scanzip(int desc, char **virname, long int *scanned, const struct cl_nod
350 350
 	    break;
351 351
 	}
352 352
 
353
+	if(DETECT_ENCRYPTED && (zdirent.d_flags & (1 | 2^6))) {
354
+	    files++;
355
+	    cli_dbgmsg("Zip -> Encrypted files found in archive.\n");
356
+	    *virname = "Encrypted.Zip";
357
+	    ret = CL_VIRUS;
358
+	    break;
359
+	}
360
+
353 361
 	if(limits) {
354 362
 	    if(limits->maxfilesize && (zdirent.st_size > limits->maxfilesize)) {
355 363
 		cli_dbgmsg("Zip -> %s: Size exceeded (%d, max: %d)\n", zdirent.d_name, zdirent.st_size, limits->maxfilesize);
... ...
@@ -763,6 +771,7 @@ int cli_magic_scandesc(int desc, char **virname, long int *scanned, const struct
763 763
 	return -1;
764 764
     }
765 765
 
766
+
766 767
     if(SCAN_ARCHIVE || SCAN_MAIL) {
767 768
         /* Need to examine file type */
768 769
 
... ...
@@ -89,6 +89,7 @@ real_readdir(ZZIP_DIR* dir)
89 89
         return -1;
90 90
 
91 91
     dir->dirent.d_csize = dir->dirent.st_size = st.st_size;
92
+    dir->dirent.d_flags = 0;
92 93
 
93 94
     if (st.st_mode)
94 95
     {
... ...
@@ -140,6 +141,8 @@ zzip_readdir(ZZIP_DIR * dir)
140 140
         dir->dirent.d_csize = dir->hdr->d_csize;
141 141
         dir->dirent.st_size = dir->hdr->d_usize;
142 142
 
143
+	dir->dirent.d_flags = dir->hdr->d_flags;
144
+
143 145
         if (! dir->hdr->d_reclen) dir->hdr = 0;
144 146
         else  dir->hdr = (struct zzip_dir_hdr *)
145 147
 		  ((char *)dir->hdr + dir->hdr->d_reclen);
... ...
@@ -365,6 +365,7 @@ __zzip_parse_root_directory(int fd,
365 365
     {
366 366
         register struct zzip_root_dirent * d;
367 367
         uint16_t u_extras, u_comment, u_namlen;
368
+	uint16_t u_flags;
368 369
 
369 370
         if (fd_map) 
370 371
 	{ d = (void*)(fd_map+fd_gap+offset); } /* fd_map+fd_gap==u_rootseek */
... ...
@@ -387,6 +388,7 @@ __zzip_parse_root_directory(int fd,
387 387
         u_extras  = ZZIP_GET16(d->z_extras); 
388 388
         u_comment = ZZIP_GET16(d->z_comment); 
389 389
         u_namlen  = ZZIP_GET16(d->z_namlen); 
390
+	u_flags   = ZZIP_GET16(d->z_flags);
390 391
         //HINT5("offset=0x%lx, size %ld, dirent *%p, hdr %p\n",
391 392
 	  //    offset+u_rootseek, (long)u_rootsize, d, hdr);
392 393
 
... ...
@@ -402,6 +404,8 @@ __zzip_parse_root_directory(int fd,
402 402
         hdr->d_usize = ZZIP_GET32(d->z_usize); 
403 403
         hdr->d_off   = ZZIP_GET32(d->z_off);
404 404
         hdr->d_compr = (uint8_t)ZZIP_GET16(d->z_compr);
405
+	hdr->d_flags = u_flags;
406
+
405 407
         /* bull: hdr->d_compr is uint8_t
406 408
 	 * if (hdr->d_compr > 255) hdr->d_compr = 255; */
407 409
 
... ...
@@ -702,6 +706,7 @@ zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * d )
702 702
     d->d_csize = dir->hdr->d_csize;
703 703
     d->st_size = dir->hdr->d_usize;
704 704
     d->d_name  = dir->hdr->d_name;
705
+    d->d_flags = dir->hdr->d_flags;
705 706
 
706 707
     if (! dir->hdr->d_reclen) 
707 708
     { dir->hdr = 0; }
... ...
@@ -34,6 +34,7 @@ struct zzip_dir_hdr
34 34
     uint16_t    d_reclen;       /* next dir_hdr structure offset */
35 35
     uint16_t    d_namlen;       /* explicit namelen of d_name */
36 36
     uint8_t     d_compr;        /* the compression type, 0 = store, 8 = inflate */
37
+    uint16_t	d_flags;	/* general purpose flags */
37 38
     char        d_name[1];      /* the actual name of the entry, may contain DIRSEPs */
38 39
 };
39 40
 #define _ZZIP_DIRENT_HAVE_D_NAMLEN
... ...
@@ -91,6 +91,7 @@ struct zzip_dirent
91 91
     int	 	d_compr;	/* compression method */
92 92
     int         d_csize;        /* compressed size */
93 93
     int	 	st_size;	/* file size / decompressed size */
94
+    unsigned short d_flags;	/* general purpose flags */
94 95
     char * 	d_name;		/* file name / strdupped name */
95 96
 };
96 97