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)
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
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)
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