逆向24-五矿
1. 分析

2. 定位
搜素关键字param: 居然有43个,当然这43个里面肯定会有一个是我们的目标,今天我们不使用这个

搜索请求URL

添加断点--->刷新(点页码)

3. 代码分析
3.1 异步
// 异步
function qn() {
return qn = Mn(g.a.mark((function A(e) {
var t;
return g.a.wrap((function(A) {
while (1)
switch (A.prev = A.next) {
case 0:
return A.next = 2,
y(e);
case 2:
return t = A.sent,
// 目标函数
A.abrupt("return", Zn.post("/open/homepage/zbs/by-lx-page ", {
param: t
}));
case 4:
case "end":
return A.stop()
}
}
), A)
}
))),
qn.apply(this, arguments)
}
上述代码,可以看出一个switch case
一般情况下 A.next 都是 0
这样的话才会进入到下面的case 0
case 0:return A.next = 2, y(e);
上面一行的代码是A.next就是下一个要执行的时候 case 2;;;;; y(e)的返回值会传递到case 2 里面的 A.sent
总结:
目标函数中的 param: t, t是A.sent,而A.sent又是case 0中的y(e)的返回值。
关键就是y(e)
3.2y(e)分析
e是参数

y是一个封装的Promise 其实就是一个包裹,只需要我们进去看看他到底在干啥




好了 可以扣代码了
4. 扣代码
- 先找 loader.js
(function(A) {
...省略...
function o(e) {
if (n[e])
return n[e].exports;
var t = n[e] = {
i: e,
l: !1,
exports: {}
};
console.log("e:::", e)
return A[e].call(t.exports, t, t.exports, o),
t.l = !0,
t.exports
}
window.loader = o,
...省略...
})({
...省略...
})
- env.js
window = global;
- rukou.js
require("./env.js")
require("./loader.js")
console.log(window.loader("9816"))

报错是没有 9816,全局搜索9816 将所在的代码放在新建的mod.js中

运行遇见一个问题和解决办法

再次运行,发现不报错了

但是我们发现只使用了两个key ,我们的代码是把所有的key都拿过来了,这样做可以,但是浪费内存,我们只需要把这两个拿到我们的loader.js的参数处即可

到这里就是代码扣完了,该进行函数的调用了
5. Rukou.js
源码再分析
// y(e)进去
function y() {
return P.apply(this, arguments)
}
再进去P
function h(A) {
return function() {
var e = this
, t = arguments;
return new Promise((function(n, r) {
// 关键的一句话啊
var a = A.apply(e, t);
function s(A) {
p(a, n, r, s, i, "next", A)
}
function i(A) {
p(a, n, r, s, i, "throw", A)
}
s(void 0)
}
))
}
}
再去A里面看看
function P() {
return P = h(g.a.mark((function A() {
var e, t, n, r, a, s, i = arguments;
return g.a.wrap((function(A) {
while (1)
switch (A.prev = A.next) {
case 0:
return e = i.length > 0 && void 0 !== i[0] ? i[0] : {},
// 这里的d我们也找到了
t = new d["a"],
A.next = 4,
f.a.post("/open/homepage/public");
case 4:
return n = A.sent,//是上面的post的返回值
r = n.data,
t.setPublicKey(r),//加密
a = m(m({}, e), {}, {
sign: B()(JSON.stringify(e)), // B()函数的一些操作
timeStamp: +new Date
}),
s = t.encryptLong(JSON.stringify(a)), // 最终生成s
A.abrupt("return", s);
case 10:
case "end":
return A.stop()
}
}
), A)
}
))),
P.apply(this, arguments)
}
5.1 代码转换和解决报错
d = window.loader("9816")
t = new d["a"]
// post的返回值,我们可以先在页面复制一份进行测试
r = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxC9/N/CXfw4loxwt2d4b0PgmHiqpBloXxDbm1rXfLbghr1+sBbwJy/xHZhzUrb0gTxgpusFWkpqcJZGzbI6t14OvfxrBCvVcaKIKvIO4XSEn5wnBrQq4sxmXfsFuljSfHrchlBYEo5LxPVpJ+ZWVEsbZw022Ay9txlJdc/EYCuQIDAQAB"
t.setPublicKey(r),
a = m(m({}, e), {}, {
sign: B()(JSON.stringify(e)),
timeStamp: +new Date
}),
s = t.encryptLong(JSON.stringify(a))
console.log(s)
代码可以转换成上面的样子
报错是没有m函数,扣代码即可
第二个


补参数
require("./env.js")
require("./loader.js")
function v(A, e) {
var t = Object.keys(A);
if (Object.getOwnPropertySymbols) {
var n = Object.getOwnPropertySymbols(A);
e && (n = n.filter((function(e) {
return Object.getOwnPropertyDescriptor(A, e).enumerable
}
))),
t.push.apply(t, n)
}
return t
}
function b(A, e, t) {
return e in A ? Object.defineProperty(A, e, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : A[e] = t,
A
}
// 补的m函数
function m(A) {
for (var e = 1; e < arguments.length; e++) {
var t = null != arguments[e] ? arguments[e] : {};
e % 2 ? v(Object(t), !0).forEach((function(e) {
b(A, e, t[e])
}
)) : Object.getOwnPropertyDescriptors ? Object.defineProperties(A, Object.getOwnPropertyDescriptors(t)) : v(Object(t)).forEach((function(e) {
Object.defineProperty(A, e, Object.getOwnPropertyDescriptor(t, e))
}
))
}
return A
}
// 补的e参数
e={
"inviteMethod": "",
"businessClassfication": "",
"mc": "",
"lx": "ZBGG",
"dwmc": "",
"pageIndex": 2
}
d = window.loader("9816")
t = new d["a"]
r = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxC9/N/CXfw4loxwt2d4b0PgmHiqpBloXxDbm1rXfLbghr1+sBbwJy/xHZhzUrb0gTxgpusFWkpqcJZGzbI6t14OvfxrBCvVcaKIKvIO4XSEn5wnBrQq4sxmXfsFuljSfHrchlBYEo5LxPVpJ+ZWVEsbZw022Ay9txlJdc/EYCuQIDAQAB"
t.setPublicKey(r),
a = m(m({}, e), {}, {
sign: B()(JSON.stringify(e)), // B()缺,见下图
timeStamp: +new Date
}),
s = t.encryptLong(JSON.stringify(a))
console.log(s)


继续

一定要放在d的下面

在运行的时候 扣一些代码,然后最后得到结果

5.2 post请求的key
可以使用python来获取
import requests
cookies = {
'Hm_lvt_f32803886966beff8fa513f7a33dea1e': '1729231821',
'Hm_lpvt_f32803886966beff8fa513f7a33dea1e': '1729231821',
'HMACCOUNT': '5B3A86709F76EACE',
'SUNWAY-ESCM-COOKIE': '9b5ab10a-8c4e-4234-9969-ddb1d234f887',
'__jsluid_s': 'f8d85e5e21c685100199520fb542f72a',
'JSESSIONID': '529704C8EC37B18C507E3216DE14FAAC',
}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
# 'Content-Length': '0',
# 'Cookie': 'Hm_lvt_f32803886966beff8fa513f7a33dea1e=1729231821; Hm_lpvt_f32803886966beff8fa513f7a33dea1e=1729231821; HMACCOUNT=5B3A86709F76EACE; SUNWAY-ESCM-COOKIE=9b5ab10a-8c4e-4234-9969-ddb1d234f887; __jsluid_s=f8d85e5e21c685100199520fb542f72a; JSESSIONID=529704C8EC37B18C507E3216DE14FAAC',
'Origin': 'https://ec.minmetals.com.cn',
'Pragma': 'no-cache',
'Referer': 'https://ec.minmetals.com.cn/open/home/purchase-info',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'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',
'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"',
}
response = requests.post('https://ec.minmetals.com.cn/open/homepage/public', cookies=cookies, headers=headers)
print(response.text)
5.3 最终代码
import requests
import execjs
cookies = {
'Hm_lvt_f32803886966beff8fa513f7a33dea1e': '1729231821',
'Hm_lpvt_f32803886966beff8fa513f7a33dea1e': '1729231821',
'HMACCOUNT': '5B3A86709F76EACE',
'SUNWAY-ESCM-COOKIE': '9b5ab10a-8c4e-4234-9969-ddb1d234f887',
'__jsluid_s': 'f8d85e5e21c685100199520fb542f72a',
'JSESSIONID': '529704C8EC37B18C507E3216DE14FAAC',
}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
# 'Content-Length': '0',
# 'Cookie': 'Hm_lvt_f32803886966beff8fa513f7a33dea1e=1729231821; Hm_lpvt_f32803886966beff8fa513f7a33dea1e=1729231821; HMACCOUNT=5B3A86709F76EACE; SUNWAY-ESCM-COOKIE=9b5ab10a-8c4e-4234-9969-ddb1d234f887; __jsluid_s=f8d85e5e21c685100199520fb542f72a; JSESSIONID=529704C8EC37B18C507E3216DE14FAAC',
'Origin': 'https://ec.minmetals.com.cn',
'Pragma': 'no-cache',
'Referer': 'https://ec.minmetals.com.cn/open/home/purchase-info',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'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',
'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"',
}
# 第一次发送请求获取 【f.a.post("/open/homepage/public")】
response = requests.post('https://ec.minmetals.com.cn/open/homepage/public', cookies=cookies, headers=headers)
key = response.text
# 获取param的加密值
param_obj = execjs.compile(open("rukou.js").read()).call("get_enc", 1, key) # 只取了第一页的数据
json_data = {
'param': param_obj,
}
response_data = requests.post(
'https://ec.minmetals.com.cn/open/homepage/zbs/by-lx-page',
cookies=cookies,
headers=headers,
json=json_data,
)
# 获取最终的数据
print(response_data.text)

浙公网安备 33010602011771号