1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| import base64 import hashlib import os import re import subprocess import tarfile import tempfile
archive = "ghost_vault.tar.gz"
def run_git(repo, *args): return subprocess.check_output( ["git", "-C", repo, *args], text=True, stderr=subprocess.STDOUT, ).strip()
with tempfile.TemporaryDirectory() as tmp: with tarfile.open(archive, "r:gz") as tf: tf.extractall(tmp)
repo = os.path.join(tmp, "ghost-vault")
shard3 = None for commit in run_git(repo, "log", "--all", "--format=%H").splitlines(): try: note = run_git(repo, "notes", "--ref=commits", "show", commit) except subprocess.CalledProcessError: continue m = re.search(r"third shard:\s*([a-z]+)", note) if m: shard3 = m.group(1) break
stash_note = run_git(repo, "show", "stash@{0}^3:drafts/reminder.txt") shard2 = re.search(r"second shard:\s*([a-z]+)", stash_note).group(1)
shard1 = None vault_enc = None fsck = run_git(repo, "fsck", "--full", "--no-reflogs", "--unreachable") for line in fsck.splitlines(): parts = line.split() if len(parts) != 3: continue _, kind, obj = parts if kind == "blob": try: data = run_git(repo, "cat-file", "-p", obj) except subprocess.CalledProcessError: continue m = re.search(r"first shard:\s*([a-z]+)", data) if m: shard1 = m.group(1) elif kind == "commit": meta = run_git(repo, "cat-file", "-p", obj) if "stage archive vault" in meta: vault_enc = run_git(repo, "show", f"{obj}:vault.enc")
passphrase = f"{shard1}-{shard2}-{shard3}".encode()
raw = base64.b64decode(vault_enc) salt_len = raw[3] salt = raw[4 : 4 + salt_len] body = raw[4 + salt_len :]
stream = bytearray() counter = 0 while len(stream) < len(body): block = hashlib.sha256( passphrase + b"|" + salt + b"|" + counter.to_bytes(4, "big") ).digest() stream.extend(block) counter += 1
flag = bytes(a ^ b for a, b in zip(body, stream)).decode()
print(passphrase.decode()) print(flag)
|