@omindu/yaksha 1.0.0

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.
@@ -0,0 +1,354 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Yaksha Firewall Evasion
5
+ * Advanced techniques to bypass firewalls and DPI (Deep Packet Inspection)
6
+ */
7
+
8
+ const crypto = require('crypto');
9
+ const Logger = require('../utils/logger');
10
+
11
+ // Common MTU values
12
+ const MTU_VALUES = [1500, 1492, 1460, 1400, 1280];
13
+
14
+ class FirewallEvasion {
15
+ constructor(securityLevel = 'medium', options = {}) {
16
+ this.securityLevel = securityLevel;
17
+ this.enabled = options.enabled !== false;
18
+ this.portHoppingEnabled = options.portHopping !== false;
19
+ this.portHoppingInterval = options.portHoppingInterval || 100; // packets or seconds
20
+ this.portRange = options.portRange || [8000, 9000];
21
+ this.currentPort = null;
22
+ this.packetCounter = 0;
23
+ this.mtu = options.mtu || 1500;
24
+
25
+ this.logger = new Logger({ prefix: 'Firewall-Evasion' });
26
+ }
27
+
28
+ /**
29
+ * Get next port for port hopping
30
+ */
31
+ _getNextPort() {
32
+ const [min, max] = this.portRange;
33
+ return crypto.randomInt(min, max + 1);
34
+ }
35
+
36
+ /**
37
+ * Check if port hop is needed
38
+ */
39
+ shouldHopPort() {
40
+ if (!this.portHoppingEnabled) {
41
+ return false;
42
+ }
43
+
44
+ this.packetCounter++;
45
+
46
+ return this.packetCounter % this.portHoppingInterval === 0;
47
+ }
48
+
49
+ /**
50
+ * Get current or next port
51
+ */
52
+ getPort(force = false) {
53
+ if (!this.currentPort || force || this.shouldHopPort()) {
54
+ this.currentPort = this._getNextPort();
55
+ this.logger.debug(`Port hopping to ${this.currentPort}`);
56
+ }
57
+
58
+ return this.currentPort;
59
+ }
60
+
61
+ /**
62
+ * Fragment packet into smaller pieces
63
+ */
64
+ fragmentPacket(data, fragmentSize = null) {
65
+ if (!this.enabled) {
66
+ return [data];
67
+ }
68
+
69
+ if (!fragmentSize) {
70
+ // Random fragment size between 500 and 1400 bytes
71
+ fragmentSize = crypto.randomInt(500, 1401);
72
+ }
73
+
74
+ const fragments = [];
75
+ let offset = 0;
76
+
77
+ while (offset < data.length) {
78
+ const chunkSize = Math.min(fragmentSize, data.length - offset);
79
+ const fragment = data.slice(offset, offset + chunkSize);
80
+ fragments.push(fragment);
81
+ offset += chunkSize;
82
+ }
83
+
84
+ this.logger.debug(`Fragmented ${data.length} bytes into ${fragments.length} fragments`);
85
+ return fragments;
86
+ }
87
+
88
+ /**
89
+ * Reassemble fragments
90
+ */
91
+ reassembleFragments(fragments) {
92
+ return Buffer.concat(fragments);
93
+ }
94
+
95
+ /**
96
+ * Add timing jitter to avoid constant rate traffic
97
+ */
98
+ calculateTimingJitter() {
99
+ if (!this.enabled) {
100
+ return 0;
101
+ }
102
+
103
+ // Random jitter between 0 and 50ms
104
+ return crypto.randomInt(0, 51);
105
+ }
106
+
107
+ /**
108
+ * Adjust MTU to avoid detection
109
+ */
110
+ adjustMTU(preferred = null) {
111
+ if (preferred && MTU_VALUES.includes(preferred)) {
112
+ this.mtu = preferred;
113
+ return this.mtu;
114
+ }
115
+
116
+ // Select random common MTU value
117
+ const index = crypto.randomInt(0, MTU_VALUES.length);
118
+ this.mtu = MTU_VALUES[index];
119
+
120
+ this.logger.debug(`MTU adjusted to ${this.mtu}`);
121
+ return this.mtu;
122
+ }
123
+
124
+ /**
125
+ * Get current MTU
126
+ */
127
+ getMTU() {
128
+ return this.mtu;
129
+ }
130
+
131
+ /**
132
+ * Apply protocol masquerading (make it look like HTTPS)
133
+ */
134
+ masqueradeProtocol(data) {
135
+ if (!this.enabled) {
136
+ return data;
137
+ }
138
+
139
+ // Prepend with TLS-like pattern
140
+ // This is a simplified version - TLS camouflage module handles full implementation
141
+ const marker = Buffer.from([0x17, 0x03, 0x03]); // TLS Application Data, TLS 1.2
142
+ const length = Buffer.allocUnsafe(2);
143
+ length.writeUInt16BE(Math.min(data.length, 16384), 0);
144
+
145
+ return Buffer.concat([marker, length, data]);
146
+ }
147
+
148
+ /**
149
+ * Remove protocol masquerade
150
+ */
151
+ unmasqueradeProtocol(data) {
152
+ if (!this.enabled || data.length < 5) {
153
+ return data;
154
+ }
155
+
156
+ // Check for TLS marker
157
+ if (data[0] === 0x17 && data[1] === 0x03 && data[2] === 0x03) {
158
+ return data.slice(5); // Skip 5-byte TLS header
159
+ }
160
+
161
+ return data;
162
+ }
163
+
164
+ /**
165
+ * Mimic burst traffic pattern (like video streaming)
166
+ */
167
+ generateBurstPattern(totalPackets) {
168
+ const pattern = [];
169
+ let remaining = totalPackets;
170
+
171
+ while (remaining > 0) {
172
+ // Burst size: 2-10 packets
173
+ const burstSize = Math.min(crypto.randomInt(2, 11), remaining);
174
+
175
+ // Send burst
176
+ for (let i = 0; i < burstSize; i++) {
177
+ pattern.push({ action: 'send', delay: 0 });
178
+ }
179
+
180
+ remaining -= burstSize;
181
+
182
+ // Pause between bursts: 50-200ms
183
+ if (remaining > 0) {
184
+ const pauseDuration = crypto.randomInt(50, 201);
185
+ pattern.push({ action: 'pause', delay: pauseDuration });
186
+ }
187
+ }
188
+
189
+ return pattern;
190
+ }
191
+
192
+ /**
193
+ * Apply traffic shaping delay
194
+ */
195
+ async applyTrafficShaping(callback, pattern = null) {
196
+ if (!this.enabled) {
197
+ await callback();
198
+ return;
199
+ }
200
+
201
+ if (!pattern) {
202
+ // Simple random delay
203
+ const delay = this.calculateTimingJitter();
204
+ if (delay > 0) {
205
+ await new Promise(resolve => setTimeout(resolve, delay));
206
+ }
207
+ await callback();
208
+ return;
209
+ }
210
+
211
+ // Apply complex pattern
212
+ for (const step of pattern) {
213
+ if (step.action === 'send') {
214
+ await callback();
215
+ } else if (step.action === 'pause') {
216
+ await new Promise(resolve => setTimeout(resolve, step.delay));
217
+ }
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Randomize packet order (within window)
223
+ */
224
+ randomizePacketOrder(packets, windowSize = 5) {
225
+ if (!this.enabled || packets.length <= 1) {
226
+ return packets;
227
+ }
228
+
229
+ const result = [];
230
+ const remaining = [...packets];
231
+
232
+ while (remaining.length > 0) {
233
+ const window = Math.min(windowSize, remaining.length);
234
+ const index = crypto.randomInt(0, window);
235
+ result.push(remaining.splice(index, 1)[0]);
236
+ }
237
+
238
+ return result;
239
+ }
240
+
241
+ /**
242
+ * Add decoy packets (fake traffic)
243
+ */
244
+ generateDecoyPacket(size = null) {
245
+ if (!size) {
246
+ size = crypto.randomInt(100, 1000);
247
+ }
248
+
249
+ return crypto.randomBytes(size);
250
+ }
251
+
252
+ /**
253
+ * Check if packet should be a decoy
254
+ */
255
+ shouldInsertDecoy(probability = 0.1) {
256
+ return this.enabled && Math.random() < probability;
257
+ }
258
+
259
+ /**
260
+ * Apply DPI evasion techniques
261
+ */
262
+ evadeDPI(data) {
263
+ if (!this.enabled) {
264
+ return data;
265
+ }
266
+
267
+ const techniques = [];
268
+
269
+ // 1. Encrypt all payload (already done by encryption module)
270
+ // 2. No plaintext headers
271
+ // 3. Randomize packet structure
272
+
273
+ // Add random padding
274
+ const paddingSize = crypto.randomInt(0, 256);
275
+ if (paddingSize > 0) {
276
+ const padding = crypto.randomBytes(paddingSize);
277
+ data = Buffer.concat([data, padding]);
278
+ techniques.push('padding');
279
+ }
280
+
281
+ // Apply protocol masquerading
282
+ data = this.masqueradeProtocol(data);
283
+ techniques.push('masquerade');
284
+
285
+ this.logger.debug(`DPI evasion applied: ${techniques.join(', ')}`);
286
+ return data;
287
+ }
288
+
289
+ /**
290
+ * Get recommended packet size to avoid detection
291
+ */
292
+ getRecommendedPacketSize() {
293
+ // Common packet sizes seen in HTTPS traffic
294
+ const commonSizes = [64, 128, 256, 512, 1024, 1400];
295
+ const index = crypto.randomInt(0, commonSizes.length);
296
+ return commonSizes[index];
297
+ }
298
+
299
+ /**
300
+ * Enable firewall evasion
301
+ */
302
+ enable() {
303
+ this.enabled = true;
304
+ this.logger.info('Firewall evasion enabled');
305
+ }
306
+
307
+ /**
308
+ * Disable firewall evasion
309
+ */
310
+ disable() {
311
+ this.enabled = false;
312
+ this.logger.info('Firewall evasion disabled');
313
+ }
314
+
315
+ /**
316
+ * Enable port hopping
317
+ */
318
+ enablePortHopping() {
319
+ this.portHoppingEnabled = true;
320
+ this.logger.info('Port hopping enabled');
321
+ }
322
+
323
+ /**
324
+ * Disable port hopping
325
+ */
326
+ disablePortHopping() {
327
+ this.portHoppingEnabled = false;
328
+ this.logger.info('Port hopping disabled');
329
+ }
330
+
331
+ /**
332
+ * Reset packet counter
333
+ */
334
+ reset() {
335
+ this.packetCounter = 0;
336
+ this.currentPort = null;
337
+ }
338
+
339
+ /**
340
+ * Get statistics
341
+ */
342
+ getStats() {
343
+ return {
344
+ enabled: this.enabled,
345
+ portHopping: this.portHoppingEnabled,
346
+ currentPort: this.currentPort,
347
+ packetCounter: this.packetCounter,
348
+ mtu: this.mtu
349
+ };
350
+ }
351
+ }
352
+
353
+ module.exports = FirewallEvasion;
354
+ module.exports.MTU_VALUES = MTU_VALUES;