asxe
asxe

# 准备

闲来无事,发篇小帖!
废话不多说,今天的主角:烯牛数据

# 正片!

# js 加密部分

找到需要逆向的接口,即:
1.png
看看其负载和返回的数据:
负载
2.png
数据
3.png
可以看到,负载有两个加密的参数,返回的数据也是加密的,先搞负载!
跟到栈堆,搜索 sig,可以找到两个,都打上断点,刷新网页,然后便断在了一个点,如下
4.png
观察这断代码,可以大致分析出,sig 就是 p,p 调用了一个 c.e 的函数和 f,f 调用了 c.c c.d 以及 l,那么就先拿下来:
5.png
现在分析其中的函数是什么,先搞 c.c,跳转过去发现是一个叫 e1 的函数
6.png
直接拿下来
c.d 也是一样的跳转到一个叫 e2 的函数,直接拿下来,然后稍微改写下代码
7.png
然后搞 c.e,跳转到一个叫 sig 的函数,如下
8.png
发现是一个 MD5 加密(这个就是原版的 MD5,不要问我怎么知道,因为我试过了,所以这里就不分析是不是魔改 MD5 了,其实你跳转过去也会发现这个就是原版的
因此直接写个 MD5 实现
9.png
最后补补环境,缺啥补啥,然后你看看运行生成的结果和浏览器的结果,肯定是一样的!
完整代码如下

const crypto = require('crypto');
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    , _p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";
function md5(text) {
    return crypto.createHash("md5").update(text).digest("hex")
}
function sig(e) {
    return md5(e + _p).toUpperCase()
}
function e1(e) {
    if (null == e)
        return null;
    for (var t, n, r, o, i, a, c, u = "", s = 0; s < e.length;)
        o = (t = e.charCodeAt(s++)) >> 2,
            i = (3 & t) << 4 | (n = e.charCodeAt(s++)) >> 4,
            a = (15 & n) << 2 | (r = e.charCodeAt(s++)) >> 6,
            c = 63 & r,
            isNaN(n) ? a = c = 64 : isNaN(r) && (c = 64),
            u = u + _keyStr.charAt(o) + _keyStr.charAt(i) + _keyStr.charAt(a) + _keyStr.charAt(c);
    return u
}
function _u_e(e) {
    if (null == e)
        return null;
    e = e.replace(/\r\n/g, "\n");
    for (var t = "", n = 0; n < e.length; n++) {
        var r = e.charCodeAt(n);
        r < 128 ? t += String.fromCharCode(r) : r > 127 && r < 2048 ? (t += String.fromCharCode(r >> 6 | 192),
            t += String.fromCharCode(63 & r | 128)) : (t += String.fromCharCode(r >> 12 | 224),
            t += String.fromCharCode(r >> 6 & 63 | 128),
            t += String.fromCharCode(63 & r | 128))
    }
    return t
}
function e2(e) {
    if (null == (e = _u_e(e)))
        return null;
    for (var t = "", n = 0; n < e.length; n++) {
        var r = _p.charCodeAt(n % _p.length);
        t += String.fromCharCode(e.charCodeAt(n) ^ r)
    }
    return t
}
var n = {
    "payload": {
        "sort": 2,  //1 为最近热门,2 为最近更新
        "start": 0,  // 每次 + 20
        "limit": 20
    }
}
var s = JSON.stringify(n)
var l = JSON.parse(s);
var f = Object(e1)(Object(e2)(JSON.stringify(l.payload)));
var p = Object(sig)(f);
console.log(f)
console.log(p)

# js 解密部分

现在搞返回的数据解密,先观察观察返回的数据,一个 code,一个 d,一个 v。如果是你,你要怎么搜索?该不会搜索 d 吧?那还不得亖啊,全篇都是 d,因此我们直接搜 code,因为这也是它返回的数据。
然后我们就发现刚刚加密的下面就有个 code,而且下面还跟着一个 JSON.parse
10.png
如果是你,你会不会看这个地方?
我们直接打上断点,刷新,然后看看这个 v 是个啥
断住后在控制台输入 v
11.png
这个 v 不就是我们要的明文数据吗?
直接开扣
12.png
注:l 就是返回数据里的 d,不信你自己看哈哈哈
然后扣出 c.a c.b
c.a 就是 d1c.b 就是 d2
然后缺啥补啥,运行看看结果,没问题的!
13.png
完整代码

var l = "这里放加密的结果";
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    , _p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";
function d1(e) {
    var t, n, r, o, i, a, c = "", u = 0;
    for (e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); u < e.length;)
        t = _keyStr.indexOf(e.charAt(u++)) << 2 | (o = _keyStr.indexOf(e.charAt(u++))) >> 4,
            n = (15 & o) << 4 | (i = _keyStr.indexOf(e.charAt(u++))) >> 2,
            r = (3 & i) << 6 | (a = _keyStr.indexOf(e.charAt(u++))),
            c += String.fromCharCode(t),
        64 != i && (c += String.fromCharCode(n)),
        64 != a && (c += String.fromCharCode(r));
    return c
}
function d2(e) {
    for (var t = "", n = 0; n < e.length; n++) {
        var r = _p.charCodeAt(n % _p.length);
        t += String.fromCharCode(e.charCodeAt(n) ^ r)
    }
    return t = _u_d(t)
}
function _u_d(e) {
    for (var t = "", n = 0, r = 0, o = 0, i = 0; n < e.length;)
        (r = e.charCodeAt(n)) < 128 ? (t += String.fromCharCode(r),
            n++) : r > 191 && r < 224 ? (o = e.charCodeAt(n + 1),
            t += String.fromCharCode((31 & r) << 6 | 63 & o),
            n += 2) : (o = e.charCodeAt(n + 1),
            i = e.charCodeAt(n + 2),
            t += String.fromCharCode((15 & r) << 12 | (63 & o) << 6 | 63 & i),
            n += 3);
    return t
}
var d = Object(d1)(l)
    , v = Object(d2)(d)
console.log(v)
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

ASXE 微信支付

微信支付

ASXE 支付宝

支付宝

ASXE 贝宝

贝宝