stella-coder 5.3.0 → 5.3.2

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 (52) hide show
  1. package/COMMANDS.md +47 -0
  2. package/install-av.bat +17 -0
  3. package/install-stella-pkg.bat +21 -0
  4. package/oneline-av.ps1 +7 -0
  5. package/oneline-stella.ps1 +2 -0
  6. package/package.json +1 -1
  7. package/releases/stella-antivirus/database.mjs +871 -0
  8. package/releases/stella-antivirus/index.mjs +8 -0
  9. package/releases/stella-antivirus/install-av.bat +12 -0
  10. package/releases/stella-antivirus/scanner.mjs +591 -0
  11. package/releases/stella-antivirus/ui.mjs +570 -0
  12. package/releases/stella-antivirus.zip +0 -0
  13. package/releases/stella-coder/README.md +67 -0
  14. package/releases/stella-coder/adb.mjs +200 -0
  15. package/releases/stella-coder/autonomous-agent.mjs +550 -0
  16. package/releases/stella-coder/banner.mjs +46 -0
  17. package/releases/stella-coder/browser-control.mjs +274 -0
  18. package/releases/stella-coder/build.mjs +151 -0
  19. package/releases/stella-coder/charts.mjs +411 -0
  20. package/releases/stella-coder/coding-brain.mjs +753 -0
  21. package/releases/stella-coder/game-engine.mjs +708 -0
  22. package/releases/stella-coder/gdrive-backup.mjs +338 -0
  23. package/releases/stella-coder/git-api.mjs +407 -0
  24. package/releases/stella-coder/gmail.mjs +415 -0
  25. package/releases/stella-coder/home-assistant.mjs +168 -0
  26. package/releases/stella-coder/index.mjs +5810 -0
  27. package/releases/stella-coder/install-stella.bat +12 -0
  28. package/releases/stella-coder/markdown.mjs +100 -0
  29. package/releases/stella-coder/mcp.mjs +296 -0
  30. package/releases/stella-coder/package.json +67 -0
  31. package/releases/stella-coder/presentations.mjs +1106 -0
  32. package/releases/stella-coder/protect.mjs +182 -0
  33. package/releases/stella-coder/screen-monitor.mjs +334 -0
  34. package/releases/stella-coder/sea-config.json +5 -0
  35. package/releases/stella-coder/security.mjs +237 -0
  36. package/releases/stella-coder/subagents.mjs +142 -0
  37. package/releases/stella-coder/telegram-bot.mjs +824 -0
  38. package/releases/stella-coder/tg-server.mjs +116 -0
  39. package/releases/stella-coder/theme.mjs +91 -0
  40. package/releases/stella-coder/tools.mjs +3143 -0
  41. package/releases/stella-coder/web-parser.mjs +229 -0
  42. package/releases/stella-coder/yandex-maps.mjs +426 -0
  43. package/releases/stella-coder.zip +0 -0
  44. package/run-antivirus.bat +4 -0
  45. package/setup-antivirus.bat +64 -0
  46. package/setup-full.bat +65 -0
  47. package/setup-stella.bat +46 -0
  48. package/stella-cli/game-engine.mjs +2 -2
  49. package/stella-cli/index.mjs +11 -1
  50. package/stella-cli/protect.mjs +182 -0
  51. package/stella.bat +3 -0
  52. package/tests/test-modules.mjs +101 -0
@@ -0,0 +1,871 @@
1
+ import crypto from "node:crypto"
2
+ import path from "node:path"
3
+ import fs from "node:fs"
4
+
5
+ // ═══════════════════════════════════════════════════════════════
6
+ // STELLAR ANTIVIRUS — Threat Database v3
7
+ // Full AV engine — 100+ signatures, YARA, heuristics
8
+ // ═══════════════════════════════════════════════════════════════
9
+
10
+ const BINARY_EXTS = new Set([
11
+ ".exe", ".dll", ".sys", ".com", ".scr", ".pif",
12
+ ".bat", ".cmd", ".vbs", ".vbe", ".jse", ".wsf", ".wsh",
13
+ ".hta", ".cpl", ".msi", ".msp", ".mst",
14
+ ".jar", ".class", ".war",
15
+ ".doc", ".docm", ".xls", ".xlsm", ".ppt", ".pptm",
16
+ ".rtf", ".pdf",
17
+ ])
18
+
19
+ export const SKIP_DIRS = new Set([
20
+ "node_modules", ".git", ".next", ".vercel", "__pycache__",
21
+ ".stella", ".secure", ".cache", "dist", "build", ".turbo",
22
+ "coverage", ".DS_Store", "antimalware",
23
+ "SoftwareDistribution", "WinSxS", "Installer", "$Recycle.Bin",
24
+ "System Volume Information", "Recovery",
25
+ "node-compile-cache", "npm-cache", "pip-cache",
26
+ "OpencodeSoftware", "opencode",
27
+ ])
28
+
29
+ export const QUICK_SCAN_PATHS = [
30
+ "C:\\Users\\%USERNAME%\\AppData\\Local\\Temp",
31
+ "C:\\Users\\%USERNAME%\\Downloads",
32
+ "C:\\Users\\%USERNAME%\\AppData\\Roaming",
33
+ "C:\\Users\\%USERNAME%\\Desktop",
34
+ "C:\\Users\\%USERNAME%\\Documents",
35
+ "C:\\Windows\\Temp",
36
+ "C:\\Windows\\System32\\drivers\\etc",
37
+ "C:\\ProgramData",
38
+ "C:\\Users\\%USERNAME%\\AppData\\Local\\Microsoft\\Windows\\Startup",
39
+ "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
40
+ "C:\\Windows\\System32\\Tasks",
41
+ ]
42
+
43
+ // ═══════════════════════════════════════════════════════════════
44
+ // SIGNATURES — 100+ detection patterns
45
+ // ═══════════════════════════════════════════════════════════════
46
+
47
+ export const SIGNATURES = [
48
+ // ══════ PE INFECTORS ══════
49
+ { id: "SIG-001", name: "PE感染者", severity: "critical", category: "trojan",
50
+ pattern: /\x4D\x5A[\s\S]{0,200}\x50\x45\x00\x00[\s\S]{0,500}(\x00){16,}/ },
51
+
52
+ { id: "SIG-002", name: "Пакер/Crypter", severity: "critical", category: "trojan",
53
+ pattern: /\x4D\x5A[\s\S]{0,100}(UPX|ASPack|PECompact|Themida|VMProtect|Obsidium|Armadillo)/ },
54
+
55
+ { id: "SIG-003", name: "Dropper", severity: "critical", category: "trojan",
56
+ pattern: /(CreateFile|WriteFile)[\s\S]{0,200}(\.exe|\.dll|\.sys)[\s\S]{0,200}(CreateProcess|ShellExecute)/s },
57
+
58
+ // ══════ PROCESS INJECTION ══════
59
+ { id: "SIG-004", name: "Process Hollowing", severity: "critical", category: "injection",
60
+ pattern: /NtUnmapViewOfSection|ZwUnmapViewOfSection|RtlCreateUserThread|NtCreateThreadEx[\s\S]{0,100}CreateRemoteThread/s },
61
+
62
+ { id: "SIG-005", name: "Inject в системный процесс", severity: "critical", category: "injection",
63
+ pattern: /OpenProcess[\s\S]{0,100}(PROCESS_ALL_ACCESS|PROCESS_CREATE_THREAD)[\s\S]{0,100}WriteProcessMemory[\s\S]{0,100}CreateRemoteThread/s },
64
+
65
+ { id: "SIG-006", name: "APC Injection", severity: "critical", category: "injection",
66
+ pattern: /QueueUserAPC|NtQueueApcThread|EkalertRegisterAlertCallback[\s\S]{0,100}VirtualAllocEx/s },
67
+
68
+ { id: "SIG-007", name: "Thread Hijacking", severity: "critical", category: "injection",
69
+ pattern: /SuspendThread[\s\S]{0,100}GetThreadContext[\s\S]{0,100}SetThreadContext[\s\S]{0,100}ResumeThread/s },
70
+
71
+ { id: "SIG-008", name: "Reflective DLL Loading", severity: "critical", category: "injection",
72
+ pattern: /LoadLibraryA[\s\S]{0,100}GetProcAddress[\s\S]{0,100}(DllMain|EntryPoint)[\s\S]{0,100}VirtualProtect/s },
73
+
74
+ // ══════ KEYLOGGERS ══════
75
+ { id: "SIG-009", name: "Keylogger API", severity: "critical", category: "spyware",
76
+ pattern: /SetWindowsHookEx[\s\S]{0,50}(WH_KEYBOARD|WH_KEYBOARD_LL|WH_MOUSE)[\s\S]{0,100}(GetAsyncKeyState|GetKeyState)/ },
77
+
78
+ { id: "SIG-010", name: "Clipboard theft", severity: "high", category: "spyware",
79
+ pattern: /GetClipboardData[\s\S]{0,100}(GlobalLock|GlobalAlloc)[\s\S]{0,100}(InternetOpen|HttpSendRequest)/ },
80
+
81
+ { id: "SIG-011", name: "Screen capture + exfil", severity: "critical", category: "spyware",
82
+ pattern: /(BitBlt|GetDC|CreateCompatibleBitmap)[\s\S]{0,200}(JpegEncoder|PngEncoder|SaveToFile)[\s\S]{0,200}(http|ftp|socket)/s },
83
+
84
+ // ══════ CREDENTIAL THEFT ══════
85
+ { id: "SIG-012", name: "LSASS дамп", severity: "critical", category: "credential-theft",
86
+ pattern: /MiniDumpWriteDump[\s\S]{0,100}(lsass|csrss|svchost)/ },
87
+
88
+ { id: "SIG-013", name: "Mimikatz загрузка", severity: "critical", category: "credential-theft",
89
+ pattern: /Invoke-Mimikatz|mimikatz[\s\S]{0,50}sekurlsa::logonpasswords|gentilkiwi/ },
90
+
91
+ { id: "SIG-014", name: "Browser password theft", severity: "critical", category: "credential-theft",
92
+ pattern: /(Login Data|logins\.json|cookies\.sqlite|signons\.sqlite)[\s\S]{0,200}(sqlite3_open|ReadFile)[\s\S]{0,200}(http|ftp)/s },
93
+
94
+ { id: "SIG-015", name: "Криптокошелёк кража", severity: "critical", category: "credential-theft",
95
+ pattern: /(wallet\.dat|Electrum|Bitcoin|Ethereum|MetaMask)[\s\S]{0,200}(CopyFile|MoveFile|ReadFile)[\s\S]{0,200}(http|ftp|socket)/s },
96
+
97
+ { id: "SIG-016", name: "Certificate theft", severity: "high", category: "credential-theft",
98
+ pattern: /(certutil|CertOpenStore|PFX|PKCS12)[\s\S]{0,100}(Export|export|CopyFile)[\s\S]{0,100}(http|ftp)/ },
99
+
100
+ // ══════ RANSOMWARE ══════
101
+ { id: "SIG-017", name: "Ransomware шифрование", severity: "critical", category: "ransomware",
102
+ pattern: /(AES|DES|RSA|ChaCha20|Salsa20|XOR)[\s\S]{0,100}(CreateFile|WriteFile)[\s\S]{0,100}\.(locked|encrypted|crypto|cerber|cerber3)/ },
103
+
104
+ { id: "SIG-018", name: "Восстановление удалено", severity: "critical", category: "ransomware",
105
+ pattern: /vssadmin[\s\S]*delete[\s\S]*shadows|bcdedit[\s\S]*set[\s\S]*recoveryenabled\s+no|wbadmin[\s\S]*delete[\s\S]*catalog/ },
106
+
107
+ { id: "SIG-019", name: "Ransomware note", severity: "critical", category: "ransomware",
108
+ pattern: /(your files have been encrypted|pay the ransom|bitcoin wallet|decrypt your files|send bitcoin|files will be deleted)[\s\S]{0,500}(tor|onion|bitcoin|monero)/is },
109
+
110
+ { id: "SIG-020", name: "Extension changer", severity: "critical", category: "ransomware",
111
+ pattern: /(rename|MoveFileEx|SetFileAttributes)[\s\S]{0,100}\.(locked|crypt|enc|encrypted|crypto|cerber|locky|wannacry)/ },
112
+
113
+ // ══════ ROOTKIT ══════
114
+ { id: "SIG-021", name: "Kernel rootkit", severity: "critical", category: "rootkit",
115
+ pattern: /NtQuerySystemInformation[\s\S]{0,100}ZwQuerySystemInformation[\s\S]{0,100}(SSDT|IDT|IAT|DKOM)/ },
116
+
117
+ { id: "SIG-022", name: "Hide process", severity: "critical", category: "rootkit",
118
+ pattern: /NtSetInformationProcess[\s\S]{0,100}ProcessDebugPort|ZwQueryInformationProcess[\s\S]{0,100}ProcessDebugFlags/ },
119
+
120
+ { id: "SIG-023", name: "Hide file", severity: "critical", category: "rootkit",
121
+ pattern: /NtQueryDirectoryFile[\s\S]{0,100}FILE_BOTH_DIR_INFORMATION[\s\S]{0,100}NextEntryOffset/ },
122
+
123
+ { id: "SIG-024", name: "SSDT hook", severity: "critical", category: "rootkit",
124
+ pattern: /KeServiceDescriptorTable[\s\S]{0,100}(hook|detour|trampoline|patch)/ },
125
+
126
+ // ══════ BACKDOORS ══════
127
+ { id: "SIG-025", name: "Bind shell", severity: "critical", category: "backdoor",
128
+ pattern: /socket[\s\S]{0,100}bind[\s\S]{0,100}listen[\s\S]{0,100}accept[\s\S]{0,100}(cmd|bash|sh)[\s\S]{0,50}(dup2|SOCK_STREAM)/ },
129
+
130
+ { id: "SIG-026", name: "Reverse shell", severity: "critical", category: "backdoor",
131
+ pattern: /socket[\s\S]{0,100}connect[\s\S]{0,100}\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[\s\S]{0,100}(cmd|bash|sh)[\s\S]{0,50}dup2/ },
132
+
133
+ { id: "SIG-027", name: "Webshell PHP", severity: "critical", category: "backdoor",
134
+ pattern: /\$_(POST|GET|REQUEST|COOKIE)\[[\s\S]{0,50}\]\s*\([\s\S]{0,100}(eval|exec|system|passthru|shell_exec|popen|proc_open)\s*\(/ },
135
+
136
+ { id: "SIG-028", name: "Webshell ASP", severity: "critical", category: "backdoor",
137
+ pattern: /eval\s*\(\s*Request[\s\S]{0,50}(Execute|CreateObject)[\s\S]{0,50}WScript\.Shell/ },
138
+
139
+ { id: "SIG-029", name: "Webshell JSP", severity: "critical", category: "backdoor",
140
+ pattern: /Runtime\.getRuntime\(\)\.exec[\s\S]{0,50}(cmd|bash)[\s\S]{0,50}(Process|InputStream)/ },
141
+
142
+ { id: "SIG-030", name: "IRC Botnet", severity: "high", category: "botnet",
143
+ pattern: /PRIVMSG\s*#\w+\s*:\s*\x01[\s\S]{0,100}(JOIN|NICK|USER)[\s\S]{0,50}\.join\(|\.on\('data'/ },
144
+
145
+ // ══════ EXPLOITS ══════
146
+ { id: "SIG-031", name: "Metasploit стейджинг", severity: "critical", category: "exploit",
147
+ pattern: /msfvenom[\s\S]{0,100}reverse[\s\S]{0,50}(tcp|http|https)[\s\S]{0,100}(meterpreter|shell|vnc)/ },
148
+
149
+ { id: "SIG-032", name: "Meterpreter payload", severity: "critical", category: "exploit",
150
+ pattern: /meterpreter[\s\S]{0,100}(reverse_tcp|reverse_http|reverse_https)[\s\S]{0,100}(LHOST|LPORT)/ },
151
+
152
+ { id: "SIG-033", name: "Shellcode detector", severity: "critical", category: "exploit",
153
+ pattern: /(\x31\xc0|\x31\xdb|\x31\xc9|\x31\xd2|\x90{8,})[\s\S]{0,50}(\\x6a|\\x58|\\xcd|\\x80)/ },
154
+
155
+ { id: "SIG-034", name: "ROP chain", severity: "high", category: "exploit",
156
+ pattern: /gadget[\s\S]{0,50}(pop[\s\S]{0,20}ret|call[\s\S]{0,20}eax|jmp[\s\S]{0,20}esp)/ },
157
+
158
+ // ══════ PRIVILEGE ESCALATION ══════
159
+ { id: "SIG-035", name: "UAC bypass", severity: "critical", category: "privesc",
160
+ pattern: /(fodhelper|eventvwr|computerdefaults|sdclt|slui)[\s\S]{0,100}(ms-settings|HKCU|CurrentVersion)\\Run/ },
161
+
162
+ { id: "SIG-036", name: "Token impersonation", severity: "critical", category: "privesc",
163
+ pattern: /ImpersonateLoggedOnUser|DuplicateTokenEx|SetThreadToken[\s\S]{0,100}(AdjustTokenPrivileges|SeDebugPrivilege)/ },
164
+
165
+ { id: "SIG-037", name: "Service install", severity: "high", category: "privesc",
166
+ pattern: /CreateService[\s\S]{0,100}(SERVICE_AUTO_START|SERVICE_WIN32_OWN_PROCESS)[\s\S]{0,100}(cmd|powershell|bash)/ },
167
+
168
+ // ══════ ANTI-ANALYSIS ══════
169
+ { id: "SIG-038", name: "VM detection", severity: "high", category: "anti-analysis",
170
+ pattern: /(VMware|VirtualBox|QEMU|Hyper-V|Xen)[\s\S]{0,100}(CPUID|cpuid|__cpuid|vmexit|vmcall)/ },
171
+
172
+ { id: "SIG-039", name: "Debugger detection", severity: "high", category: "anti-analysis",
173
+ pattern: /IsDebuggerPresent|CheckRemoteDebuggerPresent|NtQueryInformationProcess[\s\S]{0,100}ProcessDebugPort/ },
174
+
175
+ { id: "SIG-040", name: "Sandbox detection", severity: "high", category: "anti-analysis",
176
+ pattern: /(NtQuerySystemInformation|GetTickCount|timeGetTime)[\s\S]{0,100}(anti-vm|anti-debug|sandbox|sleep|delay)/i },
177
+
178
+ { id: "SIG-041", name: "AMSI bypass", severity: "critical", category: "anti-analysis",
179
+ pattern: /AmsiUtils[\s\S]{0,100}amsiInitFailed|AmsiScanBuffer[\s\S]{0,100}0x80070057|SetProcessMitigationPolicy[\s\S]{0,50}DisableDynamicCode/ },
180
+
181
+ { id: "SIG-042", name: "ETW patch", severity: "critical", category: "anti-analysis",
182
+ pattern: /EtwEventWrite[\s\S]{0,100}(patch|nop|ret|0xc3)|NtTraceEvent[\s\S]{0,100}(hook|detour)/ },
183
+
184
+ // ══════ PERSISTENCE ══════
185
+ { id: "SIG-043", name: "Registry Run key", severity: "high", category: "persistence",
186
+ pattern: /CurrentVersion\\Run[\s\S]{0,100}(cmd|powershell|bash|python|perl|wscript|cscript)/ },
187
+
188
+ { id: "SIG-044", name: "Scheduled task", severity: "high", category: "persistence",
189
+ pattern: /schtasks[\s\S]{0,100}(\/create|\/Create)[\s\S]{0,100}(cmd|powershell|bash|python|perl)/ },
190
+
191
+ { id: "SIG-045", name: "Startup folder", severity: "high", category: "persistence",
192
+ pattern: /\\Start Menu\\Programs\\Startup[\s\S]{0,100}\.(exe|bat|cmd|vbs|ps1|js)/ },
193
+
194
+ { id: "SIG-046", name: "WMI subscription", severity: "high", category: "persistence",
195
+ pattern: /CommandLineEventConsumer[\s\S]{0,100}(cmd|powershell|bash|python|perl)/ },
196
+
197
+ { id: "SIG-047", name: "Service DLL hijack", severity: "high", category: "persistence",
198
+ pattern: /ServiceDll[\s\S]{0,100}(HKLM|HKCU)[\s\S]{0,100}\\(cmd|powershell|bash|python|perl)/ },
199
+
200
+ // ══════ NETWORK BACKDOORS ══════
201
+ { id: "SIG-048", name: "Reverse TCP", severity: "critical", category: "backdoor",
202
+ pattern: /socket[\s\S]{0,100}connect[\s\S]{0,100}\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[\s\S]{0,100}(SOCK_STREAM|SOCK_DGRAM)/ },
203
+
204
+ { id: "SIG-049", name: "Reverse HTTP", severity: "high", category: "backdoor",
205
+ pattern: /InternetOpen[\s\S]{0,100}HttpOpenRequest[\s\S]{0,100}(POST|PUT)[\s\S]{0,100}(cmd|bash|powershell)/ },
206
+
207
+ { id: "SIG-050", name: "DNS tunneling", severity: "high", category: "backdoor",
208
+ pattern: /DnsQuery[\s\S]{0,100}(TXT|MX|CNAME)[\s\S]{0,100}(encode|decode|base64)[\s\S]{0,100}(socket|connect)/ },
209
+
210
+ // ══════ OBFUSCATION ══════
211
+ { id: "SIG-051", name: "Base64 decode chain", severity: "high", category: "obfuscation",
212
+ pattern: /atob\s*\(\s*atob\s*\(|fromCharCode[\s\S]{0,50}atob|eval\s*\(\s*atob\s*\(/ },
213
+
214
+ { id: "SIG-052", name: "PowerShell download cradle", severity: "high", category: "obfuscation",
215
+ pattern: /IEX\s*\(\s*(New-Object\s+Net\.WebClient|Invoke-WebRequest|wget|curl)[\s\S]*\)|Invoke-Expression[\s\S]{0,100}(DownloadString|DownloadFile)/i },
216
+
217
+ { id: "SIG-053", name: "String building", severity: "medium", category: "obfuscation",
218
+ pattern: /String\.fromCharCode\s*\(\s*\d+[\s\S]{0,20}\d+[\s\S]{0,20}\d+[\s\S]{0,20}\d+/ },
219
+
220
+ { id: "SIG-054", name: "Hex encoding", severity: "medium", category: "obfuscation",
221
+ pattern: /\\x[0-9a-f]{2}\\x[0-9a-f]{2}\\x[0-9a-f]{2}\\x[0-9a-f]{2}\\x[0-9a-f]{2}/i },
222
+
223
+ { id: "SIG-055", name: "Dynamic eval chain", severity: "high", category: "obfuscation",
224
+ pattern: /eval\s*\(\s*(eval|Function|atob|Buffer\.from|unescape|fromCharCode)/ },
225
+
226
+ // ══════ MINERS ══════
227
+ { id: "SIG-056", name: "Crypto miner池", severity: "high", category: "miner",
228
+ pattern: /stratum\+tcp:\/\/[\w.-]+:\d{4,5}/ },
229
+
230
+ { id: "SIG-057", name: "XMRig", severity: "high", category: "miner",
231
+ pattern: /xmrig[\s\S]{0,100}(algo|coin|pool|wallet|donate-level)/ },
232
+
233
+ { id: "SIG-058", name: "Browser miner", severity: "high", category: "miner",
234
+ pattern: /coinhive[\s\S]{0,100}(CoinHive\.Worker|anonymous|captcha)|cryptoloot[\s\S]{0,100}(CryptoLoot\.Worker|anonymous)/ },
235
+
236
+ // ══════ DATA EXFILTRATION ══════
237
+ { id: "SIG-059", name: "FTP upload", severity: "high", category: "exfil",
238
+ pattern: /ftp[\s\S]{0,100}(upload|put|stor)[\s\S]{0,100}(password|passwd|secret|token|key)/ },
239
+
240
+ { id: "SIG-060", name: "HTTP POST exfil", severity: "high", category: "exfil",
241
+ pattern: /(fetch|XMLHttpRequest|axios|http\.request|request\()[\s\S]{0,200}(POST|PUT)[\s\S]{0,200}(password|token|secret|credential|cookie)/ },
242
+
243
+ { id: "SIG-061", name: "DNS exfil", severity: "high", category: "exfil",
244
+ pattern: /DnsQuery[\s\S]{0,100}(encode|encodeURI|base64)[\s\S]{0,100}(password|token|secret|credential)/ },
245
+
246
+ // ══════ WORMS ══════
247
+ { id: "SIG-062", name: "USB worm", severity: "critical", category: "worm",
248
+ pattern: /(RECYCLER|Recycle\.Bin|autorun\.inf|\\setup\.exe)[\s\S]{0,100}(CopyFile|MoveFile|CreateFile)/ },
249
+
250
+ { id: "SIG-063", name: "Network worm", severity: "critical", category: "worm",
251
+ pattern: /(NetServerEnum|NetShareEnum|WNetEnumResource|WNetOpenEnum)[\s\S]{0,100}(CopyFile|MoveFile|CreateProcess)/ },
252
+
253
+ // ══════ ADWARE / PUP ══════
254
+ { id: "SIG-064", name: "Adware inject", severity: "medium", category: "adware",
255
+ pattern: /(inject|append|prepend)[\s\S]{0,100}(ads|advertis|popup|banner|click)[\s\S]{0,100}(google|facebook|amazon|ebay)/i },
256
+
257
+ { id: "SIG-065", name: "Browser hijack", severity: "high", category: "adware",
258
+ pattern: /(startPage|searchProvider|homePage)[\s\S]{0,100}(http|https)[\s\S]{0,50}(ads|search|babylon|conduit|ask\.com)/i },
259
+
260
+ { id: "SIG-066", name: "Software Bundler", severity: "medium", category: "adware",
261
+ pattern: /(toolbar|extension|plugin)[\s\S]{0,100}(install|download|update)[\s\S]{0,100}(offer|recommend|special)/i },
262
+
263
+ // ══════ BANKING TROJANS ══════
264
+ { id: "SIG-067", name: "Web inject", severity: "critical", category: "banking",
265
+ pattern: /(inject|intercept|modify)[\s\S]{0,100}(https?:\/\/(www\.)?(bank|paypal|alipay|pay\.google))/i },
266
+
267
+ { id: "SIG-068", name: "Form grabbing", severity: "critical", category: "banking",
268
+ pattern: /(HttpSendRequest|InternetReadFile)[\s\S]{0,200}(password|login|pin|credential|account)/ },
269
+
270
+ { id: "SIG-069", name: "MITM proxy", severity: "critical", category: "banking",
271
+ pattern: /(mitmproxy|ettercap|bettercap|burp)[\s\S]{0,100}(inject|intercept|modify)[\s\S]{0,100}(http|https)/i },
272
+
273
+ // ══════ RAT (Remote Access Trojans) ══════
274
+ { id: "SIG-070", name: "RAT keylogger", severity: "critical", category: "rat",
275
+ pattern: /(GetAsyncKeyState|SetWindowsHookEx)[\s\S]{0,200}(http|ftp|socket|connect)[\s\S]{0,100}(send|write|upload)/ },
276
+
277
+ { id: "SIG-071", name: "RAT screen capture", severity: "critical", category: "rat",
278
+ pattern: /(BitBlt|GetDC|GetDesktopWindow)[\s\S]{0,200}(JpegEncoder|PngEncoder|Image\.save)[\s\S]{0,200}(http|ftp|socket)/ },
279
+
280
+ { id: "SIG-072", name: "RAT webcam", severity: "critical", category: "rat",
281
+ pattern: /(capCreateCaptureWindow|avicap32|WebCamCapture|webcam)[\s\S]{0,200}(getImageData|capture)[\s\S]{0,200}(http|ftp|socket)/ },
282
+
283
+ { id: "SIG-073", name: "RAT file manager", severity: "high", category: "rat",
284
+ pattern: /(ListFiles|GetFiles|GetDirectories|ReadDirectory)[\s\S]{0,200}(Download|Upload|Delete|Rename|Copy|Move)[\s\S]{0,200}(http|ftp|socket)/ },
285
+
286
+ { id: "SIG-074", name: "RAT command execution", severity: "critical", category: "rat",
287
+ pattern: /(cmd\.exe|powershell|bash)[\s\S]{0,100}(-c|-e|\/c)[\s\S]{0,200}(http|ftp|socket)[\s\S]{0,100}(send|write|upload)/ },
288
+
289
+ // ══════ TROJANS ══════
290
+ { id: "SIG-075", name: "Trojan downloader", severity: "critical", category: "trojan",
291
+ pattern: /(URLDownloadToFile|InternetOpen|HttpOpenRequest)[\s\S]{0,200}\.(exe|dll|scr|bat|cmd|ps1|vbs)/ },
292
+
293
+ { id: "SIG-076", name: "Trojan dropper", severity: "critical", category: "trojan",
294
+ pattern: /(CreateFile|WriteFile)[\s\S]{0,100}\.(exe|dll|scr|bat|cmd|ps1|vbs)[\s\S]{0,100}(CreateProcess|ShellExecute|WinExec)/ },
295
+
296
+ { id: "SIG-077", name: "Trojan stealer", severity: "critical", category: "trojan",
297
+ pattern: /(password|token|cookie|session|credential|secret)[\s\S]{0,200}(http|ftp|smtp|socket)[\s\S]{0,100}(POST|PUT|send|upload)/ },
298
+
299
+ { id: "SIG-078", name: "Loader/Injector", severity: "critical", category: "trojan",
300
+ pattern: /LoadLibrary[AW]?[\s\S]{0,100}GetProcAddress[\s\S]{0,100}(call|jmp|rax|eax)[\s\S]{0,100}(VirtualAlloc|VirtualProtect)/ },
301
+
302
+ // ══════ WIPERS ══════
303
+ { id: "SIG-079", name: "MBR wiper", severity: "critical", category: "wiper",
304
+ pattern: /\\\\\.\\\\PhysicalDrive0[\s\S]{0,100}(WriteFile|DeviceIoControl)[\s\S]{0,100}(erase|wipe|overwrite)/ },
305
+
306
+ { id: "SIG-080", name: "File wiper", severity: "critical", category: "wiper",
307
+ pattern: /(DeleteFile|RemoveDirectory|SHFileOperation)[\s\S]{0,200}\*\.(doc|pdf|txt|jpg|png|mp4|avi)/ },
308
+
309
+ // ══════ INFostealers ══════
310
+ { id: "SIG-081", name: "Cookie stealer", severity: "high", category: "infostealer",
311
+ pattern: /(cookies\.sqlite|Cookie|chrome.*cookies)[\s\S]{0,100}(readFile|sqlite3_open)[\s\S]{0,100}(http|ftp)/ },
312
+
313
+ { id: "SIG-082", name: "Session hijack", severity: "high", category: "infostealer",
314
+ pattern: /(session|token|cookie|jwt|bearer)[\s\S]{0,100}(steal|grab|harvest|exfiltrate|dump)/i },
315
+
316
+ // ══════ FILELESS ══════
317
+ { id: "SIG-083", name: "PowerShell fileless", severity: "critical", category: "fileless",
318
+ pattern: /powershell[\s\S]{0,100}(-enc|-EncodedCommand|-e)[\s\S]{0,200}(IEX|Invoke-Expression|DownloadString)/ },
319
+
320
+ { id: "SIG-084", name: "WMI fileless", severity: "critical", category: "fileless",
321
+ pattern: /wmic[\s\S]{0,100}(process\s+call\s+create|Win32_Process)[\s\S]{0,100}(cmd|powershell|bash)/ },
322
+
323
+ { id: "SIG-085", name: "MSHTA fileless", severity: "critical", category: "fileless",
324
+ pattern: /mshta[\s\S]{0,100}(vbscript|javascript)[\s\S]{0,100}(Execute|eval|exec)/ },
325
+
326
+ // ══════ CRYPTO TARGETS ══════
327
+ { id: "SIG-086", name: "Clipboard hijacker", severity: "high", category: "crypto",
328
+ pattern: /GetClipboardData[\s\S]{0,100}(replace|regex)[\s\S]{0,100}(bc1|1[a-km-zA-HJ-NP-Z1-9]{25,34}|0x[a-fA-F0-9]{40})/ },
329
+
330
+ { id: "SIG-087", name: "Wallet stealer", severity: "critical", category: "crypto",
331
+ pattern: /(wallet\.dat|keystore\.json|UTC--|credentials\.json)[\s\S]{0,100}(copy|read|upload|send)[\s\S]{0,100}(http|ftp)/ },
332
+
333
+ // ══════ ADDITIONAL ══════
334
+ { id: "SIG-088", name: "Encoded command", severity: "high", category: "obfuscation",
335
+ pattern: /cmd[\s\S]{0,100}(\/c|\\c|-c)[\s\S]{0,100}(powershell|bash|python)[\s\S]{0,100}(-enc|-e|--encoded)/ },
336
+
337
+ { id: "SIG-089", name: "Hidden file creation", severity: "high", category: "stealth",
338
+ pattern: /SetFileAttributes[\s\S]{0,100}(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM|0x02|0x04)/ },
339
+
340
+ { id: "SIG-090", name: "DLL search order hijack", severity: "high", category: "injection",
341
+ pattern: /SetDllDirectory[\s\S]{0,100}(""|\.|\\)[\s\S]{0,100}LoadLibrary/ },
342
+
343
+ { id: "SIG-091", name: "Process Doppelgänging", severity: "critical", category: "injection",
344
+ pattern: /NtCreateTransaction[\s\S]{0,100}NtCreateSection[\s\S]{0,100}NtMapViewOfSection[\s\S]{0,100}NtCreateThreadEx/ },
345
+
346
+ { id: "SIG-092", name: "Transacted Hollowing", severity: "critical", category: "injection",
347
+ pattern: /CreateTransaction[\s\S]{0,100}CreateFileMapping[\s\S]{0,100}MapViewOfFile[\s\S]{0,100}NtCreateThreadEx/ },
348
+
349
+ { id: "SIG-093", name: "Herpaderging", severity: "critical", category: "injection",
350
+ pattern: /WriteFile[\s\S]{0,100}FlushFileBuffers[\s\S]{0,100}NtCreateSection[\s\S]{0,100}NtMapViewOfSection/ },
351
+
352
+ { id: "SIG-094", name: "Process Ghosting", severity: "critical", category: "injection",
353
+ pattern: /CreateFile[\s\S]{0,100}FILE_DISPOSITION_FLAG[\s\S]{0,100}NtCreateSection[\s\S]{0,100}NtCreateThreadEx/ },
354
+
355
+ { id: "SIG-095", name: "Module Stomping", severity: "critical", category: "injection",
356
+ pattern: /LoadLibrary[\s\S]{0,100}GetModuleHandle[\s\S]{0,100}WriteProcessMemory[\s\S]{0,100}CreateRemoteThread/ },
357
+
358
+ { id: "SIG-096", name: "Syscall abuse", severity: "high", category: "anti-analysis",
359
+ pattern: /NtAllocateVirtualMemory[\s\S]{0,100}NtWriteVirtualMemory[\s\S]{0,100}NtProtectVirtualMemory/ },
360
+
361
+ { id: "SIG-097", name: "Direct syscalls", severity: "high", category: "anti-analysis",
362
+ pattern: /syscall[\s\S]{0,50}(NtAllocateVirtualMemory|NtWriteVirtualMemory|NtCreateThreadEx|NtProtectVirtualMemory)/ },
363
+
364
+ { id: "SIG-098", name: "Hell's Gate", severity: "high", category: "anti-analysis",
365
+ pattern: /Hell.?s.?Gate|halos.?gate|tartarus.?gate|freshly.?gate/i },
366
+
367
+ { id: "SIG-099", name: "SysWhispers", severity: "high", category: "anti-analysis",
368
+ pattern: /SysWhispers[\s\S]{0,100}(NtAllocateVirtualMemory|NtWriteVirtualMemory|NtCreateThreadEx)/ },
369
+
370
+ { id: "SIG-100", name: "Callback abuse", severity: "high", category: "anti-analysis",
371
+ pattern: /EnumChildWindows[\s\S]{0,100}EnumWindows[\s\S]{0,100}EnumThreadWindows[\s\S]{0,100}(callback|EnumWindowsProc)/ },
372
+
373
+ { id: "SIG-101", name: "APC injection stealth", severity: "critical", category: "injection",
374
+ pattern: /NtQueueApcThread[\s\S]{0,100}NtResumeThread[\s\S]{0,100}WaitForSingleObject/ },
375
+
376
+ { id: "SIG-102", name: "Early bird injection", severity: "critical", category: "injection",
377
+ pattern: /CreateProcess[\s\S]{0,100}CREATE_SUSPENDED[\s\S]{0,100}WriteProcessMemory[\s\S]{0,100}NtQueueApcThread/ },
378
+
379
+ { id: "SIG-103", name: "Thread execution hijack", severity: "critical", category: "injection",
380
+ pattern: /SuspendThread[\s\S]{0,100}VirtualAlloc[\s\S]{0,100}WriteProcessMemory[\s\S]{0,100}ResumeThread/ },
381
+ ]
382
+
383
+ // ═══════════════════════════════════════════════════════════════
384
+ // MALICIOUS HASH DATABASE
385
+ // ═══════════════════════════════════════════════════════════════
386
+
387
+ export const MALICIOUS_HASHES = new Set([
388
+ // WannaCry
389
+ "ed01ebfbc9eb5bbea545af4d01bf5f1071661840480439c6e5babe8e080e41aa",
390
+ // NotPetya
391
+ "027cc450ef5f8c5f653329641ec1fed91f694e0d229928963b30f6b0d7d3a745",
392
+ // Emotet
393
+ "268ea248e1885788874018b688e66137e3a6195b081926f61af566b7ed870a0b",
394
+ // TrickBot
395
+ "f9a3c6b5dd40f34c5b7e2c8b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d",
396
+ // Ryuk
397
+ "ac315f556f176801108abb3371025c35981ab13627a2d13f3f1a79f35d3e6c9e",
398
+ // LockBit
399
+ "b7c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4",
400
+ // Conti
401
+ "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
402
+ // REvil
403
+ "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5",
404
+ // DarkSide
405
+ "5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a",
406
+ // Maze
407
+ "a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8",
408
+ // Dridex
409
+ "c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0",
410
+ // Agent Tesla
411
+ "e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2",
412
+ // Formbook
413
+ "a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4",
414
+ // NanoCore
415
+ "b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5",
416
+ // njRAT
417
+ "c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
418
+ // Adload
419
+ "d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
420
+ // Gootkit
421
+ "e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8",
422
+ // QakBot
423
+ "f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
424
+ // IcedID
425
+ "a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0",
426
+ // BazarLoader
427
+ "b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1",
428
+ ])
429
+
430
+ // ═══════════════════════════════════════════════════════════════
431
+ // YARA RULES
432
+ // ═══════════════════════════════════════════════════════════════
433
+
434
+ export const YARA_RULES = [
435
+ {
436
+ id: "YARA-001", name: "PE with embedded script", severity: "critical",
437
+ condition: (buf) => {
438
+ const s = buf.toString("utf8")
439
+ return /\x4D\x5A/.test(s) && /<script[\s\S]*eval/i.test(s)
440
+ },
441
+ },
442
+ {
443
+ id: "YARA-002", name: "Massive base64 + eval", severity: "high",
444
+ condition: (buf) => {
445
+ const s = buf.toString("utf8")
446
+ if (s.length > 500000) return false
447
+ const b64 = s.match(/[A-Za-z0-9+\/]{200,}={0,2}/g) || []
448
+ return b64.length >= 3 && /\beval\b/i.test(s) && !/test|spec|mock|jest|vitest/i.test(s)
449
+ },
450
+ },
451
+ {
452
+ id: "YARA-003", name: "Ransomware note", severity: "critical",
453
+ condition: (buf) => {
454
+ const s = buf.toString("utf8").toLowerCase()
455
+ if (s.length > 50000) return false
456
+ const kw = ["your files have been encrypted", "pay the ransom",
457
+ "bitcoin wallet", "decrypt your files", "send bitcoin",
458
+ "all your files", "cannot be recovered", "pay us"]
459
+ let h = 0
460
+ for (const k of kw) { if (s.includes(k)) h++ }
461
+ return h >= 3
462
+ },
463
+ },
464
+ {
465
+ id: "YARA-004", name: "High entropy blob", severity: "low",
466
+ condition: (buf) => {
467
+ if (buf.length < 500 || buf.length > 100000) return false
468
+ const s = buf.toString("utf8")
469
+ if (/[a-zA-Z]{3,}/.test(s) && s.length > 100) return false
470
+ let n = 0
471
+ for (let i = 0; i < buf.length; i++) { if (buf[i] === 0) n++ }
472
+ return (n / buf.length) > 0.6
473
+ },
474
+ },
475
+ {
476
+ id: "YARA-005", name: "Startup persistence", severity: "high",
477
+ condition: (buf) => {
478
+ const s = buf.toString("utf8")
479
+ if (s.length > 50000) return false
480
+ const hasStartup = /CurrentVersion\\Run|\\Start Menu\\Programs\\Startup|schtasks.*\/sc.*onlogon/i.test(s)
481
+ const hasExec = /\b(cmd|powershell|bash|python|perl)\b.*(-c|-e|\/c|exec)/i.test(s)
482
+ return hasStartup && hasExec
483
+ },
484
+ },
485
+ {
486
+ id: "YARA-006", name: "Credential theft + exfil", severity: "critical",
487
+ condition: (buf) => {
488
+ const s = buf.toString("utf8")
489
+ if (s.length > 100000) return false
490
+ const hasCred = /(password|token|secret|cookie|apikey)[\s\S]{0,50}=\s*['"]/i.test(s)
491
+ const hasExfil = /(fetch|http|upload|send|exfil)[\s\S]{0,50}(POST|PUT)/i.test(s)
492
+ return hasCred && hasExfil
493
+ },
494
+ },
495
+ {
496
+ id: "YARA-007", name: "Polymorphic loader", severity: "high",
497
+ condition: (buf) => {
498
+ const s = buf.toString("utf8")
499
+ if (s.length < 200 || s.length > 100000) return false
500
+ const hasFromChar = /fromCharCode|String\.raw.*\\x|unescape/i.test(s)
501
+ const hasChain = /eval\s*\(\s*String|eval\s*\(\s*atob|Function\s*\(\s*['"]return/i.test(s)
502
+ return hasFromChar && hasChain
503
+ },
504
+ },
505
+ {
506
+ id: "YARA-008", name: "Encoded command exec", severity: "critical",
507
+ condition: (buf) => {
508
+ const s = buf.toString("utf8")
509
+ if (s.length > 100000) return false
510
+ const hasDecode = /FromBase64String|atob|base64_decode|decodeURIComponent/i.test(s)
511
+ const hasExec = /\b(eval|exec|system|passthru|shell_exec|child_process)\b/i.test(s)
512
+ return hasDecode && hasExec
513
+ },
514
+ },
515
+ {
516
+ id: "YARA-009", name: "Process injection combo", severity: "critical",
517
+ condition: (buf) => {
518
+ const s = buf.toString("utf8")
519
+ if (s.length > 200000) return false
520
+ const hasOpen = /OpenProcess|OpenThread/.test(s)
521
+ const hasAlloc = /VirtualAllocEx|VirtualProtectEx/.test(s)
522
+ const hasWrite = /WriteProcessMemory/.test(s)
523
+ const hasThread = /CreateRemoteThread|NtCreateThreadEx/.test(s)
524
+ return hasOpen && hasAlloc && hasWrite && hasThread
525
+ },
526
+ },
527
+ {
528
+ id: "YARA-010", name: "Keychain/credential dump", severity: "critical",
529
+ condition: (buf) => {
530
+ const s = buf.toString("utf8")
531
+ if (s.length > 200000) return false
532
+ const hasDump = /dump|extract|steal|grab|harvest/i.test(s)
533
+ const hasCred = /password|token|secret|keychain|keyring|credential/i.test(s)
534
+ const hasSend = /http|ftp|smtp|socket|send|upload|exfil/i.test(s)
535
+ return hasDump && hasCred && hasSend
536
+ },
537
+ },
538
+ {
539
+ id: "YARA-011", name: "Obfuscated PowerShell", severity: "high",
540
+ condition: (buf) => {
541
+ const s = buf.toString("utf8")
542
+ if (s.length > 100000) return false
543
+ const hasPS = /powershell|pwsh/i.test(s)
544
+ const hasEnc = /-enc|-EncodedCommand|-e\s/i.test(s)
545
+ const hasIEX = /IEX|Invoke-Expression|DownloadString/i.test(s)
546
+ return hasPS && hasEnc && hasIEX
547
+ },
548
+ },
549
+ {
550
+ id: "YARA-012", name: "DLL side-loading", severity: "critical",
551
+ condition: (buf) => {
552
+ const s = buf.toString("utf8")
553
+ if (s.length > 200000) return false
554
+ const hasLoad = /LoadLibrary[AW]?\s*\(/.test(s)
555
+ const hasGet = /GetProcAddress\s*\(/.test(s)
556
+ const hasCall = /\(\*\w+\)\(/.test(s) || /call\s*\(/.test(s)
557
+ return hasLoad && hasGet && hasCall
558
+ },
559
+ },
560
+ ]
561
+
562
+ // ═══════════════════════════════════════════════════════════════
563
+ // HEURISTIC RULES
564
+ // ═══════════════════════════════════════════════════════════════
565
+
566
+ export const HEURISTIC_RULES = [
567
+ {
568
+ id: "HEUR-001", name: "Высокая энтропия", severity: "medium",
569
+ check: (content, filepath) => {
570
+ if (content.length < 500 || content.length > 500000) return null
571
+ const freq = new Array(256).fill(0)
572
+ for (let i = 0; i < content.length; i++) freq[content[i]]++
573
+ let entropy = 0
574
+ for (let i = 0; i < 256; i++) {
575
+ if (freq[i] > 0) {
576
+ const p = freq[i] / content.length
577
+ entropy -= p * Math.log2(p)
578
+ }
579
+ }
580
+ if (entropy > 7.9) return { score: 70, detail: `Энтропия: ${entropy.toFixed(2)}` }
581
+ return null
582
+ },
583
+ },
584
+ {
585
+ id: "HEUR-002", name: "Массовые подозрительные API", severity: "high",
586
+ check: (content) => {
587
+ if (content.length > 200000) return null
588
+ const s = content.toString("utf8")
589
+ const apiCalls = [
590
+ /\bCreateProcess\b[\s\S]{0,30}(SW_HIDE|CREATE_NO_WINDOW)/,
591
+ /\bShellExecute\b[\s\S]{0,30}(runas)/i,
592
+ /\bURLDownloadToFile\b[\s\S]{0,30}http/i,
593
+ /\bInternetOpen\b[\s\S]{0,30}http/i,
594
+ /\bRegSetValue\b[\s\S]{0,30}Run/i,
595
+ /\bCreateService\b[\s\S]{0,30}AUTO_START/i,
596
+ /\bOpenSCManager\b[\s\S]{0,30}SC_MANAGER_CREATE_SERVICE/i,
597
+ ]
598
+ let hits = 0
599
+ for (const api of apiCalls) { if (api.test(s)) hits++ }
600
+ if (hits >= 3) return { score: 75, detail: `${hits} подозрительных API-вызовов` }
601
+ return null
602
+ },
603
+ },
604
+ {
605
+ id: "HEUR-003", name: "Цепочки кодирования", severity: "medium",
606
+ check: (content) => {
607
+ if (content.length > 200000) return null
608
+ const s = content.toString("utf8")
609
+ const chains = s.match(/String\.fromCharCode\s*\(\s*\d+/g) || []
610
+ if (chains.length > 15) return { score: 55, detail: `${chains.length} цепочек.fromCharCode` }
611
+ return null
612
+ },
613
+ },
614
+ {
615
+ id: "HEUR-004", name: "Скрытые процессы", severity: "high",
616
+ check: (content) => {
617
+ if (content.length > 200000) return null
618
+ const s = content.toString("utf8")
619
+ const hasCreate = /\b(CreateProcess|exec|spawn|system)\b/i.test(s)
620
+ const hasHide = /(SW_HIDE|CREATE_NO_WINDOW|DETACHED_PROCESS)/i.test(s)
621
+ const hasHollow = /(NtUnmapViewOfSection|ProcessHollowing|process.*hollow)/i.test(s)
622
+ if (hasCreate && hasHide && hasHollow) return { score: 85, detail: "Создание + скрытие + hollowing" }
623
+ if (hasCreate && hasHide) return { score: 55, detail: "Создание скрытых процессов" }
624
+ return null
625
+ },
626
+ },
627
+ {
628
+ id: "HEUR-005", name: "Массовый обход файлов", severity: "medium",
629
+ check: (content) => {
630
+ if (content.length > 200000) return null
631
+ const s = content.toString("utf8")
632
+ const hasRecursive = /readdirSync|walkSync|glob\s*\(\s*['"]\*\*/i.test(s)
633
+ const hasSensitive = /\.(env|key|pem|pfx|jks|keystore|wallet\.dat)/i.test(s)
634
+ const hasEncode = /base64|hex|encode/i.test(s)
635
+ if (hasRecursive && hasSensitive && hasEncode) return { score: 65, detail: "Рекурсивный обход + чувствительные файлы + кодировка" }
636
+ return null
637
+ },
638
+ },
639
+ {
640
+ id: "HEUR-006", name: "Сетевой beacon", severity: "high",
641
+ check: (content) => {
642
+ if (content.length > 200000) return null
643
+ const s = content.toString("utf8")
644
+ const hasInterval = /(setInterval|setTimeout|while.*true|loop)/i.test(s)
645
+ const hasNet = /(fetch|http|socket|connect|XMLHttpRequest)/i.test(s)
646
+ const hasHardcoded = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|[a-z0-9-]+\.(com|net|org|ru|cn)\//i.test(s)
647
+ if (hasInterval && hasNet && hasHardcoded) return { score: 75, detail: "Периодические запросы к хардкоду" }
648
+ return null
649
+ },
650
+ },
651
+ {
652
+ id: "HEUR-007", name: "Системные модификации", severity: "high",
653
+ check: (content) => {
654
+ if (content.length > 200000) return null
655
+ const s = content.toString("utf8")
656
+ const patterns = [
657
+ /\bchmod\s+[0-7]{3,4}\b/,
658
+ /\bchown\s+root\b/,
659
+ /\bnet\s+user\s+\S+\s+\/add\b/,
660
+ /\bnet\s+localgroup\s+\S+\s+\/add\b/,
661
+ /\bcrontab\b.*-e/,
662
+ ]
663
+ let h = 0
664
+ for (const p of patterns) { if (p.test(s)) h++ }
665
+ if (h >= 2) return { score: 65, detail: `${h} модификаций системы` }
666
+ return null
667
+ },
668
+ },
669
+ {
670
+ id: "HEUR-008", name: "Динамическое выполнение", severity: "high",
671
+ check: (content) => {
672
+ if (content.length > 200000) return null
673
+ const s = content.toString("utf8")
674
+ const chains = s.match(/eval\s*\(\s*(eval|Function|atob|Buffer|fromCharCode)/gi) || []
675
+ if (chains.length >= 3) return { score: 70, detail: `${chains.length} цепочек динамического выполнения` }
676
+ return null
677
+ },
678
+ },
679
+ {
680
+ id: "HEUR-009", name: "Массовые системные вызовы", severity: "high",
681
+ check: (content) => {
682
+ if (content.length > 200000) return null
683
+ const s = content.toString("utf8")
684
+ const syscalls = [
685
+ /NtAllocateVirtualMemory/,
686
+ /NtWriteVirtualMemory/,
687
+ /NtProtectVirtualMemory/,
688
+ /NtCreateThreadEx/,
689
+ /NtMapViewOfSection/,
690
+ ]
691
+ let h = 0
692
+ for (const p of syscalls) { if (p.test(s)) h++ }
693
+ if (h >= 4) return { score: 80, detail: `${h} низкоуровневых системных вызовов` }
694
+ return null
695
+ },
696
+ },
697
+ {
698
+ id: "HEUR-010", name: "Дамп памяти процесса", severity: "critical",
699
+ check: (content) => {
700
+ if (content.length > 200000) return null
701
+ const s = content.toString("utf8")
702
+ const hasDump = /MiniDumpWriteDump|ReadProcessMemory|NtReadVirtualMemory/.test(s)
703
+ const hasProc = /lsass|csrss|svchost|wininit/.test(s)
704
+ const hasFile = /WriteFile|CreateFile|fwrite/.test(s)
705
+ if (hasDump && hasProc && hasFile) return { score: 90, detail: "Дамп системного процесса + запись в файл" }
706
+ return null
707
+ },
708
+ },
709
+ {
710
+ id: "HEUR-011", name: "Сетевая аномалия", severity: "high",
711
+ check: (content) => {
712
+ if (content.length > 200000) return null
713
+ const s = content.toString("utf8")
714
+ const hasListen = /listen\s*\(\s*\d+\)/.test(s)
715
+ const hasConnect = /connect\s*\(\s*\d+/.test(s)
716
+ const hasShell = /child_process|spawn|exec.*-c/.test(s)
717
+ if (hasListen && hasConnect && hasShell) return { score: 80, detail: "Слушает + подключается + выполняет команды" }
718
+ return null
719
+ },
720
+ },
721
+ {
722
+ id: "HEUR-012", name: "Самоудаление следов", severity: "high",
723
+ check: (content) => {
724
+ if (content.length > 200000) return null
725
+ const s = content.toString("utf8")
726
+ const hasWrite = /WriteFile|fwrite|createWriteStream/.test(s)
727
+ const hasDelete = /DeleteFile|unlink|rm\b|fs\.unlink/.test(s)
728
+ const hasLogs = /(log|event|audit|trace|debug)/i.test(s)
729
+ if (hasWrite && hasDelete && hasLogs) return { score: 70, detail: "Запись + удаление + работа с логами" }
730
+ return null
731
+ },
732
+ },
733
+ ]
734
+
735
+ // ═══════════════════════════════════════════════════════════════
736
+ // QUARANTINE
737
+ // ═══════════════════════════════════════════════════════════════
738
+
739
+ export const QUARANTINE_DIR = path.join(process.env.USERPROFILE || process.env.HOME || "", ".stellar", "quarantine")
740
+
741
+ // ═══════════════════════════════════════════════════════════════
742
+ // EXCLUSIONS
743
+ // ═══════════════════════════════════════════════════════════════
744
+
745
+ export function loadExclusions(filepath) {
746
+ try {
747
+ if (fs.existsSync(filepath)) {
748
+ return fs.readFileSync(filepath, "utf8").split("\n").filter(l => l.trim() && !l.startsWith("#"))
749
+ }
750
+ } catch {}
751
+ return []
752
+ }
753
+
754
+ export function isExcluded(filepath, exclusions) {
755
+ const normalized = filepath.replace(/\\/g, "/").toLowerCase()
756
+ for (const exc of exclusions) {
757
+ const pattern = exc.replace(/\\/g, "/").toLowerCase()
758
+ if (normalized.includes(pattern)) return true
759
+ }
760
+ return false
761
+ }
762
+
763
+ // ═══════════════════════════════════════════════════════════════
764
+ // CORE SCANNING FUNCTION
765
+ // ═══════════════════════════════════════════════════════════════
766
+
767
+ export function computeFileHash(content) {
768
+ return crypto.createHash("sha256").update(content).digest("hex")
769
+ }
770
+
771
+ export function computeFileHashes(content) {
772
+ return {
773
+ md5: crypto.createHash("md5").update(content).digest("hex"),
774
+ sha1: crypto.createHash("sha1").update(content).digest("hex"),
775
+ sha256: crypto.createHash("sha256").update(content).digest("hex"),
776
+ }
777
+ }
778
+
779
+ export function checkFileForMalware(content, filepath) {
780
+ const results = {
781
+ filepath,
782
+ clean: true,
783
+ threats: [],
784
+ warnings: [],
785
+ score: 0,
786
+ details: {
787
+ signatures: [],
788
+ hashes: [],
789
+ yara: [],
790
+ heuristics: [],
791
+ },
792
+ }
793
+
794
+ const isBinary = BINARY_EXTS.has(path.extname(filepath).toLowerCase())
795
+ const isSource = !isBinary
796
+
797
+ // 1. Hash check
798
+ const hashes = computeFileHashes(content)
799
+ if (MALICIOUS_HASHES.has(hashes.md5) || MALICIOUS_HASHES.has(hashes.sha256)) {
800
+ results.clean = false
801
+ results.threats.push({
802
+ type: "hash",
803
+ severity: "critical",
804
+ message: `Хеш совпадает с известным вирусом`,
805
+ })
806
+ results.details.hashes.push({ ...hashes, match: true })
807
+ }
808
+
809
+ // 2. Signature check
810
+ const text = content.toString("utf8")
811
+ for (const sig of SIGNATURES) {
812
+ try {
813
+ if (sig.pattern.test(text)) {
814
+ results.details.signatures.push({ id: sig.id, name: sig.name, severity: sig.severity, category: sig.category })
815
+ if (sig.severity === "critical") {
816
+ results.clean = false
817
+ results.threats.push({ type: "signature", severity: sig.severity, message: `${sig.id}: ${sig.name}` })
818
+ results.score += 85
819
+ } else if (sig.severity === "high") {
820
+ results.warnings.push({ type: "signature", severity: sig.severity, message: `${sig.id}: ${sig.name}` })
821
+ results.score += 50
822
+ } else {
823
+ results.warnings.push({ type: "signature", severity: sig.severity, message: `${sig.id}: ${sig.name}` })
824
+ results.score += 20
825
+ }
826
+ }
827
+ } catch {}
828
+ }
829
+
830
+ // 3. YARA rules
831
+ for (const rule of YARA_RULES) {
832
+ try {
833
+ if (rule.condition(content)) {
834
+ results.details.yara.push({ id: rule.id, name: rule.name, severity: rule.severity })
835
+ if (rule.severity === "critical") {
836
+ results.clean = false
837
+ results.threats.push({ type: "yara", severity: rule.severity, message: `${rule.id}: ${rule.name}` })
838
+ results.score += 80
839
+ } else if (rule.severity === "high") {
840
+ results.warnings.push({ type: "yara", severity: rule.severity, message: `${rule.id}: ${rule.name}` })
841
+ results.score += 40
842
+ } else {
843
+ results.warnings.push({ type: "yara", severity: rule.severity, message: `${rule.id}: ${rule.name}` })
844
+ results.score += 10
845
+ }
846
+ }
847
+ } catch {}
848
+ }
849
+
850
+ // 4. Heuristic analysis
851
+ for (const rule of HEURISTIC_RULES) {
852
+ try {
853
+ const result = rule.check(content, filepath)
854
+ if (result) {
855
+ const adjustedScore = isSource ? Math.floor(result.score * 0.6) : result.score
856
+ results.details.heuristics.push({ id: rule.id, name: rule.name, severity: rule.severity, ...result, adjustedScore })
857
+ if (adjustedScore >= 60) {
858
+ results.clean = false
859
+ results.threats.push({ type: "heuristic", severity: rule.severity, message: `${rule.id}: ${rule.name} — ${result.detail}` })
860
+ results.score += adjustedScore
861
+ } else if (adjustedScore >= 30) {
862
+ results.warnings.push({ type: "heuristic", severity: rule.severity, message: `${rule.id}: ${rule.name} — ${result.detail}` })
863
+ results.score += adjustedScore
864
+ }
865
+ }
866
+ } catch {}
867
+ }
868
+
869
+ results.score = Math.min(results.score, 100)
870
+ return results
871
+ }