handle file cats - wip

remotes/push_mirror/guardrails
aCaB 14 years ago
parent 6bc5d0cb45
commit 7595e1081f
  1. 137
      libclamav/asn1.c
  2. 100
      libclamav/pe.c
  3. 3
      libclamav/readdb.c

@ -1164,83 +1164,46 @@ static int asn1_parse_mscat(fmap_t *map, void *start, unsigned int size, crtmgr
break;
}
cli_dbgmsg("asn1_parse_mscat: catalog succesfully parsed\n");
return 0;
} while(0);
cli_errmsg("asn1: epic parsing fail\n");
cli_dbgmsg("asn1_parse_mscat: failed to parse catalog\n");
return 1;
}
int asn1_load_mscat(fmap_t *map, void *start, unsigned int size, struct cl_engine *engine) {
void *hashes;
unsigned int hashes_size;
return asn1_parse_mscat(map, start, size, &engine->cmgr, 0, &hashes, &hashes_size);
}
int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, const struct cl_engine *engine, uint8_t *computed_sha1) {
unsigned int content_size;
struct cli_asn1 c;
void *content;
crtmgr certs;
int ret;
crtmgr_init(&certs);
if(crtmgr_add_roots(&certs)) {
/* FIXME: do smthng here */
crtmgr_free(&certs);
return CL_CLEAN;
}
ret = asn1_parse_mscat(map, start, size, &certs, 1, &content, &content_size);
crtmgr_free(&certs);
if(ret)
return CL_VIRUS; /* FIXME */
if(asn1_parse_mscat(map, start, size, &engine->cmgr, 0, &hashes, &hashes_size))
return 1;
if(asn1_expect_objtype(map, content, &content_size, &c, 0x30))
return CL_VIRUS;
if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_SPC_PE_IMAGE_DATA_OBJID), OID_SPC_PE_IMAGE_DATA_OBJID))
return CL_VIRUS;
if(asn1_expect_objtype(map, c.next, &content_size, &c, 0x30))
return CL_VIRUS;
if(content_size) {
cli_dbgmsg("asn1_check_mscat: extra data in content\n");
return CL_VIRUS;
if(asn1_expect_objtype(map, hashes, &hashes_size, &c, 0x30))
return 1;
if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_szOID_CATALOG_LIST), OID_szOID_CATALOG_LIST))
return 1;
if(c.size) {
cli_dbgmsg("asn1_load_mscat: found extra data in szOID_CATALOG_LIST content\n");
return 1;
}
if(asn1_expect_algo(map, &c.content, &c.size, lenof(OID_sha1), OID_sha1))
return CL_VIRUS;
if(asn1_expect_obj(map, &c.content, &c.size, 0x04, SHA1_HASH_SIZE, computed_sha1))
return CL_VIRUS;
cli_dbgmsg("asn1_check_mscat: file with valid authenicode signature, whitelisted\n");
return CL_CLEAN;
}
/* dsize = deep.size; */
/* if(asn1_expect_objtype(map, deep.content, &dsize, &deep, 0x30)) */
/* break; */
/* if(asn1_expect_obj(map, &deep.content, &deep.size, 0x06, lenof(OID_szOID_CATALOG_LIST), OID_szOID_CATALOG_LIST)) /\* szOID_CATALOG_LIST - 1.3.6.1.4.1.311.12.1.1 *\/ */
/* break; */
/* if(deep.size) { */
/* cli_dbgmsg("asn1_parse_mscat: found extra data in szOID_CATALOG_LIST content\n"); */
/* break; */
/* } */
/* if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x4)) /\* List ID *\/ */
/* break; */
/* if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x17)) /\* Effective date - WTF?! *\/ */
/* break; */
/* if(asn1_expect_algo(map, &deep.next, &dsize, lenof(OID_szOID_CATALOG_LIST_MEMBER), OID_szOID_CATALOG_LIST_MEMBER)) /\* szOID_CATALOG_LIST_MEMBER *\/ */
/* break; */
/* if(asn1_expect_objtype(map, deep.next, &dsize, &deep, 0x30)) /\* hashes here *\/ */
/* break; */
/* while(deep.size) { */
/* struct cli_asn1 tag; */
/* if(asn1_expect_objtype(map, deep.content, &deep.size, &deeper, 0x30)) { */
/* deep.size = 1; */
/* break; */
/* } */
/* deep.content = deeper.next; */
if(asn1_expect_objtype(map, c.next, &hashes_size, &c, 0x4)) /* List ID */
return 1;
if(asn1_expect_objtype(map, c.next, &hashes_size, &c, 0x17)) /* Effective date - WTF?! */
return 1;
if(asn1_expect_algo(map, &c.next, &hashes_size, lenof(OID_szOID_CATALOG_LIST_MEMBER), OID_szOID_CATALOG_LIST_MEMBER)) /* szOID_CATALOG_LIST_MEMBER */
return 1;
if(asn1_expect_objtype(map, c.next, &hashes_size, &c, 0x30)) /* hashes here */
return 1;
cli_errmsg("ACAB: %u\n", hashes_size);
while(c.size) {
struct cli_asn1 tag;
if(asn1_expect_objtype(map, c.content, &c.size, &tag, 0x30)) {
c.size = 1;
break;
}
c.content = tag.next;
/* if(asn1_expect_objtype(map, deeper.content, &deeper.size, &tag, 0x04)) { /\* TAG NAME *\/ */
/* deep.size = 1; */
/* break; */
@ -1300,6 +1263,46 @@ int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, const struct c
/* deep.size = 1; */
/* break; */
/* } */
/* } */
/* if(deep.size) */
/* break; */
}
if(c.size)
return 1;
return 0;
}
int asn1_check_mscat(fmap_t *map, void *start, unsigned int size, const struct cl_engine *engine, uint8_t *computed_sha1) {
unsigned int content_size;
struct cli_asn1 c;
void *content;
crtmgr certs;
int ret;
crtmgr_init(&certs);
if(crtmgr_add_roots(&certs)) {
/* FIXME: do smthng here */
crtmgr_free(&certs);
return CL_CLEAN;
}
ret = asn1_parse_mscat(map, start, size, &certs, 1, &content, &content_size);
crtmgr_free(&certs);
if(ret)
return CL_VIRUS; /* FIXME */
if(asn1_expect_objtype(map, content, &content_size, &c, 0x30))
return CL_VIRUS;
if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_SPC_PE_IMAGE_DATA_OBJID), OID_SPC_PE_IMAGE_DATA_OBJID))
return CL_VIRUS;
if(asn1_expect_objtype(map, c.next, &content_size, &c, 0x30))
return CL_VIRUS;
if(content_size) {
cli_dbgmsg("asn1_check_mscat: extra data in content\n");
return CL_VIRUS;
}
if(asn1_expect_algo(map, &c.content, &c.size, lenof(OID_sha1), OID_sha1))
return CL_VIRUS;
if(asn1_expect_obj(map, &c.content, &c.size, 0x04, SHA1_HASH_SIZE, computed_sha1))
return CL_VIRUS;
cli_dbgmsg("asn1_check_mscat: file with valid authenicode signature, whitelisted\n");
return CL_CLEAN;
}

@ -2654,106 +2654,6 @@ int cli_scanpe(cli_ctx *ctx) {
hlen -= 8;
hptr = fmap_need_off_once(map, hsize + 8, hlen);
asn1_check_mscat(map, hptr, hlen - 4, ctx->engine, shash1);
#if 0
{
struct cli_asn1 asn1;
unsigned int old_hlen, success;
void *old_next;
uint8_t crt_sha1[SHA1_HASH_SIZE];
hlen = optional_hdr32.DataDirectory[4].Size;
hlen -= 8;
hptr = fmap_need_off_once(map, hsize + 8, hlen);
do {
if(asn1_expect_objtype(map, hptr, &hlen, &asn1, 0x30)) /* SEQUENCE */
break;
hlen = asn1.size;
if(asn1_expect_obj(map, &asn1.content, &hlen, 0x06, 9, "\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02")) /* OBJECT 1.2.840.113549.1.7.2 - pkcs7 signedData */
break;
if(asn1_expect_objtype(map, asn1.content, &hlen, &asn1, 0xa0)) /* [0] */
break;
hlen = asn1.size;
if(asn1_expect_objtype(map, asn1.content, &hlen, &asn1, 0x30)) /* SEQUENCE */
break;
hlen = asn1.size;
if(asn1_expect_obj(map, &asn1.content, &hlen, 0x02, 1, "\x01")) /* INTEGER - VERSION 1 */
break;
if(!asn1_expect_objtype(map, asn1.content, &hlen, &asn1, 0x31)) { /* SET OF DigestAlgorithmIdentifier */
success = 0;
old_hlen = hlen;
old_next = asn1.next;
hlen = asn1.size;
if(asn1_expect_objtype(map, asn1.content, &hlen, &asn1, 0x30)) /* SEQUENCE */
break;
asn1.next = asn1.content;
hlen = asn1.size;
while(hlen) {
if(asn1_get_obj(map, asn1.next, &hlen, &asn1))
break;
if(asn1.type == 0x05 && asn1.size == 0) { /* NULL or */
success++;
break;
}
if(asn1.type != 0x06) /* Algo ID */
break;
if(asn1.size == 5 && fmap_need_ptr_once(map, asn1.content, 5) && !memcmp(asn1.content, "\x2b\x0e\x03\x02\x1a", 5)) /* but only sha1 */
if(!success)
success++;
}
if(success < 2)
break;
hlen = old_hlen;
asn1.next = old_next;
} else
break;
if(asn1_expect_objtype(map, asn1.next, &hlen, &asn1, 0x30)) /* SEQUENCE */
break;
if(ms_asn1_get_sha1(map, asn1.content, asn1.size, 1, crt_sha1, NULL))
break;
for(i=0; i<sizeof(crt_sha1); i++)
sprintf(&shatxt[i*2], "%02x", crt_sha1[i]);
cli_errmsg("CRT sha: %s\n", shatxt);
if(memcmp(crt_sha1, shash1, sizeof(crt_sha1)))
break;
if(asn1_expect_objtype(map, asn1.next, &hlen, &asn1, 0xa0)) /* certificates */
break;
old_hlen = hlen;
old_next = asn1.next;
hlen = asn1.size;
asn1.next = asn1.content;
success = 1;
while(hlen) {
cli_crt x509;
/* FIXME, new proto */
/* if(!asn1_get_x509(map, &asn1.next, &hlen, &x509)) */
/* continue; */
success = 0;
break;
}
if(!success)
break;
hlen = old_hlen;
if(asn1_get_obj(map, old_next, &hlen, &asn1))
break;
if(asn1.type == 0xa1 && asn1_get_obj(map, asn1.next, &hlen, &asn1)) /* crls - unused shouldn't be present */
break;
if(asn1.type != 0x31) /* signerInfos */
break;
cli_errmsg("good %u - %p\n", hlen, asn1.next);
} while(0);
}
#endif
free(exe_sections);
return ret;

@ -2365,7 +2365,8 @@ static int cli_loadmscat(FILE *fs, struct cl_engine *engine, unsigned int option
return 1;
}
asn1_load_mscat(map, base, map->len, engine);
if(asn1_load_mscat(map, base, map->len, engine))
cli_errmsg("BIG FAIL\n");
funmap(map);
return 0;
}

Loading…
Cancel
Save