-
Notifications
You must be signed in to change notification settings - Fork 21
/
ZooFaker_Necklace.js
executable file
·165 lines (141 loc) · 5.01 KB
/
ZooFaker_Necklace.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
const https = require('https');
const fs = require('fs/promises');
const { R_OK } = require('fs').constants;
const vm = require('vm');
const UA = require('./USER_AGENTS.js').USER_AGENT;
const URL = 'https://h5.m.jd.com/babelDiy/Zeus/41Lkp7DumXYCFmPYtU3LTcnTTXTX/index.html';
const REG_SCRIPT = /<script src="([^><]+\/(main\.\w+\.js))\?t=\d+">/gm;
const REG_ENTRY = /^(.*?\.push\(\[)(\d+,\d+)/;
const REG_PIN = /pt_pin=(.+?);/m;
const KEYWORD_MODULE = 'get_risk_result:';
const DATA = {appid:'50082',sceneid:'DDhomePageh5'};
let smashUtils;
class ZooFakerNecklace {
constructor(cookie, action) {
this.cookie = cookie;
this.action = action;
}
async run(data) {
if (!smashUtils) {
await this.init();
}
const t = Math.floor(1e+6 * Math.random()).toString().padEnd(6, '8');
const mpin = this.cookie.match(REG_PIN)
let pin = '-1'
// if(mpin) pin = mpin[1];
if(mpin) pin = decodeURIComponent(mpin[1]);
const { log } = smashUtils.get_risk_result({
id: this.action,
data: {
...data,
pin,
random: t,
}
});
const body = {
...data,
random: t,
extraData: { log, sceneid: DATA.sceneid },
};
// console.log(body);
return body;
}
async init() {
console.time('ZooFakerNecklace');
process.chdir(__dirname);
const html = await ZooFakerNecklace.httpGet(URL);
const script = REG_SCRIPT.exec(html);
if (script) {
const [, scriptUrl, filename] = script;
const jsContent = await this.getJSContent(filename, scriptUrl);
const fnMock = new Function;
const ctx = {
window: { addEventListener: fnMock },
document: {
addEventListener: fnMock,
removeEventListener: fnMock,
cookie: this.cookie,
},
navigator: { userAgent: UA },
};
const _this = this;
Object.defineProperty(ctx.document,'cookie',{
get() {
return _this.cookie;
},
});
vm.createContext(ctx);
vm.runInContext(jsContent, ctx);
smashUtils = ctx.window.smashUtils;
smashUtils.init(DATA);
// console.log(ctx);
}
// console.log(html);
// console.log(script[1],script[2]);
console.timeEnd('ZooFakerNecklace');
}
async getJSContent(cacheKey, url) {
try {
await fs.access(cacheKey, R_OK);
const rawFile = await fs.readFile(cacheKey, { encoding: 'utf8' });
return rawFile;
} catch (e) {
let jsContent = await ZooFakerNecklace.httpGet(url);
const findEntry = REG_ENTRY.test(jsContent);
const ctx = {
moduleIndex: 0,
};
const injectCode = `moduleIndex=arguments[0].findIndex(s=>s&&s.toString().indexOf('${KEYWORD_MODULE}')>0);return;`;
const injectedContent = jsContent.replace(/^(!function\(\w\){)/, `$1${injectCode}`);
vm.createContext(ctx);
vm.runInContext(injectedContent, ctx);
if (!(ctx.moduleIndex && findEntry)) {
throw new Error('Module not found.');
}
jsContent = jsContent.replace(REG_ENTRY, `$1${ctx.moduleIndex},1`);
// Fix device info (actually insecure, make less sense)
jsContent = jsContent.replace(/\w+\.getDefaultArr\(7\)/, '["a","a","a","a","a","a","1"]');
fs.writeFile(cacheKey, jsContent);
return jsContent;
REG_ENTRY.lastIndex = 0;
const entry = REG_ENTRY.exec(jsContent);
console.log(ctx.moduleIndex);
console.log(entry[2]);
}
}
static httpGet(url) {
return new Promise((resolve, reject) => {
const protocol = url.indexOf('http') !== 0 ? 'https:' : '';
const req = https.get(protocol + url, (res) => {
res.setEncoding('utf-8');
let rawData = '';
res.on('error', reject);
res.on('data', chunk => rawData += chunk);
res.on('end', () => resolve(rawData));
});
req.on('error', reject);
req.end();
});
}
}
async function getBody($ = {}) {
let riskData;
switch ($.action) {
case 'startTask':
riskData = { taskId: $.id };
break;
case 'chargeScores':
riskData = { bubleId: $.id };
break;
case 'sign':
riskData = {};
default:
break;
}
const zf = new ZooFakerNecklace($.cookie, $.action);
const log = await zf.run(riskData);
// return `body=${encodeURIComponent(JSON.stringify(log))}`;
return log;
}
ZooFakerNecklace.getBody = getBody;
module.exports = ZooFakerNecklace;