def on_certificate(self, cert): name = cert.subject_common_name() issuer_name = cert.issuer_common_name() query = db.get(name) if query is None: debug_logger.debug( "\t[-] You have not pinned this certificate %s" % name) return try: spki = cert.hash_spki(deep=1, algorithm="sha256") spki = base64.b64encode(spki) except: logger.error("Getting spki of the intermediate CA %s" % name) return try: issuers = query["issuers"] for i in issuers[issuer_name]: if spki == i: debug_logger.debug("\t[+] pin correct %s " % name) return logger.info("\t[-] Pin does not match %s" % name) debug_logger.debug("\t[-] Pin does not match %s" % name) MITMNotification.notify(title="Pinning", message=cert.subject_common_name()) except: MITMNotification.notify(title="Pinning", message="Issuer different") debug_logger.debug("\t[-] issuer with different name %s" % name)
def on_certificate(self, cert): hash_t = cert.hash_spki(algorithm="sha256") name = cert.subject_common_name() algorithm = cert.get_cert_nss().subject_public_key_info.algorithm algorithm = algorithm.id_str _id = algorithm + ' - ' + name exist = db.get(_id) if exist is None: # That means that the certificate is not in the db, it's the # first time it was seen db.set_hash(hash_t, _id) debug_logger.debug("\t[+] Certificate %s first seen" % name) else: # Exist so we have to ensure that it is correct correct = db.compare(_id, hash_t) if correct is False: before = db.get(_id) debug_logger.debug("\t[-] Certificate %s has changed" % name) logger.info( "\t[-] Certificate {0} has changed from".format(name) + " \n{0}--->{1}\n ".format(before["_id"], before["hash"]) + "to \n{0}--->{1}".format(algorithm, hash_t)) MITMNotification.notify(title=self.name, message=name) else: debug_logger.debug("\t[+] Certificate %s has not changed" % name)
def on_certificate(self, cert): name = cert.subject_common_name() issuer_name = cert.issuer_common_name() query = db.get(name) if query is None: debug_logger.debug( "\t[-] You have not pinned this certificate %s" % name) return try: spki = cert.hash_spki(deep=1, algorithm="sha256") spki = base64.b64encode(spki) except: logger.error("Getting spki of the intermediate CA %s" % name) return try: issuers = query["issuers"] for i in issuers[issuer_name]: if spki == i: debug_logger.debug("\t[+] pin correct %s " % name) return logger.info("\t[-] Pin does not match %s" % name) debug_logger.debug("\t[-] Pin does not match %s" % name) MITMNotification.notify( title="Pinning", message=cert.subject_common_name()) except: MITMNotification.notify( title="Pinning", message="Issuer different") debug_logger.debug("\t[-] issuer with different name %s" % name)
def on_certificate(self, cert): name = cert.ca_name() fingerprint = cert.hash() query = db.get(fingerprint) if query is None: debug_logger.debug( "\t[+] Certificate %s is safe against blacklist" % name) else: debug_logger.debug( "\t[-] Certificate %s matched with a malware site" % name) logger.info("\t[-] Certificate %s matched with a malware site" % name) MITMNotification.notify(title=self.name, message=cert.subject_common_name())
def _get_ocsp_response(self): if self.ocsp_url is not None: try: issuerCert, _ = decoder.decode( self.issuer_cert, asn1Spec=rfc2459.Certificate()) userCert, _ = decoder.decode( self.user_cert, asn1Spec=rfc2459.Certificate()) except: return ocspReq = self.make_ocsp_request(issuerCert, userCert) try: httpReq = urllib2.Request( self.ocsp_url, encoder.encode(ocspReq), {'Content-Type': 'application/ocsp-request'} ) httpRsp = urllib2.urlopen(httpReq).read() except: return # Process OCSP response ocspRsp, _ = decoder.decode( httpRsp, asn1Spec=rfc2560.OCSPResponse()) responseStatus = ocspRsp.getComponentByName('responseStatus') responseBytes = ocspRsp.getComponentByName('responseBytes') if responseStatus == 0: try: response = responseBytes.getComponentByName('response') except: self.tbsResponseData = -1 return basicOCSPResponse, _ = decoder.decode( response, asn1Spec=rfc2560.BasicOCSPResponse() ) self.tbsResponseData = basicOCSPResponse.getComponentByName( 'tbsResponseData') else: mes = "get status %d %s" % ( responseStatus, self._name) MITMNotification.notify(title="OCSP", message=mes)
def on_certificate(self, cert): approved_usage = not intended_usage try: length = cert.length_chain() if length > 4: debug_logger.debug( "\t[-] Certificate chain large > 4." + "It's a weird situtation") MITMNotification.notify( title="chain large", message=cert.subject_common_name(), group="NSS" ) return cert_nss = cert.get_cert_nss() name = cert.ca_name() certdb = nssconfig.certdb approved_usage = cert_nss.verify_now( certdb, True, intended_usage, None) except NSPRError: cert.add_to_nssdb(cert_nss.issuer.common_name, deep=1) if length == 4: inter = cert.get_cert_nss(deep=1) cert.add_to_nssdb(inter.issuer.common_name, deep=2) try: approved_usage = cert_nss.verify_now( certdb, True, intended_usage, None) except NSPRError: pass cert.remove_from_nssdb(cert_nss.issuer.common_name) if length == 4: cert.remove_from_nssdb(inter.issuer.common_name) if approved_usage & intended_usage: debug_logger.debug( "\t[+] Certificate %s is safe using NSS library" % name) else: debug_logger.debug( "\t[-] Certificate %s is not safe using NSS library" % name) logger.info( "\t[-] Certificate %s is not safe using NSS library" % name) MITMNotification.notify( title="Chain of trust", message=cert.subject_common_name())
def on_certificate(self, cert): name = cert.ca_name() fingerprint = cert.hash() query = db.get(fingerprint) if query is None: debug_logger.debug( "\t[+] Certificate %s is safe against blacklist" % name ) else: debug_logger.debug( "\t[-] Certificate %s matched with a malware site" % name ) logger.info( "\t[-] Certificate %s matched with a malware site" % name ) MITMNotification.notify( title=self.name, message=cert.subject_common_name())
def check_sct(self, sct): sct = decoder.decode(sct)[0] sct = str(decoder.decode(str(sct))[0]) now = datetime.utcnow() seconds_from = (now - datetime(1970, 1, 1)).total_seconds() sct_list_des = DeserializeSCTList(sct) list_sct = sct_list_des.deserialize_sct_list() for i in list_sct: sct = DeserializeSCT(i).deserialize_sct() if seconds_from > sct.timestamp: debug_logger.debug( "\t[+] SCT valid found: Version" + " = {0}, LogID = {1}, utc = {2}".format(sct.version, sct.logID, time.ctime(sct.timestamp)) ) else: debug_logger.debug("\t[-] SCT not valid. Timestamp" + " in the future") MITMNotification.notify(title="CT", message="SCT in the future")
def check_sct(self, sct): sct = decoder.decode(sct)[0] sct = str(decoder.decode(str(sct))[0]) now = datetime.utcnow() seconds_from = (now - datetime(1970, 1, 1)).total_seconds() sct_list_des = DeserializeSCTList(sct) list_sct = sct_list_des.deserialize_sct_list() for i in list_sct: sct = DeserializeSCT(i).deserialize_sct() if seconds_from > sct.timestamp: debug_logger.debug( "\t[+] SCT valid found: Version" + " = {0}, LogID = {1}, utc = {2}".format( sct.version, sct.logID, time.ctime(sct.timestamp))) else: debug_logger.debug("\t[-] SCT not valid. Timestamp" + " in the future") MITMNotification.notify(title="CT", message="SCT in the future")
def on_certificate(self, cert): approved_usage = not intended_usage try: length = cert.length_chain() if length > 4: debug_logger.debug("\t[-] Certificate chain large > 4." + "It's a weird situtation") MITMNotification.notify(title="chain large", message=cert.subject_common_name(), group="NSS") return cert_nss = cert.get_cert_nss() name = cert.ca_name() certdb = nssconfig.certdb approved_usage = cert_nss.verify_now(certdb, True, intended_usage, None) except NSPRError: cert.add_to_nssdb(cert_nss.issuer.common_name, deep=1) if length == 4: inter = cert.get_cert_nss(deep=1) cert.add_to_nssdb(inter.issuer.common_name, deep=2) try: approved_usage = cert_nss.verify_now(certdb, True, intended_usage, None) except NSPRError: pass cert.remove_from_nssdb(cert_nss.issuer.common_name) if length == 4: cert.remove_from_nssdb(inter.issuer.common_name) if approved_usage & intended_usage: debug_logger.debug( "\t[+] Certificate %s is safe using NSS library" % name) else: debug_logger.debug( "\t[-] Certificate %s is not safe using NSS library" % name) logger.info("\t[-] Certificate %s is not safe using NSS library" % name) MITMNotification.notify(title="Chain of trust", message=cert.subject_common_name())
def on_certificate(self, cert): address = cert.hash() + '.notary.icsi.berkeley.edu' name = cert.ca_name() try: result = resolver.query( address, rdtype=dns.rdatatype.TXT)[0].__str__().split() except: MITMNotification.notify(title="ICSI-NO Certificate", message=cert.subject_common_name()) debug_logger.debug("\t[-] Certificate %s isn't in icsi notary" % name) return validated = int(result[4].split('=')[1][0]) first_seen = int(result[1].split('=')[1]) last_seen = int(result[2].split('=')[1]) times_seen = int(result[3].split('=')[1]) if validated is not 1: debug_logger.debug("\t[-] Certificate {0}".format(name) + " is not safe through icsi notary") logger.info("\t[-] Certificate {0}".format(name) + "is not safe through icsi notary") MITMNotification.notify(title="ICSI-NO valid", message=cert.subject_common_name()) else: s = last_seen - first_seen + 1 if s - times_seen >= config.ICSI_MAXIMUM_INTERVAL: debug_logger.debug( "\t[-] Certificate {0}".format(name) + " is not enough secure acording with icsi notary") MITMNotification.notify(title='ICSI-NO famous', message=cert.subject_common_name()) else: debug_logger.debug( "\t[+] Certificate %s is secure through icsi notary" % name)
def on_certificate(self, cert): address = cert.hash()+'.notary.icsi.berkeley.edu' name = cert.ca_name() try: result = resolver.query( address, rdtype=dns.rdatatype.TXT )[0].__str__().split() except: MITMNotification.notify( title="ICSI-NO Certificate", message=cert.subject_common_name()) debug_logger.debug( "\t[-] Certificate %s isn't in icsi notary" % name ) return validated = int(result[4].split('=')[1][0]) first_seen = int(result[1].split('=')[1]) last_seen = int(result[2].split('=')[1]) times_seen = int(result[3].split('=')[1]) if validated is not 1: debug_logger.debug( "\t[-] Certificate {0}".format(name) + " is not safe through icsi notary") logger.info( "\t[-] Certificate {0}".format(name) + "is not safe through icsi notary") MITMNotification.notify( title="ICSI-NO valid", message=cert.subject_common_name()) else: s = last_seen - first_seen + 1 if s - times_seen >= config.ICSI_MAXIMUM_INTERVAL: debug_logger.debug( "\t[-] Certificate {0}".format(name) + " is not enough secure acording with icsi notary") MITMNotification.notify( title='ICSI-NO famous', message=cert.subject_common_name()) else: debug_logger.debug( "\t[+] Certificate %s is secure through icsi notary" % name)
def on_ocsp_response(self, ocsp): ( status, certId, thisUpdate, nextUpdate, issuerHashz ) = ocsp.get_response() serial = self._cert.serial_number() issuer = self._cert.der_data(1) try: issuer_der = decoder.decode( issuer, asn1Spec=rfc2459.Certificate())[0] except: debug_logger.debug("\t[-] ERROR parsing") return issuerTbsCert = issuer_der.getComponentByName('tbsCertificate') issuerSubjectPublicKey = issuerTbsCert.getComponentByName( 'subjectPublicKeyInfo').getComponentByName('subjectPublicKey') issuerKeyHash = hashlib.sha1( self.valueOnlyBitStringEncoder(issuerSubjectPublicKey) ).digest() name = self._cert.ca_name() if status is None: debug_logger.debug("\t[-] Certificate has not OCSP URI") return if status == 3: # It is own status code debug_logger.debug("\t[-] Not bytes in OCSP response") MITMNotification.notify( title="OCSP", message="No bytes in response") return if certId == serial and issuerHashz == issuerKeyHash: if status == 'revoked': debug_logger.debug("\t[-] Certificate %s revoked" % name) logger.info("\t[-] Certificate %s revoked" % name) MITMNotification.notify( title='OCSP', message=name) return utcnow = datetime.utcnow() try: date_thisUpdate = datetime( year=int(thisUpdate[0:4]), month=int(thisUpdate[4:6]), day=int(thisUpdate[6:8]), hour=int(thisUpdate[8:10]), minute=int(thisUpdate[10:12]), second=int(thisUpdate[12:14])) except: debug_logger.debug( "\t[-] This certificate although is NOT revoked does not" + "provide information in thisUpdate") return check_thisUpdate = utcnow > date_thisUpdate try: date_NextUpdate = datetime( year=int(nextUpdate[0:4]), month=int(nextUpdate[4:6]), day=int(nextUpdate[6:8]), hour=int(nextUpdate[8:10]), minute=int(nextUpdate[10:12]), second=int(nextUpdate[12:14])) check_NextUpdate = date_NextUpdate > utcnow if check_NextUpdate is True: self._check_thisUpdate(check_thisUpdate, name) else: debug_logger.debug( "\t[-] There will not be more revocation status" + "information about %s" % name) except: self._check_thisUpdate(check_thisUpdate, name) pass else: debug_logger.debug( "\t[-] Likely you have received a bad response from OCSP" + " responder of %s" % name) logger.info( "\t[-] Likely you have received a bad response from OCSP" + " responder of %s" % name) MITMNotification.notify( title='OCSP', message="OCSP bad response")