@panguard-ai/core 0.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/dist/adapters/adapter-registry.d.ts +150 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +271 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/base-adapter.d.ts +101 -0
- package/dist/adapters/base-adapter.d.ts.map +1 -0
- package/dist/adapters/base-adapter.js +160 -0
- package/dist/adapters/base-adapter.js.map +1 -0
- package/dist/adapters/defender-adapter.d.ts +90 -0
- package/dist/adapters/defender-adapter.d.ts.map +1 -0
- package/dist/adapters/defender-adapter.js +227 -0
- package/dist/adapters/defender-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +23 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/syslog-adapter.d.ts +207 -0
- package/dist/adapters/syslog-adapter.d.ts.map +1 -0
- package/dist/adapters/syslog-adapter.js +432 -0
- package/dist/adapters/syslog-adapter.js.map +1 -0
- package/dist/adapters/types.d.ts +135 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +13 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/wazuh-adapter.d.ts +120 -0
- package/dist/adapters/wazuh-adapter.d.ts.map +1 -0
- package/dist/adapters/wazuh-adapter.js +266 -0
- package/dist/adapters/wazuh-adapter.js.map +1 -0
- package/dist/ai/claude-provider.d.ts +66 -0
- package/dist/ai/claude-provider.d.ts.map +1 -0
- package/dist/ai/claude-provider.js +166 -0
- package/dist/ai/claude-provider.js.map +1 -0
- package/dist/ai/funnel-router.d.ts +75 -0
- package/dist/ai/funnel-router.d.ts.map +1 -0
- package/dist/ai/funnel-router.js +173 -0
- package/dist/ai/funnel-router.js.map +1 -0
- package/dist/ai/index.d.ts +77 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +95 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/ollama-provider.d.ts +73 -0
- package/dist/ai/ollama-provider.d.ts.map +1 -0
- package/dist/ai/ollama-provider.js +200 -0
- package/dist/ai/ollama-provider.js.map +1 -0
- package/dist/ai/openai-provider.d.ts +70 -0
- package/dist/ai/openai-provider.d.ts.map +1 -0
- package/dist/ai/openai-provider.js +175 -0
- package/dist/ai/openai-provider.js.map +1 -0
- package/dist/ai/prompts/event-classifier.d.ts +25 -0
- package/dist/ai/prompts/event-classifier.d.ts.map +1 -0
- package/dist/ai/prompts/event-classifier.js +94 -0
- package/dist/ai/prompts/event-classifier.js.map +1 -0
- package/dist/ai/prompts/index.d.ts +13 -0
- package/dist/ai/prompts/index.d.ts.map +1 -0
- package/dist/ai/prompts/index.js +13 -0
- package/dist/ai/prompts/index.js.map +1 -0
- package/dist/ai/prompts/report-generator.d.ts +25 -0
- package/dist/ai/prompts/report-generator.d.ts.map +1 -0
- package/dist/ai/prompts/report-generator.js +131 -0
- package/dist/ai/prompts/report-generator.js.map +1 -0
- package/dist/ai/prompts/threat-analyzer.d.ts +26 -0
- package/dist/ai/prompts/threat-analyzer.d.ts.map +1 -0
- package/dist/ai/prompts/threat-analyzer.js +75 -0
- package/dist/ai/prompts/threat-analyzer.js.map +1 -0
- package/dist/ai/provider-base.d.ts +100 -0
- package/dist/ai/provider-base.d.ts.map +1 -0
- package/dist/ai/provider-base.js +166 -0
- package/dist/ai/provider-base.js.map +1 -0
- package/dist/ai/response-parser.d.ts +36 -0
- package/dist/ai/response-parser.d.ts.map +1 -0
- package/dist/ai/response-parser.js +195 -0
- package/dist/ai/response-parser.js.map +1 -0
- package/dist/ai/token-tracker.d.ts +72 -0
- package/dist/ai/token-tracker.d.ts.map +1 -0
- package/dist/ai/token-tracker.js +145 -0
- package/dist/ai/token-tracker.js.map +1 -0
- package/dist/ai/types.d.ts +138 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +12 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/cli/index.d.ts +146 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +515 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +58 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +327 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/cli/wizard.d.ts +58 -0
- package/dist/cli/wizard.d.ts.map +1 -0
- package/dist/cli/wizard.js +200 -0
- package/dist/cli/wizard.js.map +1 -0
- package/dist/discovery/firewall-checker.d.ts +28 -0
- package/dist/discovery/firewall-checker.d.ts.map +1 -0
- package/dist/discovery/firewall-checker.js +379 -0
- package/dist/discovery/firewall-checker.js.map +1 -0
- package/dist/discovery/index.d.ts +23 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +29 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/network-scanner.d.ts +60 -0
- package/dist/discovery/network-scanner.d.ts.map +1 -0
- package/dist/discovery/network-scanner.js +640 -0
- package/dist/discovery/network-scanner.js.map +1 -0
- package/dist/discovery/os-detector.d.ts +24 -0
- package/dist/discovery/os-detector.d.ts.map +1 -0
- package/dist/discovery/os-detector.js +253 -0
- package/dist/discovery/os-detector.js.map +1 -0
- package/dist/discovery/osquery-provider.d.ts +127 -0
- package/dist/discovery/osquery-provider.d.ts.map +1 -0
- package/dist/discovery/osquery-provider.js +214 -0
- package/dist/discovery/osquery-provider.js.map +1 -0
- package/dist/discovery/risk-scorer.d.ts +66 -0
- package/dist/discovery/risk-scorer.d.ts.map +1 -0
- package/dist/discovery/risk-scorer.js +294 -0
- package/dist/discovery/risk-scorer.js.map +1 -0
- package/dist/discovery/security-tools.d.ts +31 -0
- package/dist/discovery/security-tools.d.ts.map +1 -0
- package/dist/discovery/security-tools.js +346 -0
- package/dist/discovery/security-tools.js.map +1 -0
- package/dist/discovery/service-detector.d.ts +28 -0
- package/dist/discovery/service-detector.d.ts.map +1 -0
- package/dist/discovery/service-detector.js +300 -0
- package/dist/discovery/service-detector.js.map +1 -0
- package/dist/discovery/types.d.ts +502 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +12 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/discovery/user-auditor.d.ts +28 -0
- package/dist/discovery/user-auditor.d.ts.map +1 -0
- package/dist/discovery/user-auditor.js +385 -0
- package/dist/discovery/user-auditor.js.map +1 -0
- package/dist/i18n/config.d.ts +45 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/i18n/config.js +135 -0
- package/dist/i18n/config.js.map +1 -0
- package/dist/i18n/index.d.ts +8 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +8 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/monitor/event-normalizer.d.ts +102 -0
- package/dist/monitor/event-normalizer.d.ts.map +1 -0
- package/dist/monitor/event-normalizer.js +195 -0
- package/dist/monitor/event-normalizer.js.map +1 -0
- package/dist/monitor/file-monitor.d.ts +90 -0
- package/dist/monitor/file-monitor.d.ts.map +1 -0
- package/dist/monitor/file-monitor.js +222 -0
- package/dist/monitor/file-monitor.js.map +1 -0
- package/dist/monitor/index.d.ts +147 -0
- package/dist/monitor/index.d.ts.map +1 -0
- package/dist/monitor/index.js +293 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/monitor/log-monitor.d.ts +102 -0
- package/dist/monitor/log-monitor.d.ts.map +1 -0
- package/dist/monitor/log-monitor.js +245 -0
- package/dist/monitor/log-monitor.js.map +1 -0
- package/dist/monitor/network-monitor.d.ts +103 -0
- package/dist/monitor/network-monitor.d.ts.map +1 -0
- package/dist/monitor/network-monitor.js +336 -0
- package/dist/monitor/network-monitor.js.map +1 -0
- package/dist/monitor/process-monitor.d.ts +108 -0
- package/dist/monitor/process-monitor.d.ts.map +1 -0
- package/dist/monitor/process-monitor.js +245 -0
- package/dist/monitor/process-monitor.js.map +1 -0
- package/dist/monitor/threat-intel-feeds.d.ts +141 -0
- package/dist/monitor/threat-intel-feeds.d.ts.map +1 -0
- package/dist/monitor/threat-intel-feeds.js +430 -0
- package/dist/monitor/threat-intel-feeds.js.map +1 -0
- package/dist/monitor/threat-intel.d.ts +83 -0
- package/dist/monitor/threat-intel.d.ts.map +1 -0
- package/dist/monitor/threat-intel.js +215 -0
- package/dist/monitor/threat-intel.js.map +1 -0
- package/dist/monitor/types.d.ts +65 -0
- package/dist/monitor/types.d.ts.map +1 -0
- package/dist/monitor/types.js +20 -0
- package/dist/monitor/types.js.map +1 -0
- package/dist/rules/index.d.ts +115 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +244 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/rule-loader.d.ts +54 -0
- package/dist/rules/rule-loader.d.ts.map +1 -0
- package/dist/rules/rule-loader.js +167 -0
- package/dist/rules/rule-loader.js.map +1 -0
- package/dist/rules/sigma-matcher.d.ts +40 -0
- package/dist/rules/sigma-matcher.d.ts.map +1 -0
- package/dist/rules/sigma-matcher.js +447 -0
- package/dist/rules/sigma-matcher.js.map +1 -0
- package/dist/rules/sigma-parser.d.ts +36 -0
- package/dist/rules/sigma-parser.d.ts.map +1 -0
- package/dist/rules/sigma-parser.js +180 -0
- package/dist/rules/sigma-parser.js.map +1 -0
- package/dist/rules/types.d.ts +112 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +11 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/yara-scanner.d.ts +103 -0
- package/dist/rules/yara-scanner.d.ts.map +1 -0
- package/dist/rules/yara-scanner.js +421 -0
- package/dist/rules/yara-scanner.js.map +1 -0
- package/dist/scoring/achievements.d.ts +76 -0
- package/dist/scoring/achievements.d.ts.map +1 -0
- package/dist/scoring/achievements.js +211 -0
- package/dist/scoring/achievements.js.map +1 -0
- package/dist/scoring/index.d.ts +3 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +3 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/security-score.d.ts +60 -0
- package/dist/scoring/security-score.d.ts.map +1 -0
- package/dist/scoring/security-score.js +211 -0
- package/dist/scoring/security-score.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +38 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +71 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +35 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +56 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sigma YAML rule parser
|
|
3
|
+
* Sigma YAML 規則解析器
|
|
4
|
+
*
|
|
5
|
+
* Parses Sigma rules from YAML format into typed SigmaRule objects.
|
|
6
|
+
* Validates required fields and logs warnings for missing optional fields.
|
|
7
|
+
* 將 Sigma 規則從 YAML 格式解析為型別化的 SigmaRule 物件。
|
|
8
|
+
* 驗證必要欄位並對缺少的可選欄位記錄警告。
|
|
9
|
+
*
|
|
10
|
+
* @module @panguard-ai/core/rules/sigma-parser
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import yaml from 'js-yaml';
|
|
14
|
+
import { createLogger } from '../utils/logger.js';
|
|
15
|
+
const logger = createLogger('sigma-parser');
|
|
16
|
+
/** Valid Sigma rule status values / 有效的 Sigma 規則狀態值 */
|
|
17
|
+
const VALID_STATUSES = new Set(['experimental', 'test', 'stable']);
|
|
18
|
+
/** Valid severity levels / 有效的嚴重等級 */
|
|
19
|
+
const VALID_LEVELS = new Set(['info', 'low', 'medium', 'high', 'critical']);
|
|
20
|
+
/**
|
|
21
|
+
* Parse a Sigma rule from a YAML string
|
|
22
|
+
* 從 YAML 字串解析 Sigma 規則
|
|
23
|
+
*
|
|
24
|
+
* Validates required fields (title, detection, level) and normalizes
|
|
25
|
+
* optional fields with sensible defaults.
|
|
26
|
+
* 驗證必要欄位(title、detection、level)並以合理預設值標準化可選欄位。
|
|
27
|
+
*
|
|
28
|
+
* @param yamlContent - Raw YAML string content / 原始 YAML 字串內容
|
|
29
|
+
* @returns Parsed SigmaRule or null if validation fails / 解析後的 SigmaRule,驗證失敗則回傳 null
|
|
30
|
+
*/
|
|
31
|
+
export function parseSigmaYaml(yamlContent) {
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = yaml.load(yamlContent);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
38
|
+
logger.error('Failed to parse YAML content / 解析 YAML 內容失敗', { error: message });
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
if (parsed === null || parsed === undefined || typeof parsed !== 'object') {
|
|
42
|
+
logger.error('YAML content is not an object / YAML 內容不是物件');
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const doc = parsed;
|
|
46
|
+
// --- Validate required fields / 驗證必要欄位 ---
|
|
47
|
+
if (typeof doc['title'] !== 'string' || doc['title'].trim() === '') {
|
|
48
|
+
logger.error('Missing or invalid required field: title / 缺少或無效的必要欄位: title');
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
if (doc['detection'] === undefined ||
|
|
52
|
+
doc['detection'] === null ||
|
|
53
|
+
typeof doc['detection'] !== 'object') {
|
|
54
|
+
logger.error('Missing or invalid required field: detection / 缺少或無效的必要欄位: detection');
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const rawDetection = doc['detection'];
|
|
58
|
+
if (typeof rawDetection['condition'] !== 'string') {
|
|
59
|
+
logger.error('Missing or invalid required field: detection.condition / 缺少或無效的必要欄位: detection.condition');
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const levelStr = typeof doc['level'] === 'string' ? doc['level'].toLowerCase() : '';
|
|
63
|
+
if (!VALID_LEVELS.has(levelStr)) {
|
|
64
|
+
logger.error(`Invalid or missing level: "${String(doc['level'])}" / 無效或缺少嚴重等級: "${String(doc['level'])}"`, {
|
|
65
|
+
validLevels: [...VALID_LEVELS],
|
|
66
|
+
});
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
// --- Parse optional fields with warnings / 解析可選欄位並記錄警告 ---
|
|
70
|
+
if (doc['id'] === undefined) {
|
|
71
|
+
logger.warn('Missing optional field: id - a unique identifier is recommended / 缺少可選欄位: id - 建議提供唯一識別碼');
|
|
72
|
+
}
|
|
73
|
+
if (doc['author'] === undefined) {
|
|
74
|
+
logger.warn('Missing optional field: author / 缺少可選欄位: author');
|
|
75
|
+
}
|
|
76
|
+
if (doc['date'] === undefined) {
|
|
77
|
+
logger.warn('Missing optional field: date / 缺少可選欄位: date');
|
|
78
|
+
}
|
|
79
|
+
if (doc['tags'] === undefined) {
|
|
80
|
+
logger.warn('Missing optional field: tags / 缺少可選欄位: tags');
|
|
81
|
+
}
|
|
82
|
+
if (doc['falsepositives'] === undefined) {
|
|
83
|
+
logger.warn('Missing optional field: falsepositives / 缺少可選欄位: falsepositives');
|
|
84
|
+
}
|
|
85
|
+
if (doc['references'] === undefined) {
|
|
86
|
+
logger.warn('Missing optional field: references / 缺少可選欄位: references');
|
|
87
|
+
}
|
|
88
|
+
// --- Build logsource / 建立日誌來源 ---
|
|
89
|
+
const rawLogSource = typeof doc['logsource'] === 'object' && doc['logsource'] !== null
|
|
90
|
+
? doc['logsource']
|
|
91
|
+
: {};
|
|
92
|
+
const logsource = {};
|
|
93
|
+
if (typeof rawLogSource['category'] === 'string')
|
|
94
|
+
logsource.category = rawLogSource['category'];
|
|
95
|
+
if (typeof rawLogSource['product'] === 'string')
|
|
96
|
+
logsource.product = rawLogSource['product'];
|
|
97
|
+
if (typeof rawLogSource['service'] === 'string')
|
|
98
|
+
logsource.service = rawLogSource['service'];
|
|
99
|
+
// --- Build detection / 建立偵測區塊 ---
|
|
100
|
+
const detection = {
|
|
101
|
+
condition: rawDetection['condition'],
|
|
102
|
+
};
|
|
103
|
+
for (const [key, value] of Object.entries(rawDetection)) {
|
|
104
|
+
if (key === 'condition')
|
|
105
|
+
continue;
|
|
106
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
107
|
+
const selectionMap = {};
|
|
108
|
+
for (const [fieldName, fieldValue] of Object.entries(value)) {
|
|
109
|
+
if (typeof fieldValue === 'string') {
|
|
110
|
+
selectionMap[fieldName] = fieldValue;
|
|
111
|
+
}
|
|
112
|
+
else if (Array.isArray(fieldValue)) {
|
|
113
|
+
selectionMap[fieldName] = fieldValue.map(String);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
selectionMap[fieldName] = String(fieldValue);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
detection[key] = selectionMap;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// --- Normalize status / 標準化狀態 ---
|
|
123
|
+
const statusStr = typeof doc['status'] === 'string' ? doc['status'].toLowerCase() : 'experimental';
|
|
124
|
+
const status = VALID_STATUSES.has(statusStr)
|
|
125
|
+
? statusStr
|
|
126
|
+
: 'experimental';
|
|
127
|
+
if (!VALID_STATUSES.has(typeof doc['status'] === 'string' ? doc['status'].toLowerCase() : '')) {
|
|
128
|
+
logger.warn(`Invalid or missing status "${String(doc['status'])}", defaulting to "experimental" / 無效或缺少狀態,預設為 "experimental"`);
|
|
129
|
+
}
|
|
130
|
+
// --- Build tags and falsepositives arrays / 建立標籤和誤報陣列 ---
|
|
131
|
+
const tags = Array.isArray(doc['tags']) ? doc['tags'].map(String) : undefined;
|
|
132
|
+
const falsepositives = Array.isArray(doc['falsepositives'])
|
|
133
|
+
? doc['falsepositives'].map(String)
|
|
134
|
+
: undefined;
|
|
135
|
+
const references = Array.isArray(doc['references']) ? doc['references'].map(String) : undefined;
|
|
136
|
+
const rule = {
|
|
137
|
+
id: typeof doc['id'] === 'string' ? doc['id'] : `auto-${Date.now()}`,
|
|
138
|
+
title: doc['title'],
|
|
139
|
+
status,
|
|
140
|
+
description: typeof doc['description'] === 'string' ? doc['description'] : '',
|
|
141
|
+
logsource,
|
|
142
|
+
detection,
|
|
143
|
+
level: levelStr,
|
|
144
|
+
...(typeof doc['author'] === 'string' ? { author: doc['author'] } : {}),
|
|
145
|
+
...(doc['date'] !== undefined ? { date: String(doc['date']) } : {}),
|
|
146
|
+
...(tags !== undefined ? { tags } : {}),
|
|
147
|
+
...(falsepositives !== undefined ? { falsepositives } : {}),
|
|
148
|
+
...(references !== undefined ? { references } : {}),
|
|
149
|
+
};
|
|
150
|
+
logger.info(`Successfully parsed Sigma rule: "${rule.title}" (${rule.id}) / 成功解析 Sigma 規則: "${rule.title}" (${rule.id})`);
|
|
151
|
+
return rule;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Parse a Sigma rule from a YAML file on disk
|
|
155
|
+
* 從磁碟上的 YAML 檔案解析 Sigma 規則
|
|
156
|
+
*
|
|
157
|
+
* Reads the file contents and delegates to parseSigmaYaml.
|
|
158
|
+
* 讀取檔案內容並委派給 parseSigmaYaml。
|
|
159
|
+
*
|
|
160
|
+
* @param filePath - Absolute or relative path to the YAML file / YAML 檔案的絕對或相對路徑
|
|
161
|
+
* @returns Parsed SigmaRule or null if file read or parsing fails / 解析後的 SigmaRule,讀取或解析失敗則回傳 null
|
|
162
|
+
*/
|
|
163
|
+
export function parseSigmaFile(filePath) {
|
|
164
|
+
try {
|
|
165
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
166
|
+
const rule = parseSigmaYaml(content);
|
|
167
|
+
if (rule === null) {
|
|
168
|
+
logger.error(`Failed to parse Sigma file: ${filePath} / 解析 Sigma 檔案失敗: ${filePath}`);
|
|
169
|
+
}
|
|
170
|
+
return rule;
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
174
|
+
logger.error(`Failed to read Sigma file: ${filePath} / 讀取 Sigma 檔案失敗: ${filePath}`, {
|
|
175
|
+
error: message,
|
|
176
|
+
});
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=sigma-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sigma-parser.js","sourceRoot":"","sources":["../../src/rules/sigma-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sigma rules engine type definitions
|
|
3
|
+
* Sigma 規則引擎型別定義
|
|
4
|
+
*
|
|
5
|
+
* Defines all types used by the Sigma rule parser, matcher, and engine.
|
|
6
|
+
* 定義 Sigma 規則解析器、比對器和引擎使用的所有型別。
|
|
7
|
+
*
|
|
8
|
+
* @module @panguard-ai/core/rules/types
|
|
9
|
+
*/
|
|
10
|
+
import type { Severity, SecurityEvent } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Sigma log source definition
|
|
13
|
+
* Sigma 日誌來源定義
|
|
14
|
+
*
|
|
15
|
+
* Describes where a rule's log data originates from.
|
|
16
|
+
* 描述規則的日誌資料來源。
|
|
17
|
+
*/
|
|
18
|
+
export interface SigmaLogSource {
|
|
19
|
+
/** Log category (e.g., 'authentication', 'process_creation') / 日誌分類 */
|
|
20
|
+
category?: string;
|
|
21
|
+
/** Product name (e.g., 'windows', 'linux', 'any') / 產品名稱 */
|
|
22
|
+
product?: string;
|
|
23
|
+
/** Service name (e.g., 'sshd', 'sysmon') / 服務名稱 */
|
|
24
|
+
service?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sigma detection block
|
|
28
|
+
* Sigma 偵測區塊
|
|
29
|
+
*
|
|
30
|
+
* Contains named selections and a condition expression that combines them.
|
|
31
|
+
* Each selection maps field names to expected values (string or string[]).
|
|
32
|
+
* Field names may include modifiers like '|contains', '|endswith', '|startswith'.
|
|
33
|
+
* 包含命名選擇項和組合它們的條件表達式。
|
|
34
|
+
* 每個選擇項將欄位名稱映射到預期值(字串或字串陣列)。
|
|
35
|
+
* 欄位名稱可包含修飾符如 '|contains'、'|endswith'、'|startswith'。
|
|
36
|
+
*/
|
|
37
|
+
export interface SigmaDetection {
|
|
38
|
+
/** Named selections mapping field names to expected values / 命名選擇項,將欄位名映射到預期值 */
|
|
39
|
+
[selectionName: string]: Record<string, string | string[]> | string;
|
|
40
|
+
/** Condition expression combining selections (e.g., 'selection1 AND selection2') / 組合選擇項的條件表達式 */
|
|
41
|
+
condition: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Sigma rule definition
|
|
45
|
+
* Sigma 規則定義
|
|
46
|
+
*
|
|
47
|
+
* A complete Sigma rule that can be parsed from YAML and matched against events.
|
|
48
|
+
* 可從 YAML 解析並與事件比對的完整 Sigma 規則。
|
|
49
|
+
*/
|
|
50
|
+
export interface SigmaRule {
|
|
51
|
+
/** Unique rule identifier / 唯一規則識別碼 */
|
|
52
|
+
id: string;
|
|
53
|
+
/** Rule title / 規則標題 */
|
|
54
|
+
title: string;
|
|
55
|
+
/** Rule maturity status / 規則成熟度狀態 */
|
|
56
|
+
status: 'experimental' | 'test' | 'stable';
|
|
57
|
+
/** Rule description / 規則描述 */
|
|
58
|
+
description: string;
|
|
59
|
+
/** Rule author / 規則作者 */
|
|
60
|
+
author?: string;
|
|
61
|
+
/** Rule creation or last modification date / 規則建立或最後修改日期 */
|
|
62
|
+
date?: string;
|
|
63
|
+
/** Log source specification / 日誌來源規格 */
|
|
64
|
+
logsource: SigmaLogSource;
|
|
65
|
+
/** Detection logic with selections and condition / 偵測邏輯,包含選擇項和條件 */
|
|
66
|
+
detection: SigmaDetection;
|
|
67
|
+
/** Alert severity level / 警報嚴重等級 */
|
|
68
|
+
level: Severity;
|
|
69
|
+
/** Tags (e.g., MITRE ATT&CK references) / 標籤(如 MITRE ATT&CK 參考) */
|
|
70
|
+
tags?: string[];
|
|
71
|
+
/** Known false positive scenarios / 已知誤報情境 */
|
|
72
|
+
falsepositives?: string[];
|
|
73
|
+
/** External reference URLs / 外部參考連結 */
|
|
74
|
+
references?: string[];
|
|
75
|
+
/** Rule source: custom (Panguard original) or community (SigmaHQ etc.) / 規則來源 */
|
|
76
|
+
source?: 'custom' | 'community';
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Result of matching an event against a Sigma rule
|
|
80
|
+
* 安全事件與 Sigma 規則比對的結果
|
|
81
|
+
*
|
|
82
|
+
* Produced when an event matches a rule's detection logic.
|
|
83
|
+
* 當事件符合規則的偵測邏輯時產生。
|
|
84
|
+
*/
|
|
85
|
+
export interface RuleMatch {
|
|
86
|
+
/** The matched Sigma rule / 比對到的 Sigma 規則 */
|
|
87
|
+
rule: SigmaRule;
|
|
88
|
+
/** The event that triggered the match / 觸發比對的事件 */
|
|
89
|
+
event: SecurityEvent;
|
|
90
|
+
/** Field names that matched in the detection / 偵測中比對到的欄位名稱 */
|
|
91
|
+
matchedFields: string[];
|
|
92
|
+
/** ISO timestamp when the match was detected / 偵測到比對的 ISO 時間戳 */
|
|
93
|
+
timestamp: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Configuration for the rule engine
|
|
97
|
+
* 規則引擎配置
|
|
98
|
+
*
|
|
99
|
+
* Controls how the rule engine loads and manages rules.
|
|
100
|
+
* 控制規則引擎如何載入和管理規則。
|
|
101
|
+
*/
|
|
102
|
+
export interface RuleEngineConfig {
|
|
103
|
+
/** Directory containing custom Sigma rule YAML files / 包含自訂 Sigma 規則 YAML 檔案的目錄 */
|
|
104
|
+
rulesDir?: string;
|
|
105
|
+
/** Directory containing community Sigma rules (e.g., SigmaHQ) / 包含社群 Sigma 規則的目錄 */
|
|
106
|
+
communityRulesDir?: string;
|
|
107
|
+
/** Enable hot-reloading of rules when files change / 啟用檔案變更時的規則熱載入 */
|
|
108
|
+
hotReload?: boolean;
|
|
109
|
+
/** Pre-loaded custom rules / 預載入的自訂規則 */
|
|
110
|
+
customRules?: SigmaRule[];
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;IACpE,kGAAkG;IAClG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,MAAM,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3C,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,SAAS,EAAE,cAAc,CAAC;IAC1B,oEAAoE;IACpE,SAAS,EAAE,cAAc,CAAC;IAC1B,oCAAoC;IACpC,KAAK,EAAE,QAAQ,CAAC;IAChB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,iFAAiF;IACjF,MAAM,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,IAAI,EAAE,SAAS,CAAC;IAChB,mDAAmD;IACnD,KAAK,EAAE,aAAa,CAAC;IACrB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yCAAyC;IACzC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;CAC3B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sigma rules engine type definitions
|
|
3
|
+
* Sigma 規則引擎型別定義
|
|
4
|
+
*
|
|
5
|
+
* Defines all types used by the Sigma rule parser, matcher, and engine.
|
|
6
|
+
* 定義 Sigma 規則解析器、比對器和引擎使用的所有型別。
|
|
7
|
+
*
|
|
8
|
+
* @module @panguard-ai/core/rules/types
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YARA Scanner - File scanning using YARA rules
|
|
3
|
+
* YARA 掃描器 - 使用 YARA 規則掃描檔案
|
|
4
|
+
*
|
|
5
|
+
* Provides an abstraction over YARA scanning that:
|
|
6
|
+
* - Loads .yar rule files from a directory
|
|
7
|
+
* - Scans individual files or entire directories
|
|
8
|
+
* - Converts results to SecurityEvent format for unified pipeline
|
|
9
|
+
* - Gracefully degrades when YARA native bindings are not available
|
|
10
|
+
*
|
|
11
|
+
* @module @panguard-ai/core/rules/yara-scanner
|
|
12
|
+
*/
|
|
13
|
+
import type { SecurityEvent } from '../types.js';
|
|
14
|
+
/** YARA match result / YARA 比對結果 */
|
|
15
|
+
export interface YaraMatch {
|
|
16
|
+
rule: string;
|
|
17
|
+
namespace: string;
|
|
18
|
+
tags: string[];
|
|
19
|
+
meta: Record<string, string>;
|
|
20
|
+
strings: Array<{
|
|
21
|
+
identifier: string;
|
|
22
|
+
offset: number;
|
|
23
|
+
data: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
/** YARA scan result for a single file / 單一檔案的 YARA 掃描結果 */
|
|
27
|
+
export interface YaraScanResult {
|
|
28
|
+
filePath: string;
|
|
29
|
+
fileSize: number;
|
|
30
|
+
sha256: string;
|
|
31
|
+
matches: YaraMatch[];
|
|
32
|
+
scannedAt: string;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* YARA-based file scanner
|
|
37
|
+
* 基於 YARA 的檔案掃描器
|
|
38
|
+
*
|
|
39
|
+
* Supports two modes:
|
|
40
|
+
* 1. Native YARA via @automattic/yara (requires native bindings)
|
|
41
|
+
* 2. Pattern-based fallback using regex matching on file content
|
|
42
|
+
*/
|
|
43
|
+
export declare class YaraScanner {
|
|
44
|
+
private ruleFiles;
|
|
45
|
+
private compiledPatterns;
|
|
46
|
+
private yaraAvailable;
|
|
47
|
+
/** Load YARA rules from a directory (non-recursive) / 從目錄載入 YARA 規則(非遞迴) */
|
|
48
|
+
loadRules(rulesDir: string): Promise<number>;
|
|
49
|
+
/**
|
|
50
|
+
* Recursively load YARA rules from a directory tree
|
|
51
|
+
* 從目錄樹遞迴載入 YARA 規則
|
|
52
|
+
*
|
|
53
|
+
* @param rulesDir - Root directory to scan / 要掃描的根目錄
|
|
54
|
+
* @param source - Source tag for loaded rules / 載入規則的來源標記
|
|
55
|
+
* @returns Number of rule files loaded / 載入的規則檔數量
|
|
56
|
+
*/
|
|
57
|
+
loadRulesRecursive(rulesDir: string, source?: 'custom' | 'community'): Promise<number>;
|
|
58
|
+
/**
|
|
59
|
+
* Load rules from both custom and community directories
|
|
60
|
+
* 從自訂和社群目錄載入規則
|
|
61
|
+
*
|
|
62
|
+
* @param customDir - Custom rules directory / 自訂規則目錄
|
|
63
|
+
* @param communityDir - Optional community rules directory / 可選的社群規則目錄
|
|
64
|
+
* @returns Total number of rule files loaded / 載入的規則檔總數
|
|
65
|
+
*/
|
|
66
|
+
loadAllRules(customDir: string, communityDir?: string): Promise<number>;
|
|
67
|
+
/** Recursively collect .yar/.yara files and append to this.ruleFiles */
|
|
68
|
+
private loadFromDirRecursive;
|
|
69
|
+
/** Get number of loaded rule files / 取得已載入的規則檔數量 */
|
|
70
|
+
getRuleCount(): number;
|
|
71
|
+
/** Check if native YARA is available / 檢查原生 YARA 是否可用 */
|
|
72
|
+
isNativeAvailable(): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Scan a single file / 掃描單一檔案
|
|
75
|
+
*/
|
|
76
|
+
scanFile(filePath: string): Promise<YaraScanResult>;
|
|
77
|
+
/**
|
|
78
|
+
* Scan a directory recursively / 遞迴掃描目錄
|
|
79
|
+
*/
|
|
80
|
+
scanDirectory(dirPath: string, options?: {
|
|
81
|
+
maxDepth?: number;
|
|
82
|
+
extensions?: string[];
|
|
83
|
+
}): Promise<YaraScanResult[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Convert YARA scan result to SecurityEvent / 轉換 YARA 掃描結果為 SecurityEvent
|
|
86
|
+
*/
|
|
87
|
+
toSecurityEvent(result: YaraScanResult): SecurityEvent | null;
|
|
88
|
+
private checkNativeYara;
|
|
89
|
+
private scanWithNativeYara;
|
|
90
|
+
/**
|
|
91
|
+
* Fallback pattern-based scanning / 退路:基於模式的掃描
|
|
92
|
+
* Extracts string patterns from YARA rules and matches against file content
|
|
93
|
+
*/
|
|
94
|
+
private scanWithPatterns;
|
|
95
|
+
/**
|
|
96
|
+
* Parse YARA rule files into compiled patterns for fallback matching
|
|
97
|
+
* 解析 YARA 規則檔為編譯的模式(退路比對用)
|
|
98
|
+
*/
|
|
99
|
+
private compilePatterns;
|
|
100
|
+
private inferSeverity;
|
|
101
|
+
private walkDir;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=yara-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yara-scanner.d.ts","sourceRoot":"","sources":["../../src/rules/yara-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,oCAAoC;AACpC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;GAOG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,aAAa,CAAS;IAE9B,4EAA4E;IACtE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiClD;;;;;;;OAOG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IA0C5F;;;;;;;OAOG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB7E,wEAAwE;YAC1D,oBAAoB;IAoClC,oDAAoD;IACpD,YAAY,IAAI,MAAM;IAItB,yDAAyD;IACzD,iBAAiB,IAAI,OAAO;IAI5B;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyBzD;;OAEG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACzD,OAAO,CAAC,cAAc,EAAE,CAAC;IAS5B;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa,GAAG,IAAI;YAkC/C,eAAe;YASf,kBAAkB;IAsChC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAkCxB;;;OAGG;IACH,OAAO,CAAC,eAAe;IA6DvB,OAAO,CAAC,aAAa;YAeP,OAAO;CAkCtB"}
|