题十四:神枪手
该题适合JS逆向进阶人群练习,对请求参数做了特殊处理。如果首次进入页面后无数据请手动刷新浏览器
先看看他是什么加密,发现这里是参数加密
m: MTc4ZDE3NDQ1MzIzNTU1NTcA
还是老套路,进行堆栈分析,查看堆栈
点进去,发现还是跟第十三题一样,ajax被重写了,打上断点,进行调试
当他还是调试到这里的时候,就会发现,他这里面有一个xhr,大胆判断这里就是入口,点进去
然后你发现,这里也并不是入口,打上断点,继续调试,着重看xhr
这里有一个xhr.js, 点进去之后发现这里就是加密的位置,先解一下混淆,在看一下代码
解完之后可以看见这里就是加密的位置
扣出来,改下一下代码,首先仔细分析一下这个代码
function x(b) {
const f = {
"RLvtt": function (N, W) {
return N < W;
},
"IdJpS": function (N, W) {
return N % W;
}
};
ts = new Date().getTime();
dd = b;
var p = function (N) {
let W = 0;
for (let L = 0; L < N.length; L++) {
var O = N.charCodeAt(L);
for (let y = 0; y < 20; y++) {
switch (f[__sk_Q(0x199)](y, 3)) {
case 0:
W = B.apply(null, [W, O, y]);
break;
case 1:
W = J.apply(null, [W, O, y]);
break;
case 2:
W = Y[__sk_Q(0x197)](null, [W, O]);
}
}
}
return W;
}("dasdasdarqwdasdasqwdasda" + ts);
var s = ["?", "m", "="][__sk_Q(0x18e)]('');
var p = p.toString(16);
return dd += s + function (N) {
let O = '';
let L;
let y;
let k;
let H;
let D;
let K;
let S;
let I = 0;
for (; I < N.length;) {
L = N.charCodeAt(I++);
y = I < N.length ? N.charCodeAt(I++) : 0;
k = I < N[__sk_Q(0x19d)] ? N.charCodeAt(I++) : 0;
H = L >> 2;
D = (3 & L) << 4 | y >> 4;
K = (15 & y) << 2 | z[__sk_Q(0x18d)](k, 6);
S = 63 & k;
if (isNaN(y)) {
K = S = 64;
} else if (z[__sk_Q(0x194)](isNaN, k)) {
S = 64;
}
O = O + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(H) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[__sk_Q(0x181)](D) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[__sk_Q(0x181)](K) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(S);
}
return O;
}(p + ts);
}
其中ts生成的是时间戳,p是时间戳,加上一段字符串最后生成的,然后在取其中的16
位最后在把弄好的时间戳还有p全部传入最后的return的函数中,返回之后的N值
可以给这个O加上断点,看看她最后生成的是什么,最后发现生成的是我们所需要的值
那最后就是扣代码,补代码了
完整代码在这里
function B(b, f, p) {
return b ^ f << p % 8;
}
function J(b, f, p) {
return 'Vorzg' === 'Vorzg' ? b ^ f >> p % 8 : Q ^ v << d % 8;
}
function Y(b, f) {
return (b = b + f - f) ^ f;
}
function x() {
ts = new Date().getTime();
var p = function (N) {
let W = 0;
for (let L = 0; L < N.length; L++) {
var O = N.charCodeAt(L);
for (let y = 0; y < 20; y++) {
switch (y % 3) {
case 0:
W = B.apply(null, [W, O, y]);
break;
case 1:
W = J.apply(null, [W, O, y]);
break;
case 2:
W = Y.apply(null, [W, O]);
}
}
}
return W;
}("dasdasdarqwdasdasqwdasda" + ts);
var s = ["?", "m", "="].join('');
var p = p.toString(16);
return function (N) {
let O = '';
let L;
let y;
let k;
let H;
let D;
let K;
let S;
let I = 0;
for (; I < N.length;) {
L = N.charCodeAt(I++);
y = I < N.length ? N.charCodeAt(I++) : 0;
k = I < N.length ? N.charCodeAt(I++) : 0;
H = L >> 2;
D = (3 & L) << 4 | y >> 4;
K = (15 & y) << 2 | (k >> 6);
S = 63 & k;
if (isNaN(y)) {
K = S = 64;
} else if (isNaN(k)) {
S = 64;
}
O = O + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(H) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(D) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(K) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(S);
}
return O;
}(p + ts);
}
console.log(x());
最后就会获得正确结果