probe_sms_endpoint.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. """Probe 996box for the actual SMS endpoint URL.
  2. Tries common patterns and reports which return 200/4xx (real) vs 404 (wrong).
  3. Does NOT trigger actual SMS sending.
  4. """
  5. import asyncio
  6. import json
  7. import sys
  8. from pathlib import Path
  9. _HERE = Path(__file__).resolve().parent
  10. sys.path.insert(0, str(_HERE.parent / "src"))
  11. from cq2_sdk.env_loader import load_env
  12. load_env(_HERE.parent / ".env")
  13. from cq2_sdk.login import Box996Login, ManualGeetestSolver
  14. # 常见 996box SMS 接口名猜测 (按概率排序)
  15. CANDIDATE_ENDPOINTS = [
  16. "/auth/v3/login/sms/send", # 我之前的猜测 (刚 404)
  17. "/auth/v3/login/sendSmsCode", # 另一种命名
  18. "/auth/v3/sms/sendLoginCode", # 常见变体
  19. "/auth/v3/login/safe/sendSms", # 带 safe/ 前缀
  20. "/auth/v3/login/sendSms", # 短版
  21. "/auth/v3/login/sendLoginCode", # 变体
  22. "/v3/login/sms/send", # 无 /auth 前缀
  23. "/auth/v3/login/bySms/send", # bySms 路径
  24. ]
  25. LOGIN_BASE = "https://api.jiyuhz.cn"
  26. async def probe_one(box, endpoint: str, phone: str = "00000000000") -> tuple[str, int, str]:
  27. """Returns (endpoint, status, body_preview). status=0 means network error."""
  28. try:
  29. r = await box._request("POST", LOGIN_BASE, endpoint,
  30. json_body={"phone": phone, "channel_id": "", "game_id": ""})
  31. # If we got here, 996box returned 2xx
  32. body = json.dumps(r, ensure_ascii=False)[:80]
  33. return endpoint, 200, body
  34. except Exception as e:
  35. # httpx raises for 4xx/5xx; Box996Error for non-200 JSON
  36. msg = str(e)[:120]
  37. # Try to extract status code
  38. status = 0
  39. if "404" in msg:
  40. status = 404
  41. elif "400" in msg:
  42. status = 400
  43. elif "405" in msg:
  44. status = 405
  45. elif "Method Not Allowed" in msg:
  46. status = 405
  47. return endpoint, status, msg
  48. async def main() -> int:
  49. box = Box996Login(geetest=ManualGeetestSolver(),
  50. device_id="00:15:5d:0a:04:00")
  51. print(f"Probing {len(CANDIDATE_ENDPOINTS)} candidate SMS endpoints on 996box...\n")
  52. results = []
  53. for ep in CANDIDATE_ENDPOINTS:
  54. ep, status, body = await probe_one(box, ep)
  55. results.append((ep, status, body))
  56. marker = "[!!! HIT !!!]" if status == 200 else ("[404]" if status == 404 else f"[{status}]")
  57. print(f" {marker:<14} {ep:<45} {body[:50]}")
  58. print()
  59. hits = [r for r in results if r[1] != 404 and r[1] != 0]
  60. if not hits:
  61. print("[!] No candidate matched. 996box SMS endpoint is not in our guess list.")
  62. print(" Need real intel — capture from browser DevTools (see below).")
  63. else:
  64. print(f"[OK] {len(hits)} candidate(s) returned non-404:")
  65. for ep, status, body in hits:
  66. print(f" {ep} status={status} body={body[:60]}")
  67. return 0
  68. if __name__ == "__main__":
  69. sys.exit(asyncio.run(main()))