@dimzxzzx07/file-watcher 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.
Files changed (100) hide show
  1. package/.env +13 -0
  2. package/.eslintrc.json +128 -0
  3. package/.prettierrc +18 -0
  4. package/Dimzxzzx07.png +0 -0
  5. package/README.md +1024 -0
  6. package/dist/core/BackupManager.d.ts +25 -0
  7. package/dist/core/BackupManager.d.ts.map +1 -0
  8. package/dist/core/BackupManager.js +290 -0
  9. package/dist/core/BackupManager.js.map +1 -0
  10. package/dist/core/IntegrityValidator.d.ts +18 -0
  11. package/dist/core/IntegrityValidator.d.ts.map +1 -0
  12. package/dist/core/IntegrityValidator.js +212 -0
  13. package/dist/core/IntegrityValidator.js.map +1 -0
  14. package/dist/core/SecurityManager.d.ts +40 -0
  15. package/dist/core/SecurityManager.d.ts.map +1 -0
  16. package/dist/core/SecurityManager.js +320 -0
  17. package/dist/core/SecurityManager.js.map +1 -0
  18. package/dist/core/WatcherEngine.d.ts +44 -0
  19. package/dist/core/WatcherEngine.d.ts.map +1 -0
  20. package/dist/core/WatcherEngine.js +470 -0
  21. package/dist/core/WatcherEngine.js.map +1 -0
  22. package/dist/crypto/HashGenerator.d.ts +26 -0
  23. package/dist/crypto/HashGenerator.d.ts.map +1 -0
  24. package/dist/crypto/HashGenerator.js +220 -0
  25. package/dist/crypto/HashGenerator.js.map +1 -0
  26. package/dist/crypto/KeyManager.d.ts +30 -0
  27. package/dist/crypto/KeyManager.d.ts.map +1 -0
  28. package/dist/crypto/KeyManager.js +235 -0
  29. package/dist/crypto/KeyManager.js.map +1 -0
  30. package/dist/crypto/SignatureValidator.d.ts +11 -0
  31. package/dist/crypto/SignatureValidator.d.ts.map +1 -0
  32. package/dist/crypto/SignatureValidator.js +102 -0
  33. package/dist/crypto/SignatureValidator.js.map +1 -0
  34. package/dist/detectors/AnomalyDetector.d.ts +24 -0
  35. package/dist/detectors/AnomalyDetector.d.ts.map +1 -0
  36. package/dist/detectors/AnomalyDetector.js +209 -0
  37. package/dist/detectors/AnomalyDetector.js.map +1 -0
  38. package/dist/detectors/InjectionDetector.d.ts +14 -0
  39. package/dist/detectors/InjectionDetector.d.ts.map +1 -0
  40. package/dist/detectors/InjectionDetector.js +204 -0
  41. package/dist/detectors/InjectionDetector.js.map +1 -0
  42. package/dist/detectors/PatternMatcher.d.ts +28 -0
  43. package/dist/detectors/PatternMatcher.d.ts.map +1 -0
  44. package/dist/detectors/PatternMatcher.js +283 -0
  45. package/dist/detectors/PatternMatcher.js.map +1 -0
  46. package/dist/guards/FileGuard.d.ts +35 -0
  47. package/dist/guards/FileGuard.d.ts.map +1 -0
  48. package/dist/guards/FileGuard.js +357 -0
  49. package/dist/guards/FileGuard.js.map +1 -0
  50. package/dist/guards/MemoryGuard.d.ts +28 -0
  51. package/dist/guards/MemoryGuard.d.ts.map +1 -0
  52. package/dist/guards/MemoryGuard.js +256 -0
  53. package/dist/guards/MemoryGuard.js.map +1 -0
  54. package/dist/guards/ProcessGuard.d.ts +25 -0
  55. package/dist/guards/ProcessGuard.d.ts.map +1 -0
  56. package/dist/guards/ProcessGuard.js +221 -0
  57. package/dist/guards/ProcessGuard.js.map +1 -0
  58. package/dist/index.d.ts +19 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +186 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/types/index.d.ts +69 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +3 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/utils/Constants.d.ts +407 -0
  67. package/dist/utils/Constants.d.ts.map +1 -0
  68. package/dist/utils/Constants.js +505 -0
  69. package/dist/utils/Constants.js.map +1 -0
  70. package/dist/utils/Logger.d.ts +45 -0
  71. package/dist/utils/Logger.d.ts.map +1 -0
  72. package/dist/utils/Logger.js +285 -0
  73. package/dist/utils/Logger.js.map +1 -0
  74. package/dist/utils/Validator.d.ts +27 -0
  75. package/dist/utils/Validator.d.ts.map +1 -0
  76. package/dist/utils/Validator.js +245 -0
  77. package/dist/utils/Validator.js.map +1 -0
  78. package/favicon.png +0 -0
  79. package/jest.config.js +69 -0
  80. package/package.json +69 -0
  81. package/src/core/BackupManager.ts +305 -0
  82. package/src/core/IntegrityValidator.ts +200 -0
  83. package/src/core/SecurityManager.ts +348 -0
  84. package/src/core/WatcherEngine.ts +537 -0
  85. package/src/crypto/HashGenerator.ts +234 -0
  86. package/src/crypto/KeyManager.ts +249 -0
  87. package/src/crypto/SignatureValidator.ts +76 -0
  88. package/src/detectors/AnomalyDetector.ts +247 -0
  89. package/src/detectors/InjectionDetector.ts +233 -0
  90. package/src/detectors/PatternMatcher.ts +319 -0
  91. package/src/guards/FileGuard.ts +385 -0
  92. package/src/guards/MemoryGuard.ts +263 -0
  93. package/src/guards/ProcessGuard.ts +219 -0
  94. package/src/index.ts +189 -0
  95. package/src/types/index.ts +72 -0
  96. package/src/utils/Constants.ts +532 -0
  97. package/src/utils/Logger.ts +279 -0
  98. package/src/utils/Validator.ts +248 -0
  99. package/tests/setup.ts +80 -0
  100. package/tsconfig.json +42 -0
@@ -0,0 +1,247 @@
1
+ import { Logger } from '../utils/Logger';
2
+
3
+ export class AnomalyDetector {
4
+ private readonly logger: Logger;
5
+ private readonly baseline: Map<string, any>;
6
+ private readonly anomalies: any[];
7
+ private learningMode: boolean = true;
8
+ private readonly learningPeriod: number = 3600000;
9
+
10
+ constructor() {
11
+ this.logger = Logger.getInstance();
12
+ this.baseline = new Map();
13
+ this.anomalies = [];
14
+
15
+ this.startLearning();
16
+ }
17
+
18
+ private startLearning(): void {
19
+ this.logger.info('Anomaly detector starting learning mode');
20
+
21
+ setTimeout(() => {
22
+ this.learningMode = false;
23
+ this.logger.info('Anomaly detector learning complete');
24
+ }, this.learningPeriod);
25
+ }
26
+
27
+ public async detectAnomalies(filePath: string, content: Buffer): Promise<boolean> {
28
+ try {
29
+ const anomalies: string[] = [];
30
+
31
+ if (await this.isSizeAnomaly(filePath, content.length)) {
32
+ anomalies.push('size_anomaly');
33
+ }
34
+
35
+ if (await this.isTimingAnomaly(filePath)) {
36
+ anomalies.push('timing_anomaly');
37
+ }
38
+
39
+ if (await this.isContentPatternAnomaly(content)) {
40
+ anomalies.push('pattern_anomaly');
41
+ }
42
+
43
+ if (await this.isFrequencyAnomaly(filePath)) {
44
+ anomalies.push('frequency_anomaly');
45
+ }
46
+
47
+ if (await this.isStructuralAnomaly(content)) {
48
+ anomalies.push('structural_anomaly');
49
+ }
50
+
51
+ if (anomalies.length > 0) {
52
+ this.anomalies.push({
53
+ filePath,
54
+ timestamp: new Date(),
55
+ anomalies,
56
+ severity: this.calculateSeverity(anomalies.length)
57
+ });
58
+
59
+ this.logger.warning(`Anomalies detected in ${filePath}`, { anomalies });
60
+ return true;
61
+ }
62
+
63
+ return false;
64
+ } catch (error) {
65
+ this.logger.error('Error detecting anomalies', { error });
66
+ return true;
67
+ }
68
+ }
69
+
70
+ private async isSizeAnomaly(filePath: string, newSize: number): Promise<boolean> {
71
+ const stats = await this.getFileStats(filePath);
72
+ if (!stats) return false;
73
+
74
+ const avgSize = stats.sizes.reduce((a: number, b: number) => a + b, 0) / stats.sizes.length;
75
+ const stdDev = this.calculateStdDev(stats.sizes, avgSize);
76
+
77
+ return Math.abs(newSize - avgSize) > (stdDev * 3);
78
+ }
79
+
80
+ private async isTimingAnomaly(filePath: string): Promise<boolean> {
81
+ const stats = await this.getFileStats(filePath);
82
+ if (!stats) return false;
83
+
84
+ const now = Date.now();
85
+ const lastAccess = stats.lastAccess || now;
86
+ const timeDiff = now - lastAccess;
87
+
88
+ const hour = new Date().getHours();
89
+ if (hour >= 1 && hour <= 4) {
90
+ return timeDiff < 300000;
91
+ }
92
+
93
+ return false;
94
+ }
95
+
96
+ private async isContentPatternAnomaly(content: Buffer): Promise<boolean> {
97
+ const contentStr = content.toString();
98
+
99
+ const charDistribution = this.getCharacterDistribution(contentStr);
100
+
101
+ const normalDistribution = this.getNormalDistribution();
102
+
103
+ let deviation = 0;
104
+ for (const [char, count] of charDistribution) {
105
+ const normalCount = normalDistribution.get(char) || 0;
106
+ deviation += Math.abs(count - normalCount);
107
+ }
108
+
109
+ return deviation > 100;
110
+ }
111
+
112
+ private async isFrequencyAnomaly(filePath: string): Promise<boolean> {
113
+ const stats = await this.getFileStats(filePath);
114
+ if (!stats) return false;
115
+
116
+ const now = Date.now();
117
+ const recentAccesses = stats.accessTimes.filter(
118
+ (time: number) => now - time < 60000
119
+ );
120
+
121
+ return recentAccesses.length > 10;
122
+ }
123
+
124
+ private async isStructuralAnomaly(content: Buffer): Promise<boolean> {
125
+ if (content.length < 100) return false;
126
+
127
+ const bytes = Array.from(content);
128
+
129
+ let maxRunLength = 0;
130
+ let currentRun = 1;
131
+
132
+ for (let i = 1; i < bytes.length; i++) {
133
+ if (bytes[i] === bytes[i - 1]) {
134
+ currentRun++;
135
+ maxRunLength = Math.max(maxRunLength, currentRun);
136
+ } else {
137
+ currentRun = 1;
138
+ }
139
+ }
140
+
141
+ return maxRunLength > 100;
142
+ }
143
+
144
+ private async getFileStats(filePath: string): Promise<any> {
145
+ if (!this.baseline.has(filePath)) {
146
+ this.baseline.set(filePath, {
147
+ sizes: [],
148
+ accessTimes: [],
149
+ lastAccess: null,
150
+ firstSeen: new Date()
151
+ });
152
+ }
153
+
154
+ return this.baseline.get(filePath);
155
+ }
156
+
157
+ private getCharacterDistribution(text: string): Map<string, number> {
158
+ const distribution = new Map<string, number>();
159
+
160
+ for (const char of text) {
161
+ distribution.set(char, (distribution.get(char) || 0) + 1);
162
+ }
163
+
164
+ return distribution;
165
+ }
166
+
167
+ private getNormalDistribution(): Map<string, number> {
168
+ const normal = new Map<string, number>();
169
+ normal.set('e', 12.7);
170
+ normal.set('t', 9.1);
171
+ normal.set('a', 8.2);
172
+ normal.set('o', 7.5);
173
+ normal.set('i', 7.0);
174
+ normal.set('n', 6.7);
175
+ normal.set('s', 6.3);
176
+ normal.set('h', 6.1);
177
+ normal.set('r', 6.0);
178
+ normal.set('d', 4.3);
179
+ normal.set('l', 4.0);
180
+ normal.set('c', 2.8);
181
+ normal.set('u', 2.8);
182
+ normal.set('m', 2.4);
183
+ normal.set('w', 2.4);
184
+ normal.set('f', 2.2);
185
+ normal.set('g', 2.0);
186
+ normal.set('y', 2.0);
187
+ normal.set('p', 1.9);
188
+ normal.set('b', 1.5);
189
+ normal.set('v', 1.0);
190
+ normal.set('k', 0.8);
191
+ normal.set('j', 0.2);
192
+ normal.set('x', 0.2);
193
+ normal.set('q', 0.1);
194
+ normal.set('z', 0.1);
195
+
196
+ return normal;
197
+ }
198
+
199
+ private calculateStdDev(values: number[], mean: number): number {
200
+ const squareDiffs = values.map(value => Math.pow(value - mean, 2));
201
+ const avgSquareDiff = squareDiffs.reduce((a, b) => a + b, 0) / squareDiffs.length;
202
+ return Math.sqrt(avgSquareDiff);
203
+ }
204
+
205
+ private calculateSeverity(anomalyCount: number): string {
206
+ if (anomalyCount >= 4) return 'critical';
207
+ if (anomalyCount >= 2) return 'high';
208
+ return 'medium';
209
+ }
210
+
211
+ public updateBaseline(filePath: string, content: Buffer): void {
212
+ if (!this.learningMode) return;
213
+
214
+ const stats = this.baseline.get(filePath) || {
215
+ sizes: [],
216
+ accessTimes: [],
217
+ lastAccess: null,
218
+ firstSeen: new Date()
219
+ };
220
+
221
+ stats.sizes.push(content.length);
222
+ stats.accessTimes.push(Date.now());
223
+ stats.lastAccess = Date.now();
224
+
225
+ if (stats.sizes.length > 100) {
226
+ stats.sizes.shift();
227
+ }
228
+ if (stats.accessTimes.length > 100) {
229
+ stats.accessTimes.shift();
230
+ }
231
+
232
+ this.baseline.set(filePath, stats);
233
+ }
234
+
235
+ public getAnomalies(): any[] {
236
+ return [...this.anomalies];
237
+ }
238
+
239
+ public getStatus(): any {
240
+ return {
241
+ learningMode: this.learningMode,
242
+ baselineCount: this.baseline.size,
243
+ anomaliesDetected: this.anomalies.length,
244
+ learningPeriod: this.learningPeriod
245
+ };
246
+ }
247
+ }
@@ -0,0 +1,233 @@
1
+ import { Logger } from '../utils/Logger';
2
+
3
+ export class InjectionDetector {
4
+ private readonly logger: Logger;
5
+
6
+ private readonly suspiciousPatterns = [
7
+ /eval\s*\(/i,
8
+ /Function\s*\(/i,
9
+ /setTimeout\s*\(\s*['"`]/i,
10
+ /setInterval\s*\(\s*['"`]/i,
11
+ /new\s+Function\s*\(/i,
12
+ /require\(['"][^'"]+['"]\)/i,
13
+ /process\.(binding|dlopen|kill)/i,
14
+ /child_process/,
15
+ /exec(File)?(Sync)?\s*\(/i,
16
+ /spawn(Sync)?\s*\(/i,
17
+ /fork\s*\(/i,
18
+ /vm\.(runIn|create)/i,
19
+ /\[\s*[\s\S]{100,}\s*\]/,
20
+ /String\.fromCharCode/,
21
+ /unescape\s*\(/i,
22
+ /escape\s*\(/i,
23
+ /decodeURI(Component)?\s*\(/i,
24
+ /atob\s*\(/i,
25
+ /btoa\s*\(/i,
26
+ /Buffer\.from\s*\(/i,
27
+ /new\s+Buffer\s*\(/i,
28
+ /__defineGetter__/,
29
+ /__defineSetter__/,
30
+ /__lookupGetter__/,
31
+ /__lookupSetter__/,
32
+ /Object\.(defineProperty|defineProperties)\s*\([^)]*(?:writable:\s*true|configurable:\s*true)/i,
33
+ /Reflect\.(set|defineProperty)/i,
34
+ /Proxy\s*\(/i,
35
+ /WeakMap|WeakSet/,
36
+ /FinalizationRegistry/,
37
+ /WebAssembly/,
38
+ /SharedArrayBuffer/,
39
+ /Atomics\./,
40
+ /globalThis/,
41
+ /global\s*\[/,
42
+ /this\.constructor/,
43
+ /\[\s*['"`]__proto__['"`]\s*\]/i,
44
+ /Object\.setPrototypeOf/,
45
+ /module\.constructor\._load/,
46
+ /process\.mainModule/,
47
+ /require\.cache/,
48
+ /module\.children/,
49
+ /\[\s*['"`]length['"`]\s*\]/
50
+ ];
51
+
52
+ private readonly malwareSignatures = [
53
+ 'Injection by',
54
+ 'Bypass',
55
+ 'bypass',
56
+ 'Injeksi',
57
+ 'injeksi',
58
+ 'Ultra-Audit V80',
59
+ 'Ghost-FS',
60
+ 'b64'
61
+ ];
62
+
63
+ constructor() {
64
+ this.logger = Logger.getInstance();
65
+ }
66
+
67
+ public async detectInjection(content: string): Promise<boolean> {
68
+ try {
69
+ if (this.hasMalwareSignature(content)) {
70
+ this.logger.warning('Malware signature detected');
71
+ return true;
72
+ }
73
+
74
+ if (this.hasSuspiciousPatterns(content)) {
75
+ this.logger.warning('Suspicious pattern detected');
76
+ return true;
77
+ }
78
+
79
+ if (this.hasEncodedContent(content)) {
80
+ this.logger.warning('Encoded content detected');
81
+ return true;
82
+ }
83
+
84
+ if (this.isObfuscated(content)) {
85
+ this.logger.warning('Obfuscated code detected');
86
+ return true;
87
+ }
88
+
89
+ if (this.isSelfModifying(content)) {
90
+ this.logger.warning('Self-modifying code detected');
91
+ return true;
92
+ }
93
+
94
+ return false;
95
+ } catch (error) {
96
+ this.logger.error('Injection detection error', { error });
97
+ return true;
98
+ }
99
+ }
100
+
101
+ private hasMalwareSignature(content: string): boolean {
102
+ return this.malwareSignatures.some(signature =>
103
+ content.includes(signature)
104
+ );
105
+ }
106
+
107
+ private hasSuspiciousPatterns(content: string): boolean {
108
+ let suspiciousCount = 0;
109
+
110
+ for (const pattern of this.suspiciousPatterns) {
111
+ const matches = content.match(new RegExp(pattern.source, 'g')) || [];
112
+ suspiciousCount += matches.length;
113
+
114
+ if (suspiciousCount > 5) {
115
+ return true;
116
+ }
117
+ }
118
+
119
+ return false;
120
+ }
121
+
122
+ private hasEncodedContent(content: string): boolean {
123
+ const base64Pattern = /[A-Za-z0-9+/]{50,}={0,2}/g;
124
+ const base64Matches = content.match(base64Pattern) || [];
125
+
126
+ for (const match of base64Matches) {
127
+ try {
128
+ const decoded = Buffer.from(match, 'base64').toString();
129
+ if (this.hasSuspiciousPatterns(decoded)) {
130
+ return true;
131
+ }
132
+ } catch {
133
+ }
134
+ }
135
+
136
+ const hexPattern = /[0-9a-fA-F]{50,}/g;
137
+ const hexMatches = content.match(hexPattern) || [];
138
+
139
+ for (const match of hexMatches) {
140
+ try {
141
+ const decoded = Buffer.from(match, 'hex').toString();
142
+ if (this.hasSuspiciousPatterns(decoded)) {
143
+ return true;
144
+ }
145
+ } catch {
146
+ }
147
+ }
148
+
149
+ const urlEncodedPattern = /%[0-9a-fA-F]{2}/g;
150
+ const urlMatches = content.match(urlEncodedPattern) || [];
151
+
152
+ if (urlMatches.length > 20) {
153
+ try {
154
+ const decoded = decodeURIComponent(content);
155
+ if (this.hasSuspiciousPatterns(decoded)) {
156
+ return true;
157
+ }
158
+ } catch {
159
+ }
160
+ }
161
+
162
+ return false;
163
+ }
164
+
165
+ private isObfuscated(content: string): boolean {
166
+ const entropy = this.calculateEntropy(content);
167
+ if (entropy > 6.5) {
168
+ return true;
169
+ }
170
+
171
+ const varNamePattern = /(?:var|let|const)\s+([a-zA-Z_$][0-9a-zA-Z_$]*)/g;
172
+ const varNames: string[] = [];
173
+ let match;
174
+
175
+ while ((match = varNamePattern.exec(content)) !== null) {
176
+ if (match[1]) {
177
+ varNames.push(match[1]);
178
+ }
179
+ }
180
+
181
+ const avgVarLength = varNames.reduce((sum, name) => sum + name.length, 0) / varNames.length;
182
+ if (avgVarLength > 15) {
183
+ return true;
184
+ }
185
+
186
+ const lines = content.split('\n');
187
+ if (lines.length === 1 && content.length > 1000) {
188
+ return true;
189
+ }
190
+
191
+ const bracketCount = (content.match(/[{}()[\]]/g) || []).length;
192
+ const bracketRatio = bracketCount / content.length;
193
+ if (bracketRatio > 0.3) {
194
+ return true;
195
+ }
196
+
197
+ return false;
198
+ }
199
+
200
+ private isSelfModifying(content: string): boolean {
201
+ const selfModifyingPatterns = [
202
+ /Function\s*\(['"`][^)]*['"`]\s*\)/,
203
+ /eval\s*\(/,
204
+ /new\s+Function/,
205
+ /writeFileSync.*__filename/,
206
+ /unlinkSync.*__filename/,
207
+ /require\(['"`]fs['"`]\)/,
208
+ /process\.argv/,
209
+ /module\.exports\s*=/,
210
+ /exports\.[a-zA-Z_]+\s*=/
211
+ ];
212
+
213
+ return selfModifyingPatterns.some(pattern => pattern.test(content));
214
+ }
215
+
216
+ private calculateEntropy(content: string): number {
217
+ const frequencies: { [key: string]: number } = {};
218
+
219
+ for (const char of content) {
220
+ frequencies[char] = (frequencies[char] || 0) + 1;
221
+ }
222
+
223
+ let entropy = 0;
224
+ const length = content.length;
225
+
226
+ for (const freq of Object.values(frequencies)) {
227
+ const probability = freq / length;
228
+ entropy -= probability * Math.log2(probability);
229
+ }
230
+
231
+ return entropy;
232
+ }
233
+ }