Beispiel #1
0
    def test_software_update(self):
        with open(str(root_dir / "test_data" / "SoftwareUpdate.exe"),
                  "rb") as f:
            fingerprinter = AuthenticodeFingerprinter(f)
            fingerprinter.add_authenticode_hashers(hashlib.sha1)
            hashes = fingerprinter.hash()

            # Sanity check that the authenticode hash is still correct
            self.assertEqual(
                binascii.hexlify(hashes['sha1']).decode('ascii'),
                '978b90ace99c764841d2dd17d278fac4149962a3')

            pefile = SignedPEFile(f)

            # This should not raise any errors.
            signed_datas = list(pefile.signed_datas)
            # There may be multiple of these, if the windows binary was signed multiple
            # times, e.g. by different entities. Each of them adds a complete SignedData
            # blob to the binary. For our sample, there is only one blob.
            self.assertEqual(len(signed_datas), 1)
            signed_data = signed_datas[0]

            self.assertEqual(signed_data._rest_data, b'\0')

            signed_data.verify()

            # should work as well
            pefile.verify()
Beispiel #2
0
 def test_0d8c_valid(self):
     with open(
             str(root_dir / "test_data" /
                 "0d8c2bcb575378f6a88d17b5f6ce70e794a264cdc8556c8e812f0b5f9c709198"
                 ), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify()
Beispiel #3
0
 def test_pciide(self):
     with open(str(root_dir / "test_data" / "pciide.sys"), "rb") as f:
         pefile = SignedPEFile(f)
         signed_datas = list(pefile.signed_datas)
         self.assertEqual(len(signed_datas), 1)
         signed_data = signed_datas[0]
         signed_data.verify()
         pefile.verify()
Beispiel #4
0
 def test_3a7de393a36ca8911cd0842a9a25b058_valid_different_contenttype(
         self):
     """uses a different contenttype, 1.2.840.113549.1.9.16.1.4 instead of Data"""
     with open(
             str(root_dir / "test_data" /
                 "3a7de393a36ca8911cd0842a9a25b058"), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify()
Beispiel #5
0
 def test_0d8c_valid(self):
     with open(
             str(root_dir / "test_data" /
                 "0d8c2bcb575378f6a88d17b5f6ce70e794a264cdc8556c8e812f0b5f9c709198"
                 ), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify(
             trusted_certificate_store=TRUSTED_CERTIFICATE_STORE_NO_CTL)
Beispiel #6
0
 def test_jameslth_revoked(self):
     """this certificate is revoked"""
     with open(str(root_dir / "test_data" / "jameslth"), "rb") as f:
         pefile = SignedPEFile(f)
         with self.assertRaises(VerificationError):
             pefile.verify(verification_context_kwargs={
                 'allow_fetching': True,
                 'revocation_mode': 'hard-fail'
             })
Beispiel #7
0
 def test_sw_reporter(self):
     """Test for SHA256 hashes used in sig"""
     with open(str(root_dir / "test_data" / "software_reporter_tool.exe"),
               "rb") as f:
         pefile = SignedPEFile(f)
         signed_datas = list(pefile.signed_datas)
         self.assertEqual(len(signed_datas), 1)
         signed_data = signed_datas[0]
         signed_data.verify()
         pefile.verify()
Beispiel #8
0
 def test_19e8_valid_within_period(self):
     with open(
             str(root_dir / "test_data" /
                 "19e818d0da361c4feedd456fca63d68d4b024fbbd3d9265f606076c7ee72e8f8.ViR"
                 ), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify(
             verification_context_kwargs={
                 'timestamp':
                 datetime.datetime(2013, 1, 1, tzinfo=datetime.timezone.utc)
             })
Beispiel #9
0
 def test_19e8_expired(self):
     with open(
             str(root_dir / "test_data" /
                 "19e818d0da361c4feedd456fca63d68d4b024fbbd3d9265f606076c7ee72e8f8.ViR"
                 ), "rb") as f:
         pefile = SignedPEFile(f)
         self.assertRaises(VerificationError, pefile.verify)
Beispiel #10
0
 def test_modified_pciide_fails(self):
     with open(str(root_dir / "test_data" / "pciide.sys"), "rb") as f:
         data = bytearray(f.read())
     data[1024] = 3
     bt = io.BytesIO(data)
     pefile = SignedPEFile(bt)
     signed_datas = list(pefile.signed_datas)
     self.assertEqual(len(signed_datas), 1)
     self.assertRaises(AuthenticodeVerificationError, signed_datas[0].verify)
     self.assertRaises(AuthenticodeVerificationError, pefile.verify)
Beispiel #11
0
    def add_authenticode_hashers(self, *hashers):
        """Specialized method of :meth:`add_hashers` to add hashers with ranges limited to those that are needed to
        calculate the hash of signed PE Files.
        """

        pefile = SignedPEFile(self.file)
        omit = pefile.get_authenticode_omit_sections()

        if omit is None:
            return False

        ranges = []
        start = 0
        for start_length in sorted(omit.values()):
            ranges.append(Range(start, start_length.start))
            start = sum(start_length)
        ranges.append(Range(start, self._filelength))

        self.add_hashers(*hashers, ranges=ranges, description='authentihash')
        return True
Beispiel #12
0
def main():
    data_file = sys.argv[1]
    try:
        with open(data_file, 'rb') as objf:
            pefile = SignedPEFile(objf)
            try:
                pefile.verify()
            except AuthenticodeVerificationError:
                print("could not verify cert")
            except Exception as error:
                print("error with verify")
                print(error.__class__.__name__ + ": " + error.message)
                return {}

            for signed_data in pefile.signed_datas:
                print(signed_data.signer_info.program_name)
                for cert in signed_data.certificates:
                    print(cert)
    except Exception as error:
        print("Gen error")
        print(error.__class__.__name__ + ": " + error.message)
Beispiel #13
0
 def test_potential_chains(self):
     with open(
             str(root_dir / "test_data" /
                 "19e818d0da361c4feedd456fca63d68d4b024fbbd3d9265f606076c7ee72e8f8.ViR"
                 ), "rb") as f:
         pefile = SignedPEFile(f)
         for signed_data in pefile.signed_datas:
             context = VerificationContext(TRUSTED_CERTIFICATE_STORE,
                                           signed_data.certificates)
             potential_chains = list(
                 signed_data.signer_info.potential_chains(context))
             self.assertEqual(len(potential_chains), 2)
Beispiel #14
0
def parse_certificates(data):
    # set up string io as we get data
    buffer = BytesIO()
    buffer.write(data)
    buffer.seek(0)

    try:
        pefile = SignedPEFile(buffer)
        signed_datas = list(pefile.signed_datas)
    except (SignedPEParseError, SignerInfoParseError, AuthenticodeParseError,
            VerificationError, CertificateVerificationError,
            SignerInfoVerificationError, AuthenticodeVerificationError) as e:
        logging.info(f"signify threw error {e} when processing PE file")
        return {}

    cert_list = []
    signer_list = []
    counter_signer_list = []

    for signed_data in signed_datas:
        try:
            certs = signed_data.certificates
            for cert in certs:
                asn1 = cert.to_asn1crypto
                issuer = asn1.issuer.native
                cert_dict = {
                    "country_name":
                    issuer.get("country_name"),
                    "organization_name":
                    issuer.get("organization_name"),
                    "organizational_unit_name":
                    issuer.get("organizational_unit_name"),
                    "common_name":
                    issuer.get("common_name"),
                    "serial_number":
                    str(cert.serial_number),
                    "issuer_dn":
                    cert.issuer_dn,
                    "subject_dn":
                    cert.subject_dn,
                    "valid_from":
                    cert.valid_from.isoformat(),
                    "valid_to":
                    cert.valid_to.isoformat(),
                    # "signature_algorithim": cert.signature_algorithm
                }
                cert_list.append(cert_dict)

            signer_dict = {
                'issuer': signed_data.signer_info.issuer_dn,
                'serial': str(signed_data.signer_info.serial_number),
                'program_name': signed_data.signer_info.program_name,
                'more_info': signed_data.signer_info.more_info
            }
            # signer information
            signer_list.append(signer_dict)

            if signed_data.signer_info.countersigner:
                counter_signer_dict = {
                    'issuer_dn':
                    signed_data.signer_info.countersigner.issuer_dn,
                    'serial_number':
                    str(signed_data.signer_info.countersigner.serial_number),
                    'signing_time':
                    signed_data.signer_info.countersigner.signing_time.
                    isoformat()
                }
                counter_signer_list.append(counter_signer_dict)

        except SignedPEParseError:
            logging.debug("no certificate in signed data")

    security_dict = {
        'certificates': cert_list,
        'signers': signer_list,
        'counter_signers': counter_signer_list
    }

    try:
        pefile.verify()
        security_dict["verification"] = True
    except Exception as e:
        security_dict['verification'] = False
        security_dict['verification_error'] = str(e)

    return security_dict
Beispiel #15
0
 def test_simple(self):
     with open(str(root_dir / "test_data" / "simple"), "rb") as f:
         pefile = SignedPEFile(f)
         self.assertRaises(SignedPEParseError, list, pefile.signed_datas)
         self.assertRaises(SignedPEParseError, pefile.verify)
Beispiel #16
0
 def test_2A6E(self):
     with open(str(root_dir / "test_data" / "___2A6E.tmp"), "rb") as f:
         pefile = SignedPEFile(f)
         self.assertRaises(VerificationError, pefile.verify)
Beispiel #17
0
 def test_whois_valid_countersignature_rfc3161(self):
     """whois includes a 1.3.6.1.4.1.311.3.3.1 type countersignature"""
     with open(str(root_dir / "test_data" / "whois.exe"), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify()
Beispiel #18
0
 def test_zonealarm_rfc3161_different_hash_and_digest_algorithms(self):
     """this tests a RFC3161 sample that has distinct hash and digest algorithms"""
     with open(str(root_dir / "test_data" / "zonealarm.exe"), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify()
Beispiel #19
0
 def test_7z1900_invalid_cve2020_0601(self):
     # This tests against CVE-2020-0601
     with open(str(root_dir / "test_data" / "7z1900-x64_signed.exe"), "rb") as f:
         pefile = SignedPEFile(f)
         self.assertRaises(VerificationError, pefile.verify)
Beispiel #20
0
 def test_solwarwinds_valid_countersignature_rfc3161(self):
     # Solarwinds includes a 1.3.6.1.4.1.311.3.3.1 type countersignature
     with open(str(root_dir / "test_data" / "SolarWinds.exe"), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify()
Beispiel #21
0
 def test_jameslth_valid_when_revocation_not_checked(self):
     # this certificate is revoked
     with open(str(root_dir / "test_data" / "jameslth"), "rb") as f:
         pefile = SignedPEFile(f)
         pefile.verify()