Browse code

bb5638

Add dumpcerts command-line option for clamscan. Only show certs in the PE file, not certs loaded by the certs db.

Shawn Webb authored on 2013/01/09 05:10:03
Showing 7 changed files
... ...
@@ -255,6 +255,7 @@ void help(void)
255 255
     mprintf("    --detect-broken[=yes/no(*)]          Try to detect broken executable files\n");
256 256
     mprintf("    --block-encrypted[=yes/no(*)]        Block encrypted archives\n");
257 257
     mprintf("    --nocerts                            Disable authenticode certificate chain verification in PE files\n");
258
+    mprintf("    --dumpcerts                          Dump authenticode certificate chain in PE files\n");
258 259
     mprintf("\n");
259 260
     mprintf("    --max-filesize=#n                    Files larger than this will be skipped and assumed clean\n");
260 261
     mprintf("    --max-scansize=#n                    The maximum amount of data to scan for each container file (**)\n");
... ...
@@ -697,6 +697,9 @@ int scanmanager(const struct optstruct *opts)
697 697
     if (optget(opts, "nocerts")->enabled)
698 698
         engine->dconf->pe |= PE_CONF_DISABLECERT;
699 699
 
700
+    if (optget(opts, "dumpcerts")->enabled)
701
+        engine->dconf->pe |= PE_CONF_DUMPCERT;
702
+
700 703
     /* set limits */
701 704
 
702 705
     if((opt = optget(opts, "max-scansize"))->active) {
... ...
@@ -740,7 +740,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
740 740
     return 1;
741 741
 }
742 742
 
743
-static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmgr *cmgr, int embedded, const void **hashes, unsigned int *hashes_size) {
743
+static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmgr *cmgr, int embedded, const void **hashes, unsigned int *hashes_size, struct cl_engine *engine) {
744 744
     struct cli_asn1 asn1, deep, deeper;
745 745
     uint8_t sha1[SHA1_HASH_SIZE], issuer[SHA1_HASH_SIZE], md[SHA1_HASH_SIZE], serial[SHA1_HASH_SIZE];
746 746
     const uint8_t *message, *attrs;
... ...
@@ -840,6 +840,21 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg
840 840
 		x509 = newcerts.crts;
841 841
 		cli_dbgmsg("asn1_parse_mscat: %u new certificates collected\n", newcerts.items);
842 842
 		while(x509) {
843
+            if (engine->dconf->pe & PE_CONF_DUMPCERT) {
844
+                char issuer[SHA1_HASH_SIZE*2+1], subject[SHA1_HASH_SIZE*2+1], serial[SHA1_HASH_SIZE*2+1];
845
+                char mod[1024], exp[1024];
846
+                int j=1024;
847
+
848
+                fp_toradix_n(&x509->n, mod, 16, j);
849
+                fp_toradix_n(&x509->e, exp, 16, j);
850
+                for (j=0; j < SHA1_HASH_SIZE; j++) {
851
+                    sprintf(&issuer[j*2], "%02x", x509->issuer[j]);
852
+                    sprintf(&subject[j*2], "%02x", x509->subject[j]);
853
+                    sprintf(&serial[j*2], "%02x", x509->serial[j]);
854
+                }
855
+
856
+                cli_dbgmsg_internal("cert subject:%s serial:%s pubkey:%s i:%s %lu->%lu %s %s %s\n", subject, serial, mod, issuer, (unsigned long)x509->not_before, (unsigned long)x509->not_after, x509->certSign ? "cert" : "", x509->codeSign ? "code" : "", x509->timeSign ? "time" : "");
857
+            }
843 858
 		    cli_crt *parent = crtmgr_verify_crt(cmgr, x509);
844 859
 		    if(parent) {
845 860
                 if (parent->isBlacklisted)
... ...
@@ -1297,7 +1312,7 @@ int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) {
1297 1297
     struct cli_matcher *db;
1298 1298
     int i;
1299 1299
 
1300
-    if(asn1_parse_mscat(map, 0, map->len, &engine->cmgr, 0, &c.next, &size))
1300
+    if(asn1_parse_mscat(map, 0, map->len, &engine->cmgr, 0, &c.next, &size, engine))
1301 1301
         return 1;
1302 1302
 
1303 1303
     if(asn1_expect_objtype(map, c.next, &size, &c, 0x30))
... ...
@@ -1454,7 +1469,7 @@ int asn1_check_mscat(struct cl_engine *engine, fmap_t *map, size_t offset, unsig
1454 1454
 	crtmgr_free(&certs);
1455 1455
 	return CL_VIRUS;
1456 1456
     }
1457
-    ret = asn1_parse_mscat(map, offset, size, &certs, 1, &content, &content_size);
1457
+    ret = asn1_parse_mscat(map, offset, size, &certs, 1, &content, &content_size, engine);
1458 1458
     crtmgr_free(&certs);
1459 1459
     if(ret)
1460 1460
 	return CL_VIRUS;
... ...
@@ -137,24 +137,6 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) {
137 137
 	m->crts->prev = i;
138 138
     m->crts = i;
139 139
 
140
-    if(cli_debug_flag) {
141
-        char issuer[SHA1_HASH_SIZE*2+1], subject[SHA1_HASH_SIZE*2+1], serial[SHA1_HASH_SIZE*2+1];
142
-        char mod[1024], exp[1024];
143
-        int j=1024;
144
-        // mod first
145
-        fp_toradix_n(&i->n, mod, 16, j);
146
-        // exp next
147
-        fp_toradix_n(&i->e, exp, 16, j);
148
-        // subject and issuer hashes
149
-        for(j=0; j<SHA1_HASH_SIZE; j++) {
150
-            sprintf(&issuer[j*2], "%02x", i->issuer[j]);
151
-            sprintf(&subject[j*2], "%02x", i->subject[j]);
152
-            sprintf(&serial[j*2], "%02x", i->serial[j]);
153
-        }
154
-        // printing lines, broken up to minimize truncation
155
-        cli_dbgmsg("crtmgr_add: added cert subject:%s serial:%s pubkey:%s i:%s %lu->%lu %s%s%s\n", subject, serial, mod, issuer, (unsigned long)i->not_before, (unsigned long)i->not_after, i->certSign ? "cert ":"", i->codeSign ? "code ":"", i->timeSign ? "time":"");
156
-        cli_dbgmsg("crtmgr_add: e:%s \n", exp);
157
-    }
158 140
     m->items++;
159 141
     return 0;
160 142
 }
... ...
@@ -72,6 +72,7 @@ static struct dconf_module modules[] = {
72 72
     { "PE",	    "ASPACK",	    PE_CONF_ASPACK,	    1 },
73 73
     { "PE",	    "CATALOG",	    PE_CONF_CATALOG,	    1 },
74 74
     { "PE",     "DISABLECERT",  PE_CONF_DISABLECERT,    0 },
75
+    { "PE",     "DUMPCERT",     PE_CONF_DUMPCERT,       0 },
75 76
 
76 77
     { "ELF",	    NULL,	    0x1,		    1 },
77 78
 
... ...
@@ -61,6 +61,7 @@ struct cli_dconf {
61 61
 #define PE_CONF_ASPACK	    0x8000
62 62
 #define PE_CONF_CATALOG	    0x10000
63 63
 #define PE_CONF_DISABLECERT 0x20000
64
+#define PE_CONF_DUMPCERT    0x40000
64 65
 
65 66
 /* Archive flags */
66 67
 #define ARCH_CONF_RAR	    0x1
... ...
@@ -68,6 +68,7 @@ const struct clam_option __clam_options[] = {
68 68
     { NULL, "version", 'V', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_CLAMSCAN | OPT_CLAMDSCAN | OPT_SIGTOOL | OPT_MILTER | OPT_CLAMCONF | OPT_CLAMDTOP | OPT_CLAMBC, "", "" },
69 69
     { NULL, "debug", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMBC | OPT_CLAMD | OPT_FRESHCLAM | OPT_CLAMSCAN | OPT_SIGTOOL, "", "" },
70 70
     { NULL, "verbose", 'v', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM | OPT_CLAMSCAN | OPT_CLAMDSCAN | OPT_SIGTOOL, "", "" },
71
+    { NULL, "dumpcerts", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN, "Dump authenticode certificate chain.", "" },
71 72
     { NULL, "quiet", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM | OPT_CLAMSCAN | OPT_CLAMDSCAN | OPT_SIGTOOL, "", "" },
72 73
     { NULL, "leave-temps", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN, "", "" },
73 74
     { NULL, "no-warnings", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "", "" },