声明
本文中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文未经许可禁止转载,禁止任何形式的修改后进行二次传播,若有侵权,请联系作者删除!
温馨提示:本案例只提供参考,扣的js代码放到本地运行会报错,根据提示补全剩余代码即可~
逆向目标
- 网站:aHR0cHM6Ly9lYy5taW5tZXRhbHMuY29tLmNuL29wZW4vaG9tZS9wdXJjaGFzZS1pbmZv
- 逆向位置
分析
首先F12打开开发者工具,打开网络界面,点击左侧标签,进行抓包,会发现每次请求都会加载两个接口。其中by-lx-page接口会发送我们需要定位的加密数据。
public接口返回一串密文数据,因其每次都与by-lx-page接口同时请求,猜测其返回的数据具有一定的作用。
首先分析by-lx-page接口,根据xhr断点跟栈分析,找到加密位置,并打上DOM断点进行调试。
通过断点调试发现e的值,是参数加密前最初始的数据。
往下分析发现t.setPublicKey(r) 、t.encryptLong(JSON.stringify(a)) 等相关代码推测加密方法很可能与t变量有关。要解决的参数有t,a,r。其中r参数由/open/homepage/public接口返回,这里先固定,后续进行分析。
r固定之后,我们来分析t和a参数,创建一个js文件
t = new d["a"]
r = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWKvALKh+55PRUzvZ4WO5dYar9yi7NN3IUSO5pOY3zQ2PhoMMZLQfoB0WRJhm3H+JUrTy7QXni+vnYbKPlJll8WpB0w77ArYdvkgqGObg5O7vHjtmXgWruLMg/isLPlsEAXhRIrZBjwq4owOa4QR7sLh8VZccWJ57x2eFMb4hZhwIDAQAB" // 这里先固定r值
t.setPublicKey(publcKey)
a = m(m({}, e), {}, {
sign: B()(JSON.stringify(e)),
timeStamp: +new Date
})
s = t.encryptLong(JSON.stringify(a)) // 加密位置
首先分析m方法,发现m方法是为了给参数a添加sign签名和timeStamp时间戳,至于sign签名的加密方式如下
发现有md5字段,推测其为标准的md5加密方式,后经其它值检验,发现其确实为标准md5加密,于是参数a得以解决。
// md5加密代码模板如下
const crypt = require('crypto-js')
function MD5Encrypt(data) {
return crypt.MD5(data).toString()
}
接下来分析参数t
看到t = new d["a"],我们需要跟到d的位置,向上找发现存在d = t("9816"),很明显是一个webpack,
这里我们需要扣出webpack相关代码,不会的话网上有相关教程。
扣出webpack代码如下,注意需要全局导出o函数,比如定义一个变量g,让g来接收o,方便后面调用
var g;
!function (e) {
var t = {};
function n(r) {
if (t[r])
return t[r].exports;
var o = t[r] = {
i: r,
l: !1,
exports: {}
};
return e[r].call(o.exports, o, o.exports, n),
o.l = !0,
o.exports
}
n.m = e
g = n // 使用全局变量导出n
}({
// 此处存放模块代码
})
接下来需要补全模块中用到的代码,首先是9816,点击chunkxxxxxx.js文件进入到其中,去搜索9816
将代码扣出放入刚才准备的存放模块代码位置,运行发现缺少模块,在原有加载器代码基础上加上
console.log(o)
发现缺少a524模块,全局搜索a524,并将其放入刚才准备的存放模块代码位置。
接下来分析加密位置t.encryptLong,点击进入到代码内部扣出代码,发现其中存在w函数,跟进w函数,将其扣出。
大致代码框架如下
const crypt = require('crypto-js')
function MD5Encrypt(data) {
return crypt.MD5(data).toString()
}
window = global
var g;
!function (e) {
var t = {};
function n(r) {
if (t[r])
return t[r].exports;
var o = t[r] = {
i: r,
l: !1,
exports: {}
};
return e[r].call(o.exports, o, o.exports, n),
o.l = !0,
o.exports
}
n.m = e
g = n
}({
9816:function(e,t,n){},
a524:function(e){}
}) // 模块代码请读者自行网上扣取
d = g(9816)
function w(A) {
var e, t, n = "", r = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", a = "=";
// 此处有省略,请读者根据前面的步骤自行获取
}
e = {
// 明文参数请读者自行获取
}
// 请求publc返回的公钥
const axios = require('axios')
headers = {
// 读者自行补充
}
url = "xxxxxxxxxxxxxxx" // 请求public接口获取r参数
axios.post(url, {
headers: headers,
}).then(function (response) {
publcKey = response.data // 获取公钥
d["a"].prototype.encryptLong = function (A) {
// 读者自行获取
}
t = new d["a"]
t.setPublicKey(publcKey)
// a添加sign和时间戳
a = e
a['sign'] = MD5Encrypt(e)
a['timeStamp'] = +new Date()
//params加密为s
s = t.encryptLong(JSON.stringify(a))
json_data = {
param: s
}
headers = {
// 读者自行补全
}
url = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // 读者自行补全
axios.post(url, json_data, {
headers: headers,
}).then(function (response) {
// 接收回数据调
}).catch(function (error) {
// 异常输出
});
}).catch(function (error) {
// 异常输出
});
结果验证
温馨提示:本案例只提供参考,根据提示补全剩余代码即可~
再次 声明本文中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!!!!
本文未经许可禁止转载,禁止任何形式的修改后进行二次传播,若有侵权,请联系作者删除!
本次逆向到此就结束了,由于是新手,大佬看见还请多多指导。