Created
May 26, 2020 14:27
-
-
Save woodruffw/d163c761af63a94add73d125f210406a to your computer and use it in GitHub Desktop.
uthenticode snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| auto *md = indir_data->messageDigest; | |
| auto nid = OBJ_obj2nid(md->digestAlgorithm->algorithm); | |
| auto digest = std::vector<std::uint8_t>(md->digest->data, md->digest->data + md->digest->length); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct win_certificate { | |
| uint32_t length; /* dwLength */ | |
| uint16_t revision; /* wRevision */ | |
| uint16_t certificate_type; /* wCertificateType */ | |
| uint8_t certificate[/* length */]; /* bCertificate */ | |
| } __attribute__((aligned (8))); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SpcSerializedObject ::= SEQUENCE { | |
| classId SpcUuid, | |
| serializedData Impl_SpcSerializedData | |
| } | |
| Impl_SpcSerializedData ::= SET OF Impl_SpcPageHash | |
| Impl_SpcPageHash ::= SEQUENCE { | |
| type OBJECT IDENTIFIER, | |
| pageHashes OCTETSTRING | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct impl_page_hash { | |
| /* page_offset corresponds to a real file offset within each section, | |
| * and should be aligned by page size. | |
| */ | |
| uint32_t page_offset; | |
| uint8_t page_hash[IMPL_PAGE_HASH_SIZE]; | |
| } __attribute__((packed)); | |
| typedef impl_page_hash *impl_page_hashes; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SpcIndirectDataContent ::= SEQUENCE { | |
| data SpcAttributeTypeAndOptionalValue, | |
| messageDigest DigestInfo | |
| } | |
| SpcAttributeTypeAndOptionalValue ::= SEQUENCE { | |
| type OBJECT IDENTIFIER, | |
| value [0] EXPLICIT ANY OPTIONAL | |
| } | |
| DigestInfo ::= SEQUENCE { | |
| digestAlgorithm AlgorithmIdentifier, | |
| digest OCTETSTRING | |
| } | |
| AlgorithmIdentifier ::= SEQUENCE { | |
| algorithm OBJECT IDENTIFIER, | |
| parameters [0] EXPLICIT ANY OPTIONAL | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| typedef struct { | |
| ASN1_OBJECT *type; | |
| ASN1_TYPE *value; | |
| } Authenticode_SpcAttributeTypeAndOptionalValue; | |
| typedef struct { | |
| X509_ALGOR *digestAlgorithm; | |
| ASN1_OCTET_STRING *digest; | |
| } Authenticode_DigestInfo; | |
| typedef struct { | |
| Authenticode_SpcAttributeTypeAndOptionalValue *data; | |
| Authenticode_DigestInfo *messageDigest; | |
| } Authenticode_SpcIndirectDataContent; | |
| ASN1_SEQUENCE(Authenticode_SpcAttributeTypeAndOptionalValue) = { | |
| ASN1_SIMPLE(Authenticode_SpcAttributeTypeAndOptionalValue, type, ASN1_OBJECT), | |
| ASN1_OPT(Authenticode_SpcAttributeTypeAndOptionalValue, value, ASN1_ANY) | |
| } ASN1_SEQUENCE_END(Authenticode_SpcAttributeTypeAndOptionalValue) | |
| IMPLEMENT_ASN1_FUNCTIONS(Authenticode_SpcAttributeTypeAndOptionalValue) | |
| ASN1_SEQUENCE(Authenticode_DigestInfo) = { | |
| ASN1_SIMPLE(Authenticode_DigestInfo, digestAlgorithm, X509_ALGOR), | |
| ASN1_SIMPLE(Authenticode_DigestInfo, digest, ASN1_OCTET_STRING) | |
| } ASN1_SEQUENCE_END(Authenticode_DigestInfo) | |
| IMPLEMENT_ASN1_FUNCTIONS(Authenticode_DigestInfo) | |
| ASN1_SEQUENCE(Authenticode_SpcIndirectDataContent) = { | |
| ASN1_SIMPLE(Authenticode_SpcIndirectDataContent, data, Authenticode_SpcAttributeTypeAndOptionalValue), | |
| ASN1_SIMPLE(Authenticode_SpcIndirectDataContent, messageDigest, Authenticode_DigestInfo) | |
| } ASN1_SEQUENCE_END(Authenticode_SpcIndirectDataContent) | |
| IMPLEMENT_ASN1_FUNCTIONS(Authenticode_SpcIndirectDataContent) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| TimeStampRequest ::= SEQUENCE { | |
| countersignatureType OBJECT IDENTIFIER, | |
| attributes Attributes OPTIONAL, | |
| content ContentInfo | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <uthenticode.h> | |
| #include <iostream> | |
| int main(int argc, char **argv) { | |
| auto *pe = peparse::ParsePEFromFile(argv[1]); | |
| std::cout << argv[1] << " has a " | |
| << (uthenticode::verify(pe) ? "valid" : "invalid") | |
| << " signature!"; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Assuming that buf is an OpenSSL BIO* containing the DER-encoded PKCS#7 object */ | |
| auto *p7 = d2i_PKCS7_bio(buf, nullptr); | |
| auto *contents = p7->d.sign->contents; | |
| /* The d2i_ family increments the pointer passed to it, so we make a copy. */ | |
| auto *indir_data_inc_ptr = contents->d.other->value.sequence->data; | |
| auto *indir_data = d2i_Authenticode_SpcIndirectDataContent( | |
| nullptr, &indir_data_inc_ptr, contents->d.other->value.sequence->length); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| STACK_OF(X509) *certs = p7->d.sign->cert; | |
| /* Re-serialize the SpcIndirectDataContent to DER... */ | |
| std::uint8_t indir_data_buf = nullptr; | |
| i2d_Authenticode_SpcIndirectDataContent(indir_data, &indir_data_buf); | |
| /* ...so that we can unwrap its sequence here. */ | |
| const auto *signed_data_seq = indir_data_buf; | |
| long length = 0; | |
| int tag = 0, tag_class = 0; | |
| ASN1_get_object(&signed_data_seq, &length, &tag, &tag_class, buf_size); | |
| assert(tag == V_ASN1_SEQUENCE); | |
| auto *signed_data = BIO_new_mem_buf(signed_data_seq, length); | |
| /* Our stack of certs isn't guaranteed to include the root cert, | |
| * so pass PKCS7_NOVERIFY. | |
| */ | |
| PKCS7_verify(p7, certs, nullptr, signed_data, nullptr, PKCS7_NOVERIFY); | |
| assert(status == 1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment