JS-逆向 特x电(X-Token、WTS、WVER、logininfo)参数

概要

特x电(js逆向)
提示:仅供学习,不得用做商业交易,如有侵权请及时联系!
URL:aHR0cHM6Ly91c2VyLnRlbGQuY24vbmV3bG9naW4/c291cmNlPTImcmVkaXJlY3RfdXJpPWh0dHBzJTNBJTJGJTJGd3d3LnRlbGQuY24lMkY=

逆向参数:
表单参数:X-Token、WTS、WVER、logininfo

整体架构流程

提示:进入网址-分析js代码-验证加密算法-实现python代码

  • 进入网址,找到对应参数
    在这里插入图片描述

进行断点调试

在这里插入图片描述

进入函数内部发现取的是cookie值

在这里插入图片描述

那么我们可以删除浏览器cookie值为teldk的值,使用hook进行重新获取

在这里插入图片描述

hook-cookie代码

(function () {
  'use strict';
  var cookieTemp = '';
  Object.defineProperty(document, 'cookie', {
    set: function (val) {
      debugger;
      console.log('Hook捕获到cookie设置->', val);
      cookieTemp = val;
      return val;
    },
    get: function () {
      return cookieTemp;
    },
  });
})();

成功拦截teldk

在这里插入图片描述

回溯进行分析

在这里插入图片描述

进一步观察data我们发现,它是UserAPI-WEBUI-ASLogin接口返回

在这里插入图片描述

进入加密内部我们发现是aes解密,其中分俩次进行解密,第一次解密的key和iv固定,第二次则是第一次解密和的值。

在这里插入图片描述

接下来我们应该验证是否是标准AES还是魔改的、

在这里插入图片描述

继续第二次解密

在这里插入图片描述
*

AES在线网址:https://www.mklab.cn/utils/aes
Python实现AES加密、解密

BLOCK_SIZE = 16  # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
                chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]


def aesDecrypt(data,key=None,iv=None):
    '''

    :param key: 密钥
    :param data: 加密后的数据(密文)
    :return:明文
    '''
    if key == None or iv == None:
        iv = '98d71fe589499967'
        key = '7fb498553e3c462988c3b9573692bd5f'

    data = base64.b64decode(data)
    cipher = AES.new(key.encode('utf8'), AES.MODE_CBC,iv.encode('utf8'))

    # 去补位
    text_decrypted = unpad(cipher.decrypt(data))
    text_decrypted = text_decrypted.decode('utf8')

    return text_decrypted

def aesEncrypt(text,key=None,iv=None):
    if key == None or iv == None:
        iv = '98d71fe589499967'
        key = '7fb498553e3c462988c3b9573692bd5f'

    cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
    pad = 16 - len(text) % 16
    text = text + pad * chr(pad)
    encrypted_text = cipher.encrypt(text.encode('utf-8'))
    return  base64.b64encode(encrypted_text).decode('utf-8')

继续分析WVER、WTS参数~继续搜索进行断点

在这里插入图片描述

断点发现WTS为10位时间戳,WVER为WTS进行加密

在这里插入图片描述

发现为RSA魔改

在这里插入图片描述

代码实现:

function i(e) {
            $ = new Array(e);
            for (var t = 0; t < $.length; t++)
                $[t] = 0;
            I = new r,
            (M = new r).digits[0] = 1
        }
function r(e) {
    this.digits = "boolean" == typeof e && 1 == e ? null : $.slice(0),
    this.isNeg = !1
}
function o(e) {
    var t = new r(!0);
    return t.digits = e.digits.slice(0),
    t.isNeg = e.isNeg,
    t
}
function s(e) {
    for (var t = "", n = e.length - 1; n > -1; --n)
        t += e.charAt(n);
    return t
}
function a(e, t) {
    var n = new r;
    n.digits[0] = t;
    for (var i = O(e, n), o = R[i[1].digits[0]]; 1 == S(i[0], I); )
        i = O(i[0], n),
        digit = i[1].digits[0],
        o += R[i[1].digits[0]];
    return (e.isNeg ? "-" : "") + s(o)
}
function l(e) {
    var t = ""
      , n = 0;
    for (n = 0; n < 4; ++n)
        t += V[15 & e],
        e >>>= 4;
    return s(t)
}
function u(e) {
    for (var t = "", n = (m(e),
    m(e)); n > -1; --n)
        t += l(e.digits[n]);
    return t
}
function c(e) {
    return e >= 48 && e <= 57 ? e - 48 : e >= 65 && e <= 90 ? 10 + e - 65 : e >= 97 && e <= 122 ? 10 + e - 97 : 0
}
function h(e) {
    for (var t = 0, n = Math.min(e.length, 4), i = 0; i < n; ++i)
        t <<= 4,
        t |= c(e.charCodeAt(i));
    return t
}
function f(e) {
    for (var t = new r, n = e.length, i = 0; n > 0; n -= 4,
    ++i)
        t.digits[i] = h(e.substr(Math.max(n - 4, 0), Math.min(n, 4)));
    return t
}
function d(e, t) {
    var n;
    if (e.isNeg != t.isNeg)
        t.isNeg = !t.isNeg,
        n = p(e, t),
        t.isNeg = !t.isNeg;
    else {
        n = new r;
        for (var i, o = 0, s = 0; s < e.digits.length; ++s)
            i = e.digits[s] + t.digits[s] + o,
            n.digits[s] = i % j,
            o = Number(i >= j);
        n.isNeg = e.isNeg
    }
    return n
}
function p(e, t) {
    var n;
    if (e.isNeg != t.isNeg)
        t.isNeg = !t.isNeg,
        n = d(e, t),
        t.isNeg = !t.isNeg;
    else {
        var i, o;
        n = new r,
        o = 0;
        for (var s = 0; s < e.digits.length; ++s)
            i = e.digits[s] - t.digits[s] + o,
            n.digits[s] = i % j,
            n.digits[s] < 0 && (n.digits[s] += j),
            o = 0 - Number(i < 0);
        if (-1 == o) {
            o = 0;
            for (s = 0; s < e.digits.length; ++s)
                i = 0 - n.digits[s] + o,
                n.digits[s] = i % j,
                n.digits[s] < 0 && (n.digits[s] += j),
                o = 0 - Number(i < 0);
            n.isNeg = !e.isNeg
        } else
            n.isNeg = e.isNeg
    }
    return n
}
function m(e) {
    for (var t = e.digits.length - 1; t > 0 && 0 == e.digits[t]; )
        --t;
    return t
}
function v(e) {
    var t, n = m(e), i = e.digits[n], r = (n + 1) * A;
    for (t = r; t > r - A && 0 == (32768 & i); --t)
        i <<= 1;
    return t
}
function g(e, t) {
    var n, i, o, s, a, l = m(e), u = m(t);
    a = new r;
    for (var c = 0; c <= u; ++c) {
        for (n = 0,
        s = c,
        i = 0; i <= l; ++i,
        ++s)
            o = a.digits[s] + e.digits[i] * t.digits[c] + n,
            a.digits[s] = o & B,
            n = o >>> N;
        a.digits[c + l + 1] = n
    }
    return a.isNeg = e.isNeg != t.isNeg,
    a
}
function y(e, t) {
    var n, i, o, s;
    s = new r,
    n = m(e),
    i = 0;
    for (var a = 0; a <= n; ++a)
        o = s.digits[a] + e.digits[a] * t + i,
        s.digits[a] = o & B,
        i = o >>> N;
    return s.digits[1 + n] = i,
    s
}
function b(e, t, n, i, r) {
    for (var o = Math.min(t + r, e.length), s = t, a = i; s < o; ++s,
    ++a)
        n[a] = e[s]
}
function _(e, t) {
    var n = Math.floor(t / A)
      , i = new r;
    b(e.digits, 0, i.digits, n, i.digits.length - n);
    for (var o = t % A, s = A - o, a = i.digits.length - 1, l = a - 1; a > 0; --a,
    --l)
        i.digits[a] = i.digits[a] << o & B | (i.digits[l] & z[o]) >>> s;
    return i.digits[0] = i.digits[a] << o & B,
    i.isNeg = e.isNeg,
    i
}
function w(e, t) {
    var n = Math.floor(t / A)
      , i = new r;
    b(e.digits, n, i.digits, 0, e.digits.length - n);
    for (var o = t % A, s = A - o, a = 0, l = a + 1; a < i.digits.length - 1; ++a,
    ++l)
        i.digits[a] = i.digits[a] >>> o | (i.digits[l] & H[o]) << s;
    return i.digits[i.digits.length - 1] >>>= o,
    i.isNeg = e.isNeg,
    i
}
function x(e, t) {
    var n = new r;
    return b(e.digits, 0, n.digits, t, n.digits.length - t),
    n
}
function C(e, t) {
    var n = new r;
    return b(e.digits, t, n.digits, 0, n.digits.length - t),
    n
}
function k(e, t) {
    var n = new r;
    return b(e.digits, 0, n.digits, 0, t),
    n
}
function S(e, t) {
    if (e.isNeg != t.isNeg)
        return 1 - 2 * Number(e.isNeg);
    for (var n = e.digits.length - 1; n >= 0; --n)
        if (e.digits[n] != t.digits[n])
            return e.isNeg ? 1 - 2 * Number(e.digits[n] > t.digits[n]) : 1 - 2 * Number(e.digits[n] < t.digits[n]);
    return 0
}
function O(e, t) {
    var n, i, s = v(e), a = v(t), l = t.isNeg;
    if (s < a)
        return e.isNeg ? ((n = o(M)).isNeg = !t.isNeg,
        e.isNeg = !1,
        t.isNeg = !1,
        i = p(t, e),
        e.isNeg = !0,
        t.isNeg = l) : (n = new r,
        i = o(e)),
        new Array(n,i);
    n = new r,
    i = e;
    for (var u = Math.ceil(a / A) - 1, c = 0; t.digits[u] < L; )
        t = _(t, 1),
        ++c,
        ++a,
        u = Math.ceil(a / A) - 1;
    i = _(i, c),
    s += c;
    for (var h = Math.ceil(s / A) - 1, f = x(t, h - u); -1 != S(i, f); )
        ++n.digits[h - u],
        i = p(i, f);
    for (var g = h; g > u; --g) {
        var b = g >= i.digits.length ? 0 : i.digits[g]
          , C = g - 1 >= i.digits.length ? 0 : i.digits[g - 1]
          , k = g - 2 >= i.digits.length ? 0 : i.digits[g - 2]
          , O = u >= t.digits.length ? 0 : t.digits[u]
          , E = u - 1 >= t.digits.length ? 0 : t.digits[u - 1];
        n.digits[g - u - 1] = b == O ? B : Math.floor((b * j + C) / O);
        for (var D = n.digits[g - u - 1] * (O * j + E), T = b * F + (C * j + k); D > T; )
            --n.digits[g - u - 1],
            D = n.digits[g - u - 1] * (O * j | E),
            T = b * j * j + (C * j + k);
        (i = p(i, y(f = x(t, g - u - 1), n.digits[g - u - 1]))).isNeg && (i = d(i, f),
        --n.digits[g - u - 1])
    }
    return i = w(i, c),
    n.isNeg = e.isNeg != l,
    e.isNeg && (n = l ? d(n, M) : p(n, M),
    i = p(t = w(t, c), i)),
    0 == i.digits[0] && 0 == m(i) && (i.isNeg = !1),
    new Array(n,i)
}
function E(e) {
    this.modulus = o(e),
    this.k = m(this.modulus) + 1;
    var t = new r;
    t.digits[2 * this.k] = 1,
    this.mu = function(e, t) {
        return O(e, t)[0]
    }(t, this.modulus),
    this.bkplus1 = new r,
    this.bkplus1.digits[this.k + 1] = 1,
    this.modulo = D,
    this.multiplyMod = T,
    this.powMod = P
}
function D(e) {
    var t = C(g(C(e, this.k - 1), this.mu), this.k + 1)
      , n = p(k(e, this.k + 1), k(g(t, this.modulus), this.k + 1));
    n.isNeg && (n = d(n, this.bkplus1));
    for (var i = S(n, this.modulus) >= 0; i; )
        i = S(n = p(n, this.modulus), this.modulus) >= 0;
    return n
}
function T(e, t) {
    var n = g(e, t);
    return this.modulo(n)
}
function P(e, t) {
    var n = new r;
    n.digits[0] = 1;
    for (var i = e, o = t; 0 != (1 & o.digits[0]) && (n = this.multiplyMod(n, i)),
    0 != (o = w(o, 1)).digits[0] || 0 != m(o); )
        i = this.multiplyMod(i, i);
    return n
}
var $, I, M, N = 16, A = N, j = 65536, L = j >>> 1, F = j * j, B = j - 1;
i(20);
var R = (function(e) {
    var t = new r;
    t.isNeg = e < 0,
    e = Math.abs(e);
    for (var n = 0; e > 0; )
        t.digits[n++] = e & B,
        e = Math.floor(e / j)
}(1e15),
new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"))
  , V = new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f")
  , z = new Array(0,32768,49152,57344,61440,63488,64512,65024,65280,65408,65472,65504,65520,65528,65532,65534,65535)
  , H = new Array(0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535);
var e = {}
e.RSAKeyPair = function(e, t, n) {
    this.e = f(e),
    this.d = f(t),
    this.m = f(n),
    this.digitSize = 2 * m(this.m) + 2,
    this.chunkSize = this.digitSize - 11,
    this.radix = 16,
    this.barrett = new E(this.m)
}
,
e.twoDigit = function(e) {
    return (e < 10 ? "0" : "") + String(e)
}
,
e.encryptedString = function(e, t) {
    if (e.chunkSize > e.digitSize - 11)
        return "Error";
    for (var n = new Array, i = t.length, o = 0; o < i; )
        n[o] = t.charCodeAt(o),
        o++;
    var s, l, c, h = n.length, f = "";
    for (o = 0; o < h; o += e.chunkSize) {
        c = new r,
        s = 0;
        var d, p = o + e.chunkSize > h ? h % e.chunkSize : e.chunkSize, m = new Array;
        for (d = 0; d < p; d++)
            m[d] = n[o + p - 1 - d];
        m[p] = 0;
        var v = Math.max(8, e.digitSize - 3 - p);
        for (d = 0; d < v; d++)
            m[p + 1 + d] = Math.floor(254 * Math.random()) + 1;
        for (m[e.digitSize - 2] = 2,
        m[e.digitSize - 1] = 0,
        l = 0; l < e.digitSize; ++s)
            c.digits[s] = m[l++],
            c.digits[s] += m[l++] << 8;
        var g = e.barrett.powMod(c, e.e);
        f += (16 == e.radix ? u(g) : a(g, e.radix)) + " "
    }
    return f.substring(0, f.length - 1)
}

function rasEncrypt(times){
    i(129);
    var rsa = new e.RSAKeyPair("010001","","C2D84A72668932EBE5CC2BADB5DE288E59AD587775C1E45F33F6CC9DAB376C793AFF12050C0648D5C3016F685B9F4FA2460A59B6B07793808B4E68A883CA2830FD7895C66F68F64A829DB99DEDE978EC2E04711184A872C1F43956B1B72CFA803C1D677BAE386209368B3F3ED7A8CB06BEC64B0D0369EE62A49E6B417FC55959");
    var encrypted = e.encryptedString(rsa,'' + times).replace(/\s+/g, "");
    return encrypted;
}

最后呢说一下loginInfo参数,这个其实很简单也是标准的AES加密

def getloginInfo():
    loginInfo = '{"DeviceType":"WEB","ReqSource":100,"ClientIP":"223.104.74.189"}'
    UTS = f'{int(time.time())}'
    UVER = aesEncrypt(UTS)[:16]
    Data = aesEncrypt(loginInfo,UTS + '000000',UVER)
    UUID = f'{int(time.time() * 1e3)}' + ''.join(random.sample('1234567890', 10))
    infos = {
        'Data':Data,
        'UTS':UTS,
        'UVER':UVER,
        'UUID':UUID
    }
    loginInfo = json.dumps(infos,separators=(',',':'))
    WTS = f'{int(time.time())}'
    WVER = execjs.compile(open('./rsa.js','r',encoding='utf-8').read()).call('rasEncrypt',WTS)
    return {
        'loginInfo':loginInfo,
        'WTS':WTS,
        'WVER':WVER,
        "WSDI": "",
        "WRS": "WEB",
        "WCOI": "",
        "WCOL": ""
    }

技术细节

提示:有需要可加v:wzwzwz0613

例如:

  • API
  • 支持模型类型

小结

提示:加密挺多,AES、RSA(登录会出现另一种魔改)
学习交流群:可联系v:wzwzwz0613拉进群

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值