import hashlib import struct import argparse from Crypto.Cipher import AES #pip install pycryptodome def decrypt(blob, key): """Decrypt PDQ credential blobs""" #Format for the blob is [header][ivlen][iv][encdata] #Example blob: 28656e63727970746564290010644d18eb7817dad6de5f531b1b0b60113087662f3cf0ffdaa7760418c15ee6ea #Example blob: [28656e637279707465642900][10][644d18eb7817dad6de5f531b1b0b6011][3087662f3cf0ffdaa7760418c15ee6ea] #Header: 28656e637279707465642900 #IVlen: 10 #IV 644d18eb7817dad6de5f531b1b0b6011 #encdata: 3087662f3cf0ffdaa7760418c15ee6ea encrypted_data = bytearray.fromhex(blob) header = b"(encrypted)\0" if not encrypted_data.startswith(header): print("Missing (encrypted) header for PDQ blob") exit() #trim the header and skip the IV length, IV length should always be 16 (10 in hex) until they change it? data = encrypted_data[len(header):] iv_length = data[0] if iv_length != 16: print(f"Warning: Unexpected IV length: {iv_length} (expected 16)") iv = data[1:1+iv_length] encdata = data[1+iv_length:] #encryption key is first 16 bytes of sha256 hash of the 3 combined guids key_hash = hashlib.sha256(key.encode('utf-8')).digest() aes_key = key_hash[:16] cipher = AES.new(aes_key, AES.MODE_CBC, iv) decrypted = cipher.decrypt(encdata) #first 4 bytes of decrypted bytes are password length try: plaintext_length = struct.unpack("