bobocup commited on
Commit
d388885
·
verified ·
1 Parent(s): 58799a0

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +76 -284
index.js CHANGED
@@ -18,7 +18,8 @@ const CONFIG = {
18
  BASE_URL: process.env.DENO_URL || "https://partyrock.aws/stream/getCompletion",//如果需要多号循环,需要设置你自己的denourl
19
  API_KEY: process.env.API_KEY || "sk-123456",//自定义你自己的认证密钥,记得修改
20
  RedisUrl: process.env.RedisUrl,
21
- RedisToken: process.env.RedisToken
 
22
  },
23
  SERVER: {
24
  PORT: process.env.PORT || 3000,
@@ -85,109 +86,6 @@ var RedisClient = class {
85
  }
86
  }
87
  };
88
-
89
- // 添加 Capsolver 相关配置
90
- const CAPSOLVER_CONFIG = {
91
- API_KEY: process.env.CAPSOLVER_KEY || "YOUR_CAPSOLVER_KEY",
92
- API_URL: "https://api.capsolver.com"
93
- };
94
-
95
- class CapsolverClient {
96
- constructor(apiKey) {
97
- this.apiKey = apiKey;
98
- }
99
-
100
- async createTask(websiteURL, websiteKey, extraParams = {}) {
101
- // 第一步:发送初始化请求获取验证码 - 改用 GET 请求
102
- const initResponse = await fetch(`${extraParams.captchaUrl}/captcha`, {
103
- method: 'GET',
104
- headers: {
105
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
106
- 'sec-ch-ua': '"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
107
- 'sec-ch-ua-platform': '"Windows"',
108
- 'sec-ch-ua-mobile': '?0',
109
- 'Referer': 'https://partyrock.aws/',
110
- 'Origin': 'https://partyrock.aws'
111
- }
112
- });
113
-
114
- if (!initResponse.ok) {
115
- console.error('初始化验证码失败:', await initResponse.text());
116
- throw new Error('初始化验证码失败');
117
- }
118
-
119
- const initData = await initResponse.json();
120
- console.log('验证码初始化数据:', initData);
121
-
122
- // 第二步:创建 Capsolver 任务
123
- const requestBody = JSON.stringify({
124
- clientKey: this.apiKey,
125
- task: {
126
- type: "AwsWafClassification",
127
- websiteURL: websiteURL,
128
- websiteKey: websiteKey,
129
- metadata: {
130
- images: initData.images || [],
131
- question: initData.question || '',
132
- context: extraParams.gokuProps.context,
133
- iv: extraParams.gokuProps.iv,
134
- key: extraParams.gokuProps.key
135
- }
136
- }
137
- });
138
-
139
- console.log('发送到Capsolver的数据:', requestBody);
140
-
141
- const response = await fetch(`${CAPSOLVER_CONFIG.API_URL}/createTask`, {
142
- method: 'POST',
143
- headers: {
144
- 'Content-Type': 'application/json'
145
- },
146
- body: requestBody
147
- });
148
-
149
- if (!response.ok) {
150
- console.error('Capsolver API 响应不成功:', response.status);
151
- const errorText = await response.text();
152
- console.error('错误响应内容:', errorText);
153
- throw new Error(`Capsolver API 请求失败: ${response.status}`);
154
- }
155
-
156
- const result = await response.json();
157
- console.log('Capsolver 返回结果:', result);
158
-
159
- // 第三步:提交验证结果
160
- if (result.solution) {
161
- const verifyResponse = await fetch(extraParams.captchaUrl + '/verify', {
162
- method: 'POST',
163
- headers: {
164
- 'Content-Type': 'application/json',
165
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
166
- 'sec-ch-ua': '"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
167
- 'sec-ch-ua-platform': '"Windows"',
168
- 'sec-ch-ua-mobile': '?0',
169
- 'Referer': 'https://partyrock.aws/',
170
- 'Origin': 'https://partyrock.aws'
171
- },
172
- body: JSON.stringify({
173
- solution: result.solution,
174
- context: extraParams.gokuProps.context,
175
- iv: extraParams.gokuProps.iv,
176
- key: extraParams.gokuProps.key
177
- })
178
- });
179
-
180
- if (!verifyResponse.ok) {
181
- throw new Error('验证提交失败');
182
- }
183
-
184
- return await verifyResponse.json();
185
- }
186
-
187
- return result;
188
- }
189
- }
190
-
191
  class TokenManager {
192
  async updateRedisTokens() {
193
  await redisClient.set(`tokens_${currentIndex}`, JSON.stringify(Tokens[currentIndex]));
@@ -205,167 +103,20 @@ class TokenManager {
205
  CONFIG.DEFAULT_HEADERS["request-id"] = `request-id-${Utils.uuidv4()}`;
206
  }
207
 
208
- async extractChallengeInfo(html) {
209
- console.log('开始提取验证码信息...');
210
- try {
211
- // 提取 gokuProps
212
- const gokuPropsMatch = html.match(/window\.gokuProps\s*=\s*({[\s\S]*?});/);
213
- if (!gokuPropsMatch) {
214
- console.error('未找到 gokuProps');
215
- return null;
216
- }
217
-
218
- // 提取验证码和challenge URL
219
- const captchaUrlMatch = html.match(/src="(https:\/\/[^"]+\/captcha\.js)"/);
220
- const challengeUrlMatch = html.match(/src="(https:\/\/[^"]+\/challenge\.js)"/);
221
-
222
- if (!captchaUrlMatch || !challengeUrlMatch) {
223
- console.error('未找到验证码或challenge URL');
224
- return null;
225
- }
226
-
227
- const gokuProps = JSON.parse(gokuPropsMatch[1]);
228
- const captchaUrl = captchaUrlMatch[1].replace('/captcha.js', '');
229
- const challengeUrl = challengeUrlMatch[1].replace('/challenge.js', '');
230
-
231
- console.log('提取的信息:', {
232
- gokuProps,
233
- captchaUrl,
234
- challengeUrl
235
- });
236
-
237
- return {
238
- gokuProps,
239
- captchaUrl,
240
- challengeUrl
241
- };
242
- } catch (error) {
243
- console.error('提取验证码信息时出错:', error);
244
- return null;
245
- }
246
- }
247
-
248
- async solveCaptcha(challengeInfo) {
249
- console.log('开始处理验证码...');
250
- const capsolverClient = new CapsolverClient(CAPSOLVER_CONFIG.API_KEY);
251
-
252
- try {
253
- const websiteKey = challengeInfo.captchaUrl.split('/')[2].split('.')[0];
254
- console.log('提取的websiteKey:', websiteKey);
255
-
256
- console.log('创建验证码任务...');
257
- const createTaskResponse = await capsolverClient.createTask(
258
- "partyrock.aws",
259
- websiteKey,
260
- {
261
- gokuProps: challengeInfo.gokuProps,
262
- captchaUrl: challengeInfo.captchaUrl,
263
- challengeUrl: challengeInfo.challengeUrl
264
- }
265
- );
266
-
267
- console.log('创建任务响应:', JSON.stringify(createTaskResponse, null, 2));
268
-
269
- if (createTaskResponse.errorId > 0) {
270
- throw new Error(`创建验证码任务失败: ${createTaskResponse.errorDescription}`);
271
- }
272
-
273
- console.log('等待验证码解决结果...');
274
- let taskResult;
275
- for (let i = 0; i < 30; i++) {
276
- console.log(`第 ${i + 1} 次尝试获取结果...`);
277
- await new Promise(resolve => setTimeout(resolve, 2000));
278
- taskResult = await capsolverClient.getTaskResult(createTaskResponse.taskId);
279
- console.log('获取结果响应:', JSON.stringify(taskResult, null, 2));
280
-
281
- if (taskResult.status === 'ready') {
282
- console.log('验证码已解决!');
283
- break;
284
- }
285
- }
286
-
287
- if (!taskResult || taskResult.status !== 'ready') {
288
- console.error('验证码解决超时');
289
- throw new Error('验证码解决超时');
290
- }
291
-
292
- console.log('验证码解决方案:', JSON.stringify(taskResult.solution, null, 2));
293
- return taskResult.solution;
294
-
295
- } catch (error) {
296
- console.error('验证码解决过程中出错:', error);
297
- throw error;
298
- }
299
- }
300
-
301
  async updateTokens(response, isWaf = false) {
302
  if (isWaf) {
303
- console.log('检测到WAF验证请求');
304
- try {
305
- console.log('Response headers:', JSON.stringify(Object.fromEntries([...response.headers]), null, 2));
306
-
307
- // 获取HTML内容
308
- const html = await response.text();
309
- console.log('收到HTML响应');
310
-
311
- // 提取验证码信息
312
- const challengeInfo = await this.extractChallengeInfo(html);
313
- if (!challengeInfo) {
314
- throw new Error('无法提取验证码信息');
315
- }
316
-
317
- console.log('开始处理WAF验证码...');
318
- const solution = await this.solveCaptcha(challengeInfo);
319
-
320
- console.log('提交验证码解决方案...');
321
- const verifyResponse = await fetch(`${challengeInfo.captchaUrl}/verify`, {
322
- method: 'POST',
323
- headers: {
324
- 'Content-Type': 'application/json',
325
- 'Referer': 'https://partyrock.aws/',
326
- 'Origin': 'https://partyrock.aws'
327
- },
328
- body: JSON.stringify(solution)
329
- });
330
-
331
- console.log('验证响应状态:', verifyResponse.status);
332
- console.log('验证响应headers:', JSON.stringify(Object.fromEntries([...verifyResponse.headers]), null, 2));
333
-
334
- if (verifyResponse.ok) {
335
- const voucherResponse = await verifyResponse.json();
336
- console.log('获取到voucher:', voucherResponse);
337
-
338
- // 提交voucher
339
- const submitResponse = await fetch(`${challengeInfo.challengeUrl}/voucher`, {
340
- method: 'POST',
341
- headers: {
342
- 'Content-Type': 'application/json',
343
- 'Referer': 'https://partyrock.aws/',
344
- 'Origin': 'https://partyrock.aws'
345
- },
346
- body: JSON.stringify({
347
- voucher: voucherResponse.voucher
348
- })
349
- });
350
-
351
- if (submitResponse.ok) {
352
- console.log('验证成功,更新WAF token...');
353
- const wafToken = await Utils.extractWaf();
354
- if (wafToken) {
355
- Tokens[currentIndex].aws_waf_token = wafToken;
356
- await this.updateCacheTokens();
357
- this.updateRedisTokens();
358
- console.log("成功更新 aws-waf-token");
359
- }
360
- }
361
- }
362
- } catch (error) {
363
- console.error('处理验证码过程中发生错误:', error);
364
- console.error('错误堆栈:', error.stack);
365
  }
366
-
367
- currentIndex = (currentIndex + 1) % Tokens.length;
368
-
369
  } else {
370
  const newCsrfToken = response.headers.get('anti-csrftoken-a2z');
371
  const cookies = response.headers.get('set-cookie');
@@ -384,6 +135,7 @@ class TokenManager {
384
  }
385
  }
386
 
 
387
  class Utils {
388
  static async getRandomUserAgent() {
389
  try {
@@ -398,18 +150,42 @@ class Utils {
398
  return type[Math.floor(Math.random() * type.length)]
399
  }
400
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  static async extractWaf() {
402
  puppeteer.use(StealthPlugin())
403
  const browser = await puppeteer.launch({
404
  headless: true,
405
- args: [
406
- '--no-sandbox',
407
- '--disable-setuid-sandbox',
408
- '--disable-dev-shm-usage',
409
- '--disable-gpu'
410
- ],
411
  executablePath: CONFIG.CHROME_PATH
412
  });
 
413
  try {
414
  const page = await browser.newPage();
415
  await page.setExtraHTTPHeaders({
@@ -418,32 +194,48 @@ class Utils {
418
  await page.setUserAgent(
419
  CONFIG.DEFAULT_HEADERS["User-Agent"]
420
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  await page.goto(Tokens[currentIndex].refreshUrl, {
422
  waitUntil: 'networkidle2',
423
  timeout: 30000
424
  });
425
- await page.evaluate(() => {
426
- // 随机滚动
427
- window.scrollBy(0, Math.random() * 500)
428
- })
429
- await page.evaluate(() => {
430
- return new Promise(resolve => setTimeout(resolve, 2000))
431
- })
432
- // 直接从页面 cookies 中提取 aws-waf-token
433
  const awsWafToken = (await page.cookies()).find(
434
  cookie => cookie.name.toLowerCase() === 'aws-waf-token'
435
  )?.value;
436
 
437
- if (awsWafToken) {
438
- await browser.close();
439
- return awsWafToken;
440
- } else {
441
- await browser.close();
442
- return null;
443
- }
444
 
445
  } catch (error) {
446
- console.error('获取 aws-waf-token 出错:', error);
447
  await browser.close();
448
  return null;
449
  }
 
18
  BASE_URL: process.env.DENO_URL || "https://partyrock.aws/stream/getCompletion",//如果需要多号循环,需要设置你自己的denourl
19
  API_KEY: process.env.API_KEY || "sk-123456",//自定义你自己的认证密钥,记得修改
20
  RedisUrl: process.env.RedisUrl,
21
+ RedisToken: process.env.RedisToken,
22
+ CAPSOLVER_KEY: "CAP-D6D78FCBD7B944444E992346185BE6384287DEDDA5085490CA16E371A9D55660" // 新增Capsolver密钥
23
  },
24
  SERVER: {
25
  PORT: process.env.PORT || 3000,
 
86
  }
87
  }
88
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  class TokenManager {
90
  async updateRedisTokens() {
91
  await redisClient.set(`tokens_${currentIndex}`, JSON.stringify(Tokens[currentIndex]));
 
103
  CONFIG.DEFAULT_HEADERS["request-id"] = `request-id-${Utils.uuidv4()}`;
104
  }
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  async updateTokens(response, isWaf = false) {
107
  if (isWaf) {
108
+ var wafToken = await Utils.extractWaf();
109
+ if (wafToken) {
110
+ Tokens[currentIndex].aws_waf_token = wafToken;
111
+ await this.updateCacheTokens();
112
+ this.updateRedisTokens();
113
+ currentIndex = (currentIndex + 1) % Tokens.length;
114
+ console.log("���功提取 aws-waf-token");
115
+ } else {
116
+ currentIndex = (currentIndex + 1) % Tokens.length;
117
+ await this.updateCacheTokens();
118
+ console.log("提取aws-waf-token失败");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  }
 
 
 
120
  } else {
121
  const newCsrfToken = response.headers.get('anti-csrftoken-a2z');
122
  const cookies = response.headers.get('set-cookie');
 
135
  }
136
  }
137
 
138
+
139
  class Utils {
140
  static async getRandomUserAgent() {
141
  try {
 
150
  return type[Math.floor(Math.random() * type.length)]
151
  }
152
  }
153
+ static async solveAwsWaf(images, questionType = 'aws:grid') {
154
+ try {
155
+ const response = await fetch('https://api.capsolver.com/createTask', {
156
+ method: 'POST',
157
+ headers: {
158
+ 'Content-Type': 'application/json',
159
+ },
160
+ body: JSON.stringify({
161
+ clientKey: CONFIG.API.CAPSOLVER_KEY,
162
+ task: {
163
+ type: 'AwsWafClassification',
164
+ websiteURL: Tokens[currentIndex].refreshUrl,
165
+ images: images,
166
+ question: questionType
167
+ }
168
+ })
169
+ });
170
+
171
+ const data = await response.json();
172
+ if (data.errorId === 0 && data.status === 'ready') {
173
+ return data.solution;
174
+ }
175
+ return null;
176
+ } catch (error) {
177
+ console.error('Capsolver请求失败:', error);
178
+ return null;
179
+ }
180
+ }
181
  static async extractWaf() {
182
  puppeteer.use(StealthPlugin())
183
  const browser = await puppeteer.launch({
184
  headless: true,
185
+ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu'],
 
 
 
 
 
186
  executablePath: CONFIG.CHROME_PATH
187
  });
188
+
189
  try {
190
  const page = await browser.newPage();
191
  await page.setExtraHTTPHeaders({
 
194
  await page.setUserAgent(
195
  CONFIG.DEFAULT_HEADERS["User-Agent"]
196
  )
197
+
198
+ // 监听验证挑战
199
+ page.on('response', async (response) => {
200
+ if (response.url().includes('aws-waf-challenge')) {
201
+ const screenshots = [];
202
+
203
+ // 截取验证图片
204
+ const challengeElements = await page.$$('.aws-waf-challenge');
205
+ for (const element of challengeElements) {
206
+ const screenshot = await element.screenshot({ encoding: 'base64' });
207
+ screenshots.push(`data:image/png;base64,${screenshot}`);
208
+ }
209
+
210
+ // 调用Capsolver
211
+ const solution = await this.solveAwsWaf(screenshots, 'aws:grid');
212
+
213
+ if (solution?.objects) {
214
+ // 自动点击验证答案
215
+ await page.evaluate((objects) => {
216
+ document.querySelectorAll('.grid-item').forEach((el, index) => {
217
+ if (objects.includes(index)) el.click();
218
+ });
219
+ }, solution.objects);
220
+ }
221
+ }
222
+ });
223
+
224
  await page.goto(Tokens[currentIndex].refreshUrl, {
225
  waitUntil: 'networkidle2',
226
  timeout: 30000
227
  });
228
+
229
+ // 获取最终token
 
 
 
 
 
 
230
  const awsWafToken = (await page.cookies()).find(
231
  cookie => cookie.name.toLowerCase() === 'aws-waf-token'
232
  )?.value;
233
 
234
+ await browser.close();
235
+ return awsWafToken;
 
 
 
 
 
236
 
237
  } catch (error) {
238
+ console.error('获取aws-waf-token出错:', error);
239
  await browser.close();
240
  return null;
241
  }