stella-coder 3.9.1 → 4.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/.mcp.json +11 -0
- package/.opencode/skills/banner-design/SKILL.md +196 -0
- package/.opencode/skills/banner-design/references/banner-sizes-and-styles.md +118 -0
- package/.opencode/skills/brand/SKILL.md +97 -0
- package/.opencode/skills/brand/references/approval-checklist.md +169 -0
- package/.opencode/skills/brand/references/asset-organization.md +157 -0
- package/.opencode/skills/brand/references/brand-guideline-template.md +140 -0
- package/.opencode/skills/brand/references/color-palette-management.md +186 -0
- package/.opencode/skills/brand/references/consistency-checklist.md +94 -0
- package/.opencode/skills/brand/references/logo-usage-rules.md +185 -0
- package/.opencode/skills/brand/references/messaging-framework.md +85 -0
- package/.opencode/skills/brand/references/typography-specifications.md +214 -0
- package/.opencode/skills/brand/references/update.md +118 -0
- package/.opencode/skills/brand/references/visual-identity.md +96 -0
- package/.opencode/skills/brand/references/voice-framework.md +88 -0
- package/.opencode/skills/brand/scripts/extract-colors.cjs +341 -0
- package/.opencode/skills/brand/scripts/inject-brand-context.cjs +349 -0
- package/.opencode/skills/brand/scripts/sync-brand-to-tokens.cjs +248 -0
- package/.opencode/skills/brand/scripts/tests/test_sync_brand_to_tokens.py +52 -0
- package/.opencode/skills/brand/scripts/validate-asset.cjs +387 -0
- package/.opencode/skills/brand/templates/brand-guidelines-starter.md +275 -0
- package/.opencode/skills/design/SKILL.md +313 -0
- package/.opencode/skills/design/data/cip/deliverables.csv +51 -0
- package/.opencode/skills/design/data/cip/industries.csv +21 -0
- package/.opencode/skills/design/data/cip/mockup-contexts.csv +21 -0
- package/.opencode/skills/design/data/cip/styles.csv +21 -0
- package/.opencode/skills/design/data/icon/styles.csv +16 -0
- package/.opencode/skills/design/data/logo/colors.csv +56 -0
- package/.opencode/skills/design/data/logo/industries.csv +56 -0
- package/.opencode/skills/design/data/logo/styles.csv +56 -0
- package/.opencode/skills/design/references/banner-sizes-and-styles.md +118 -0
- package/.opencode/skills/design/references/cip-deliverable-guide.md +95 -0
- package/.opencode/skills/design/references/cip-design.md +121 -0
- package/.opencode/skills/design/references/cip-prompt-engineering.md +84 -0
- package/.opencode/skills/design/references/cip-style-guide.md +68 -0
- package/.opencode/skills/design/references/design-routing.md +207 -0
- package/.opencode/skills/design/references/icon-design.md +122 -0
- package/.opencode/skills/design/references/logo-color-psychology.md +101 -0
- package/.opencode/skills/design/references/logo-design.md +92 -0
- package/.opencode/skills/design/references/logo-prompt-engineering.md +158 -0
- package/.opencode/skills/design/references/logo-style-guide.md +109 -0
- package/.opencode/skills/design/references/slides-copywriting-formulas.md +84 -0
- package/.opencode/skills/design/references/slides-create.md +4 -0
- package/.opencode/skills/design/references/slides-html-template.md +295 -0
- package/.opencode/skills/design/references/slides-layout-patterns.md +137 -0
- package/.opencode/skills/design/references/slides-strategies.md +94 -0
- package/.opencode/skills/design/references/slides.md +42 -0
- package/.opencode/skills/design/references/social-photos-design.md +329 -0
- package/.opencode/skills/design/scripts/cip/core.py +215 -0
- package/.opencode/skills/design/scripts/cip/generate.py +484 -0
- package/.opencode/skills/design/scripts/cip/render-html.py +424 -0
- package/.opencode/skills/design/scripts/cip/search.py +127 -0
- package/.opencode/skills/design/scripts/icon/generate.py +487 -0
- package/.opencode/skills/design/scripts/logo/core.py +175 -0
- package/.opencode/skills/design/scripts/logo/generate.py +362 -0
- package/.opencode/skills/design/scripts/logo/search.py +114 -0
- package/.opencode/skills/design-system/SKILL.md +244 -0
- package/.opencode/skills/design-system/data/slide-backgrounds.csv +11 -0
- package/.opencode/skills/design-system/data/slide-charts.csv +26 -0
- package/.opencode/skills/design-system/data/slide-color-logic.csv +14 -0
- package/.opencode/skills/design-system/data/slide-copy.csv +26 -0
- package/.opencode/skills/design-system/data/slide-layout-logic.csv +16 -0
- package/.opencode/skills/design-system/data/slide-layouts.csv +26 -0
- package/.opencode/skills/design-system/data/slide-strategies.csv +16 -0
- package/.opencode/skills/design-system/data/slide-typography.csv +15 -0
- package/.opencode/skills/design-system/references/component-specs.md +236 -0
- package/.opencode/skills/design-system/references/component-tokens.md +214 -0
- package/.opencode/skills/design-system/references/primitive-tokens.md +203 -0
- package/.opencode/skills/design-system/references/semantic-tokens.md +215 -0
- package/.opencode/skills/design-system/references/states-and-variants.md +241 -0
- package/.opencode/skills/design-system/references/tailwind-integration.md +251 -0
- package/.opencode/skills/design-system/references/token-architecture.md +224 -0
- package/.opencode/skills/design-system/scripts/embed-tokens.cjs +99 -0
- package/.opencode/skills/design-system/scripts/fetch-background.py +317 -0
- package/.opencode/skills/design-system/scripts/generate-slide.py +770 -0
- package/.opencode/skills/design-system/scripts/generate-tokens.cjs +205 -0
- package/.opencode/skills/design-system/scripts/html-token-validator.py +327 -0
- package/.opencode/skills/design-system/scripts/search-slides.py +218 -0
- package/.opencode/skills/design-system/scripts/slide-token-validator.py +35 -0
- package/.opencode/skills/design-system/scripts/slide_search_core.py +453 -0
- package/.opencode/skills/design-system/scripts/tests/test_validate_tokens.py +48 -0
- package/.opencode/skills/design-system/scripts/validate-tokens.cjs +246 -0
- package/.opencode/skills/design-system/templates/design-tokens-starter.json +143 -0
- package/.opencode/skills/slides/SKILL.md +40 -0
- package/.opencode/skills/slides/references/copywriting-formulas.md +84 -0
- package/.opencode/skills/slides/references/create.md +4 -0
- package/.opencode/skills/slides/references/html-template.md +295 -0
- package/.opencode/skills/slides/references/layout-patterns.md +137 -0
- package/.opencode/skills/slides/references/slide-strategies.md +94 -0
- package/.opencode/skills/ui-styling/LICENSE.txt +202 -0
- package/.opencode/skills/ui-styling/SKILL.md +324 -0
- package/.opencode/skills/ui-styling/references/canvas-design-system.md +320 -0
- package/.opencode/skills/ui-styling/references/shadcn-accessibility.md +471 -0
- package/.opencode/skills/ui-styling/references/shadcn-components.md +424 -0
- package/.opencode/skills/ui-styling/references/shadcn-theming.md +373 -0
- package/.opencode/skills/ui-styling/references/tailwind-customization.md +483 -0
- package/.opencode/skills/ui-styling/references/tailwind-responsive.md +382 -0
- package/.opencode/skills/ui-styling/references/tailwind-utilities.md +455 -0
- package/.opencode/skills/ui-styling/scripts/requirements.txt +17 -0
- package/.opencode/skills/ui-styling/scripts/shadcn_add.py +308 -0
- package/.opencode/skills/ui-styling/scripts/tailwind_config_gen.py +473 -0
- package/.opencode/skills/ui-styling/scripts/tests/coverage-ui.json +1 -0
- package/.opencode/skills/ui-styling/scripts/tests/requirements.txt +3 -0
- package/.opencode/skills/ui-styling/scripts/tests/test_shadcn_add.py +266 -0
- package/.opencode/skills/ui-styling/scripts/tests/test_tailwind_config_gen.py +394 -0
- package/.opencode/skills/ui-ux-pro-max/SKILL.md +396 -0
- package/.opencode/skills/ui-ux-pro-max/data/_sync_all.py +414 -0
- package/.opencode/skills/ui-ux-pro-max/data/app-interface.csv +31 -0
- package/.opencode/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.opencode/skills/ui-ux-pro-max/data/colors.csv +193 -0
- package/.opencode/skills/ui-ux-pro-max/data/design.csv +1776 -0
- package/.opencode/skills/ui-ux-pro-max/data/draft.csv +1779 -0
- package/.opencode/skills/ui-ux-pro-max/data/google-fonts.csv +1924 -0
- package/.opencode/skills/ui-ux-pro-max/data/icons.csv +106 -0
- package/.opencode/skills/ui-ux-pro-max/data/landing.csv +35 -0
- package/.opencode/skills/ui-ux-pro-max/data/motion.csv +17 -0
- package/.opencode/skills/ui-ux-pro-max/data/products.csv +193 -0
- package/.opencode/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/avalonia.csv +57 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/javafx.csv +76 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +71 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/uno.csv +60 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/uwp.csv +56 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/winui.csv +60 -0
- package/.opencode/skills/ui-ux-pro-max/data/stacks/wpf.csv +57 -0
- package/.opencode/skills/ui-ux-pro-max/data/styles.csv +85 -0
- package/.opencode/skills/ui-ux-pro-max/data/typography.csv +75 -0
- package/.opencode/skills/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
- package/.opencode/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.opencode/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc +0 -0
- package/.opencode/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-312.pyc +0 -0
- package/.opencode/skills/ui-ux-pro-max/scripts/core.py +274 -0
- package/.opencode/skills/ui-ux-pro-max/scripts/design_system.py +1329 -0
- package/.opencode/skills/ui-ux-pro-max/scripts/search.py +127 -0
- package/README.md +5 -0
- package/STELLA.md +1 -1
- package/dist/antimalware/database.mjs +871 -0
- package/dist/antimalware/index.mjs +8 -0
- package/dist/antimalware/scanner.mjs +591 -0
- package/dist/antimalware/ui.mjs +570 -0
- package/dist/banner.mjs +46 -0
- package/dist/index.mjs +3073 -0
- package/dist/markdown.mjs +100 -0
- package/dist/sea-config.json +4 -0
- package/dist/security.mjs +237 -0
- package/dist/theme.mjs +89 -0
- package/dist/tools.mjs +3145 -0
- package/install-stella.bat +44 -0
- package/package.json +12 -3
- package/presentation-advanced-features-demo/README.md +27 -0
- package/presentation-advanced-features-demo/index.html +371 -0
- package/presentation-advanced-features-demo/print.html +81 -0
- package/presentation-advanced-features-demo/slide-01.html +98 -0
- package/presentation-advanced-features-demo/slide-02.html +101 -0
- package/presentation-advanced-features-demo/slide-03.html +100 -0
- package/presentation-advanced-features-demo/slide-04.html +100 -0
- package/presentation-advanced-features-demo/slide-05.html +100 -0
- package/presentation-advanced-features-demo/slide-06.html +64 -0
- package/presentation-advanced-features-demo/slide-07.html +101 -0
- package/presentation-advanced-features-demo/slide-08.html +91 -0
- package/presentation-stella-coder---ai-coding-agent/README.md +27 -0
- package/presentation-stella-coder---ai-coding-agent/index.html +168 -0
- package/presentation-stella-coder---ai-coding-agent/slide-01.html +98 -0
- package/presentation-stella-coder---ai-coding-agent/slide-02.html +101 -0
- package/presentation-stella-coder---ai-coding-agent/slide-03.html +100 -0
- package/presentation-stella-coder---ai-coding-agent/slide-04.html +100 -0
- package/presentation-stella-coder---ai-coding-agent/slide-05.html +100 -0
- package/presentation-stella-coder---ai-coding-agent/slide-06.html +100 -0
- package/presentation-stella-coder---ai-coding-agent/slide-07.html +100 -0
- package/presentation-stella-coder---ai-coding-agent/slide-08.html +64 -0
- package/presentation-stella-coder---ai-coding-agent/slide-09.html +101 -0
- package/presentation-stella-coder---ai-coding-agent/slide-10.html +91 -0
- package/presentation-stella-coder-demo/README.md +27 -0
- package/presentation-stella-coder-demo/index.html +371 -0
- package/presentation-stella-coder-demo/slide-01.html +98 -0
- package/presentation-stella-coder-demo/slide-02.html +101 -0
- package/presentation-stella-coder-demo/slide-03.html +100 -0
- package/presentation-stella-coder-demo/slide-04.html +100 -0
- package/presentation-stella-coder-demo/slide-05.html +100 -0
- package/presentation-stella-coder-demo/slide-06.html +64 -0
- package/presentation-stella-coder-demo/slide-07.html +101 -0
- package/presentation-stella-coder-demo/slide-08.html +91 -0
- package/presentation-stella-coder-features/README.md +27 -0
- package/presentation-stella-coder-features/index.html +364 -0
- package/presentation-stella-coder-features/print.html +77 -0
- package/presentation-stella-coder-features/slide-01.html +98 -0
- package/presentation-stella-coder-features/slide-02.html +101 -0
- package/presentation-stella-coder-features/slide-03.html +100 -0
- package/presentation-stella-coder-features/slide-04.html +100 -0
- package/presentation-stella-coder-features/slide-05.html +64 -0
- package/presentation-stella-coder-features/slide-06.html +101 -0
- package/presentation-stella-coder-features/slide-07.html +91 -0
- package/presentation-test-presentation/README.md +27 -0
- package/presentation-test-presentation/index.html +350 -0
- package/presentation-test-presentation/print.html +69 -0
- package/presentation-test-presentation/slide-01.html +98 -0
- package/presentation-test-presentation/slide-02.html +101 -0
- package/presentation-test-presentation/slide-03.html +64 -0
- package/presentation-test-presentation/slide-04.html +101 -0
- package/presentation-test-presentation/slide-05.html +91 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/README.md +27 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/index.html +159 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-01.html +98 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-02.html +101 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-03.html +100 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-04.html +100 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-05.html +64 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-06.html +101 -0
- package/presentation-/321/202/320/265/321/201/321/202/320/276/320/262/320/260/321/217-/320/277/321/200/320/265/320/267/320/265/320/275/321/202/320/260/321/206/320/270/321/217/slide-07.html +91 -0
- package/stella-cli/coding-brain.mjs +753 -0
- package/stella-cli/index.mjs +931 -15
- package/stella-cli/mcp.mjs +296 -0
- package/stella-cli/presentations.mjs +1106 -0
- package/stella-cli/subagents.mjs +142 -0
- package/stella-cli/telegram-bot.mjs +824 -0
- package/stella-cli/tg-bg.bat +13 -0
- package/stella-cli/tg-server.bat +15 -0
- package/stella-cli/tg-server.mjs +116 -0
- package/stella-cli/theme.mjs +6 -4
- package/stella-coder-3.9.2.tgz +0 -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
|
+
}
|