28_某易云 Params | encSecKey 参数逆向

Date
Dec 8, 2023
Created
Mar 2, 2024 03:07 PM
Tags
JS逆向实战

声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

目标

目标网站
aHR0cHM6Ly9tdXNpYy4xNjMuY29tLyMvcGxheWxpc3Q/aWQ9MzY3NjQ5MzAz
目标接口
aHR0cHM6Ly9tdXNpYy4xNjMuY29tL3dlYXBpL3NvbmcvZW5oYW5jZS9wbGF5ZXIvdXJsL3YxP2NzcmZfdG9rZW49
目标
获取接口中post请求加密的 Params encSecKey 从而获取真实的链接地址

逆向分析

获取参数如下
notion image
直接搜索 参数 encSecKey 第二个就是加密处
notion image
notion image
获取如下代码
var bVg5l = window.asrsea(JSON.stringify(i3x), bsk0x(["流泪", "强"]), bsk0x(WH9y.md), bsk0x(["爱心", "女孩", "惊恐", "大笑"]));

window.asrsea
话就不多说了。直接去看这个加密过程
进栈
notion image
这个可以看到 window.asrsea 这个参数复制给了d 函数。
继续往上看。把这一段自执行函数 全部扣下来。我们逐步分析。
!function() { function a(a) { var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = ""; for (d = 0; a > d; d += 1) e = Math.random() * b.length, e = Math.floor(e), c += b.charAt(e); return c } function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse("0102030405060708") , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() } function c(a, b, c) { var d, e; return setMaxDigits(131), d = new RSAKeyPair(b,"",c), e = encryptedString(d, a) } function d(d, e, f, g) { var h = {} , i = a(16); return h.encText = b(d, g), h.encText = b(h.encText, i), h.encSecKey = c(i, e, f), h } function e(a, b, d, e) { var f = {}; return f.encText = c(a + e, b, d), f } window.asrsea = d, window.ecnonasr = e }();
对比调用的函数来看
var bVg5l = window.asrsea(JSON.stringify(i3x), bsk0x(["流泪", "强"]), bsk0x(WH9y.md), bsk0x(["爱心", "女孩", "惊恐", "大笑"]));
继续看到调用的值。我们先在控制台中看看
notion image
可以看到,如上图所示,加密的值由window.asrsea这个函数生成。需要传递三个参数。分别是
1. JSON.stringify(i3x) 2. bsk0x(["流泪", "强"]) 3. bsk0x(WH9y.md) 4. bsk0x(["爱心", "女孩", "惊恐", "大笑"])
我们分别在console控制台中看看这几个值
notion image
其实经过很多次分析。可以得知。1,2,3 是不变的。我们写死就可以了。但是为了保证知识的完整性。我们直接去看看。这里面的内容

JSON.stringify(i3x)
这个值我认为没什么好说的。直接就是 一个固定参数。需要把song_id传入。其他的都是定值。
notion image

bsk0x(XXXX)
直接把这个函数扣出来就行。这里不多BB 。至于WH9y.md 则是一开始的一个数组
notion image
所以现在每个值我们都已经搞出来了。所以就可以继续分析window.asrsea这个函数了。
上文提到了。主要是调用了d这个函数。
我们就逐步来分析这个d函数。
var h = {} , i = a(16); return h.encText = b(d, g), h.encText = b(h.encText, i), h.encSecKey = c(i, e, f), h
先定义一个h字典。
然后i=a(16)。 继续向上找a函数。得知这个a。其实就是生成一个随机数。
notion image
h.encText 则是调用了两次 b这个函数。而b本质上是AES加密。第二次加密的key用到了a
notion image
h.encSecKey 则是使用了 RSA加密。把传入的b和c加密变成私钥、然后把刚刚的那个随机数a作为加密值。生成了encSecKey 。说实话 既然 都是固定的。还有一个也是随机值。那这个encSecKey 也是可以写死的呀。
notion image
瞬间一切就明白了。我们来重新总结一些。
  1. params参数 即是encText。经过两次AES加密。得到了params
  1. encSecKey 参数经过了Rsa加密。公钥私钥都是固定值。只有加密值 是随机数。

代码

这里提供个简单版。(即无bsk0x函数。传参值写死,且encSecKey值也是死的
这里注意:AES这里给的key值源代码是随机值。我写死了。必须和encSecKey写死。不然你会失败得不到值。
const CryptoJS = require("crypto-js") window = global; !function () { function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse("0102030405060708") , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() } function d(d, e, f, g) { var h = {} , i = "q9USNwbhTWoYLUdK"; return h.encText = b(d, g), h.encText = b(h.encText, i), h.encSecKey = f, h } window.asrsea = d }(); function get_encrypt_data(post_data) { var md = "caa7eba83c7bbdd9a3779a3d587030455906ec50e8b12bcc224966691dcfcfb13371bc742df6ab1c7018a4411c066782e370f71fb3290ac2e7fc4b203fc0fe65959cd94aac27fc23d240ef4e6f0f47da4f6ede4990a7e097baac83fe7d1fdb4495987b9895dab657b70599967eba75d0b91100cc887a7cd5f39cc09e18bdb563"; var bVg5l = window.asrsea(JSON.stringify(post_data), "010001", md, "0CoJUm6Qyw8W8jud") return { params: bVg5l.encText, encSecKey: bVg5l.encSecKey } } // console.log(get_encrypt_data({ "ids": '[2012390001]', "level": 'standard', "encodeType": 'aac', "csrf_token": '' }))
后续也可以通过python改写。很简单 这里就不演示了。
直接看看结果吧。
notion image