发送加密逆向
这里可以查看发送的拦截器函数,打断点后刷新页面:
在发送请求的拦截器函数里打断点,发现和发送参数里一样的 data
变量,找到处理 data
变量的两个步骤,分别打断点:
进入对应的函数查看,并打断点,其实到这里就可以发现发送参数的加密过程了:
依然是 CryptoJS
库!!!
最后得到的加密 JS 如下:
var jt = {}
jt.a = require("crypto-js")
var Zt = "$shanghaidianqi$"
var Vt = "2023050814260000"
var sr = function(Xe) {
Xe = JSON.stringify(Xe);
var ot = jt.a.enc.Utf8.parse(Zt)
, Kt = jt.a.enc.Utf8.parse(Vt)
, kt = jt.a.AES.encrypt(Xe, ot, {
iv: Kt,
mode: jt.a.mode.CBC,
padding: jt.a.pad.Pkcs7
});
return JSON.stringify({
data: kt.toString()
});
}
返回解密逆向
和上面不同的是,接受拦截器的回调函数代码如下图,就是红色框起来的地方:
这里调用了他本身,传入一个叫 arguments
的参数,这里需要注意的是,cr
里面是一个异步框架的原型,他的大概写法如下:
for(;;)
switch (Jt.prev = Jt.next) {
case 0:
return xxx()
case 1:
Jt.sent
return yyy()
return 2:
kt = xxx.sent
abrupt("return", kt)
}
这里的每一个 case 都是一个 await,这里的 return 也不是返回,而是到下一个 case。这里 return 后在下一个 case 的地方会使用 sent 接收。这种异步框架就不要单步调试了,他是一个死循环,具体调试步骤看下面的断点。
做好以上工作之后,开始调试:
可以发现,到 case3
的地方,密文出现了,注意下面这一行代码:
kt = JSON.parse(mr(kt))
在图片中可以清晰的看到他是密文,但是他经过了 mr
函数之后,就可以 JOSN.parse
转成字符串了,那么这个函数不就是解密函数吗,点进函数查看如下:
很熟悉的格式,一看就是 CryptoJS
库。
最后得到的解密代码如下:
var jt = {}
jt.a = require("crypto-js")
var Zt = "$shanghaidianqi$"
var Vt = "2023050814260000"
var mr = function(Xe) {
var ot = jt.a.enc.Utf8.parse(Zt)
, Kt = jt.a.enc.Utf8.parse(Vt)
, kt = jt.a.AES.decrypt(Xe, ot, {
iv: Kt,
mode: jt.a.mode.CBC,
padding: jt.a.pad.Pkcs7
})
, yr = kt.toString(jt.a.enc.Utf8);
return JSON.parse(yr.toString());
}
上爬虫
import execjs
import requests
import json
from docutils.nodes import organization
url = "https://www.hfhuizhan.com/prod-api/hfhz-exhibition/back/exhibition/listExhibitionNotPage"
accept_file = open("accept_js.js", "r", encoding="utf-8")
accept_code = accept_file.read()
accept_file.close()
send_file = open("send_js.js", "r", encoding="utf-8")
send_code = send_file.read()
send_file.close()
accept_fn = execjs.compile(accept_code)
send_fn = execjs.compile(send_code)
headers = {
"accept": "application/json",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "zh-CN,zh;q=0.9",
"authorization": "null",
"cache-control": "no-cache",
"content-length": "55",
"content-type": "application/json;charset=UTF-8, application/json;charset=UTF-8",
"origin": "https://www.hfhuizhan.com",
"pragma": "no-cache",
"priority": "u=1, i",
"referer": "https://www.hfhuizhan.com/schedule",
"sec-ch-ua": "\"Chromium\";v=\"135\", \"Not-A.Brand\";v=\"8\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
}
ming_data = {
"yyyyMM":"2024-04"
}
payload_data = send_fn.call("sr", ming_data)
resp = requests.post(url=url, data=payload_data, headers=headers)
ming = accept_fn.call("mr", resp.text)
data = ming["data"]
for item in data:
name = item["name"]
organizer = item["organizer"]
startTime = item["startTime"]
endTime = item["endTime"]
print(f"name:{name},organizer:{organizer},startTime:{startTime},endTime:{endTime}")
评论