注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!!
第一步:分析页面和请求方式
aHR0cHM6Ly95Z3AuZ2R6d2Z3Lmdvdi5jbi8jLzQ0L2p5Z2c=
此网站经过分析,可以看出请求网址和参数均无加密,响应内容无加密。真正可以让我们进行学习的则是headers里两个比较明显的参数,可以看出是可以研究的。X-Dgi-Req-Nonce 和X-Dgi-Req-Signature
第二步:请求页面并分析请求,定位headers
经过分析,headers里的内容有加密参数,则我们开始全文找headers。经过 search 全文找,可以检索到N多的headers相关的内容。我们不能一个一个去验证,很麻烦。因此我暂时按照我的方式进行headers定位(不是最优方案,仅做参考)
在请求前,将请求段(不一定完整的请求)添加在XHR/fetch Breakpoints 中,进行请求。可以看到请求后,断点会在send 处停止,此刻我们在当前页可以 检索 headers = ,可以看到有17处,由于不确定真正位置,因此,我们将17处依次打了断点。清除cookie ,去掉 XHR/fetch Breakpoints 的断点。重新请求
第三步:headers定位,以及确定参数加密位置进行分析
重新请求后,依次查看headers断点,可以看到o.headers 中已经有加密后的内容。因此我们可以看到 a, l,c 均已生成
第四步:逆向分析加密信息
确定加密位置后,可以将headers相关的断点勾掉。对a, l, c处进行断点添加。重新请求。(这一步可以省略,主要是为了显示加密后内容)。
可以看到X-Dgi-Req-Nonce 是由l 生成的。l=hne(16)
而 X-Dgi-Req-Signature 是由t1 (p:s, t:a, n:l, k:c) 生成 ,s 是请求参数(在调试中会慢慢呈现,默认是undefined);a 是时间戳毫秒级;l 是 X-Dgi-Req-Nonce;c是常量 。【注意这部分经过调试即可】。注意!注意!注意! 调试过程中会遇到函数uk(),经过一步一步分析,可知函数uk 是sha256 的加密方法,所以确定加密方式可以直接使用 js crypto-sha256进行加密即可
第五步:代码展示
/* =====================
#@Time : 2024/5/9 15:58
#@Author: 水兵没月
#@File : XXXXXXXXXX.js
#@Software: PyCharm
=======================*/const crypto = require('crypto');// X-Dgi-Req-Nonce
const lF = "zxcvbnmlkjhgfdsaqwertyuiop0987654321QWERTYUIOPLKJHGFDSAZXCVBNM", fne = lF + "-@#$%^&*+!";
function qu(e=[]) {return e.map(t=>fne[t]).join("")
}function dne(e, t) {switch (arguments.length) {case 1:return parseInt(Math.random() * e + 1, 10);case 2:return parseInt(Math.random() * (t - e + 1) + e, 10);default:return 0}
}function Nonce() {var e = 16return [...Array(e)].map(()=>lF[dne(0, 61)]).join("")
}// l = Nonce(e)
// X-Dgi-Req-Timestamp
function Timestamp (){return Date.now()
}// X-Dgi-Req-Signature
// c = qu([8, 28, 20, 42, 21, 53, 65, 6])
// d = {
// [qu([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 54, 25, 25])]: qu([11, 11, 0, 21, 62, 25, 24, 19, 20, 15, 7]),
// [qu([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 60, 24, 5, 2, 18])]: Nonce(),
// [qu([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 40, 23, 6, 18, 14, 20, 15, 6, 25])]: Timestamp()
// }function pne(e) {let t = "";return typeof e == "object" ? t = Object.keys(e).map(n=>`${n}=${e[n]}`).sort().join("&") : typeof e == "string" && (t = e.split("&").sort().join("&")),t
}
function uK(str) {const hash = crypto.createHash('sha256');hash.update(str);return hash.digest('hex');
}
function Signature(e={}) {const {p: t, t: n, n: u, k: o} = e, r = pne(t);console.log(u + o + decodeURIComponent(r) + n)return uK(u + o + decodeURIComponent(r) + n)
}// console.log(Nonce())
// console.log(Timestamp())
// console.log(Signature({p: 'keyword=&openConvert=false&pageNo=1&pageSize=10&projectType=&publishEndTime=&publishStartTime=&secondType=A&siteCode=44&thirdType=%5B%5D&tradingProcess=&type=trading-type', t: Timestamp(), n: Nonce(), k: 'k8tUyS$m'}))