Ejemplo n.º 1
0
 def on_ocsp_response(self, ocsp):
     sct = ocsp.check_certificate_transparency()
     if sct is not None:
         self.check_sct(sct)
     else:
         debug_logger.debug("\t[-] Certificate %s has not SCT" %
                            self._ca_name)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
 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())
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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())
Ejemplo n.º 7
0
    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")
Ejemplo n.º 8
0
    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")
Ejemplo n.º 9
0
    def dispatch_certificate(self):
        # Do everything related with certificate
        if self.certs is not None:
            # verify certificate
            try:
                chain = X509Chain(self.certs)
            except Exception:
                return
            if chain.length_chain() == 1:
                try:
                    debug_logger.debug(
                        '[-] Chain incomplete from %s' % chain.ca_name()
                        )
                    logger.info(
                        "The chain is incomplete %s"
                        % chain.subject_common_name()
                        )
                except Exception:
                    debug_logger.debug('[-] Chain incomplete')
                    logger.info('[-] Chain incomplete')
            else:
                # TODO ask ocsp status when is only necessary
                ocsp = Ocsp(chain)
                debug_logger.debug('[+] Verifying certificate')
                for cls in handlers.store:
                    handlers.store[cls](chain, ocsp)

        else:
            pass
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
    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())
Ejemplo n.º 13
0
    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())
Ejemplo n.º 14
0
    def dispatch_certificate(self):
        # Do everything related with certificate
        if self.certs is not None:
            # verify certificate
            try:
                chain = X509Chain(self.certs)
            except Exception:
                return
            if chain.length_chain() == 1:
                try:
                    debug_logger.debug("[-] Chain incomplete from %s" % chain.ca_name())
                    logger.info("The chain is incomplete %s" % chain.subject_common_name())
                except Exception:
                    debug_logger.debug("[-] Chain incomplete")
                    logger.info("[-] Chain incomplete")
            else:
                # TODO ask ocsp status when is only necessary
                ocsp = Ocsp(chain)
                debug_logger.debug("[+] Verifying certificate")
                for cls in handlers.store:
                    handlers.store[cls](chain, ocsp)

        else:
            pass
Ejemplo n.º 15
0
 def _check_thisUpdate(self, check_thisUpdate, name):
     if check_thisUpdate is True:
         debug_logger.debug(
             "\t[+] Certificate %s is not revoked" % name)
     elif check_thisUpdate is False:
         debug_logger.debug('\t[-] Awkward Situation %s' % name)
Ejemplo n.º 16
0
 def on_ocsp_response(self, ocsp):
     sct = ocsp.check_certificate_transparency()
     if sct is not None:
         self.check_sct(sct)
     else:
         debug_logger.debug("\t[-] Certificate %s has not SCT" % self._ca_name)
Ejemplo n.º 17
0
    def on_certificate(self, cert):

        def verify(url):
            try:
                answer = dns.resolver.query('_443._tcp.' + url, 'TLSA')
            except:
                # print "Unexpected error:", sys.exc_info()[0]
                return -1

            (
                cert_usage,
                selector,
                match_type,
                associated_data
            ) = [str(ans) for ans in answer][0].split(' ')
            funct = [cert.der_data, cert.subject_public_key_info]
            hash_funct = [None, hashlib.sha256, hashlib.sha512]
            temp = hash_funct[int(match_type)]

            # depend on the match_type we need use different algorithms

            if cert_usage == '3' or cert_usage == '1':
                # depend on the selector file we use the whole certificate or
                # only the subjectPublicKeyInfo
                data = funct[int(selector)]()
                if temp is not None:
                    m = temp(data)
                    data = m.hexdigest()
                if data == associated_data:
                    return True
                else:
                    return False

            if cert_usage == '0' or cert_usage == '2':
                # We must check for each certificate in the chain that the
                # associated data is presented

                for cer in xrange(0, cert.length_chain()):
                    data = funct[int(selector)](deep=cer)
                    if temp is not None:
                        m = temp(data)
                        data = m.hexdigest()

                    if data == associated_data:
                        if cert_usage == '0':
                            return True
                        else:
                            cert.add_to_nssdb(
                                cert.subject_common_name(deep=cer),
                                deep=cer)
                            value = self.verify_chain(cert)
                            cert.remove_from_nssdb(
                                cert.subject_common_name(deep=cer)
                                )
                            return value
                return False

        try:
            url = cert.subject_common_name()
        except IndexError:
            debug_logger.debug("\t[-] ERROR extracting subject_common_name")
            return

        result = False
        result = verify(url)

        if result is True:
            debug_logger.debug(
                "\t[+] Certificate %s has a valid TLSA record" %
                cert.ca_name()
                )
            return

        if url[0:3] == "www":
            url = url.replace("www.", '')
            result = verify(url)

        if url[0] == '*':
            url = url.replace('*', 'www')
            result = verify(url)
            if result is True:
                debug_logger.debug(
                    "\t[+] Certificate %s has a valid TLSA record" %
                    cert.ca_name()
                    )
                return

            url = url.replace('www', '*')

        if url[0] == '*.':
            url = url.replace('*.', '')
            result = verify(url)

        if result is True:
            debug_logger.debug(
                "\t[+] Certificate %s has a valid TLSA record" %
                cert.ca_name()
                )
            return
        if result == -1:
            debug_logger.debug(
                "\t[-] Certificate {0} does not implement DANE".format(
                    cert.ca_name()))
            return

        debug_logger.debug(
            "\t[-] Certificate {0} has not a valid TLSA".format(
                cert.ca_name()))
Ejemplo n.º 18
0
    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")