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... | ... |
@@ -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 |
|
... | ... |
@@ -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, "", "" }, |