TCaptcha 有哪些检测机制?
What does TCaptcha detect and collect?
前言
由于我最近在做 QQQR 的验证码部分,比如
,在 Qzone2TG 的前面一些版本里,我都是用 Selenium 爬取图像配合模拟拖动来做的,当然也需要一定程度的 CV 技术。
但上面这种办法虽说理论可行,但并非真的万无一失。事实上,在一开始开发的时候跑通之后,这个办法就再也没能稳定工作。等到后来我用 Selenium 抓二维码登录,乃至 QQQR 的第一个版本能够实现协议二维码登录的时候,我就更不倾向于依赖这种不可靠的办法了。
直到 QQQR 的开发到了 2.3.0,我重新开始研究验证码的破解之道,在长达十余天乃至数十天的研究中仔细分析抓包结果和 TCaptcha 相关的 JS 代码,我才终于意识到,使用 Selenium 这些模拟登录的办法究竟处在一种怎样危险的境地。
截至目前,我还没有解决 23003 网络环境异常 的问题。我相信唯一可能暴露的地方就在于验证码检测。尽管如此,我仍然发现了很多腾讯检测浏览器特征的机制。
2022 年 6 月 16 到 17 日腾讯似乎升级了 TCaptcha,然而应该只是简化流程,基本的逻辑、采集的信息都没有太大变化。
tdx.js
在加载 TCaptcha 的时候,页面会载入 tdx.js。这个 JS 本质上是一个虚拟机,准确来说是一个指令集加栈加纸带的组合。我在这方面的知识有限,有时不理解加密何以需要如此复杂的实现。但不得不承认,JS 混淆加上这种叫做 TENCENT_CHAOS_VM 的技术的确可以大大阻碍逆向分析。遗憾的是,腾讯曾举办过一场大赛,这种虚拟机的机制已经被参赛的研究者们看透。我这种一开始不明就里的人,在 GitHub 上查阅相关资料后便大致理解了。
上述指令集、栈与纸带的组合完全决定了程序的逻辑。我的目标就是在这段混淆代码中找出腾讯究竟收集了哪些信息,进而判断出当前环境异常。
我首先尝试了一些手动反汇编的办法,给每个命令加输出,类似编译器。但受限于我本身的水平,得到的结果不够准确,无法交给机器处理,实用性有限。不过从另一个角度,这一步让我真正深入到了指令运行的内部,从而为后面的调试打下了基础。
到底检测了什么
背景和步骤到此为止,下面列出一些检测的条目,给包括我在内的初学者一点警醒:Selenium 等模拟手段并不可靠。
自动化测试工具
这一类比较通用,用于检测客户端是否受自动化控制。
window.callPhantomwindow._phantomwindow.WebPagewindow.fxdriver_idwindow.__fxdriver_unwrappedwindow.domAutomationwindow.ubotwindow.CasperErrorwindow.casperwindow.patchRequirenavigator.webdriverdocument.$cdc_asdjflasutopfhvcZLmcfl_document.__webdriver_script_fn
正常情况下这些属性的值应为 undefined。在使用某些特定工具时,这些值会被设置,从而可以直接断定当前访问受自动化控制。
例如 window.navigator.webdriver,使用 Selenium 时该项会被设为 true;
window.document.$cdc_asdjflasutopfhvcZLmcfl_ 是 ChromeDriver 的特征属性,正常的浏览器中并不存在。
环境信息
tdx.js 也会读取以下信息,通过分析这些数据可以判断客户端所处的环境。虽然没有直接证据,但我认为 23003 错误应该就是在此处触发的。
document.mozHidden
用于检查标签页是否可见,在 Chromium 上为 undefined。
navigator
navigator.userAgentnavigator.appVersionnavigator.platformnavigator.cookieEnablednavigator.languagesnavigator.vendornavigator.appNamenavigator.pluginsnavigator.getBattery
document & location
document.charsetdocument.cookiedocument.referrerdocument.documentElement.clientWidthdocument.documentElement.clientHeightdocument.getElementByIdlocation.href
screen & other display properties
screen.colorDepthscreen.widthscreen.heightscreen.availHeightscreen.pixelDepthwindow.innerWidthwindow.innerHeight
上述属性和方法均是被检查的对象。这些也正是 Selenium 等工具的优势所在:它们能和正常浏览器保持一致。
对于普通的爬虫来说,通常不会有如此细致的检查,毕竟常见的场景仅限于爬取 HTML。但 QQQR 需要直接与验证码交互,其本质不仅仅是爬虫,使用的工具也是 requests 和 nodejs 的基础组合,因此这些细节都需要注意。
操作环境
TCaptcha 会尝试在环境中调用 CreateElement、FindElementById 等函数,创建和修改包括 img、iframe 等在内的众多元素。目前尚不清楚创建这些元素是否关联其他操作,但这对我们使用的模拟环境也是一个考验。
用户操作
人类访问需要操作,而爬虫没有这个必要。因此 tdx.js 也会收集用户的动作(正常情况下通过 Listener 收集,但当 CreateElement 不可用时,会暴露 tdc.set_data 接口,允许外部传入模拟数据)。
- 客户端类型(手机/PC)
- 坐标系(验证码位置,缩放比)
- 拖动拼图时鼠标的时间-坐标关系
未完待续
Hook this up to your favourite commenting platform — Giscus, Disqus, or your own.