Exemplo n.º 1
0
def sigchecker(file):
    print (header("Digital Signature Info.:"))

    """
    sigcheck - not as useful compared to when on M$ platforms of course, but can provide info.
    """
    opts = " -q -a "
    cmd = wine + ' ' + sigcheck + opts + q(file)
    p = subprocess.Popen(cmd,stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
    (stdout, stderr) = p.communicate()
    if stdout:
        print "[-] Sigcheck:"
        print stdout
    else: print stderr

    """
    Verify-sigs - requires pyasn1 & m2crypto (apt-get insatll python-pyasn1 python-m2crypto)
    """
    print "[-] Verify-sigs:"
    with open(file, 'rb') as f:
        fingerprinter = fingerprint.Fingerprinter(f)
        is_pecoff = fingerprinter.EvalPecoff()
        fingerprinter.EvalGeneric()
        results = fingerprinter.HashIt()
        #print fingerprint.FormatResults(file_obj, results)
        if is_pecoff:
            # using a try statement here because of: http://code.google.com/p/verify-sigs/issues/detail?id=2
            try:
                fingerprint.FindPehash(results)
            except Exception, msg:
                print "[!] ERROR: %s" % msg
        else: print "Doesn't appear to be a PE/COFF file"
Exemplo n.º 2
0
def get_auth_data(filename):
    with open(filename, 'rb') as objf:
        fingerprinter = fingerprint.Fingerprinter(objf)
        fingerprinter.EvalGeneric()
        results = fingerprinter.HashIt()

    signed_pecoffs = [
        x for x in results if x['name'] == 'pecoff' and 'SignedData' in x
    ]

    if not signed_pecoffs:
        print('This PE/COFF binary has no signature. Exiting.')
        return

    signed_pecoff = signed_pecoffs[0]
    signed_datas = signed_pecoff['SignedData']

    # 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.
    # TODO(user): Process all instances
    signed_data = signed_datas[0]
    blob = pecoff_blob.PecoffBlob(signed_data)
    auth = auth_data.AuthData(blob.getCertificateBlob())
    content_hasher_name = auth.digest_algorithm().name
    computed_content_hash = signed_pecoff[content_hasher_name]

    return auth, computed_content_hash
Exemplo n.º 3
0
 def testReasonableInterval(self):
     # Check if the limit on maximum blocksize for processing still holds.
     dummy = StringIO.StringIO("")
     fp = fingerprint.Fingerprinter(dummy)
     big_finger = fingerprint.Finger(None, [fingerprint.Range(0, 1000001)],
                                     None)
     fp.fingers.append(big_finger)
     start, stop = fp._GetNextInterval()
     self.assertEquals(0, start)
     self.assertEquals(1000000, stop)
def main():
    os.chdir('test_data')
    files = os.listdir('.')
    for fnam in files:
        if not fnam.lower().endswith('.res'):
            print('Scanning %s' % fnam)
            with open(fnam, 'rb') as objf:
                fingerprinter = fingerprint.Fingerprinter(objf)
                fingerprinter.EvalPecoff()
                fingerprinter.EvalGeneric()
                results = fingerprinter.HashIt()
                with open(fnam + '.res', 'wb') as resf:
                    pickle.dump(results, resf, pickle.HIGHEST_PROTOCOL)
Exemplo n.º 5
0
 def testHashBlock(self):
     # Does it invoke a hash function?
     dummy = "12345"
     fp = fingerprint.Fingerprinter(StringIO.StringIO(dummy))
     big_finger = fingerprint.Finger(None,
                                     [fingerprint.Range(0, len(dummy))],
                                     None)
     hasher = self.MockHasher()
     big_finger.hashers = [hasher]
     fp.fingers.append(big_finger)
     # Let's process the block
     fp._HashBlock(dummy, 0, len(dummy))
     self.assertEquals(hasher.seen, dummy)
Exemplo n.º 6
0
 def testRunTestData(self):
     # Walk through all data files in the test_data folder, and compare output
     # with precomputed expected output.
     data_dir = os.path.join("test_data")
     files = os.listdir(data_dir)
     for fnam in files:
         if not fnam.lower().endswith(".res"):
             with file(os.path.join(data_dir, fnam), "rb") as objf:
                 fp = fingerprint.Fingerprinter(objf)
                 fp.EvalGeneric()
                 fp.EvalPecoff()
                 results = fp.HashIt()
                 with file(os.path.join(data_dir, fnam + ".res"),
                           "rb") as resf:
                     exp_results = pickle.load(resf)
                     diff = (exp_results != results)
                     if diff:
                         print
                         print fingerprint.FormatResults(resf, exp_results)
                         print fingerprint.FormatResults(objf, results)
                         self.fail()
Exemplo n.º 7
0
    def testAdjustments(self):
        dummy = StringIO.StringIO("")
        fp = fingerprint.Fingerprinter(dummy)
        big_finger = fingerprint.Finger(None, [fingerprint.Range(10, 20)],
                                        None)
        fp.fingers.append(big_finger)

        # The remaining range should not yet be touched...
        fp._AdjustIntervals(9, 10)
        self.assertEquals([fingerprint.Range(10, 20)], fp.fingers[0].ranges)
        # Trying to consume into the range. Blow up.
        self.assertRaises(RuntimeError, fp._AdjustIntervals, 9, 11)
        # We forgot a byte. Blow up.
        self.assertRaises(RuntimeError, fp._AdjustIntervals, 11, 12)
        # Consume a byte
        fp._AdjustIntervals(10, 11)
        self.assertEquals([fingerprint.Range(11, 20)], fp.fingers[0].ranges)
        # Consumed too much. Blow up.
        self.assertRaises(RuntimeError, fp._AdjustIntervals, 11, 21)
        # Consume exactly.
        fp._AdjustIntervals(11, 20)
        self.assertEquals(0, len(fp.fingers[0].ranges))
Exemplo n.º 8
0
def main():
    data_file = sys.argv[1]

    with file(data_file, 'rb') as objf:
        fingerprinter = fingerprint.Fingerprinter(objf)
        is_pecoff = fingerprinter.EvalPecoff()
        fingerprinter.EvalGeneric()
        results = fingerprinter.HashIt()

    print('Generic hashes:')
    hashes = [x for x in results if x['name'] == 'generic']
    if len(hashes) > 1:
        print('More than one generic finger? Only printing first one.')
    for hname in sorted(hashes[0].keys()):
        if hname != 'name':
            print('%s: %s' % (hname, hashes[0][hname].encode('hex')))
    print

    if not is_pecoff:
        print('This is not a PE/COFF binary. Exiting.')
        return

    print('PE/COFF hashes:')
    hashes = [x for x in results if x['name'] == 'pecoff']
    if len(hashes) > 1:
        print('More than one PE/COFF finger? Only printing first one.')
    for hname in sorted(hashes[0].keys()):
        if hname != 'name' and hname != 'SignedData':
            print('%s: %s' % (hname, hashes[0][hname].encode('hex')))
    print

    signed_pecoffs = [
        x for x in results if x['name'] == 'pecoff' and 'SignedData' in x
    ]

    if not signed_pecoffs:
        print('This PE/COFF binary has no signature. Exiting.')
        return

    signed_pecoff = signed_pecoffs[0]

    signed_datas = signed_pecoff['SignedData']

    if len(signed_datas) > 1:
        raise Exception(
            "TODO Add support for printing more than one certificate")
    # 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.
    # TODO(user): Process all instances
    signed_data = signed_datas[0]

    debugging_fd = open(
        '/tmp/%s_extracted_cert.p7b' % os.path.basename(data_file), 'wb')
    debugging_fd.write(signed_data[2])
    debugging_fd.close()

    blob = pecoff_blob.PecoffBlob(signed_data)

    auth = auth_data.AuthData(blob.getCertificateBlob())
    content_hasher_name = auth.digest_algorithm().name
    computed_content_hash = signed_pecoff[content_hasher_name]

    try:
        auth.ValidateAsn1()
        auth.ValidateHashes(computed_content_hash)
        auth.ValidateSignatures()
        auth.ValidateCertChains(time.gmtime())
    except auth_data.Asn1Error:
        if auth.openssl_error:
            print('OpenSSL Errors:\n%s' % auth.openssl_error)
        raise

    print('Program: %s, URL: %s' % (repr(auth.program_name), auth.program_url))
    if auth.has_countersignature:
        print('Countersignature is present. Timestamp: %s UTC' %
              time.asctime(time.gmtime(auth.counter_timestamp)))
    else:
        print('Countersignature is not present.')

    print('Binary is signed with cert issued by:')
    pprint.pprint(auth.signing_cert_id)
    print

    print('Cert chain head issued by:')
    pprint.pprint(auth.cert_chain_head[2])
    print('  Chain not before: %s UTC' %
          (time.asctime(time.gmtime(auth.cert_chain_head[0]))))
    print('  Chain not after: %s UTC' %
          (time.asctime(time.gmtime(auth.cert_chain_head[1]))))
    print

    if auth.has_countersignature:
        print('Countersig chain head issued by:')
        pprint.pprint(auth.counter_chain_head[2])
        print('  Countersig not before: %s UTC' %
              (time.asctime(time.gmtime(auth.counter_chain_head[0]))))
        print('  Countersig not after: %s UTC' %
              (time.asctime(time.gmtime(auth.counter_chain_head[1]))))
        print

    print('Certificates')
    for (issuer, serial), cert in auth.certificates.items():
        print('  Issuer: %s' % issuer)
        print('  Serial: %s' % serial)
        subject = cert[0][0]['subject']
        subject_dn = str(dn.DistinguishedName.TraverseRdn(subject[0]))
        print('  Subject: %s' % subject_dn)
        not_before = cert[0][0]['validity']['notBefore']
        not_after = cert[0][0]['validity']['notAfter']
        not_before_time = not_before.ToPythonEpochTime()
        not_after_time = not_after.ToPythonEpochTime()
        print('  Not Before: %s UTC (%s)' %
              (time.asctime(time.gmtime(not_before_time)), not_before[0]))
        print('  Not After: %s UTC (%s)' %
              (time.asctime(time.gmtime(not_after_time)), not_after[0]))
        bin_cert = der_encoder.encode(cert)
        print('  MD5: %s' % hashlib.md5(bin_cert).hexdigest())
        print('  SHA1: %s' % hashlib.sha1(bin_cert).hexdigest())
        print

    if auth.trailing_data:
        print('Signature Blob had trailing (unvalidated) data (%d bytes): %s' %
              (len(auth.trailing_data), auth.trailing_data.encode('hex')))