Files
live-hub-py/tools/full_auto_safe.py
T

78 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""一键全自动(含新账号safe_auth滑块): 账号密码 -> 页面cookie(biztoken)。
与 full_auto_test.py 的区别: 可信账号直出cred之外,
新/异地账号触发 safe_auth 时自动解 udbrtt 滑块并重发登录, 全程零人工。
用法:
.venv/bin/python tools/full_auto_safe.py <账号如hy_xxx或300023887> <密码>
前提: evidence/cert_keycap.json 内有较新鲜的 wupData 信封
(过期则先在设备上跑 scripts/hook_cert_keycap.py 刷新)。
"""
import base64
import json
import re
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "tools"))
from app_login_flow import QrAuthRequiredError, login_cred # noqa: E402
from cert_forge import build_p1, decrypt_cert, forge_cert, parse_p1 # noqa: E402
from envelope_forge import Envelope # noqa: E402
def forge(cred: bytes) -> str:
"""复用信封原证书的nonce/指纹/key_idx仅换cred(纯随机nonce必40020)."""
env = Envelope.load()
orig = base64.b64decode(env.cert_b64)
f = parse_p1(decrypt_cert(orig))
P1 = build_p1(f["app_id"], f["fingerprint"], cred, rnd=f["rnd"])
return forge_cert(P1, key_idx=orig[1]).hex()
def bind_for_cookie(cred_json_path: Path) -> bool:
"""复用扫码绑定四步流(QrRole), 返回是否拿到biztoken。"""
probe = ROOT / "scripts/probe_forge_cert_bind.py"
src = probe.read_text()
src = re.sub(r'open\("evidence/hycred_[a-z_]+\.json"\)',
f'open("{cred_json_path.as_posix()}")', src)
tmp = ROOT / "scripts/_probe_auto.py"
tmp.write_text(src)
r = subprocess.run([sys.executable, str(tmp)], capture_output=True, text=True)
print(r.stdout[-800:])
return '"ok": true' in r.stdout or "'ok': True" in r.stdout
def main() -> int:
acct, pwd = sys.argv[1], sys.argv[2]
print("[1/3] 纯Python密码登录 (遇safe_auth自动过滑块) ...")
try:
cred = login_cred(acct, pwd)
except QrAuthRequiredError as exc:
print(f"❌ {exc}")
return 2
print(f" cred OK: {len(cred)}B {cred[:8].hex()}")
print("[2/3] 铸造证书 ...")
cert_hex = forge(cred)
out = ROOT / "evidence/auto_test_cred.json"
out.write_text(json.dumps({"p1": "", "cert_hex": cert_hex,
"cred_hex": cred.hex()}))
print(f" 证书 OK: {len(cert_hex)//2}B")
print("[3/3] 扫码绑定取cookie ...")
if bind_for_cookie(out):
print("\n🎉 全链路成功: 密码已换出页面cookie(biztoken)!")
return 0
print("\n❌ 绑定失败——若40020多为信封过期, 请刷新wupData后重试")
return 1
if __name__ == "__main__":
raise SystemExit(main())