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

1. 首先准备python请求-copy-cURL 这里略
2. 找js入口
搜索decrypt 点击 - 打断点 - 刷新

看到那一串的数据,就知道是我们想要的
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 是一个固定值 还是一个动态值呢?

因为是动态的,所有我们找一下哪里来的这个 e

根据代码逻辑

// 扣出来进行一下修改
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:

解决办法copyen函数

报错2:

分析ee是个啥子

我们可以看到ee是一个webpack的数据了
终于到了我们的知识点了---兴奋一下吧
解决办法
第一步:定位

第二步:刷新页面,悬浮n函数,只是n函数


好了-其实有了加载器我们算是找到了老巢 哈哈哈哈
第三步:把加载器copy到我们自己的环境中

看上面的代码是不是觉得不对劲啊----最后调用的()里是没有参数的
我们之前讲的时候都是带参数的 详情请见
其实我们讲的是单文件运行,这里是多文件运行,也就是说参数是通过其他的文件传递过来的,怎么传过来的呢,往下看吧。哈哈
第四步:我们在第三步copy过来的代码调用--加两行代码

第五步:在js代码中使用-js代码是前面解决报错的时候的代码

第六步:找参数
我们在第一步的时候知道参数是81354,我们先利用这个全局搜索一下


第七步:copy出来,并导入js代码

第八步:运行解决报错
报错1:

报错2:

分析:

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

注意:在这个案例中mod.js是有t9的参数,如果没有的话会报错,我们全局搜索27885确定在那个js中,再copy一次
现在我们运行的时候就可以完全的把数据解出来了

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

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;
.........
后面的省略了
第四个:传递参数文件
文件太大,省略

浙公网安备 33010602011771号