security-detections-mcp 2.1.1 → 3.1.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/README.md +186 -17
- package/dist/db/detections.d.ts +8 -8
- package/dist/db/detections.js +14 -7
- package/dist/db/schema.js +15 -9
- package/dist/db.d.ts +3 -3
- package/dist/db.js +27 -15
- package/dist/index.js +5 -3
- package/dist/indexer.d.ts +5 -1
- package/dist/indexer.js +40 -2
- package/dist/parsers/crowdstrike_cql.d.ts +2 -0
- package/dist/parsers/crowdstrike_cql.js +302 -0
- package/dist/parsers/elastic.js +3 -0
- package/dist/parsers/kql.js +6 -0
- package/dist/parsers/sigma.js +3 -0
- package/dist/parsers/splunk.js +3 -0
- package/dist/parsers/sublime.d.ts +2 -0
- package/dist/parsers/sublime.js +106 -0
- package/dist/resources/index.js +1 -1
- package/dist/tools/detections/analysis.js +4 -4
- package/dist/tools/detections/comparison.js +3 -3
- package/dist/tools/detections/filters.js +1 -1
- package/dist/tools/detections/search.js +1 -1
- package/dist/tools/engineering/index.js +2 -2
- package/dist/types/detection.d.ts +46 -4
- package/dist/types/detection.js +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +1 -1
- package/dist/types/stats.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,105 @@
|
|
|
1
1
|
# Security Detections MCP
|
|
2
2
|
|
|
3
|
-
An MCP (Model Context Protocol) server that lets LLMs query a unified database of **Sigma**, **Splunk ESCU**, **Elastic**, and **
|
|
3
|
+
An MCP (Model Context Protocol) server that lets LLMs query a unified database of **Sigma**, **Splunk ESCU**, **Elastic**, **KQL**, **Sublime**, and **CrowdStrike CQL** security detection rules.
|
|
4
|
+
|
|
5
|
+
> **New here? Start with the [Setup Guide](./SETUP.md)** -- covers macOS, Windows (WSL & native), and Linux step by step.
|
|
6
|
+
|
|
7
|
+
## What's New in 3.1 - New Detection Sources
|
|
8
|
+
|
|
9
|
+
- **CrowdStrike CQL Hub** - Query and search CrowdStrike Query Language (CQL) detections from the CQL Hub community repository
|
|
10
|
+
- **Sublime Rules** - Query and search Sublime Security detection rules for email-based threats
|
|
11
|
+
|
|
12
|
+
## What's New in 3.0 - Autonomous Detection Platform
|
|
13
|
+
|
|
14
|
+
Version 3.0 transforms this MCP into a **fully autonomous detection engineering platform**. Feed it threat intelligence, and it automatically:
|
|
15
|
+
|
|
16
|
+
1. **Extracts TTPs** from threat reports, CISA alerts, or manual input
|
|
17
|
+
2. **Analyzes coverage gaps** against your existing detections
|
|
18
|
+
3. **Generates detections** in your SIEM's native format (SPL, KQL, EQL, or Sigma)
|
|
19
|
+
4. **Runs Atomic Red Team tests** against your lab environment
|
|
20
|
+
5. **Validates detections fire** by querying your SIEM
|
|
21
|
+
6. **Exports attack data** for reproducibility
|
|
22
|
+
7. **Stages DRAFT PRs** to your detection repo (never auto-merges)
|
|
23
|
+
|
|
24
|
+
> **Multi-SIEM**: Set `SIEM_PLATFORM` to `splunk`, `sentinel`, `elastic`, or `sigma` in your `.env`. The pipeline was built on Splunk + Attack Range but adapts to any SIEM. See the **[E2E Testing Guide](./docs/E2E-TESTING-GUIDE.md)** for complete setup instructions per platform.
|
|
25
|
+
|
|
26
|
+
### Architecture: LangGraph + Cursor Subagents
|
|
27
|
+
|
|
28
|
+
The 3.0 architecture uses two complementary systems:
|
|
29
|
+
|
|
30
|
+
| Component | Purpose | Location |
|
|
31
|
+
|-----------|---------|----------|
|
|
32
|
+
| **LangGraph Pipeline** | Core autonomous workflow - portable, testable, CI/CD ready | `agents/` |
|
|
33
|
+
| **Cursor Subagents** | Interactive IDE agents for manual tasks | `.cursor/agents/` |
|
|
34
|
+
|
|
35
|
+
### Quick Start - Autonomous Mode
|
|
36
|
+
|
|
37
|
+
**Prerequisites**: Node.js 20+, an Anthropic API key. Full details in the [Setup Guide](./SETUP.md).
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Install the agents package
|
|
41
|
+
cd agents && npm install --registry https://registry.npmjs.org/
|
|
42
|
+
|
|
43
|
+
# Configure
|
|
44
|
+
cp .env.example .env
|
|
45
|
+
# Edit .env: set SIEM_PLATFORM, ANTHROPIC_API_KEY, SECURITY_CONTENT_PATH
|
|
46
|
+
|
|
47
|
+
# Test with dry run first (uses mock data, no LLM calls)
|
|
48
|
+
DRY_RUN=true npm run orchestrate -- --type technique --input "T1566.004 Spearphishing Voice"
|
|
49
|
+
|
|
50
|
+
# Run with real LLM (creates actual detections)
|
|
51
|
+
npm run orchestrate -- --type technique --input "T1566.004 Spearphishing Voice"
|
|
52
|
+
|
|
53
|
+
# Or analyze a CISA alert
|
|
54
|
+
npm run orchestrate -- --type cisa_alert --url https://www.cisa.gov/news-events/alerts/...
|
|
55
|
+
|
|
56
|
+
# Or feed it a threat report
|
|
57
|
+
npm run orchestrate -- --type threat_report --file ./report.md
|
|
58
|
+
|
|
59
|
+
# Note: Use T1566.004 for testing - it has no existing coverage so will create a detection
|
|
60
|
+
# T1003.001 has 100+ existing detections, so the pipeline will correctly skip it (no gap)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Pipeline Stages
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
┌─────────────┐ ┌──────────────────┐ ┌────────────────────┐
|
|
67
|
+
│ CTI Analyst │───>│ Coverage Analyzer│───>│ Detection Engineer │
|
|
68
|
+
└─────────────┘ └──────────────────┘ └────────────────────┘
|
|
69
|
+
│
|
|
70
|
+
▼
|
|
71
|
+
┌───────────┐ ┌──────────────────┐ ┌──────────────────────┐
|
|
72
|
+
│ PR Stager │<───│ Data Dumper │<───│ Splunk Validator │
|
|
73
|
+
└───────────┘ └──────────────────┘ └──────────────────────┘
|
|
74
|
+
▲
|
|
75
|
+
│
|
|
76
|
+
┌──────────────────┐
|
|
77
|
+
│ Atomic Executor │
|
|
78
|
+
└──────────────────┘
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### MCP Integration
|
|
82
|
+
|
|
83
|
+
The autonomous pipeline integrates with existing MCPs:
|
|
84
|
+
- **security-detections** - Coverage analysis and gap identification
|
|
85
|
+
- **splunk-mcp** - Detection validation (`run_detection`, `export_dump`)
|
|
86
|
+
- **mitre-attack** - Technique lookups
|
|
87
|
+
|
|
88
|
+
### Human-in-the-Loop
|
|
89
|
+
|
|
90
|
+
**CRITICAL**: The system NEVER auto-commits or auto-merges. All PRs are created as **DRAFT** requiring human review:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
[PR Stager] ✓ security_content DRAFT PR created: https://github.com/splunk/security_content/pull/123
|
|
94
|
+
[PR Stager] ✓ attack_data DRAFT PR created: https://github.com/splunk/attack_data/pull/456
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
See the [Autonomous Platform Documentation](./docs/AUTONOMOUS.md) for full details, and the [E2E Testing Guide](./docs/E2E-TESTING-GUIDE.md) for per-SIEM setup (Splunk, Sentinel, Elastic, Sigma).
|
|
4
98
|
|
|
5
99
|
[](https://cursor.com/en/install-mcp?name=security-detections&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNlY3VyaXR5LWRldGVjdGlvbnMtbWNwIl0sImVudiI6eyJTSUdNQV9QQVRIUyI6Ii9wYXRoL3RvL3NpZ21hL3J1bGVzLC9wYXRoL3RvL3NpZ21hL3J1bGVzLXRocmVhdC1odW50aW5nIiwiU1BMVU5LX1BBVEhTIjoiL3BhdGgvdG8vc2VjdXJpdHlfY29udGVudC9kZXRlY3Rpb25zIiwiU1RPUllfUEFUSFMiOiIvcGF0aC90by9zZWN1cml0eV9jb250ZW50L3N0b3JpZXMiLCJFTEFTVElDX1BBVEhTIjoiL3BhdGgvdG8vZGV0ZWN0aW9uLXJ1bGVzL3J1bGVzIiwiS1FMX1BBVEhTIjoiL3BhdGgvdG8va3FsLXJ1bGVzIn19)
|
|
6
100
|
|
|
101
|
+
> **Detailed setup**: See the **[Setup Guide](./SETUP.md)** for step-by-step install on macOS, Windows (WSL & native), and Linux with troubleshooting for common issues.
|
|
102
|
+
|
|
7
103
|
## 🐛 Version 2.1.1 (Bug Fix)
|
|
8
104
|
|
|
9
105
|
- **Fixed Windows EBUSY crash** - SQLite database recreation now handles Windows file locking with retry logic. Previously, Windows users would get `EBUSY: resource busy or locked` on startup.
|
|
@@ -122,7 +218,7 @@ Claude will:
|
|
|
122
218
|
- **🆕 Server Instructions** - Built-in usage guide with examples for better LLM understanding
|
|
123
219
|
- **🆕 Structured Errors** - Helpful error messages with suggestions and similar items
|
|
124
220
|
- **🆕 Interactive Tools** - Gap prioritization and sprint planning with form-based input (Cursor 0.42+)
|
|
125
|
-
- **Unified Search** - Query Sigma, Splunk ESCU, Elastic, and
|
|
221
|
+
- **Unified Search** - Query Sigma, Splunk ESCU, Elastic, KQL, Sublime, and CrowdStrike CQL detections from a single interface
|
|
126
222
|
- **Full-Text Search** - SQLite FTS5 powered search across names, descriptions, queries, MITRE tactics, CVEs, process names, and more
|
|
127
223
|
- **MITRE ATT&CK Mapping** - Filter detections by technique ID or tactic
|
|
128
224
|
- **CVE Coverage** - Find detections for specific CVE vulnerabilities
|
|
@@ -130,7 +226,7 @@ Claude will:
|
|
|
130
226
|
- **Analytic Stories** - Query by Splunk analytic story (optional - enhances context)
|
|
131
227
|
- **KQL Categories** - Filter KQL queries by category (Defender For Endpoint, Azure AD, Threat Hunting, etc.)
|
|
132
228
|
- **Auto-Indexing** - Automatically indexes detections on startup from configured paths
|
|
133
|
-
- **Multi-Format Support** - YAML (Sigma, Splunk), TOML (Elastic), Markdown (KQL)
|
|
229
|
+
- **Multi-Format Support** - YAML (Sigma, Splunk, Sublime, CrowdStrike CQL), TOML (Elastic), Markdown (KQL)
|
|
134
230
|
- **Logsource Filtering** - Filter Sigma rules by category, product, or service
|
|
135
231
|
- **Severity Filtering** - Filter by criticality level
|
|
136
232
|
|
|
@@ -170,7 +266,9 @@ Add to your MCP config (`~/.cursor/mcp.json` or `.cursor/mcp.json` in your proje
|
|
|
170
266
|
"SPLUNK_PATHS": "/path/to/security_content/detections",
|
|
171
267
|
"ELASTIC_PATHS": "/path/to/detection-rules/rules",
|
|
172
268
|
"STORY_PATHS": "/path/to/security_content/stories",
|
|
173
|
-
"KQL_PATHS": "/path/to/Hunting-Queries-Detection-Rules"
|
|
269
|
+
"KQL_PATHS": "/path/to/Hunting-Queries-Detection-Rules",
|
|
270
|
+
"SUBLIME_PATHS": "/path/to/sublime-rules/detection-rules",
|
|
271
|
+
"CQL_HUB_PATHS": "/path/to/cql-hub/queries"
|
|
174
272
|
}
|
|
175
273
|
}
|
|
176
274
|
}
|
|
@@ -192,7 +290,9 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
192
290
|
"SPLUNK_PATHS": "/Users/you/security_content/detections",
|
|
193
291
|
"ELASTIC_PATHS": "/Users/you/detection-rules/rules",
|
|
194
292
|
"STORY_PATHS": "/Users/you/security_content/stories",
|
|
195
|
-
"KQL_PATHS": "/Users/you/Hunting-Queries-Detection-Rules"
|
|
293
|
+
"KQL_PATHS": "/Users/you/Hunting-Queries-Detection-Rules",
|
|
294
|
+
"SUBLIME_PATHS": "/Users/you/sublime-rules/detection-rules",
|
|
295
|
+
"CQL_HUB_PATHS": "/Users/you/cql-hub/queries"
|
|
196
296
|
}
|
|
197
297
|
}
|
|
198
298
|
}
|
|
@@ -214,7 +314,9 @@ Add to `~/.vscode/mcp.json`:
|
|
|
214
314
|
"SPLUNK_PATHS": "/Users/you/security_content/detections",
|
|
215
315
|
"ELASTIC_PATHS": "/Users/you/detection-rules/rules",
|
|
216
316
|
"KQL_PATHS": "/Users/you/kql-bertjanp,/Users/you/kql-jkerai1",
|
|
217
|
-
"STORY_PATHS": "/Users/you/security_content/stories"
|
|
317
|
+
"STORY_PATHS": "/Users/you/security_content/stories",
|
|
318
|
+
"SUBLIME_PATHS": "/Users/you/sublime-rules/detection-rules",
|
|
319
|
+
"CQL_HUB_PATHS": "/Users/you/cql-hub/queries"
|
|
218
320
|
}
|
|
219
321
|
}
|
|
220
322
|
}
|
|
@@ -236,7 +338,9 @@ Add to `~/.vscode/mcp.json`:
|
|
|
236
338
|
"SPLUNK_PATHS": "/Users/you/security_content/detections",
|
|
237
339
|
"ELASTIC_PATHS": "/Users/you/detection-rules/rules",
|
|
238
340
|
"KQL_PATHS": "/Users/you/kql-bertjanp,/Users/you/kql-jkerai1",
|
|
239
|
-
"STORY_PATHS": "/Users/you/security_content/stories"
|
|
341
|
+
"STORY_PATHS": "/Users/you/security_content/stories",
|
|
342
|
+
"SUBLIME_PATHS": "/Users/you/sublime-rules/detection-rules",
|
|
343
|
+
"CQL_HUB_PATHS": "/Users/you/cql-hub/queries"
|
|
240
344
|
}
|
|
241
345
|
}
|
|
242
346
|
}
|
|
@@ -250,6 +354,8 @@ Add to `~/.vscode/mcp.json`:
|
|
|
250
354
|
| `SPLUNK_PATHS` | Comma-separated paths to Splunk ESCU detection directories | At least one source required |
|
|
251
355
|
| `ELASTIC_PATHS` | Comma-separated paths to Elastic detection rule directories | At least one source required |
|
|
252
356
|
| `KQL_PATHS` | Comma-separated paths to KQL hunting query directories | At least one source required |
|
|
357
|
+
| `SUBLIME_PATHS` | Comma-separated paths to Sublime Security rule directories | At least one source required |
|
|
358
|
+
| `CQL_HUB_PATHS` | Comma-separated paths to CQL Hub (CrowdStrike) query directories | At least one source required |
|
|
253
359
|
| `STORY_PATHS` | Comma-separated paths to Splunk analytic story directories | No (enhances context) |
|
|
254
360
|
|
|
255
361
|
## Getting Detection Content
|
|
@@ -278,11 +384,20 @@ cd detection-rules && git sparse-checkout set rules && cd ..
|
|
|
278
384
|
git clone --depth 1 https://github.com/Bert-JanP/Hunting-Queries-Detection-Rules.git kql-bertjanp
|
|
279
385
|
git clone --depth 1 https://github.com/jkerai1/KQL-Queries.git kql-jkerai1
|
|
280
386
|
|
|
387
|
+
# Download Sublime Security email detection rules (~900+ rules)
|
|
388
|
+
git clone --depth 1 --filter=blob:none --sparse https://github.com/sublime-security/sublime-rules.git
|
|
389
|
+
cd sublime-rules && git sparse-checkout set detection-rules && cd ..
|
|
390
|
+
|
|
391
|
+
# Download CQL Hub CrowdStrike queries (~139+ queries)
|
|
392
|
+
git clone --depth 1 https://github.com/ByteRay-Labs/Query-Hub.git cql-hub
|
|
393
|
+
|
|
281
394
|
echo "Done! Configure your MCP with these paths:"
|
|
282
395
|
echo " SIGMA_PATHS: $(pwd)/sigma/rules,$(pwd)/sigma/rules-threat-hunting"
|
|
283
396
|
echo " SPLUNK_PATHS: $(pwd)/security_content/detections"
|
|
284
397
|
echo " ELASTIC_PATHS: $(pwd)/detection-rules/rules"
|
|
285
398
|
echo " KQL_PATHS: $(pwd)/kql-bertjanp,$(pwd)/kql-jkerai1"
|
|
399
|
+
echo " SUBLIME_PATHS: $(pwd)/sublime-rules/detection-rules"
|
|
400
|
+
echo " CQL_HUB_PATHS: $(pwd)/cql-hub/queries"
|
|
286
401
|
echo " STORY_PATHS: $(pwd)/security_content/stories"
|
|
287
402
|
```
|
|
288
403
|
|
|
@@ -307,6 +422,14 @@ git clone https://github.com/elastic/detection-rules.git
|
|
|
307
422
|
git clone https://github.com/Bert-JanP/Hunting-Queries-Detection-Rules.git
|
|
308
423
|
git clone https://github.com/jkerai1/KQL-Queries.git
|
|
309
424
|
# Use entire repos, combine paths with comma
|
|
425
|
+
|
|
426
|
+
# Sublime Security Rules
|
|
427
|
+
git clone https://github.com/sublime-security/sublime-rules.git
|
|
428
|
+
# Use detection-rules/ directory
|
|
429
|
+
|
|
430
|
+
# CQL Hub (CrowdStrike Query Language)
|
|
431
|
+
git clone https://github.com/ByteRay-Labs/Query-Hub.git
|
|
432
|
+
# Use queries/ directory
|
|
310
433
|
```
|
|
311
434
|
|
|
312
435
|
## 🆕 MCP Resources - Readable Context
|
|
@@ -336,7 +459,7 @@ The server provides **autocomplete suggestions** as you type argument values:
|
|
|
336
459
|
| `process_name` | Process names in your detections (powershell.exe, etc.) |
|
|
337
460
|
| `tactic` | All 14 MITRE tactics |
|
|
338
461
|
| `severity` | informational, low, medium, high, critical |
|
|
339
|
-
| `source_type` | sigma, splunk_escu, elastic, kql |
|
|
462
|
+
| `source_type` | sigma, splunk_escu, elastic, kql, sublime, crowdstrike_cql |
|
|
340
463
|
| `threat_profile` | ransomware, apt, initial-access, persistence, etc. |
|
|
341
464
|
|
|
342
465
|
This prevents typos and helps discover what values are available in your detection corpus.
|
|
@@ -395,7 +518,7 @@ Tool: prioritize_gaps(threat_profile="ransomware")
|
|
|
395
518
|
| `search(query, limit)` | Full-text search across all detection fields (names, descriptions, queries, CVEs, process names, etc.) |
|
|
396
519
|
| `get_by_id(id)` | Get a single detection by its ID |
|
|
397
520
|
| `list_all(limit, offset)` | Paginated list of all detections |
|
|
398
|
-
| `list_by_source(source_type)` | Filter by `sigma`, `splunk_escu`, `elastic`, or `
|
|
521
|
+
| `list_by_source(source_type)` | Filter by `sigma`, `splunk_escu`, `elastic`, `kql`, `sublime`, or `crowdstrike_cql` |
|
|
399
522
|
| `get_raw_yaml(id)` | Get the original YAML/TOML/Markdown content |
|
|
400
523
|
| `get_stats()` | Get index statistics |
|
|
401
524
|
| `rebuild_index()` | Force re-index from configured paths |
|
|
@@ -746,7 +869,7 @@ Tool: list_by_cve(cve_id="CVE-2024-27198")
|
|
|
746
869
|
```
|
|
747
870
|
LLM: "What detections do we have for credential dumping?"
|
|
748
871
|
Tool: search(query="credential dumping", limit=10)
|
|
749
|
-
→ Returns results from Sigma, Splunk, Elastic, AND
|
|
872
|
+
→ Returns results from Sigma, Splunk, Elastic, KQL, Sublime, AND CrowdStrike CQL
|
|
750
873
|
```
|
|
751
874
|
|
|
752
875
|
#### Find Web Server Attack Detections
|
|
@@ -771,6 +894,22 @@ LLM: "What KQL queries do we have for Defender For Endpoint?"
|
|
|
771
894
|
Tool: list_by_kql_category(category="Defender For Endpoint")
|
|
772
895
|
```
|
|
773
896
|
|
|
897
|
+
#### Find BEC/Phishing Email Detections
|
|
898
|
+
|
|
899
|
+
```
|
|
900
|
+
LLM: "What email detections do we have for BEC fraud?"
|
|
901
|
+
Tool: list_by_source(source_type="sublime")
|
|
902
|
+
→ Returns Sublime Security email detection rules for BEC, phishing, malware, etc.
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
#### Find CrowdStrike CQL Hunting Queries
|
|
906
|
+
|
|
907
|
+
```
|
|
908
|
+
LLM: "What CrowdStrike queries do we have for lateral movement?"
|
|
909
|
+
Tool: list_by_source(source_type="crowdstrike_cql")
|
|
910
|
+
→ Returns CQL Hub queries for CrowdStrike NextGen SIEM and Falcon LogScale
|
|
911
|
+
```
|
|
912
|
+
|
|
774
913
|
#### Search for BloodHound Detections
|
|
775
914
|
|
|
776
915
|
```
|
|
@@ -781,7 +920,7 @@ Tool: search(query="bloodhound", limit=10)
|
|
|
781
920
|
|
|
782
921
|
## Unified Schema
|
|
783
922
|
|
|
784
|
-
All detection sources (Sigma, Splunk, Elastic, KQL) are normalized to a common schema:
|
|
923
|
+
All detection sources (Sigma, Splunk, Elastic, KQL, Sublime, CrowdStrike CQL) are normalized to a common schema:
|
|
785
924
|
|
|
786
925
|
### Core Fields
|
|
787
926
|
|
|
@@ -790,8 +929,8 @@ All detection sources (Sigma, Splunk, Elastic, KQL) are normalized to a common s
|
|
|
790
929
|
| `id` | Unique identifier |
|
|
791
930
|
| `name` | Detection name/title |
|
|
792
931
|
| `description` | What the detection looks for |
|
|
793
|
-
| `query` | Detection logic (Sigma YAML, Splunk SPL, Elastic EQL, or
|
|
794
|
-
| `source_type` | `sigma`, `splunk_escu`, `elastic`, or `
|
|
932
|
+
| `query` | Detection logic (Sigma YAML, Splunk SPL, Elastic EQL, KQL, Sublime MQL, or CrowdStrike CQL) |
|
|
933
|
+
| `source_type` | `sigma`, `splunk_escu`, `elastic`, `kql`, `sublime`, or `crowdstrike_cql` |
|
|
795
934
|
| `severity` | Detection severity level |
|
|
796
935
|
| `status` | Rule status (stable, test, experimental, production, etc.) |
|
|
797
936
|
| `author` | Rule author |
|
|
@@ -823,6 +962,14 @@ All detection sources (Sigma, Splunk, Elastic, KQL) are normalized to a common s
|
|
|
823
962
|
| `kql_keywords` | Security keywords extracted for search |
|
|
824
963
|
| `platforms` | Platforms (windows, azure-ad, office-365, etc.) |
|
|
825
964
|
|
|
965
|
+
### Sublime-Specific Fields
|
|
966
|
+
|
|
967
|
+
| Field | Description |
|
|
968
|
+
|-------|-------------|
|
|
969
|
+
| `sublime_attack_types` | Attack types (BEC/Fraud, Credential Phishing, Malware/Ransomware, etc.) |
|
|
970
|
+
| `sublime_detection_methods` | Detection methods (Content analysis, URL analysis, Computer Vision, etc.) |
|
|
971
|
+
| `sublime_tactics` | Tactics and techniques (Evasion, Impersonation: Brand, Social engineering, etc.) |
|
|
972
|
+
|
|
826
973
|
## Database
|
|
827
974
|
|
|
828
975
|
The index is stored at `~/.cache/security-detections-mcp/detections.sqlite`.
|
|
@@ -860,6 +1007,22 @@ From [Elastic Detection Rules](https://github.com/elastic/detection-rules):
|
|
|
860
1007
|
- Optional: `rule.description`, `rule.query`, `rule.severity`, `rule.tags`, `rule.threat` (MITRE mappings)
|
|
861
1008
|
- Supports EQL, KQL, Lucene, and ESQL query languages
|
|
862
1009
|
|
|
1010
|
+
### Sublime Security Rules (YAML)
|
|
1011
|
+
|
|
1012
|
+
From [Sublime Security](https://github.com/sublime-security/sublime-rules):
|
|
1013
|
+
- Required: `name`, `type` (rule/exclusion), `source` (MQL query)
|
|
1014
|
+
- Optional: `description`, `severity`, `id`, `references`, `tags`, `authors`, `attack_types`, `tactics_and_techniques`, `detection_methods`, `false_positives`
|
|
1015
|
+
- Uses MQL (Message Query Language) for email-specific detection logic
|
|
1016
|
+
- Covers BEC/fraud, credential phishing, malware delivery, spam, and more
|
|
1017
|
+
|
|
1018
|
+
### CrowdStrike CQL Queries (YAML)
|
|
1019
|
+
|
|
1020
|
+
From [CQL Hub](https://github.com/ByteRay-Labs/Query-Hub):
|
|
1021
|
+
- Required: `name`, `cql` (CrowdStrike Query Language query)
|
|
1022
|
+
- Optional: `description`, `mitre_ids`, `author`, `log_sources`, `tags`, `cs_required_modules`, `explanation`
|
|
1023
|
+
- Community-driven detection and hunting queries for CrowdStrike NextGen SIEM and Falcon LogScale
|
|
1024
|
+
- Covers endpoint, network, cloud, and identity detection use cases
|
|
1025
|
+
|
|
863
1026
|
### KQL Hunting Queries (Markdown & Raw .kql)
|
|
864
1027
|
|
|
865
1028
|
Supports multiple KQL repositories:
|
|
@@ -944,6 +1107,8 @@ SIGMA_PATHS="./detections/sigma/rules" \
|
|
|
944
1107
|
SPLUNK_PATHS="./detections/splunk/detections" \
|
|
945
1108
|
ELASTIC_PATHS="./detections/elastic/rules" \
|
|
946
1109
|
KQL_PATHS="./detections/kql" \
|
|
1110
|
+
SUBLIME_PATHS="./detections/sublime-rules/detection-rules" \
|
|
1111
|
+
CQL_HUB_PATHS="./detections/cql-hub/queries" \
|
|
947
1112
|
STORY_PATHS="./detections/splunk/stories" \
|
|
948
1113
|
npm start
|
|
949
1114
|
```
|
|
@@ -958,11 +1123,13 @@ When fully indexed with all sources:
|
|
|
958
1123
|
| Splunk ESCU | ~2,000+ |
|
|
959
1124
|
| Elastic Rules | ~1,500+ |
|
|
960
1125
|
| KQL Queries | ~420+ |
|
|
1126
|
+
| Sublime Rules | ~900+ |
|
|
1127
|
+
| CrowdStrike CQL | ~139+ |
|
|
961
1128
|
| Analytic Stories | ~330 |
|
|
962
|
-
| **Total Detections** | **~
|
|
1129
|
+
| **Total Detections** | **~8,200+** |
|
|
963
1130
|
| **Indexed Patterns** | **10,235+** |
|
|
964
1131
|
| **Techniques with Patterns** | **528+** |
|
|
965
|
-
| **Detection Formats** | **
|
|
1132
|
+
| **Detection Formats** | **6** (Sigma, Splunk, Elastic, KQL, Sublime, CrowdStrike CQL) |
|
|
966
1133
|
| **Total Tools** | **71+** |
|
|
967
1134
|
| **MCP Prompts** | **11** |
|
|
968
1135
|
| **MCP Resources** | **9 static + 5 templates** |
|
|
@@ -1067,7 +1234,7 @@ For detailed information on v2.1 features:
|
|
|
1067
1234
|
|
|
1068
1235
|
| MCP | Purpose |
|
|
1069
1236
|
|-----|---------|
|
|
1070
|
-
| **security-detections-mcp** | Query
|
|
1237
|
+
| **security-detections-mcp** | Query 8,100+ detection rules + 11 expert workflow prompts |
|
|
1071
1238
|
| **mitre-attack-mcp** | ATT&CK framework data, threat groups, Navigator layers |
|
|
1072
1239
|
|
|
1073
1240
|
### With MCP Prompts (Easiest)
|
|
@@ -1133,7 +1300,9 @@ LLM workflow:
|
|
|
1133
1300
|
"SIGMA_PATHS": "/path/to/sigma/rules",
|
|
1134
1301
|
"SPLUNK_PATHS": "/path/to/security_content/detections",
|
|
1135
1302
|
"ELASTIC_PATHS": "/path/to/detection-rules/rules",
|
|
1136
|
-
"KQL_PATHS": "/path/to/kql-hunting-queries"
|
|
1303
|
+
"KQL_PATHS": "/path/to/kql-hunting-queries",
|
|
1304
|
+
"SUBLIME_PATHS": "/path/to/sublime-rules/detection-rules",
|
|
1305
|
+
"CQL_HUB_PATHS": "/path/to/cql-hub/queries"
|
|
1137
1306
|
}
|
|
1138
1307
|
},
|
|
1139
1308
|
"mitre-attack": {
|
package/dist/db/detections.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface ValidationResult {
|
|
|
12
12
|
similar?: string[];
|
|
13
13
|
}
|
|
14
14
|
export interface TechniqueIdFilters {
|
|
15
|
-
source_type?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql';
|
|
15
|
+
source_type?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql';
|
|
16
16
|
tactic?: string;
|
|
17
17
|
severity?: string;
|
|
18
18
|
}
|
|
@@ -59,7 +59,7 @@ export interface DetectionSuggestion {
|
|
|
59
59
|
export interface NavigatorLayerOptions {
|
|
60
60
|
name: string;
|
|
61
61
|
description?: string;
|
|
62
|
-
source_type?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql';
|
|
62
|
+
source_type?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql';
|
|
63
63
|
tactic?: string;
|
|
64
64
|
severity?: string;
|
|
65
65
|
}
|
|
@@ -107,7 +107,7 @@ export declare function listDetections(limit?: number, offset?: number): Detecti
|
|
|
107
107
|
/**
|
|
108
108
|
* List detections filtered by source type.
|
|
109
109
|
*/
|
|
110
|
-
export declare function listBySource(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql', limit?: number, offset?: number): Detection[];
|
|
110
|
+
export declare function listBySource(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql', limit?: number, offset?: number): Detection[];
|
|
111
111
|
/**
|
|
112
112
|
* List detections by MITRE technique ID.
|
|
113
113
|
*/
|
|
@@ -183,15 +183,15 @@ export declare function getTechniqueIds(filters?: TechniqueIdFilters): string[];
|
|
|
183
183
|
/**
|
|
184
184
|
* Analyze coverage by tactic and identify strengths/weaknesses.
|
|
185
185
|
*/
|
|
186
|
-
export declare function analyzeCoverage(sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql'): CoverageReport;
|
|
186
|
+
export declare function analyzeCoverage(sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql'): CoverageReport;
|
|
187
187
|
/**
|
|
188
188
|
* Identify gaps based on a threat profile.
|
|
189
189
|
*/
|
|
190
|
-
export declare function identifyGaps(threatProfile: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql'): GapAnalysis;
|
|
190
|
+
export declare function identifyGaps(threatProfile: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql'): GapAnalysis;
|
|
191
191
|
/**
|
|
192
192
|
* Suggest detections for a technique.
|
|
193
193
|
*/
|
|
194
|
-
export declare function suggestDetections(techniqueId: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql'): DetectionSuggestion;
|
|
194
|
+
export declare function suggestDetections(techniqueId: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql'): DetectionSuggestion;
|
|
195
195
|
/**
|
|
196
196
|
* Generate an ATT&CK Navigator layer from detection coverage.
|
|
197
197
|
*/
|
|
@@ -203,7 +203,7 @@ export declare function searchDetectionList(query: string, limit?: number): Dete
|
|
|
203
203
|
/**
|
|
204
204
|
* List detections by source with optional name filter, returning lightweight results.
|
|
205
205
|
*/
|
|
206
|
-
export declare function listDetectionsBySourceLight(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql', nameFilter?: string, limit?: number): DetectionListItem[];
|
|
206
|
+
export declare function listDetectionsBySourceLight(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql', nameFilter?: string, limit?: number): DetectionListItem[];
|
|
207
207
|
/**
|
|
208
208
|
* Compare detections across sources for a topic.
|
|
209
209
|
*/
|
|
@@ -211,7 +211,7 @@ export declare function compareDetectionsBySource(topic: string, limit?: number)
|
|
|
211
211
|
/**
|
|
212
212
|
* Get detection names and IDs matching a pattern, grouped by source.
|
|
213
213
|
*/
|
|
214
|
-
export declare function getDetectionNamesByPattern(pattern: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql'): {
|
|
214
|
+
export declare function getDetectionNamesByPattern(pattern: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql'): {
|
|
215
215
|
source: string;
|
|
216
216
|
detections: Array<{
|
|
217
217
|
name: string;
|
package/dist/db/detections.js
CHANGED
|
@@ -75,6 +75,9 @@ function rowToDetection(row) {
|
|
|
75
75
|
kql_category: row.kql_category,
|
|
76
76
|
kql_tags: safeJsonParse(row.kql_tags, []),
|
|
77
77
|
kql_keywords: safeJsonParse(row.kql_keywords, []),
|
|
78
|
+
sublime_attack_types: safeJsonParse(row.sublime_attack_types, []),
|
|
79
|
+
sublime_detection_methods: safeJsonParse(row.sublime_detection_methods, []),
|
|
80
|
+
sublime_tactics: safeJsonParse(row.sublime_tactics, []),
|
|
78
81
|
};
|
|
79
82
|
}
|
|
80
83
|
function rowToListItem(row) {
|
|
@@ -95,15 +98,16 @@ function rowToListItem(row) {
|
|
|
95
98
|
export function insertDetection(detection) {
|
|
96
99
|
const database = getDb();
|
|
97
100
|
const stmt = database.prepare(`
|
|
98
|
-
INSERT OR REPLACE INTO detections
|
|
99
|
-
(id, name, description, query, source_type, mitre_ids, logsource_category,
|
|
100
|
-
logsource_product, logsource_service, severity, status, author,
|
|
101
|
+
INSERT OR REPLACE INTO detections
|
|
102
|
+
(id, name, description, query, source_type, mitre_ids, logsource_category,
|
|
103
|
+
logsource_product, logsource_service, severity, status, author,
|
|
101
104
|
date_created, date_modified, refs, falsepositives, tags, file_path, raw_yaml,
|
|
102
105
|
cves, analytic_stories, data_sources, detection_type, asset_type, security_domain,
|
|
103
|
-
process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords
|
|
104
|
-
|
|
106
|
+
process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords,
|
|
107
|
+
sublime_attack_types, sublime_detection_methods, sublime_tactics)
|
|
108
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
105
109
|
`);
|
|
106
|
-
stmt.run(detection.id, detection.name, detection.description, detection.query, detection.source_type, JSON.stringify(detection.mitre_ids), detection.logsource_category, detection.logsource_product, detection.logsource_service, detection.severity, detection.status, detection.author, detection.date_created, detection.date_modified, JSON.stringify(detection.references), JSON.stringify(detection.falsepositives), JSON.stringify(detection.tags), detection.file_path, detection.raw_yaml, JSON.stringify(detection.cves), JSON.stringify(detection.analytic_stories), JSON.stringify(detection.data_sources), detection.detection_type, detection.asset_type, detection.security_domain, JSON.stringify(detection.process_names), JSON.stringify(detection.file_paths), JSON.stringify(detection.registry_paths), JSON.stringify(detection.mitre_tactics), JSON.stringify(detection.platforms), detection.kql_category, JSON.stringify(detection.kql_tags), JSON.stringify(detection.kql_keywords));
|
|
110
|
+
stmt.run(detection.id, detection.name, detection.description, detection.query, detection.source_type, JSON.stringify(detection.mitre_ids), detection.logsource_category, detection.logsource_product, detection.logsource_service, detection.severity, detection.status, detection.author, detection.date_created, detection.date_modified, JSON.stringify(detection.references), JSON.stringify(detection.falsepositives), JSON.stringify(detection.tags), detection.file_path, detection.raw_yaml, JSON.stringify(detection.cves), JSON.stringify(detection.analytic_stories), JSON.stringify(detection.data_sources), detection.detection_type, detection.asset_type, detection.security_domain, JSON.stringify(detection.process_names), JSON.stringify(detection.file_paths), JSON.stringify(detection.registry_paths), JSON.stringify(detection.mitre_tactics), JSON.stringify(detection.platforms), detection.kql_category, JSON.stringify(detection.kql_tags), JSON.stringify(detection.kql_keywords), JSON.stringify(detection.sublime_attack_types), JSON.stringify(detection.sublime_detection_methods), JSON.stringify(detection.sublime_tactics));
|
|
107
111
|
}
|
|
108
112
|
/**
|
|
109
113
|
* Get a detection by its ID.
|
|
@@ -348,6 +352,7 @@ export function getStats() {
|
|
|
348
352
|
const splunk = database.prepare("SELECT COUNT(*) as count FROM detections WHERE source_type = 'splunk_escu'").get().count;
|
|
349
353
|
const elastic = database.prepare("SELECT COUNT(*) as count FROM detections WHERE source_type = 'elastic'").get().count;
|
|
350
354
|
const kql = database.prepare("SELECT COUNT(*) as count FROM detections WHERE source_type = 'kql'").get().count;
|
|
355
|
+
const sublime = database.prepare("SELECT COUNT(*) as count FROM detections WHERE source_type = 'sublime'").get().count;
|
|
351
356
|
// Count by severity
|
|
352
357
|
const severityRows = database.prepare(`
|
|
353
358
|
SELECT severity, COUNT(*) as count FROM detections
|
|
@@ -425,6 +430,7 @@ export function getStats() {
|
|
|
425
430
|
splunk_escu: splunk,
|
|
426
431
|
elastic,
|
|
427
432
|
kql,
|
|
433
|
+
sublime,
|
|
428
434
|
by_severity,
|
|
429
435
|
by_logsource_product,
|
|
430
436
|
mitre_coverage,
|
|
@@ -863,6 +869,7 @@ export function compareDetectionsBySource(topic, limit = 100) {
|
|
|
863
869
|
splunk_escu: [],
|
|
864
870
|
elastic: [],
|
|
865
871
|
kql: [],
|
|
872
|
+
sublime: [],
|
|
866
873
|
};
|
|
867
874
|
const byTactic = {};
|
|
868
875
|
for (const row of rows) {
|
|
@@ -936,7 +943,7 @@ export function countDetectionsBySource(topic) {
|
|
|
936
943
|
GROUP BY d.source_type
|
|
937
944
|
`);
|
|
938
945
|
const rows = stmt.all(topic);
|
|
939
|
-
const result = { sigma: 0, splunk_escu: 0, elastic: 0, kql: 0 };
|
|
946
|
+
const result = { sigma: 0, splunk_escu: 0, elastic: 0, kql: 0, sublime: 0, crowdstrike_cql: 0 };
|
|
940
947
|
for (const row of rows) {
|
|
941
948
|
result[row.source_type] = row.count;
|
|
942
949
|
}
|
package/dist/db/schema.js
CHANGED
|
@@ -56,7 +56,10 @@ function createDetectionsTable(db) {
|
|
|
56
56
|
platforms TEXT,
|
|
57
57
|
kql_category TEXT,
|
|
58
58
|
kql_tags TEXT,
|
|
59
|
-
kql_keywords TEXT
|
|
59
|
+
kql_keywords TEXT,
|
|
60
|
+
sublime_attack_types TEXT,
|
|
61
|
+
sublime_detection_methods TEXT,
|
|
62
|
+
sublime_tactics TEXT
|
|
60
63
|
)
|
|
61
64
|
`);
|
|
62
65
|
}
|
|
@@ -83,6 +86,9 @@ function createDetectionsFts(db) {
|
|
|
83
86
|
kql_category,
|
|
84
87
|
kql_tags,
|
|
85
88
|
kql_keywords,
|
|
89
|
+
sublime_attack_types,
|
|
90
|
+
sublime_detection_methods,
|
|
91
|
+
sublime_tactics,
|
|
86
92
|
content='detections',
|
|
87
93
|
content_rowid='rowid'
|
|
88
94
|
)
|
|
@@ -95,24 +101,24 @@ function createDetectionsTriggers(db) {
|
|
|
95
101
|
// After INSERT trigger
|
|
96
102
|
db.exec(`
|
|
97
103
|
CREATE TRIGGER IF NOT EXISTS detections_ai AFTER INSERT ON detections BEGIN
|
|
98
|
-
INSERT INTO detections_fts(rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords)
|
|
99
|
-
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.description, NEW.query, NEW.mitre_ids, NEW.tags, NEW.cves, NEW.analytic_stories, NEW.data_sources, NEW.process_names, NEW.file_paths, NEW.registry_paths, NEW.mitre_tactics, NEW.platforms, NEW.kql_category, NEW.kql_tags, NEW.kql_keywords);
|
|
104
|
+
INSERT INTO detections_fts(rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords, sublime_attack_types, sublime_detection_methods, sublime_tactics)
|
|
105
|
+
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.description, NEW.query, NEW.mitre_ids, NEW.tags, NEW.cves, NEW.analytic_stories, NEW.data_sources, NEW.process_names, NEW.file_paths, NEW.registry_paths, NEW.mitre_tactics, NEW.platforms, NEW.kql_category, NEW.kql_tags, NEW.kql_keywords, NEW.sublime_attack_types, NEW.sublime_detection_methods, NEW.sublime_tactics);
|
|
100
106
|
END
|
|
101
107
|
`);
|
|
102
108
|
// After DELETE trigger
|
|
103
109
|
db.exec(`
|
|
104
110
|
CREATE TRIGGER IF NOT EXISTS detections_ad AFTER DELETE ON detections BEGIN
|
|
105
|
-
INSERT INTO detections_fts(detections_fts, rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords)
|
|
106
|
-
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.description, OLD.query, OLD.mitre_ids, OLD.tags, OLD.cves, OLD.analytic_stories, OLD.data_sources, OLD.process_names, OLD.file_paths, OLD.registry_paths, OLD.mitre_tactics, OLD.platforms, OLD.kql_category, OLD.kql_tags, OLD.kql_keywords);
|
|
111
|
+
INSERT INTO detections_fts(detections_fts, rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords, sublime_attack_types, sublime_detection_methods, sublime_tactics)
|
|
112
|
+
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.description, OLD.query, OLD.mitre_ids, OLD.tags, OLD.cves, OLD.analytic_stories, OLD.data_sources, OLD.process_names, OLD.file_paths, OLD.registry_paths, OLD.mitre_tactics, OLD.platforms, OLD.kql_category, OLD.kql_tags, OLD.kql_keywords, OLD.sublime_attack_types, OLD.sublime_detection_methods, OLD.sublime_tactics);
|
|
107
113
|
END
|
|
108
114
|
`);
|
|
109
115
|
// After UPDATE trigger
|
|
110
116
|
db.exec(`
|
|
111
117
|
CREATE TRIGGER IF NOT EXISTS detections_au AFTER UPDATE ON detections BEGIN
|
|
112
|
-
INSERT INTO detections_fts(detections_fts, rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords)
|
|
113
|
-
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.description, OLD.query, OLD.mitre_ids, OLD.tags, OLD.cves, OLD.analytic_stories, OLD.data_sources, OLD.process_names, OLD.file_paths, OLD.registry_paths, OLD.mitre_tactics, OLD.platforms, OLD.kql_category, OLD.kql_tags, OLD.kql_keywords);
|
|
114
|
-
INSERT INTO detections_fts(rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords)
|
|
115
|
-
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.description, NEW.query, NEW.mitre_ids, NEW.tags, NEW.cves, NEW.analytic_stories, NEW.data_sources, NEW.process_names, NEW.file_paths, NEW.registry_paths, NEW.mitre_tactics, NEW.platforms, NEW.kql_category, NEW.kql_tags, NEW.kql_keywords);
|
|
118
|
+
INSERT INTO detections_fts(detections_fts, rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords, sublime_attack_types, sublime_detection_methods, sublime_tactics)
|
|
119
|
+
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.description, OLD.query, OLD.mitre_ids, OLD.tags, OLD.cves, OLD.analytic_stories, OLD.data_sources, OLD.process_names, OLD.file_paths, OLD.registry_paths, OLD.mitre_tactics, OLD.platforms, OLD.kql_category, OLD.kql_tags, OLD.kql_keywords, OLD.sublime_attack_types, OLD.sublime_detection_methods, OLD.sublime_tactics);
|
|
120
|
+
INSERT INTO detections_fts(rowid, id, name, description, query, mitre_ids, tags, cves, analytic_stories, data_sources, process_names, file_paths, registry_paths, mitre_tactics, platforms, kql_category, kql_tags, kql_keywords, sublime_attack_types, sublime_detection_methods, sublime_tactics)
|
|
121
|
+
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.description, NEW.query, NEW.mitre_ids, NEW.tags, NEW.cves, NEW.analytic_stories, NEW.data_sources, NEW.process_names, NEW.file_paths, NEW.registry_paths, NEW.mitre_tactics, NEW.platforms, NEW.kql_category, NEW.kql_tags, NEW.kql_keywords, NEW.sublime_attack_types, NEW.sublime_detection_methods, NEW.sublime_tactics);
|
|
116
122
|
END
|
|
117
123
|
`);
|
|
118
124
|
}
|
package/dist/db.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare function insertDetection(detection: Detection): void;
|
|
|
8
8
|
export declare function searchDetections(query: string, limit?: number): Detection[];
|
|
9
9
|
export declare function getDetectionById(id: string): Detection | null;
|
|
10
10
|
export declare function listDetections(limit?: number, offset?: number): Detection[];
|
|
11
|
-
export declare function listBySource(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql', limit?: number, offset?: number): Detection[];
|
|
11
|
+
export declare function listBySource(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql', limit?: number, offset?: number): Detection[];
|
|
12
12
|
export declare function listByMitre(techniqueId: string, limit?: number, offset?: number): Detection[];
|
|
13
13
|
export declare function listByLogsource(category?: string, product?: string, service?: string, limit?: number, offset?: number): Detection[];
|
|
14
14
|
export declare function listBySeverity(level: string, limit?: number, offset?: number): Detection[];
|
|
@@ -117,9 +117,9 @@ export interface SourceComparisonResult {
|
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
export declare function searchDetectionList(query: string, limit?: number): DetectionListItem[];
|
|
120
|
-
export declare function listDetectionsBySourceLight(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql', nameFilter?: string, limit?: number): DetectionListItem[];
|
|
120
|
+
export declare function listDetectionsBySourceLight(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql', nameFilter?: string, limit?: number): DetectionListItem[];
|
|
121
121
|
export declare function compareDetectionsBySource(topic: string, limit?: number): SourceComparisonResult;
|
|
122
|
-
export declare function getDetectionNamesByPattern(pattern: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql'): {
|
|
122
|
+
export declare function getDetectionNamesByPattern(pattern: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql'): {
|
|
123
123
|
source: string;
|
|
124
124
|
detections: Array<{
|
|
125
125
|
name: string;
|