login_bruteforce.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """Brute-force CS 2001 with multiple field-name variants.
  2. The 0-byte close tells us params/encoding is wrong. Try all likely
  3. account/otpType combinations.
  4. """
  5. import asyncio
  6. import base64
  7. import json
  8. import random
  9. import struct
  10. import sys
  11. from pathlib import Path
  12. sys.path.insert(0, "src")
  13. from cq2_sdk.env_loader import load_env
  14. load_env()
  15. from cq2_sdk.utils.encoding import encode6bit
  16. raw = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json").read_bytes()
  17. text = raw.decode("utf-8", errors="replace")
  18. idx = text.find("eyJ")
  19. b64 = text[idx:].rstrip()
  20. padded = b64 + "=" * ((-len(b64)) % 4)
  21. env = json.loads(base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace"))
  22. password = env["token"] # back to env["token"], the most likely candidate
  23. # also try gameAccount-style account
  24. channel_id = env.get("channel", "110585")
  25. pwd_enc = encode6bit(password.encode()).decode("ascii")
  26. ch_enc = encode6bit(channel_id.encode()).decode("ascii")
  27. main_server_id = 14414736
  28. async def attempt(account, otpType, otpCode_raw, otpCode_send, label):
  29. if otpCode_raw == "null":
  30. otp_send = "null"
  31. elif otpCode_raw == "":
  32. otp_send = ""
  33. else:
  34. otp_send = encode6bit(otpCode_raw.encode()).decode("ascii")
  35. body = f"{account}/{pwd_enc}/{ch_enc}/{otpType}/{otp_send}"
  36. frame = struct.pack("<6i", 2001, 900_000, random.randint(100_000_000, 2_100_000_000) & 0xFFFF00FF, main_server_id, 8021, len(body.encode())) + body.encode()
  37. print(f"--- {label}")
  38. print(f" body: {body[:100]}")
  39. try:
  40. r, w = await asyncio.wait_for(asyncio.open_connection("gfgame.dhsf.xqhuyu.com", 12000), timeout=5)
  41. except Exception as e:
  42. print(f" connect: {e}"); return
  43. data = b""
  44. try:
  45. w.write(frame); await w.drain()
  46. data = await asyncio.wait_for(r.read(4096), timeout=6)
  47. except asyncio.TimeoutError:
  48. print(" TIMEOUT")
  49. except Exception as e:
  50. print(f" err: {e}")
  51. finally:
  52. try:
  53. w.close(); await w.wait_closed()
  54. except Exception:
  55. pass
  56. if not data:
  57. print(" 0 bytes (closed)")
  58. elif len(data) >= 24:
  59. msg_id, *_ = struct.unpack("<6i", data[:24])
  60. print(f" REPLY msg_id={msg_id} len={len(data)}B")
  61. if msg_id == 529:
  62. print(f" *** *** SC 529 LOGIN KEY! *** ***")
  63. print(f" body: {data[24:][:200]!r}")
  64. sys.exit(0)
  65. else:
  66. print(f" short {len(data)}B")
  67. await asyncio.sleep(0.5)
  68. async def main():
  69. u = env["uid"]
  70. g = env["gameAccount"]
  71. k = env["u_key"]
  72. variants = [
  73. (u, "0", "0", "0", "uid / otp 0/0"),
  74. (g, "0", "0", "0", "gameAccount / otp 0/0"),
  75. (u, "1", "0", "0", "uid / otp 1/0 (SMS)"),
  76. (g, "1", "0", "0", "gameAccount / otp 1/0"),
  77. (u, "0", "1", "0", "uid / otp 0/1"),
  78. (u, k, "0", "0", "uid / otp=u_key/0"),
  79. (u, k[:4], "0", "0", "uid / otp=u_key[:4]/0"),
  80. (u, "3", k, "0", "uid / otp 3/u_key"),
  81. (u, "100", k, "0", "uid / otp 100/u_key"),
  82. (u, "0", "null", "null", "uid / otp 0/null"),
  83. (u, "0", "", "empty", "uid / otp 0/(empty)"),
  84. (u, "0", u, "0", "uid / otp 0/uid"),
  85. (u, "1", u, "0", "uid / otp 1/uid"),
  86. ]
  87. for acct, ot, raw, send, label in variants:
  88. await attempt(acct, ot, raw, send, label)
  89. asyncio.run(main())