概要
特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拉进群