Files
video_extractor/find_root_key.py
T

85 lines
2.7 KiB
Python
Raw Normal View History

2026-08-08 12:35:28 +02:00
#!/usr/bin/env python3
"""
Brute-force search for the AES root key in libwvdrmengine.so
that decrypts the ay64.dat keybox.
"""
from Crypto.Cipher import AES
import struct
CDM_LIB = "libwvdrmengine.so"
KEYBOX = "L3/ay64.dat"
keybox = open(KEYBOX, "rb").read() # 128 bytes
cdm = open(CDM_LIB, "rb").read()
# The decrypted keybox plaintext should look like structured data.
# Known Widevine keybox magic signatures to check for.
MAGIC_PATTERNS = [
b"KBPI", b"KEYB", b"kbpi",
b"\x01\x00\x00\x00",
b"\x00\x00\x00\x01",
]
# Also check if decrypted bytes look like a DER-encoded structure
def looks_like_der(data):
return data[0] == 0x30 and data[1] in (0x81, 0x82)
def looks_like_rsa_key(data):
# SEQUENCE { INTEGER 0, INTEGER (modulus)... }
return data[:4] == b"\x30\x82" or data[:2] == b"\x30\x81"
hits = []
step = 1 # slide byte by byte
print(f"Scanning {len(cdm):,} bytes of libwvdrmengine.so for AES root key...")
print(f"Keybox first block: {keybox[:16].hex()}")
print()
for i in range(0, len(cdm) - 16, step):
candidate_key = cdm[i:i+16]
# Skip keys that are all zeros, all same byte, or look like code
if len(set(candidate_key)) < 4:
continue
try:
# Try ECB first (no IV needed)
cipher = AES.new(candidate_key, AES.MODE_ECB)
decrypted = cipher.decrypt(keybox)
for magic in MAGIC_PATTERNS:
if decrypted.startswith(magic):
print(f"[!] MAGIC HIT at offset {i:#010x}: key={candidate_key.hex()}")
print(f" Decrypted: {decrypted.hex()}")
hits.append(("ECB", i, candidate_key, decrypted))
if looks_like_der(decrypted):
print(f"[!] DER HIT (ECB) at offset {i:#010x}: key={candidate_key.hex()}")
hits.append(("ECB-DER", i, candidate_key, decrypted))
# Try CBC with first block as IV
iv = keybox[:16]
cipher2 = AES.new(candidate_key, AES.MODE_CBC, iv)
dec2 = cipher2.decrypt(keybox[16:])
for magic in MAGIC_PATTERNS:
if dec2.startswith(magic):
print(f"[!] CBC MAGIC HIT at offset {i:#010x}: key={candidate_key.hex()}")
hits.append(("CBC", i, candidate_key, dec2))
if looks_like_der(dec2):
print(f"[!] DER HIT (CBC) at offset {i:#010x}: key={candidate_key.hex()}")
hits.append(("CBC-DER", i, candidate_key, dec2))
except Exception:
pass
if i % 500000 == 0:
print(f" Progress: {i:,}/{len(cdm):,} ({100*i/len(cdm):.1f}%)")
if hits:
print(f"\nFound {len(hits)} candidate(s)!")
else:
print("\nNo direct AES magic hits found.")
print("The root key may be derived at runtime (not stored as a raw 16-byte value).")