逆向06 coinglass案例解析-使用webpack

coinglass

接口:https://capi.coinglass.com/api/home/v2/coinMarkets?sort=&order=&keyword=&pageNum=1&pageSize=20&ex=all

image

1. 首先准备python请求-copy-cURL 这里略

2. 找js入口

搜索decrypt 点击 - 打断点 - 刷新

image
看到那一串的数据,就知道是我们想要的

3. 分析js代码

做到这里的我们将js代码抠出来

er = function(t, e) {
	var n = en(ee.AES.decrypt(t, ee.enc.Utf8.parse(e), {
	mode: ee.mode.ECB,
	padding: ee.pad.Pkcs7
	}).toString(ee.enc.Hex));
	return '"' == n.charAt(0) && (n = n.substring(1, n.length)),
	 '"' == n.charAt(n.length - 1) && (n = n.substring(0, n.length - 1)),
	n
	}
//这里面的t是我们要破解的数据--肯定是一个动态值【现在先不管它】
// e 是一个固定值 还是一个动态值呢?

image
因为是动态的,所有我们找一下哪里来的这个 e
image
根据代码逻辑
image

// 扣出来进行一下修改
n = er(t.headers.user, n); 
//t.headers.user 我们可以先悬浮copy;n是啥呢--〉是"Y29pbmdsYXNzL2Fw"
var r = er(t.data.data, n);
// t.data.data 是我们要解密的数据,这个n是上面生成的
---------分割线---------
n = er("xxxxxxxxxxxxxxxxx" ,"Y29pbmdsYXNzL2Fw"); 
//t.headers.user 我们可以先悬浮copy;n是啥呢--〉是"Y29pbmdsYXNzL2Fw"
var r = er("需要解密的数据", n);

er也是需要扣出来的

部分代码

er = function(t, e) {
  var n = en(ee.AES.decrypt(t, ee.enc.Utf8.parse(e), {
      mode: ee.mode.ECB,
      padding: ee.pad.Pkcs7
  }).toString(ee.enc.Hex));
  return '"' == n.charAt(0) && (n = n.substring(1, n.length)),
  '"' == n.charAt(n.length - 1) && (n = n.substring(0, n.length - 1)),
  n
}
// er 需要两个参数 一个是t,一个是e【t是我们要解密的数据先不用管】
// e也就是n-见上面的分析

// t 省略了一部分
let t = "yUaadF2NfakdHYtFIUx3oYsc7uf+yZ5Ak8qpH9BqwAVCUruVYdUAME2+oE2Bh9UDE1vwj/eAqNeR/r7VW16/";
let user = "GXbfk1zgG8GplI0tVCuQ/pFAZsDr3inC2VSv8tqzdKR/UDUoiTOfkPwwxCNuSzik";
n = er(user, "Y29pbmdsYXNzL2Fw");
r = er(data, n);

console.log(r);

4. 解析了运行解决报错

报错1:
image
解决办法copyen函数
image

报错2:
image
分析ee是个啥子
image
我们可以看到ee是一个webpack的数据了
终于到了我们的知识点了---兴奋一下吧

解决办法
第一步:定位
image

第二步:刷新页面,悬浮n函数,只是n函数
image
image
好了-其实有了加载器我们算是找到了老巢 哈哈哈哈
第三步:把加载器copy到我们自己的环境中
image
看上面的代码是不是觉得不对劲啊----最后调用的()里是没有参数的
我们之前讲的时候都是带参数的 详情请见

其实我们讲的是单文件运行,这里是多文件运行,也就是说参数是通过其他的文件传递过来的,怎么传过来的呢,往下看吧。哈哈
第四步:我们在第三步copy过来的代码调用--加两行代码
image
第五步:在js代码中使用-js代码是前面解决报错的时候的代码
image
第六步:找参数
我们在第一步的时候知道参数是81354,我们先利用这个全局搜索一下
image
image
第七步:copy出来,并导入js代码
image
第八步:运行解决报错
报错1:
image
报错2:

image
分析:
image

有了前面找ee的过程我们这里就不再详细写找t9了
image

注意:在这个案例中mod.js是有t9的参数,如果没有的话会报错,我们全局搜索27885确定在那个js中,再copy一次

现在我们运行的时候就可以完全的把数据解出来了
image

5. 结合python代码-修改动态参数

image

6. 总代码

一共四个文件【py代码,js入口文件,加载器文件,传递参数文件】

第一个:py代码

import requests
import execjs
url = "https://capi.coinglass.com/api/home/v2/coinMarkets?sort=&order=&keyword=&pageNum=1&pageSize=20&ex=all"

payload = {}
headers = {
  'accept': 'application/json',
  'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
  'cache-ts': '1721808140495',
  'encryption': 'true',
  'language': 'zh',
  'origin': 'https://www.coinglass.com',
  'priority': 'u=1, i',
  'referer': 'https://www.coinglass.com/',
  'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
  'sec-ch-ua-mobile': '?0',
  'sec-ch-ua-platform': '"macOS"',
  'sec-fetch-dest': 'empty',
  'sec-fetch-mode': 'cors',
  'sec-fetch-site': 'same-site',
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
}
response = requests.request("GET", url, headers=headers, data=payload)
# 需要解密的数据
data = response.json().get("data")
# user数据
user = response.headers.get("user")

# 解密
data_e = execjs.compile(open("./07conn.js").read()).call("test",data, user)
print(data_e)

第二个:js入口文件------主要是我们写的test函数,外部要调用

require("./07jiazaiqi") // 加载器
require("./07mod") // 加载器需要的参数的js

en = function(t) {
  var e, n = t9.ZP.inflate(new Uint8Array(t.match(/[\da-f]{2}/gi).map(function(t) {
      return parseInt(t, 16)
  }))), r = "";
  for (e = 0; e < n.length / 16384; e++)
      r += String.fromCharCode.apply(null, n.slice(16384 * e, (e + 1) * 16384));
  return decodeURIComponent(escape(r += String.fromCharCode.apply(null, n.slice(16384 * e))))
}
// window.loader // 这里就可以使用了 但是没有参数啊 我们去找参数
t9 = window.loader("27885")
ee = window.loader("81354")
er = function(t, e) {
  var n = en(ee.AES.decrypt(t, ee.enc.Utf8.parse(e), {
      mode: ee.mode.ECB,
      padding: ee.pad.Pkcs7
  }).toString(ee.enc.Hex));
  return '"' == n.charAt(0) && (n = n.substring(1, n.length)),
  '"' == n.charAt(n.length - 1) && (n = n.substring(0, n.length - 1)),
  n
}
// er 需要两个参数 一个是t,一个是e【t是我们要解密的数据先不用管】
// e我们刷新之后发现是一个动态的值

function test(data, user){
  n = er(user, "Y29pbmdsYXNzL2Fw");
  r = er(data, n);
  return r;
}

第三个:加载器文件

window = global;
!function() {
    "use strict";
    var e, t, n, c, a, r, f, s, u, i, o, d, b = {}, l = {};
    function h(e) {
        var t = l[e];
        if (void 0 !== t)
            return t.exports;
        var n = l[e] = {
            id: e,
            loaded: !1,
            exports: {}
        }
          , c = !0;
        try {
            b[e].call(n.exports, n, n.exports, h),
            c = !1
        } finally {
            c && delete l[e]
        }
        return n.loaded = !0,
        n.exports
    }
    window.loader = h;
	.........
	后面的省略了

第四个:传递参数文件

文件太大,省略

代码链接

posted @ 2024-07-24 17:50  流年中渲染了微笑  阅读(71)  评论(1)    收藏  举报