Example #1
0
def extract_emotet_rsakey(pe):
    for section in pe.sections:
        if section.Name.replace(b"\x00", b"") == b".data":
            data_section = section.get_data()
            data_size = len(data_section)
    res_list = []
    if data_size:
        delta = 0
        while delta < data_size:
            xor_key = int.from_bytes(data_section[delta:delta + 4],
                                     byteorder="little")
            encoded_size = int.from_bytes(data_section[delta + 4:delta + 8],
                                          byteorder="little")
            decoded_size = ((xor_key ^ encoded_size) & 0xFFFFFFFC) + 4
            if decoded_size == 0x6C:
                res_list.append(
                    emotet_decode(data_section[delta:], decoded_size, xor_key))
                break
            delta += 4
        if res_list:
            res_list = list(set(res_list))
            pub_key = res_list[0][:106]
            seq = asn1.DerSequence()
            try:
                seq.decode(pub_key)
            except Exception as e:
                logging.exception(e)
                return
            return RSA.construct((seq[0], seq[1]))
    for section in pe.sections:
        if section.Name.replace(b"\x00", b"") == b".text":
            code_section = section.get_data()
            code_size = len(code_section)
    if code_size:
        delta = 0
        while delta < code_size:
            xor_key = int.from_bytes(code_section[delta:delta + 4],
                                     byteorder="little")
            encoded_size = int.from_bytes(code_section[delta + 4:delta + 8],
                                          byteorder="little")
            decoded_size = ((xor_key ^ encoded_size) & 0xFFFFFFFC) + 4
            if decoded_size == 0x6C:
                res_list.append(
                    emotet_decode(code_section[delta:], decoded_size, xor_key))
                break
            delta += 4
        if res_list:
            res_list = list(set(res_list))
            pub_key = res_list[0][:106]
            seq = asn1.DerSequence()
            try:
                seq.decode(pub_key)
            except ValueError as e:
                log.error(e)
                return
            return RSA.construct((seq[0], seq[1]))
 def testImportKey12(self):
     """Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
     der = asn1.DerSequence([17, 3]).encode()
     pem = der2pem(der)
     key = RSA.importKey(pem)
     self.assertEqual(key.n, 17)
     self.assertEqual(key.e, 3)
 def testImportKey11(self):
     """Verify import of RSAPublicKey DER SEQUENCE"""
     der = asn1.DerSequence([17, 3]).encode()
     key = RSA.importKey(der)
     self.assertEqual(key.n, 17)
     self.assertEqual(key.e, 3)
Example #4
0
def auth(username, password, **kwargs):
    '''
    Returns True if the given user cert (password is the cert contents)
    was issued by the CA and if cert's Common Name is equal to username.

    Returns False otherwise.

    ``username``: we need it to run the auth function from CLI/API;
                  it should be in master config auth/acl
    ``password``: contents of user certificate (pem-encoded user public key);
                  why "password"? For CLI, it's the only available name

    Configure the CA cert in the master config file:

    .. code-block:: yaml

        external_auth:
          pki:
            ca_file: /etc/pki/tls/ca_certs/trusted-ca.crt
            your_user:
              - .*
    '''
    c = OpenSSL.crypto
    pem = password
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, pem)

    cacert_file = __salt__['config.get']('external_auth:pki:ca_file')
    with salt.utils.files.fopen(cacert_file) as f:
        cacert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())

    log.debug('Attempting to authenticate via pki.')
    log.debug('Using CA file: {0}'.format(cacert_file))
    log.debug('Certificate contents: {0}'.format(pem))

    # Get the signing algorithm
    algo = cert.get_signature_algorithm()

    # Get the ASN1 format of the certificate
    cert_asn1 = c.dump_certificate(c.FILETYPE_ASN1, cert)

    # Decode the certificate
    der = asn1.DerSequence()
    der.decode(cert_asn1)

    # The certificate has three parts:
    # - certificate
    # - signature algorithm
    # - signature
    # http://usefulfor.com/nothing/2009/06/10/x509-certificate-basics/
    der_cert = der[0]
    #der_algo = der[1]
    der_sig = der[2]

    # The signature is a BIT STRING (Type 3)
    # Decode that as well
    der_sig_in = asn1.DerObject()
    der_sig_in.decode(der_sig)

    # Get the payload
    sig0 = der_sig_in.payload

    # Do the following to see a validation error for tests
    # der_cert=der_cert[:20]+'1'+der_cert[21:]

    # First byte is the number of unused bits. This should be 0
    # http://msdn.microsoft.com/en-us/library/windows/desktop/bb540792(v=vs.85).aspx
    if sig0[0] != '\x00':
        raise Exception('Number of unused bits is strange')
    # Now get the signature itself
    sig = sig0[1:]

    # And verify the certificate
    try:
        c.verify(cacert, sig, der_cert, algo)
        assert dict(cert.get_subject().get_components())['CN'] == username, "Certificate's CN should match the username"
        log.info('Successfully authenticated certificate: {0}'.format(pem))
        return True
    except (OpenSSL.crypto.Error, AssertionError):
        log.info('Failed to authenticate certificate: {0}'.format(pem))
    return False
Example #5
0
    def verify(self, signing_cert_str, cert_str):
        """
        Verifies if a certificate is valid and signed by a given certificate.

        :param signing_cert_str: This certificate will be used to verify the
                                  signature. Must be a string representation
                                 of the certificate. If you only have a file
                                 use the method read_str_from_file to
                                 get a string representation.
        :param cert_str:         This certificate will be verified if it is
                                  correct. Must be a string representation
                                 of the certificate. If you only have a file
                                 use the method read_str_from_file to
                                 get a string representation.
        :return:                 Valid, Message
                                 Valid = True if the certificate is valid,
                                 otherwise false.
                                 Message = Why the validation failed.
        """
        try:
            ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM,
                                              signing_cert_str)
            cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_str)

            if self.certificate_not_valid_yet(ca_cert):
                return False, "CA certificate is not valid yet."

            if ca_cert.has_expired() == 1:
                return False, "CA certificate is expired."

            if cert.has_expired() == 1:
                return False, "The signed certificate is expired."

            if self.certificate_not_valid_yet(cert):
                return False, "The signed certificate is not valid yet."

            if ca_cert.get_subject().CN == cert.get_subject().CN:
                return False, (
                    "CN may not be equal for CA certificate and the "
                    "signed certificate.")

            cert_algorithm = cert.get_signature_algorithm()
            if six.PY3:
                cert_algorithm = cert_algorithm.decode('ascii')

            cert_asn1 = crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)

            der_seq = asn1.DerSequence()
            der_seq.decode(cert_asn1)

            cert_certificate = der_seq[0]
            #cert_signature_algorithm=der_seq[1]
            cert_signature = der_seq[2]

            cert_signature_decoded = asn1.DerObject()
            cert_signature_decoded.decode(cert_signature)

            signature_payload = cert_signature_decoded.payload

            sig_pay0 = signature_payload[0]
            if ((isinstance(sig_pay0, int) and sig_pay0 != 0)
                    or (isinstance(sig_pay0, str) and sig_pay0 != '\x00')):
                return (False,
                        "The certificate should not contain any unused bits.")

            signature = signature_payload[1:]

            try:
                crypto.verify(ca_cert, signature, cert_certificate,
                              cert_algorithm)
                return True, "Signed certificate is valid and correctly signed by CA certificate."
            except crypto.Error as e:
                return False, "Certificate is incorrectly signed."
        except Exception as e:
            return False, "Certificate is not valid for an unknown reason. %s" % str(
                e)
Example #6
0
def extract_config(filebuf):
    conf_dict = {}
    pe = None
    try:
        pe = pefile.PE(data=filebuf, fast_load=False)
    except Exception:
        pass

    if pe is None:
        return

    image_base = pe.OPTIONAL_HEADER.ImageBase
    c2found = False
    c2list_va_offset = 0
    c2_list_offset = 0
    delta = 0

    yara_matches = yara_scan(filebuf)
    if yara_matches.get("$snippet3"):
        c2list_va_offset = int(yara_matches["$snippet3"])
        c2_list_va = struct.unpack(
            "I", filebuf[c2list_va_offset + 2:c2list_va_offset + 6])[0]
        c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base
        try:
            c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
        except pefile.PEFormatError:
            pass

        while True:
            try:
                ip = struct.unpack(
                    "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0]
            except Exception:
                return
            if ip == 0:
                return
            c2_address = socket.inet_ntoa(struct.pack("!L", ip))
            port = str(
                struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset +
                                           6])[0])
            if not c2_address or not port:
                return
            conf_dict.setdefault("address", []).append(f"{c2_address}:{port}")
            c2_list_offset += 8
    elif yara_matches.get("$snippet4"):
        c2list_va_offset = int(yara_matches["$snippet4"])
        c2_list_va = struct.unpack(
            "I", filebuf[c2list_va_offset + 8:c2list_va_offset + 12])[0]
        c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base
        try:
            c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
        except pefile.PEFormatError:
            pass
        while True:
            try:
                ip = struct.unpack(
                    "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0]
            except Exception:
                return
            if ip == 0:
                return
            c2_address = socket.inet_ntoa(struct.pack("!L", ip))
            port = str(
                struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset +
                                           6])[0])
            if not c2_address or not port:
                return
            conf_dict.setdefault("address", []).append(f"{c2_address}:{port}")
            c2_list_offset += 8
    elif any(
            yara_matches.get(name, False)
            for name in ("$snippet5", "$snippet8", "$snippet9", "$snippetB",
                         "$snippetC", "$comboA1", "$comboA2")):
        delta = 5
        if yara_matches.get("$snippet5"):
            refc2list = yara_matches.get("$snippet5")
        elif yara_matches.get("$snippet8"):
            refc2list = yara_matches.get("$snippet8")
        elif yara_matches.get("$snippet9"):
            refc2list = yara_matches.get("$snippet8")
            c2list_va_offset = int(yara_matches["$snippet9"])
            tb = struct.unpack(
                "b", filebuf[c2list_va_offset + 5:c2list_va_offset + 6])[0]
            if tb == 0x48:
                delta += 1
        elif yara_matches.get("$snippetB"):
            delta = 9
            refc2list = yara_matches.get("$snippetB")
        elif yara_matches.get("$snippetC"):
            delta = 8
            refc2list = yara_matches.get("$snippetC")
        elif yara_matches.get("$comboA1"):
            refc2list = yara_matches.get("$comboA1")
        elif yara_matches.get("$comboA2"):
            delta = 6
            refc2list = yara_matches.get("$comboA2")

        if refc2list:
            c2list_va_offset = int(refc2list)
            c2_list_va = struct.unpack(
                "I", filebuf[c2list_va_offset + delta:c2list_va_offset +
                             delta + 4])[0]
            c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x40000 else c2_list_va - image_base
            try:
                c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
            except pefile.PEFormatError as err:
                log.error(err)
                return
            while True:
                preip = filebuf[c2_list_offset:c2_list_offset + 4]
                if not preip:
                    return
                try:
                    ip = struct.unpack("<I", preip)[0]
                except Exception as e:
                    log.error(e)
                    break
                if ip == 0:
                    break
                c2_address = socket.inet_ntoa(struct.pack("!L", ip))
                port = str(
                    struct.unpack(
                        "H",
                        filebuf[c2_list_offset + 4:c2_list_offset + 6])[0])
                if not c2_address or not port:
                    break
                conf_dict.setdefault("address",
                                     []).append(f"{c2_address}:{port}")
                c2found = True
                c2_list_offset += 8
    elif yara_matches.get("$snippet6"):
        c2list_va_offset = int(yara_matches["$snippet6"])
        c2_list_va = struct.unpack(
            "I", filebuf[c2list_va_offset + 15:c2list_va_offset + 19])[0]
        c2_list_rva = c2_list_va - image_base
        try:
            c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
        except pefile.PEFormatError:
            pass
        while True:
            preip = filebuf[c2_list_offset:c2_list_offset + 4]
            if not preip:
                break
            try:
                ip = struct.unpack("<I", preip)[0]
            except Exception as e:
                log.error(e)
                break
            if ip == 0:
                break
            c2_address = socket.inet_ntoa(struct.pack("!L", ip))
            port = str(
                struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset +
                                           6])[0])
            if not c2_address or not port:
                break
            conf_dict.setdefault("address", []).append(f"{c2_address}:{port}")
            c2found = True
            c2_list_offset += 8
    elif yara_matches.get("$snippet7"):
        c2list_va_offset = int(yara_matches["$snippet7"])
        delta = 26
        hb = struct.unpack(
            "b", filebuf[c2list_va_offset + 29:c2list_va_offset + 30])[0]
        if hb:
            delta += 1
        c2_list_va = struct.unpack(
            "I",
            filebuf[c2list_va_offset + delta:c2list_va_offset + delta + 4])[0]
        c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base
        try:
            c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
        except pefile.PEFormatError:
            pass
        while True:
            try:
                ip = struct.unpack(
                    "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0]
            except Exception:
                break
            if ip == 0:
                break
            c2_address = socket.inet_ntoa(struct.pack("!L", ip))
            port = str(
                struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset +
                                           6])[0])
            if not c2_address or not port:
                break
            conf_dict.setdefault("address", []).append(f"{c2_address}:{port}")
            c2found = True
            c2_list_offset += 8
    elif yara_matches.get("$snippetA"):
        c2list_va_offset = int(yara_matches["$snippetA"])
        c2_list_va = struct.unpack(
            "I", filebuf[c2list_va_offset + 24:c2list_va_offset + 28])[0]
        c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base
        try:
            c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
        except pefile.PEFormatError:
            pass
        while True:
            try:
                ip = struct.unpack(
                    "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0]
            except Exception:
                break
            if ip == 0:
                break
            c2_address = socket.inet_ntoa(struct.pack("!L", ip))
            port = str(
                struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset +
                                           6])[0])
            if not c2_address or not port:
                break
            conf_dict.setdefault("address", []).append(f"{c2_address}:{port}")
            c2found = True
            c2_list_offset += 8
    elif yara_matches.get("$snippetD"):
        delta = 6
        c2list_va_offset = int(yara_matches["$snippetD"])
    elif yara_matches.get("$snippetE"):
        delta = 13
        c2list_va_offset = int(yara_matches["$snippetE"])
    elif yara_matches.get("$snippetF"):
        delta = 9
        c2list_va_offset = int(yara_matches["$snippetF"])
    elif yara_matches.get("$snippetG"):
        delta = -4
        c2list_va_offset = int(yara_matches["$snippetG"])
    elif yara_matches.get("$snippetH"):
        delta = 12
        c2list_va_offset = int(yara_matches["$snippetH"])
    elif yara_matches.get("$snippetI"):
        delta = -4
        c2list_va_offset = int(yara_matches["$snippetI"])
    elif yara_matches.get("$snippetJ"):
        delta = 14
        c2list_va_offset = int(yara_matches["$snippetJ"])
    elif yara_matches.get("$snippetK"):
        delta = -5
        c2list_va_offset = int(yara_matches["$snippetK"])
    elif yara_matches.get("$snippetL"):
        delta = -4
        c2list_va_offset = int(yara_matches["$snippetL"])
    elif yara_matches.get("$snippetM"):
        delta = 12
        c2list_va_offset = int(yara_matches["$snippetM"])
    elif yara_matches.get("$snippetN"):
        delta = 9
        c2list_va_offset = int(yara_matches["$snippetN"])
    elif yara_matches.get("$snippetO"):
        delta = 5
        c2list_va_offset = int(yara_matches["$snippetO"])
    elif yara_matches.get("$snippetP"):
        delta = 17
        c2list_va_offset = int(yara_matches["$snippetP"])
    elif yara_matches.get("$snippetQ"):
        delta = 5
        c2list_va_offset = int(yara_matches["$snippetQ"])
    elif yara_matches.get("$snippetR"):
        delta = 18
        c2list_va_offset = int(yara_matches["$snippetR"])
    elif yara_matches.get("$snippetS"):
        delta = -4
        c2list_va_offset = int(yara_matches["$snippetS"])
    elif yara_matches.get("$snippetT"):
        delta = 13
        c2list_va_offset = int(yara_matches["$snippetT"])
    elif yara_matches.get("$snippetU"):
        delta = 13
        c2list_va_offset = int(yara_matches["$snippetU"])
    elif yara_matches.get("$snippetV"):
        delta = 14
        c2list_va_offset = int(yara_matches["$snippetV"])
    elif yara_matches.get("$snippetW"):
        delta = 10
        c2_delta_offset = int(yara_matches["$snippetW"])
    elif yara_matches.get("$snippetX"):
        delta = 3
        c2_delta_offset = int(yara_matches["$snippetX"])
    if delta:
        if c2list_va_offset:
            c2_list_va = struct.unpack(
                "I", filebuf[c2list_va_offset + delta:c2list_va_offset +
                             delta + 4])[0]
            c2_list_rva = c2_list_va - image_base
            try:
                c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
            except pefile.PEFormatError as err:
                log.error(err)
                return
        elif c2_delta_offset:
            c2_delta = struct.unpack(
                "i", filebuf[c2_delta_offset + delta:c2_delta_offset + delta +
                             4])[0]
            c2_list_rva = pe.get_rva_from_offset(
                c2_delta_offset) + c2_delta + delta + 4
            c2_list_offset = pe.get_offset_from_rva(c2_list_rva)
        key = filebuf[c2_list_offset:c2_list_offset + 4]
        presize = filebuf[c2_list_offset + 4:c2_list_offset + 8]
        if not presize:
            return
        size = struct.unpack("I", presize)[0] ^ struct.unpack("I", key)[0]
        if size > 1000:
            log.info("Anomalous C2 list size 0x%x", size)
            return
        c2_list_offset += 8
        c2_list = xor_data(filebuf[c2_list_offset:], key)
        offset = 0
        while offset < size:
            try:
                ip = struct.unpack(">I", c2_list[offset:offset + 4])[0]
            except Exception:
                break
            if ip == struct.unpack(">I", key)[0]:
                break
            c2_address = socket.inet_ntoa(struct.pack("!L", ip))
            port = str(struct.unpack(">H", c2_list[offset + 4:offset + 6])[0])
            if not c2_address or not port:
                break
            conf_dict.setdefault("address", []).append(f"{c2_address}:{port}")
            c2found = True
            offset += 8

    if not c2found:
        return
    pem_key = False
    try:
        pem_key = extract_emotet_rsakey(pe)
    except ValueError as e:
        log.error(e)
    if pem_key:
        # self.reporter.add_metadata("other", {"RSA public key": pem_key.exportKey().decode()})
        conf_dict.setdefault("RSA public key", pem_key.exportKey().decode())
    else:
        if yara_matches.get("$ref_rsa"):
            ref_rsa_offset = int(yara_matches["$ref_rsa"])
            ref_rsa_va = 0
            zb = struct.unpack(
                "b", filebuf[ref_rsa_offset + 31:ref_rsa_offset + 32])[0]
            if not zb:
                ref_rsa_va = struct.unpack(
                    "I", filebuf[ref_rsa_offset + 28:ref_rsa_offset + 32])[0]
            else:
                zb = struct.unpack(
                    "b", filebuf[ref_rsa_offset + 29:ref_rsa_offset + 30])[0]
                if not zb:
                    ref_rsa_va = struct.unpack(
                        "I",
                        filebuf[ref_rsa_offset + 26:ref_rsa_offset + 30])[0]
                else:
                    zb = struct.unpack(
                        "b",
                        filebuf[ref_rsa_offset + 28:ref_rsa_offset + 29])[0]
                    if not zb:
                        ref_rsa_va = struct.unpack(
                            "I", filebuf[ref_rsa_offset + 25:ref_rsa_offset +
                                         29])[0]
                    else:
                        zb = struct.unpack(
                            "b", filebuf[ref_rsa_offset + 38:ref_rsa_offset +
                                         39])[0]
                        if not zb:
                            ref_rsa_va = struct.unpack(
                                "I", filebuf[ref_rsa_offset +
                                             35:ref_rsa_offset + 39])[0]
            if not ref_rsa_va:
                return
            ref_rsa_rva = ref_rsa_va - image_base
            try:
                ref_rsa_offset = pe.get_offset_from_rva(ref_rsa_rva)
            except Exception:
                return
            key = struct.unpack("<I",
                                filebuf[ref_rsa_offset:ref_rsa_offset + 4])[0]
            xorsize = key ^ struct.unpack(
                "<I", filebuf[ref_rsa_offset + 4:ref_rsa_offset + 8])[0]
            rsa_key = xor_data(
                filebuf[ref_rsa_offset + 8:ref_rsa_offset + 8 + xorsize],
                struct.pack("<I", key))
            seq = asn1.DerSequence()
            seq.decode(rsa_key)
            # self.reporter.add_metadata("other", {"RSA public key": RSA.construct((seq[0], seq[1])).exportKey()})
            conf_dict.setdefault("RSA public key",
                                 RSA.construct((seq[0], seq[1])).exportKey())
        else:
            ref_ecc_offset = 0
            delta1 = 0
            delta2 = 0
            if yara_matches.get("$ref_ecc1"):
                ref_ecc_offset = int(yara_matches["$ref_ecc1"])
                delta1 = 9
                delta2 = 62
            elif yara_matches.get("$ref_ecc2"):
                ref_ecc_offset = int(yara_matches["$ref_ecc2"])
                delta1 = 22
                delta2 = 71
            elif yara_matches.get("$ref_ecc3"):
                ref_ecc_offset = int(yara_matches["$ref_ecc3"])
                delta1 = 8
                delta2 = 47
            elif yara_matches.get("$ref_ecc4"):
                ref_ecc_offset = int(yara_matches["$ref_ecc4"])
                delta1 = -4
                delta2 = 49
            elif yara_matches.get("$ref_ecc5"):
                ref_ecc_offset = int(yara_matches["$ref_ecc5"])
                delta1 = 15
                delta2 = 65
            elif yara_matches.get("$ref_ecc6"):
                ref_ecc_offset = int(yara_matches["$ref_ecc6"])
                delta1 = -4
                delta2 = 48
            elif yara_matches.get("$ref_ecc7"):
                ref_ecc_offset = int(yara_matches["$ref_ecc7"])
                delta1 = 23
                delta2 = 47
            elif yara_matches.get("$ref_ecc8"):
                ref_ecc_offset = int(yara_matches["$ref_ecc8"])
                delta1 = -5
                delta2 = 44
            elif yara_matches.get("$ref_ecc9"):
                ref_ecc_offset = int(yara_matches["$ref_ecc9"])
                delta1 = -4
                delta2 = 24
            elif yara_matches.get("$ref_eccA"):
                ref_ecc_offset = int(yara_matches["$ref_eccA"])
                delta1 = 12
                delta2 = 55
            elif yara_matches.get("$ref_eccB"):
                ref_ecc_offset = int(yara_matches["$ref_eccB"])
                delta1 = 15
                delta2 = 58
            elif yara_matches.get("$ref_eccC"):
                ref_ecc_offset = int(yara_matches["$ref_eccC"])
                delta1 = 8
                delta2 = 37
            elif yara_matches.get("$ref_eccD"):
                ref_ecc_offset = int(yara_matches["$ref_eccD"])
                delta1 = 26
                delta2 = 72
            elif yara_matches.get("$ref_eccE"):
                ref_ecc_offset = int(yara_matches["$ref_eccE"])
                delta1 = 8
                delta2 = 36
            elif yara_matches.get("$ref_eccF"):
                ref_ecc_offset = int(yara_matches["$ref_eccF"])
                delta1 = -4
                delta2 = 48
            elif yara_matches.get("$ref_eccG"):
                ref_ecc_offset = int(yara_matches["$ref_eccG"])
                delta1 = 30
                delta2 = 76
            if yara_matches.get("$ref_eccH"):
                ref_ecc_offset = int(yara_matches["$ref_eccH"])
                delta1 = 9
                delta2 = 59
            if yara_matches.get("$ref_eccI"):
                ref_ecc_offset = int(yara_matches["$ref_eccI"])
                delta1 = 22
                delta2 = 58
            if yara_matches.get("$ref_eccJ"):
                ref_ecc_offset = int(yara_matches["$ref_eccJ"])
                delta1 = 10
                delta2 = 245
            if yara_matches.get("$ref_eccK"):
                ref_ecc_offset = int(yara_matches["$ref_eccK"])
                delta1 = 14
                delta2 = 166
            if yara_matches.get("$ref_eccK"):
                ref_ecc_offset = int(yara_matches["$ref_eccK"])
                delta1 = 14
                delta2 = 166
            if yara_matches.get("$ref_eccL"):
                ecc_delta_offset = int(yara_matches["$ref_eccL"])
                delta1 = 8
                delta2 = 97
            if yara_matches.get("$ref_eccM"):
                ecc_delta_offset = int(yara_matches["$ref_eccM"])
                delta1 = 3
                delta2 = 234
            if yara_matches.get("$ref_eccN"):
                ecc_delta_offset = int(yara_matches["$ref_eccN"])
                delta1 = 3
                delta2 = 107
            if yara_matches.get("$ref_eccO"):
                ecc_delta_offset = int(yara_matches["$ref_eccO"])
                delta1 = 3
                delta2 = 206
            if delta1 or delta2:
                if ref_ecc_offset:
                    ref_eck_rva = struct.unpack(
                        "I", filebuf[ref_ecc_offset + delta1:ref_ecc_offset +
                                     delta1 + 4])[0] - image_base
                    ref_ecs_rva = struct.unpack(
                        "I", filebuf[ref_ecc_offset + delta2:ref_ecc_offset +
                                     delta2 + 4])[0] - image_base
                    try:
                        eck_offset = pe.get_offset_from_rva(ref_eck_rva)
                        ecs_offset = pe.get_offset_from_rva(ref_ecs_rva)
                    except Exception as e:
                        log.error(e)
                        return
                elif ecc_delta_offset:
                    eck_delta = struct.unpack(
                        "i", filebuf[ecc_delta_offset +
                                     delta1:ecc_delta_offset + delta1 + 4])[0]
                    ecs_delta = struct.unpack(
                        "i", filebuf[ecc_delta_offset +
                                     delta2:ecc_delta_offset + delta2 + 4])[0]
                    ref_eck_rva = pe.get_rva_from_offset(
                        ecc_delta_offset) + eck_delta + delta1 + 4
                    ref_ecs_rva = pe.get_rva_from_offset(
                        ecc_delta_offset) + ecs_delta + delta2 + 4
                    eck_offset = pe.get_offset_from_rva(ref_eck_rva)
                    ecs_offset = pe.get_offset_from_rva(ref_ecs_rva)
                key = filebuf[eck_offset:eck_offset + 4]
                size = struct.unpack("I", filebuf[eck_offset + 4:eck_offset +
                                                  8])[0] ^ struct.unpack(
                                                      "I", key)[0]
                eck_offset += 8
                eck_key = xor_data(filebuf[eck_offset:eck_offset + size], key)
                key_len = struct.unpack("<I", eck_key[4:8])[0]
                conf_dict.setdefault(
                    "ECC ECK1",
                    ECC.construct(
                        curve="p256",
                        point_x=int.from_bytes(eck_key[8:8 + key_len], "big"),
                        point_y=int.from_bytes(eck_key[8 + key_len:], "big"),
                    ).export_key(format="PEM"),
                )
                key = filebuf[ecs_offset:ecs_offset + 4]
                size = struct.unpack("I", filebuf[ecs_offset + 4:ecs_offset +
                                                  8])[0] ^ struct.unpack(
                                                      "I", key)[0]
                ecs_offset += 8
                ecs_key = xor_data(filebuf[ecs_offset:ecs_offset + size], key)
                key_len = struct.unpack("<I", ecs_key[4:8])[0]
                conf_dict.setdefault(
                    "ECC ECS1",
                    ECC.construct(
                        curve="p256",
                        point_x=int.from_bytes(ecs_key[8:8 + key_len], "big"),
                        point_y=int.from_bytes(ecs_key[8 + key_len:], "big"),
                    ).export_key(format="PEM"),
                )
    return conf_dict