• js加密进阶与搭建Node服务


    js加密进阶与搭建Node服务

    X = 1621779426453
    U = 1621779410888
    w = 1621779395276
    jt.data = 1621779395276
    
    • 1
    • 2
    • 3
    • 4

    加密参数

    • s

      • O

        监听垂直滚动条事件(scrollTop)

        window.document.body.scrollTop
        
        • 1
        O.data = [{
        	scrollTop: xxx,
        	timestamp = Date.now() - w   // w = 1621523124040
        }]
        
        • 1
        • 2
        • 3
        • 4
      • R

        监听鼠标点击事件, 按下鼠标(mousedown)

        R.data = [
        {
        	clientX: 715
            clientY: 325
            elementId: ""
            timestamp: Date.now() - w
        	},
        	....
        ]
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
      • 时间戳w

        Lt
                                    case "0":
                                        r[n("0x97", "bpr9")](qt);
                                        continue;
                                    case "1":
                                        this[n("0x132", "GmkI")](t[j] || 879609302220);
                                        continue;
                                    case "2":
                                        r[n("0xf2", "^o[d")](Gt, Z, et);
                                        continue;
                                    case "3":
                                        Z = ot[w]();
                                        continue;
                                    case "4":
                                        r[n("0x150", "%LaC")](It);
                                        continue
                                    }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
    • Wt

      监听鼠标点击事件(click), 如果Wt.data > 1执行Wt.data.shift(). 即记录的是最后一条点击事件

      Wt.data = [{
      	clientX: 715
          clientY: 325
          elementId: ""
          timestamp: Date.now() - w
      }]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • pt

      当前页面地址

      document.location.href
      
      • 1
      pt.data = {
      	href: "http://yangkeduo.com/pincard_share_card_popup.html?_pdd_fs=1&_pdd_tc=00ffffff&categoryId=39236&refer_origin_page_sn=17542&refer_page_name=list_channel&refer_page_id=67387_1615819189608_3dep3yqyuo&refer_page_sn=67387&refer_abtest_info=%7B%7D",
      	port: ""
      }
      
      • 1
      • 2
      • 3
      • 4
    • mt

      mt.data = {
          availHeight: 1025,
          availWidth: 1891
      }
      
      • 1
      • 2
      • 3
      • 4
    • vt

      vt.data = "3287976604829790-1621528579964"  // vt.data = 随机数-U
      
      • 1
      • U

        Lt[d("0x1d", "s2FC")][d("0x40", "cn*L")] = function(t) {
            X = ot[w](),
            U = t       // 1621528579964
        }
        
        • 1
        • 2
        • 3
        • 4
    • bt

      验证浏览器环境

      bt.data = 8192
      
      # bt的验证参数r
      r = [
          0: 0   // 判断当前window.outHeight < 1 || window.outWidth < 1
          1: 0   // 判断档期是否有windwow._phantom || window.callPhantom
          2: 0   // 判断有无window.Buffer
          3: 0   // 判断有无window.emit
          4: 0   // 判断有无window.spawn
          5: 0   // 判断有无navigator.webdriver
          6: 0   // 判断有无window.domAutomation
          8: 0   // 判断navigator.plugins是否大于0
          9: 0   // 判断navigator.language是否为""
          10: 0  // 判断有无window.vendor
          11: 0  // 判断有无window.Modernizr
          12: 0  // 判断有无window.chrome
          13: 1  // 判断'webdriver' in navigaotr
          14: 0  // 判断navigator.hasOwnProperty('webdriver')是否为true
          15: 0  // 判断History.back.toString()中是否有'ipcRenderer'
          16: 0  // 判断browser.versions 是否有module
          17: 0  // 判断window.document.getElementById.toString() 是否含有native code
          ]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    • gt

      gt.data = c.pbc(window.location.href)
      
      • 1
    • kt

      // DeviceOrientationEvent 表示手机屏幕翻转
      kt.data  = 'n'   // 网页端固定为n
      
      • 1
      • 2
    • _t

      // DeviceMotionEvent位置和方向改变速度的信号
      _t.data = 'n'   // 网页端固定为n
      
      • 1
      • 2
    • yt

      yt.data = Date.now() - X    // x = 1621528592265
      
      • 1
    • wt

      wt.data = User-Agent
      
      • 1
    • Ct

      cookie中的_nano_fp

      Ct.data = {
      	nano_cookie_fp: "XpEaX0galpCxlpXylT_1I6dtvD7pLG1UO7xZIpLs",
      	nano_storage_fp: "XpEaX0galpCxlpXylT_1I6dtvD7pLG1UO7xZIpLs"
      }
      
      • 1
      • 2
      • 3
      • 4
    • St

      St.data = window.document.referrer.split("?")[0]
      
      • 1
    • Ot

      cookie中的pdd_user_id

      Ot.data = "pdd_user_id"
      
      • 1
    • Rt

      cookie中的api_uid

      Rt.data = "CksBgV/4eYkFCwBSPt8WAg=="
      
      • 1
    • Pt

      请求anti_content的次数

      Pt.data = 7
      
      • 1
    • jt

      页面初始化的时候产生的时间戳

      jt.data = w
      
      • 1
    • Dt

      cookie中的pdd_vds

      Dt.data = "gaLLNIyLQNiimoGtPyOQEQOIaomoabtNNGbGnQQmIbnLPEQatNOtbPOaLLam"
      
      • 1
    • 扣加密函数的时候最好用源文件来扣, 我们自己还原的文件可能会有略微差异, 也就是说我们还原的文件只适合参考

    • 混淆变量的函数可能不唯一, 导致了结果不同

    函数角度调用加密函数

    • 扣函数的要求
      • 熟悉全部参数获取流程, 加工流程, 加密流程;
      • 工作量非常大;

    对象角度调用加密函数

    • AntiContent生成函数At的环境和调用c.encode的环境是不一样的

      • At

        控制anti_content生成的流程

      • c

        实际加密, 加工参数的对象, 里面有各种加密函数

      • Lt

        初始化参数中的一些时间戳

    • 找到两者作用域的合集fbeZ

    • 补全fbez所需要的参数, 并调用fbez

    • 对比真实环境和我们node环境下上下文环境是否一致

    • 将需要的window环境和document环境补全

      • 复制特殊对象

        d = {}
        for (let key in window.navigator){d[key] = window.navigator[key]}
        
        • 1
        • 2

        封装getAntiContent函数

    搭建Node服务

    • 安装环境

      npm install express     //服务框架
      npm install body-parser // 解析库
      
      • 1
      • 2
    • 启动服务

      const express = require('express');
      const bodyParser = require("body-parser");
      const getAntiContent = require("./obj_anti_content").getAntiContent
      
      const app = express()
      app.use(bodyParser.json({limit: '50mb'}))
      app.use(bodyParser.urlencoded({ extend: true, limit: '50mb'}))
      
      app.post("/anti_content", function (req, res){
      	...
      })
      
      const server = app.listen(1111, function (){
          let host = server.address().address;
          let port = server.address().port;
          console.log("Server is running at http: //%s: %s", host, port)
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    Python模拟请求

    • 传递给node服务的参数, 如果是[]会被node服务解析json数据格式的时候忽略掉;
      • 需要将传递的鼠标事件通过json.dumps转为json数据格式传递
      • 相应的, node服务中getAnticontent需要使用JSON.parse解析json数据格式
      • 参数传递过程中整数类型会被转变为字符串, 需要通过parseInt转变为整数
    • Python时间戳是秒, JS时间戳是毫秒
    • 请求次数requestTimes和当前page是有关系的, 不可以随便给, 当前`requestTime >= page
  • 相关阅读:
    C++标准库分析总结(九)——<适配器、istream_iterator、ostream_iterator、bind>
    解锁学习电路设计的正确姿势!
    Android-SQLite数据库实战
    压力管道的分类
    FireFox禁用HTTP2
    未来已来:探索IT行业的革新与大模型技术的突破
    Django搭建一个简易GPT网站
    论文笔记《Admix: Enhancing the Transferability of Adversarial Attacks》
    SpringBoot+Vue项目餐饮管理系统
    【Make YOLO Great Again】YOLOv1-v7全系列大解析(Head篇)(尝鲜版)
  • 原文地址:https://blog.csdn.net/m0_57713054/article/details/128070654