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"
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
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)
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)
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()
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))
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')))