某动云盘分享得云朵逆向分析

查看 132|回复 10
作者:kittylang   
前言
注册好几年了,才几十积分,想着写点东西刷刷积分争取早日到 200,可是空瓶子又倒不出啥技术,前段时间不是发了个某云盘每日任务的脚本么,干脆就记录一下抓取 API 的过程吧。
没有技术含量,就想着记录仔细点,万一哪个萌新看到了呢。
活动分析
先看看活动位置


理一下任务步骤
[ol]
  • 点击去查看,到达活动页面,发现就是底部栏的"发现"页面
  • 点击分享,弹出分享方式
  • 不分享直接退出活动,查看任务是否完成。(答案是并没有)
  • 回到第二步,不过这次需要点击某个方式了
  • 分享成功后,查看任务是否完成。(ok 的)
  • 云盘这个任务点进 QQ 就行了,不用真发送也能成功完成任务
    [/ol]
    那么抓包就是重点分析第 4 步了,如果没成再看前面的(因为有时候活动需要前置请求激活才能完成)。
    HttpCanary 抓包
    通过上面的分析,我们在弹出分享方式后,打开抓包,点击 QQ 后停止抓包,这样可以获得较少的请求(如果没有找到想要的才扩大范围)。
    抓取到 12 条请求

    简单的查看 url 和 请求体,并没有发现可疑的有 share 关键字或者类似的请求。
    先尝试下重放请求。发一条请求查看一下云朵记录,结果重放第一条就行了,这就是运气吧!再重放两次也是 OK 的。

    请求分析
    POST /datacenter/ HTTP/1.1
    Host: datacenter.mail.10086.cn
    Connection: keep-alive
    Content-Length: 1731
    sec-ch-ua: "Not A(Brand";v="99", "Android WebView";v="121", "Chromium";v="121"
    Content-type: application/x-www-form-urlencoded
    platform: h5
    source: content-open
    User-Agent: Mozilla/5.0 (Linux; Android 13; mi6 Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/121.0.6167.178 Mobile Safari/537.36 MCloudApp/10.5.1
    sec-ch-ua-mobile: ?1
    sec-ch-ua-platform: "Android"
    Accept: */*
    Origin: https://h.139.com
    X-Requested-With: com.chinamobile.mcloud
    Sec-Fetch-Site: cross-site
    Sec-Fetch-Mode: cors
    Sec-Fetch-Dest: empty
    Referer: https://h.139.com/content/discoverNewVersion?columnId=20&token=STuid0000011008510086uasdjikoadakhbsw&targetSourceId=001005
    Accept-Encoding: gzip, deflate, br, zstd
    Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
    data=eyJ0cmFjZUlkIjo5Nzxxxxxxxxxxxxxxxxn0%3D&ext=crc%3D-1412813306
    可以看到在 Header 中既无 Cookie 也无 Authorization,那么鉴权信息只能是在请求体中了。
    先看 data,eyJxxx 开头,最后%3D(就是=编码后的),典型的 base64 啊,打开在线工具查看一下,先 URL 解码(因为这个复制出来有%3D 之类的),再 Base64 解码
    得到了

    不急着分析字段,接下来看 ext。
    ext=crc=-1412813306 这硬看也看不出啥名堂,只知道是 CRC 循环冗余校验
    目光再次来到请求,发现 Referer 是个网页

    这也就简单多了,直接查看调用栈,试着 debuger

    先搜素一下关键字 crc=

    搜索下 hashCode,好家伙,直接出结果了,debugger 都免了。这不就是 Java 的 hashCode 用 JavaScript 实现的么?
    _.hashCode = function (str) {
      if (typeof str !== 'string') {
        return 0;
      }
      var hash = 0;
      var char = null;
      if (str.length == 0) {
        return hash;
      }
      for (var i = 0; i
    把 data 传入尝试一下得到 -1412813306,ok,结束了。
    编写代码
    直接在浏览器中运行一下
    const data = {
      traceId: Number(Math.random().toString().substring(10)),
      tackTime: Date.now(),
      distinctId: '18d7cccee76678-08d30cfe3e81ee8-4c657b58-1327104-18d7cccee7711fc',
      eventName: 'discoverNewVersion.Page.Share',
      event: '$manual',
      flushTime: Date.now(),
      model: 'Nexus 5',
      osVersion: '',
      appVersion: '',
      manufacture: 'LG',
      screenHeight: 700,
      os: 'Android',
      screenWidth: 352,
      lib: 'js',
      libVersion: '1.17.2',
      networkType: '',
      resumeFromBackground: '',
      screenName: '',
      title: '【精选】一站式资源宝库',
      eventDuration: '',
      elementPosition: '',
      elementId: '',
      elementContent: '',
      elementType: '',
      downloadChannel: '',
      crashedReason: '',
      phoneNumber: '10086',
      storageTime: '',
      channel: '',
      activityName: '',
      platform: 'h5',
      sdkVersion: '1.0.1',
      elementSelector: '',
      referrer: '',
      scene: '',
      latestScene: '',
      source: 'content-open',
      urlPath: '',
      IP: '',
      url: 'https://h.139.com/content/discoverNewVersion?columnId=20&token=STuid0000011008510086uasdjikoadakhbsw&targetSourceId=001005',
      elementName: '',
      browser: 'Edge',
      elementTargetUrl: '',
      referrerHost: '',
      browerVersion: '122.0.0.0',
      latitude: '',
      pageDuration: '',
      longtitude: '',
      urlQuery: '',
      shareDepth: '',
      arriveTimeStamp: '',
      spare: { mobile: '10086', channel: '' },
      public: '',
      province: '',
      city: '',
      carrier: '',
    };
    function hashCode(str) {
      if (typeof str !== 'string') {
        return 0;
      }
      var hash = 0;
      var char = null;
      if (str.length == 0) {
        return hash;
      }
      for (var i = 0; i
    起初用的是最精简的 Header,并没有增加云朵,依次测试后发现 platform 是必须的。
    直接修改 phoneNumber 为小号的手机号码,测试成功。
    修改 traceId,distinctId 这些后也是成功的,最后发现其实大部分字段都是可以删除的,确定用户身份唯一字段就是 phoneNumber。也就是不需要登录,只要手机号码就可以完成这个任务了。
    其他
    编辑
    有同学已经发现之前的代码再浏览器中并不能成功运行,出现了
    VM2516:1 Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
        at :1:1
    值得庆幸的是,有人真的试了。但是为啥不去尝试解决呢。
    翻译一下

    无法在“Window”上执行“btoa”:要编码的字符串包含 Latin1 范围之外的字符。

    直接百度你就能得到一个 btoa(unescape(encodeURIComponent(JSON.stringify(data)))) 这样的结果,不是太简单了么?
    当然,你已经看完这篇文章,_.hashCode 找到了,用同样方式找到  _.base64Encode 不就行了。
    发这个的目的不是为了发最后那几行代码,而是分析一个简单的过程,授人以鱼不如授人以渔。这几行代码没有太多的意义,我已经在站内分享了这个开源程序(前言提到的)

    发现, 云朵

  • anson1599   

    是不是可以做成自动签到的脚本了?
    pdcba   

    谢谢大佬分享,上次用了wps脚本,很好用,之前显示2个每日任务完成情况有点问题,尝试修改了一下。想学整个工作的方法论,没想到就有这一篇 文章了,谢谢!
    89684828   

    感谢楼主分享,支持一下!
    devilpanama   

    时间戳需要实时么
    blackdarks   

    楼主能讲讲代码如何使用吗?我直接在PC网页F12输入代码好像反馈有bug
    BestSum   

    楼主是否可以做一个自动化签到的脚本,可以一键把任务能做的都做了,还有那个pc登录,每个月都要发一次验证码登录,烦得很。。
    p100200300   

    感谢分享!
    readboy   

    这个好,我的也比较少,可以用这个了。
    kittylang
    OP
      


    blackdarks 发表于 2024-3-10 09:59
    楼主能讲讲代码如何使用吗?我直接在PC网页F12输入代码好像反馈有bug

    btoa 的参数有问题是吧,查看编辑后的最后一部分,把 btoa 替换为那一行就行了
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部