Skip to content

Instantly share code, notes, and snippets.

Last active October 1, 2021 17:13
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Decryptor for signalino - Midnight Sun CTF 2021
#!/usr/bin/env python3
Based on
import plistlib
from bpylist import archiver, archive_types
import dataclasses
from Crypto.Cipher import AES
from pyasn1.codec.der.decoder import decode
class SFAuthenticatedCiphertext(archive_types.DataclassArchiver):
SFCiphertext: bytes = b""
SFInitializationVector: bytes = b""
SFAuthenticationCode: bytes = b""
archiver.update_class_map({'_SFAuthenticatedCiphertext': SFAuthenticatedCiphertext})
def decript_entry(entry):
if 'data' not in entry:
return None
c = archiver.unarchive(entry['data']['ciphertext'])
unwrapedKey = entry['data']['unwrappedKey']
authCode = c.SFAuthenticationCode
iv = c.SFInitializationVector
ciphertext = c.SFCiphertext
gcm =, AES.MODE_GCM, iv)
decrypted = gcm.decrypt_and_verify(ciphertext, authCode)
decoded = decode(decrypted)[0]
data = {}
for k in decoded:
if 'Octet' in str(type(k[1])):
data.update({str(k[0]): bytes(k[1])})
data.update({str(k[0]): str(k[1])})
return data
if __name__ == "__main__":
with open("backup_keychain_v2.plist", "rb") as f:
plist = plistlib.load(f)
for i in range(len(plist['keychainEntries'])):
print("Entry {}".format(i))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment