腾讯滑块验证码
腾讯行为验证码 滑块拼图验证
抓包分析
请求了https://t.captcha.qq.com GET方法
parms参数为
1 | aid=2000000008&protocol=https&accver=1&showtype=full&ua=TW96aWxsYS81LjAgKExpbnV4OyBBbmRyb2lkIDEzOyBNT01PRSBCdWlsZC9US1ExLjIyMDgyOS4wMDI7IHd2KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBWZXJzaW9uLzQuMCBDaHJvbWUvMTExLjAuNTU2My4xMTYgTW9iaWxlIFNhZmFyaS81MzcuMzYgWFdFQi8xMTEwMDUzIE1NV0VCU0RLLzIwMjMxMTA1IE1NV0VCSUQvNTI3MyBNaWNyb01lc3Nlbmdlci84LjAuNDQuMjUwMigweDI4MDAyQzM3KSBXZUNoYXQvYXJtNjQgV2VpeGluIE5ldFR5cGUvV0lGSSBMYW5ndWFnZS96aF9DTiBBQkkvYXJtNjQ%3D&noheader=1&fb=1&aged=0&enableAged=0&enableDarkMode=0&grayscale=1&clientype=2&userLanguage=zh-cn&cap_cd=&uid=&wxLang=&lang=zh-cn&entry_url=&elder_captcha=0&js=%2Ftcaptcha-frame.921213.js&login_appid=&wb=1&subsid=1&callback=_aq_99695&sess= |
拆开一条条看
1 | aid=2000000008 |
有三个关键参数 分别是aid ua callback
ua为base64后的 callback决定了返回的json起始值
返回值
1 | _aq_99695({"state":1,"ticket":"","capclass":"1","subcapclass":"10144","src_1":"cap_union_new_show","src_2":"template/new_placeholder.html","src_3":"template/new_slide_placeholder.html","sess":"s0XdZ2kavzZ4lMrQ4uwCfaXhEbuMZNR2MsyBPJmeK4mVInREcH1vqyhSe7G6MlWm-fTKVGCdkqkf3jEmZXaOMnELsMWZj9sgB5lexBUxzPD08ERn-Z3pxYIgBcxXvbds63HGgnY9HBQaI2hB3L5HYHdcwqM1Rwy4HBGElODCyNfcYXmJoqXO2aal0lW3-P3JTgy0yay97hg2tyNVSSlmVJft--TJdt2pquRgRgjg-dP3wj1tCyp7Rv-aNVcOcOfBsdiF58Uo3vDppW4ntaagLkR3fvcKynqh_jCnKswt892qqqAl03wq7-9mJFprEu3hdehv3gfitjm6VIuPsulX9lq658W6yS4H0oB-xMXDqJU2p7EYddI2mVgnZxrC3VBSyaosj5Cng5eSrhtBILTLTBIWKGXpPokIYStV-EMjLJiVE*","randstr":"","sid":"7198604069692559360","log_js":"","extra":"{\"rainbow\":\"{\\n \\\"samplingRate\\\":0.1,\\n \\\"apiReportThrottle\\\":200,\\n \\\"sourceReportThrottle\\\":300,\\n \\\"loadReportThrottle\\\":1000,\\n \\\"sampleAppidList\\\":[\\\"2053860784\\\",\\\"2091569087\\\"]\\n}\"}","data":{"comm_captcha_cfg":{"tdc_path":"/tdc.js?app_data=7198604069692559360&t=1213916534","feedback_url":"https://support.qq.com/products/304457","pow_cfg":{"prefix":"2c4eae921213dcf2#","md5":"ef7d702689e9682a8a6f93b695c6383b"}},"dyn_show_info":{"lang":"zh-cn","instruction":"拖动下方滑块完成拼图","bg_elem_cfg":{"sprite_pos":[0,0],"size_2d":[672,480],"img_url":"/cap_union_new_getcapbysig?img_index=1&image=02a027000000001a0000001eb7f57e512fc3&sess=s0S6ZReNGNUQ43mWmkryTKQ-GtePsp7eN7mZyFCs7Vu2_IwXtvWdMKhUTZJDs71_GuUZiO_4zCcQ-N4FcqIvY4mEOPRNIyyuaUuB7Qilkem_02OF5uRqtXakeQteZuF0VcmxW177S1Sa1XrHPKdR3xaHwdAnNKrqqoE46B3roBjidIYCdEeOp18snNq4bpz_B405I6acSRC7SSOBzFC0xQAOIMiZhQHsnY8h67lLuEbesyJCjzPfVyahFwTsQiR2K98OisU5xWDf73uc0QEgBcBEfYky8P3FLbfFPxttlFPNYsqdWHM02ibttaVaRIn_30wyKOLeYSRqagkZkK8BxE-twNQUY36xgYyeJ3ZR6QUs87YMvO8cSydJRURGBcVffG5IsmgCw3erjF64ap_3CeXLx4trYeZqt9xFDXj3bI-Bo*"},"fg_elem_list":[{"id":3,"sprite_pos":[0,422],"size_2d":[672,32],"init_pos":[0,422]},{"id":1,"sprite_pos":[140,490],"size_2d":[120,120],"init_pos":[50,109],"move_cfg":{"track_limit":"x>=50&&x<=552","move_factor":[1,0],"data_type":["DynAnswerType_POS"]}},{"id":2,"sprite_pos":[0,490],"size_2d":[130,70],"init_pos":[45,402],"move_cfg":{"track_limit":"x>=50&&x<=552","move_factor":[1,0]},"type":"slider"}],"fg_binding_list":[{"master":1,"slave":2,"bind_type":"DynBindType_DX_DX","bind_factor":1},{"master":2,"slave":1,"bind_type":"DynBindType_DX_DX","bind_factor":1}],"sprite_url":"/cap_union_new_getcapbysig?img_index=0&image=02a027000000001a0000001eb7f57e512fc3&sess=s0S6ZReNGNUQ43mWmkryTKQ-GtePsp7eN7mZyFCs7Vu2_IwXtvWdMKhUTZJDs71_GuUZiO_4zCcQ-N4FcqIvY4mEOPRNIyyuaUuB7Qilkem_02OF5uRqtXakeQteZuF0VcmxW177S1Sa1XrHPKdR3xaHwdAnNKrqqoE46B3roBjidIYCdEeOp18snNq4bpz_B405I6acSRC7SSOBzFC0xQAOIMiZhQHsnY8h67lLuEbesyJCjzPfVyahFwTsQiR2K98OisU5xWDf73uc0QEgBcBEfYky8P3FLbfFPxttlFPNYsqdWHM02ibttaVaRIn_30wyKOLeYSRqagkZkK8BxE-twNQUY36xgYyeJ3ZR6QUs87YMvO8cSydJRURGBcVffG5IsmgCw3erjF64ap_3CeXLx4trYeZqt9xFDXj3bI-Bo*","color_scheme":"#26C067"}},"uip":"11.4.5.14"}) |
去掉_aq开头进行格式化
1 | { |
需要注意的参数为
1 | "tdc_path": "/tdc.js?app_data=7198604069692559360&t=1213916534" |
img_url与sprite_url分别代表背景图和缺口图
最终提交验证的地址为 https://t.captcha.qq.com/cap_union_new_verify
提交的参数格式为form-data
1 | collect=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&tlg=3416&eks=KT0GxYUSVeYeeXHunYofyH3jHR7V3YVvp0/XHzAUjMC92n1V5230gK6MxAaCp2fYMHpWsYx/WeiR1S6sO1UBL3NofUZfsO8CQqoAQNy2WyUTeiKpyBk0ZeXM2JI8FX+N0xk5Rr70QiWX6zKyq8P8S0yoQMSZFf14YZQGw68dzXnryUtFbB3l3uW/XUjrYctEqThF2x7UOzqbDALD1nBeqsxE8U84XKJ8lR6syYdd/pI=&sess=s0XdZ2kavzZ4lMrQ4uwCfaXhEbuMZNR2MsyBPJmeK4mVInREcH1vqyhSe7G6MlWm-fTKVGCdkqkf3jEmZXaOMnELsMWZj9sgB5lexBUxzPD08ERn-Z3pxYIgBcxXvbds63HGgnY9HBQaI2hB3L5HYHdcwqM1Rwy4HBGElODCyNfcYXmJoqXO2aal0lW3-P3JTgy0yay97hg2tyNVSSlmVJft--TJdt2pquRgRgjg-dP3wj1tCyp7Rv-aNVcOcOfBsdiF58Uo3vDppW4ntaagLkR3fvcKynqh_jCnKswt892qqqAl03wq7-9mJFprEu3hdehv3gfitjm6VIuPsulX9lq658W6yS4H0oB-xMXDqJU2p7EYddI2mVgnZxrC3VBSyaosj5Cng5eSrhtBILTLTBIWKGXpPokIYStV-EMjLJiVE*&ans=[{"elem_id":1,"type":"DynAnswerType_POS","data":"465,109"}]&pow_answer=2c4eae921213dcf2#290&pow_calc_time=50 |
参数分析
参数有点多 精简一下看重点
1 | collect= |
其中collect与eks为tdc.js计算得到 collect为getData参数 eks为getInfo参数
提交验证无误后服务器会返回
1 | { |
所需要的参数randstr ticket
tds使用腾讯自家的TENCENT_CHAOS_VM
技术 这部分可以参考下面链接
分析参考:
Zhihu: https://zhuanlan.zhihu.com/p/621903162
JamzumSum: https://zzsblog.top/tcaptcha.html
模拟计算
这里咱们使用Python ChaosVM Executor 来模拟执行tdc.js获取collect与eks参数
1 | //参考代码 注释由Ai生成 |
鼠标轨迹算法参考
1 | def imitate_drago(x1: int, x2: int, y: int) -> t.Tuple[t.List[int], t.List[int]]: |
现在解决了collect和eks 来看后面的ans 可以看到ans的DynAnswerType_POS就是滑块正确位置
X坐标465 Y坐标109 滑块的Y坐标为固定 可以从"init_pos": [50, 109]
提取Y坐标
这里再介绍一个Python库 DdddOcr 带带弟弟OCR通用验证码识别
1 | Demo代码 |
传入背景图与缺口图即可识别坐标 但是因为缺口图有边框透明背景 识别率并不是很满意
这里加入一些图像操作 对缺口图进行暴力裁切以符合匹配条件
1 | def cropmatch_imagem(reference_image: bytes, target_image: bytes) -> int: |
图像匹配的问题解决 继续看下一个参数
1 | pow_answer=2c4eae921213dcf2#290&pow_calc_time=50 |
腾讯这边的pow算法为prefix#步数 计算MD5 匹配给出的md5
这里 2c4eae921213dcf2#290 得到的MD5即为->ef7d702689e9682a8a6f93b695c6383b
直接上代码
1 | // 注释由Ai生成 |
至此参数准备完成
参考代码
1 | async def TencentCAPTCHA(self) -> bool: |
- FetchData为封装的httpx函数