@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.
- package/LICENSE +21 -0
- package/bin/yaksha.js +329 -0
- package/package.json +28 -0
- package/src/bypass/firewall-evasion.js +354 -0
- package/src/client/index.js +544 -0
- package/src/core/connection.js +393 -0
- package/src/core/encryption.js +299 -0
- package/src/core/protocol.js +268 -0
- package/src/features/dns-override.js +403 -0
- package/src/features/multi-path.js +394 -0
- package/src/features/sni-spoof.js +355 -0
- package/src/features/tls-camouflage.js +369 -0
- package/src/features/traffic-obfuscation.js +338 -0
- package/src/index.js +106 -0
- package/src/security/auth.js +441 -0
- package/src/security/levels.js +316 -0
- package/src/server/index.js +551 -0
- package/src/utils/buffer-pool.js +150 -0
- package/src/utils/config.js +205 -0
- package/src/utils/logger.js +105 -0
|
@@ -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;
|