78 lines
4.3 KiB
Python
78 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
|
"""一键: 账号密码 -> 完整网页Cookie全套。
|
|
用法: python tools/full_web_cookie.py <账号> <密码>
|
|
产出: 打印全部cookie并写 evidence/web_cookies_full.txt
|
|
"""
|
|
import sys, json, re, hashlib
|
|
ACCT, PWD = sys.argv[1], sys.argv[2]
|
|
sys.argv = [sys.argv[0]]
|
|
import sys,json,time,base64
|
|
from urllib.parse import quote
|
|
sys.path.insert(0,'scripts'); sys.path.insert(0,'tools')
|
|
from probe_forge_cert_bind import load_capture, parse_p1, build_p1, forge_cert
|
|
from probe_huya_qr_bind import QrRole, web_behavior
|
|
from core.huya.device_fingerprint import get_huya_sdid
|
|
qurl,P1_old=load_capture()
|
|
fields=parse_p1(P1_old)
|
|
import hashlib,requests as _rq
|
|
from huya_wup_encoder import build_password_login_wup
|
|
_raw=(__import__('pathlib').Path(__file__).resolve().parent.parent/'evidence/wup_passwordlogin_taf.bin').read_bytes()
|
|
_mj=json.loads(re.search(rb'(\{"associationId.*?\})',_raw).group(1))
|
|
_ua=re.search(rb'(\{"curl".*?"user_action":\[.*?\]\})',_raw).group().decode()
|
|
_sd=re.search(rb'PQwemAN9[A-Za-z0-9+/=]+',_raw).group().decode()
|
|
_dev={"app_version":"13.4.22","sdk_version":"1.0.80138","vendor":"xiaomi","model":"M2102J2SC","os":"android","ip":"127.0.0.1","fingerprint":"02df398797432eadefcc12767119ad5e80999389","screen":"M2102J2SC,30,11","width":"1080","height":"2120","device_id":"7c5387e0539c023c31c4ff0e807e7256117385ee"}
|
|
_pkt=build_password_login_wup(ACCT[3:] if ACCT.startswith("hy_") else ACCT, hashlib.sha1(PWD.encode()).hexdigest(),_sd,"ed0db8334cadd236c00cadf7e11ab5a5",_mj["session"],_mj["traceId"],_ua,_dev)
|
|
_r=_rq.post("https://wup.huya.com",data=_pkt,headers={"Content-Type":"application/multipart-formdata; charset=UTF-8","User-Agent":"Dalvik/2.1.0"},timeout=15)
|
|
_b=_r.content; _s=_b.find(b'\x0a\x0a',0x40); _e=_b.find(b'_wup_header'); _d=_b[_s:_e-6]
|
|
_m=re.search(rb'\x3d\x00\x00.',_d)
|
|
if not _m:
|
|
_u=re.search(rb'https://aq\.huya\.com[^\x00\x20]{20,}',_d)
|
|
if _u:
|
|
print('❌ 该账号触发了安全验证(safe_auth), 无法直接取cred')
|
|
print(' 解决: 先用该账号在手机虎牙App上正常登录一次(建立设备信任),')
|
|
print(' 之后本脚本即可全自动。验证页:', _u.group()[:100].decode())
|
|
else:
|
|
print('❌ 登录未返回cred(密码错误或账号异常), 响应',len(_b),'B')
|
|
sys.exit(1)
|
|
_l=_m.group()[3]
|
|
cred=_d[_m.start()+4:_m.start()+4+_ln]
|
|
print('新鲜cred:',len(cred),cred[:8].hex())
|
|
P1n=build_p1(b"5008",fields["fingerprint"],cred,rnd=fields["rnd"])
|
|
cert=base64.b64encode(forge_cert(P1n,key_idx=fields and 0x20)).decode()
|
|
raw=base64.b64decode(qurl)
|
|
i=raw.find(base64.b64encode(forge_cert(build_p1(b"5008",fields["fingerprint"],b"\x0a"*114,rnd=fields["rnd"]),key_idx=0x20)))
|
|
# 直接替换原证书段: 找原cert b64 span——用原P1重建
|
|
old_b64=None
|
|
from probe_forge_cert_bind import find_cert_span as _fcs; j=_fcs(raw)
|
|
if True:
|
|
# 退路: 用find_cert_span
|
|
from probe_forge_cert_bind import find_cert_span
|
|
s0,s1,_=find_cert_span(raw); raw=raw[:s0]+cert.encode()+raw[s1:]
|
|
else:
|
|
raw=raw[:j]+cert.encode()+raw[j+len(old_b64):]
|
|
wup=base64.b64encode(raw).decode()
|
|
sdid=get_huya_sdid(allow_fallback=False).sdid
|
|
pc=QrRole(pc=True,sdid=sdid); ph=QrRole(pc=False,sdid=sdid)
|
|
beh,page=web_behavior()
|
|
resp=pc.call("/qrLgn/getQrId","70001",{"behavior":beh,"type":"","domainList":"","page":page})
|
|
qrid=resp["data"]["qrId"]
|
|
cp=f"https://aq.huya.com/r/confirm.html?k={qrid}&id=5002"
|
|
ph.call("/qrLgn/scanQrPicNotify","70005",{"qrId":qrid,"wupData":wup,"behavior":quote("[]",safe=""),"page":quote(cp,safe="")})
|
|
r2=ph.call("/qrLgn/bindQrLoginUser","70007",{"qrId":qrid,"wupData":wup,"behavior":quote("[]",safe=""),"page":quote(cp,safe="")})
|
|
print("bind rc",r2.get("returnCode"))
|
|
for i in range(10):
|
|
rt=pc.call("/qrLgn/tryQrLogin","70003",{"qrId":qrid,"remember":"1","domainList":"","behavior":beh,"page":page})
|
|
dt=rt.get("data") or {}
|
|
if dt.get("stage")==2:
|
|
print(json.dumps(dt,ensure_ascii=False,indent=1)[:1800]); break
|
|
time.sleep(2)
|
|
|
|
# 追加: cookie verify 兑换
|
|
sess = getattr(pc,'session',None) or getattr(pc,'s',None) or getattr(pc,'_sess',None)
|
|
r=sess.post("https://udblgn.huya.com/web/cookie/verify",json={"appId":5002},timeout=15)
|
|
print('verify HTTP',r.status_code)
|
|
for h in r.headers.get('Set-Cookie','').split('\n') or [r.headers.get('Set-Cookie','')]:
|
|
if h: print('SET:',h[:110])
|
|
print('cookie jar:')
|
|
for c in sess.cookies: print(' ',c.name,'=',c.value[:50])
|