某网站破解备忘

某网站采用了多种反破解手段,特此开贴记录分析破解过程。

工具和参考

  • awesome-java-crawler - 我收集的爬虫相关工具和资料
  • java-curl - 本人写的java HTTP库,可用来替换chrome网络后端,更方便控制底层行为,如缓存、代理、监控、修改请求和应答等
  • cdp4j - java版的Chrome Devtools Protocol实现,用于控制Chrome浏览器,没有特征哟
  • beautifier.io - js代码在线格式化
  • 类似网站的破解 - 神箭手云的大佬写的
  • 很早的一篇分析文 - 看特征是这种加密的早期版本

网站反破解手段

反动态分析(即反调试)

  • Chrome中,F12打开开发者控制台,发现立即停在断点上了
  • 断点处源码为:
(function() {var a = new Date(); debugger; return new Date() - a > 100;}())
  • 此处可能有两种作用:

    1. 使用debugger调用显式设定断点,且使用定时器高频次调用此段代码,如果破解者不厌其烦,禁用调试,那么破解者等于自缚手脚,也无法设定断点进行动态分析了
    2. 此方法返回了debugger语句的执行时间是否大于100毫秒,意味着可以根据返回值判断出是否有破解者正在试图调试当前脚本

代码动态混淆

  • 代码经过混淆,所有变量,方法都被更名为形似"_$xx",代码中所有字符串和部分常量也被替换,部分常用方法也被替换。因此基本上不可读
  • 以上述方式加密的代码共分4部分。

    • 一部份代码加密混淆后放在html文档内部,同时还在文档头部有大量高度混淆的纯数据,此部分估计也是加密的代码,类似

    • 一代码直接在页面加载js获取
    • 还有两小段代码应是页面js执行过程中动态加载
  • 以上述方式加密的4段js代码,每次刷新都会变化,不仅仅是变量名有变化,方法顺序也有变化,估计要么是服务端有一堆预先生成的js,或者是每次服务器端根据AST重新命名并乱序后生成等价的js
  • 此手段导致很难动态跟踪分析,因为在pretty print后的某行代码上设定断点后重新刷新执行,由于js变化了,之前设的断点就失败了
  • 对策,本地代理+自定义缓存,避免每次代码变动,这样既可进行动态跟踪分析

客户端生成Cookie

  • 页面加载完成后,分析cookie,发现有一个FSSBBIl1UgzbN7N80T的值和前面应答中Set-Cookie的值不一致,说明客户端js对cookie进行了修改
  • 此Cookie的值很长,估计包含浏览器特征等关键信息
  • 常规手段无法对cookie的读写设定断点,不过github上找到几个可以增强js断点能力的库/插件
  • 目前采用javascript-breakpoint-collection来在cookie修改处设定断点
  • 具体方法是用Page.addScriptToEvaluateOnNewDocument()把上述库js代码注入,这样可以确保在其它脚本加载前注入
  • 设定断点后,发现页面首次加载会设定一次cookie值,然后每隔1分钟左右还会更新该值
  • 但是因为代码高度加密,尚无法解析cookie值生成算法

反PhantomJS, Selenium

  • 通过动态分析调试,可知此种加密算法将全部字符串常量保存在全局对象中,其变量名特征为_$xx
  • 因此,可以在控制台运行一小段程序遍历window对象中所有前缀为_$的变量,从而获取到字符串映射表
  • 通过此方法导出的映射表中包含以下内容:
    "_$iQ": "_Selenium_IDE_Recorder,_selenium,callSelenium",
    "_$cv": "__driver_evaluate,__webdriver_evaluate,__selenium_evaluate,__fxdriver_evaluate,__driver_unwrapped,__webdriver_unwrapped,__selenium_unwrapped,__fxdriver_unwrapped,__webdriver_script_func,__webdriver_script_fn",
    "_$a6": "webdriver-evaluate",
    "_$bs": "callPhantom,_phantom",
  • 由以上代码可知,前端代码对phantomjs, selenium等常用浏览器自动化框架的特征有判断或采集行为,并可采取针对性措施,比如应答错误数据等
  • 因此,如果使用基于浏览器的破解方案,只能采取以下述方案之一:

    • 自行修改自动化框架,修改特征
    • 修改前端js代码,改掉特征检测逻辑
    • 使用其它不基于webdriver (selenium), phantomjs的浏览器自动化框架

禁用桌面版浏览器

  • 以前用cdp4j控制chrome模拟整个流程是ok的,但是某网最近一次更新后,彻底禁用了桌面版chrome,其表现为可以打开前几个页面,但是登录和计费提交时返回201,404等非正常应答
  • 估计是在前面步骤收集浏览器特征,加密后放到cookie中,在若干关键步骤如登录和计费的服务端处理中,解析出浏览器特征,禁用掉桌面版浏览器
  • 试过覆盖User-Agent, navigator.platform='Linux armv7l'和window.width/height等,但无效,在未能分析完整特征收集代码的情况下,很难猜测其逻辑

使用安卓版浏览器的坑

  • 使用真实手机安装Chrome69版,确保adb连接后,使用这篇文档的方法,即可从桌面浏览器连接到手机Chrome并可使用inspector页面远程控制
  • 但是安卓版inspector的地址在blogspot上,在墙外,因此还需要……
  • 因为真实手机对整个程序的架构和成本有重大影响,因此尝试改用模拟器
  • 测试过逍遥和夜神,后来选用逍遥
  • 使用前面的chrome apk包可以正常安装,但打开页面空白
  • 经搜索发现需要x86版的chrome,在apkmirror下载到69版,模拟器安装后可以正常使用
  • 使用cdp4j连接,发现连接成功的几率非常低,Target.createTarget返回的targetId无法正常连接
  • 在连接成功的一次中,发现模拟鼠标滑动失效,怀疑是桌面版和安卓版的坐标计算方法不同
  • 可能需要综合分析inspector的api调用顺序后,自己编写cdp连接chrome的代码。需要借助chrome-protocol-proxy分析inspector的具体逻辑
  • 或者验证下chrome-remote-interface能否正常连接chrome,如正常则可以参考node版本编写java版本

IP限制

  • 注册用户/修改密码的SSO站点和主站地址不一样,估计是另一批人做的,这个站点对IP进行限制
  • 目前发现的规则是:

    • 所有的ISP(机房)IP 直接封掉,这一招干掉了所有用云主机和肉鸡做代理的
    • 芝麻代理等几家的收费IP也大部分不可用,估计是同行用过被加入黑名单了

鼠标动作收集

  • 使用注入js代码模拟点击按钮即可实现大部分页面的操作
  • 但是在计费对话框页面上,直接js代码导致服务器返回错误
  • 发现需要模拟真实鼠标点击,而且不能简单直接点击按钮,需要在页面的其它部分先点击一下再点击提交按钮才能生效,估计是js收集了鼠标动作,提交时将数据加密后放到"MmEwMD"参数中

目前已发现使用此手段加密的网站收集:

  • 食品药品监督管理局
  • 中国商标网
  • 裁判文书网
  • 咪咕阅读
  • 神州租车
  • 湖南移动
  • 网上房地产

你可能感兴趣的:(某网站破解备忘)