"""Extract JWT token from 996box Electron app's localStorage (LevelDB). The app's web UI stores the login session in: C:\\Users\\\\AppData\\Roaming\\996传奇盒子\\Local Storage\\leveldb\\ Key is 'React-ant-Admin-user' (the redux user state from chunk.js code). Value is JSON: {"token": "eyJ...", "userinfo": {...}} We search all .ldb files for the JWT prefix (eyJ) and extract the full token. """ import json import re import sys from pathlib import Path # 996box Electron app's userData path APPDATA = Path.home() / "AppData" / "Roaming" USER_DATA = APPDATA / "996传奇盒子" LEVELDB_DIR = USER_DATA / "Local Storage" / "leveldb" # JWT pattern: header.payload.signature (3 base64url segments) JWT_PATTERN = re.compile(r"eyJ[A-Za-z0-9_\-]{20,}\.eyJ[A-Za-z0-9_\-]{20,}\.[A-Za-z0-9_\-]{20,}") # Also try base64-without-dots (in case storage truncates dots) LOOSE_PATTERN = re.compile(r'"token"\s*:\s*"(eyJ[^"]{50,})"') # Loose: just look for any long eyJ string LONG_EYJ = re.compile(rb"eyJ[A-Za-z0-9_\-\.]{80,}") def find_tokens_in_ldbs() -> list[dict]: """Scan all .ldb files, return candidate tokens.""" candidates = [] for ldb_file in sorted(LEVELDB_DIR.glob("*.ldb")): try: data = ldb_file.read_bytes() except Exception as e: print(f" [warn] can't read {ldb_file.name}: {e}") continue # Search for JWT-shaped strings for m in JWT_PATTERN.finditer(data.decode("utf-8", errors="ignore")): candidates.append({"file": ldb_file.name, "token": m.group(0), "kind": "jwt-3part"}) # Also try loose match (in case of escaping) for m in LONG_EYJ.finditer(data): t = m.group(0).decode("utf-8", errors="ignore") # Filter to JWT-shaped (3 dots) or plausibly long single if t.count(".") == 2 and len(t) > 100: if not any(c["token"] == t for c in candidates): candidates.append({"file": ldb_file.name, "token": t, "kind": "loose-3dot"}) elif len(t) > 200: # Very long base64 - could be truncated JWT if not any(c["token"].startswith(t[:50]) for c in candidates): candidates.append({"file": ldb_file.name, "token": t, "kind": "long-eyJ"}) return candidates def main() -> int: print(f"=== Scanning {LEVELDB_DIR} for JWT tokens ===\n") if not LEVELDB_DIR.exists(): print(f"[FAIL] {LEVELDB_DIR} does not exist") return 1 candidates = find_tokens_in_ldbs() if not candidates: print("[!] No JWT-like strings found in LevelDB files") print(" Possible reasons:") print(" - 996box has never been logged in successfully on this machine") print(" - localStorage was cleared") print(" - Files are DPAPI-encrypted (Chrome v80+ with --enable-encryption)") return 0 print(f"Found {len(candidates)} candidate(s):\n") for i, c in enumerate(candidates[:5], 1): t = c["token"] kind = c["kind"] print(f" [{i}] kind={kind} file={c['file']}") print(f" token[:40] = {t[:40]}...") print(f" length = {len(t)}") print(f" 3-part JWT = {'YES' if t.count('.') == 2 else 'NO'}") print() return 0 if __name__ == "__main__": sys.exit(main())