@modular-intelligence/yara-scanner 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +504 -0
- package/dist/index.js +45052 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
# YARA Scanner MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server wrapping YARA for malware detection, pattern matching, and security analysis. Provides comprehensive tools for scanning files, directories, and processes with YARA rules.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **File Scanning**: Scan individual files with custom or built-in YARA rules
|
|
8
|
+
- **Directory Scanning**: Recursively scan directories with file extension filtering
|
|
9
|
+
- **Process Scanning**: Scan running process memory (requires root)
|
|
10
|
+
- **Rule Management**: Compile, validate, and generate YARA rules
|
|
11
|
+
- **Built-in Rulesets**: Use curated rulesets for malware, webshells, exploits, and more
|
|
12
|
+
- **Security**: Path validation, rule content validation, sandboxed execution
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
### Required
|
|
17
|
+
|
|
18
|
+
- **YARA CLI**: Install the YARA command-line tool
|
|
19
|
+
```bash
|
|
20
|
+
# macOS
|
|
21
|
+
brew install yara
|
|
22
|
+
|
|
23
|
+
# Ubuntu/Debian
|
|
24
|
+
sudo apt-get install yara
|
|
25
|
+
|
|
26
|
+
# From source
|
|
27
|
+
git clone https://github.com/VirusTotal/yara.git
|
|
28
|
+
cd yara
|
|
29
|
+
./bootstrap.sh
|
|
30
|
+
./configure
|
|
31
|
+
make
|
|
32
|
+
sudo make install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Optional
|
|
36
|
+
|
|
37
|
+
- **Built-in Rulesets**: For `yara_scan_with_builtin` tool
|
|
38
|
+
- Set `YARA_RULES_PATH` environment variable, or
|
|
39
|
+
- Install rules to `/opt/yara-rules/`
|
|
40
|
+
- Recommended: [Awesome YARA rules](https://github.com/InQuest/awesome-yara)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Example: Install common rulesets
|
|
44
|
+
sudo mkdir -p /opt/yara-rules
|
|
45
|
+
cd /opt/yara-rules
|
|
46
|
+
|
|
47
|
+
# Download popular rule repositories
|
|
48
|
+
git clone https://github.com/Yara-Rules/rules.git yara-rules-repo
|
|
49
|
+
|
|
50
|
+
# Organize by category
|
|
51
|
+
cp yara-rules-repo/malware/*.yar malware.yar
|
|
52
|
+
cp yara-rules-repo/webshells/*.yar webshell.yar
|
|
53
|
+
# ... etc
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd yara-scanner
|
|
60
|
+
bun install
|
|
61
|
+
bun run build
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Configuration
|
|
65
|
+
|
|
66
|
+
Add to your MCP settings file:
|
|
67
|
+
|
|
68
|
+
### Claude Desktop
|
|
69
|
+
|
|
70
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
71
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"yara-scanner": {
|
|
77
|
+
"command": "bun",
|
|
78
|
+
"args": ["run", "/absolute/path/to/yara-scanner/src/index.ts"],
|
|
79
|
+
"env": {
|
|
80
|
+
"YARA_RULES_PATH": "/opt/yara-rules"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Environment Variables
|
|
88
|
+
|
|
89
|
+
- `YARA_RULES_PATH`: Base directory for built-in rulesets (default: `/opt/yara-rules`)
|
|
90
|
+
|
|
91
|
+
## Tools
|
|
92
|
+
|
|
93
|
+
### yara_scan_file
|
|
94
|
+
|
|
95
|
+
Scan a single file with YARA rules.
|
|
96
|
+
|
|
97
|
+
**Parameters:**
|
|
98
|
+
- `file_path` (required): Absolute path to file to scan
|
|
99
|
+
- `rule_path` (optional): Path to YARA rule file (.yar/.yara)
|
|
100
|
+
- `rule_content` (optional): YARA rule content (alternative to rule_path)
|
|
101
|
+
- `timeout` (optional): Maximum scan duration in seconds (default: 60, max: 300)
|
|
102
|
+
|
|
103
|
+
**Note**: Must provide either `rule_path` or `rule_content`, not both.
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
```typescript
|
|
107
|
+
{
|
|
108
|
+
"file_path": "/home/user/suspicious.exe",
|
|
109
|
+
"rule_path": "/opt/yara-rules/malware.yar",
|
|
110
|
+
"timeout": 60
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Returns:**
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"file": "/home/user/suspicious.exe",
|
|
118
|
+
"matches": [
|
|
119
|
+
{
|
|
120
|
+
"rule": "Win32_Trojan_Generic",
|
|
121
|
+
"tags": ["trojan", "win32"],
|
|
122
|
+
"strings": [
|
|
123
|
+
{
|
|
124
|
+
"offset": "0x1234",
|
|
125
|
+
"identifier": "$suspicious_string",
|
|
126
|
+
"data": "malicious payload"
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"match_count": 1
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### yara_scan_directory
|
|
136
|
+
|
|
137
|
+
Scan a directory (optionally recursive) with YARA rules.
|
|
138
|
+
|
|
139
|
+
**Parameters:**
|
|
140
|
+
- `dir_path` (required): Absolute path to directory to scan
|
|
141
|
+
- `rule_path` (optional): Path to YARA rule file
|
|
142
|
+
- `rule_content` (optional): YARA rule content
|
|
143
|
+
- `recursive` (optional): Scan directories recursively (default: false)
|
|
144
|
+
- `file_extensions` (optional): Filter by file extensions (e.g., [".exe", ".dll"])
|
|
145
|
+
- `timeout` (optional): Maximum scan duration in seconds (default: 60)
|
|
146
|
+
|
|
147
|
+
**Example:**
|
|
148
|
+
```typescript
|
|
149
|
+
{
|
|
150
|
+
"dir_path": "/var/www/html",
|
|
151
|
+
"rule_path": "/opt/yara-rules/webshell.yar",
|
|
152
|
+
"recursive": true,
|
|
153
|
+
"file_extensions": [".php", ".jsp", ".asp"]
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Returns:**
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"directory": "/var/www/html",
|
|
161
|
+
"files_scanned": 42,
|
|
162
|
+
"matches": [
|
|
163
|
+
{
|
|
164
|
+
"file": "/var/www/html/upload/shell.php",
|
|
165
|
+
"rule": "PHP_Webshell",
|
|
166
|
+
"tags": ["webshell", "php"],
|
|
167
|
+
"strings": [...]
|
|
168
|
+
}
|
|
169
|
+
],
|
|
170
|
+
"total_matches": 1
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### yara_scan_process
|
|
175
|
+
|
|
176
|
+
Scan a running process memory with YARA rules. **Requires root privileges.**
|
|
177
|
+
|
|
178
|
+
**Parameters:**
|
|
179
|
+
- `pid` (required): Process ID to scan (positive integer)
|
|
180
|
+
- `rule_path` (optional): Path to YARA rule file
|
|
181
|
+
- `rule_content` (optional): YARA rule content
|
|
182
|
+
- `timeout` (optional): Maximum scan duration in seconds (default: 60)
|
|
183
|
+
|
|
184
|
+
**Example:**
|
|
185
|
+
```typescript
|
|
186
|
+
{
|
|
187
|
+
"pid": 1234,
|
|
188
|
+
"rule_content": "rule suspicious { strings: $a = \"malware\" condition: $a }"
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Returns:**
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"pid": 1234,
|
|
196
|
+
"matches": [
|
|
197
|
+
{
|
|
198
|
+
"rule": "suspicious",
|
|
199
|
+
"tags": [],
|
|
200
|
+
"strings": [...]
|
|
201
|
+
}
|
|
202
|
+
],
|
|
203
|
+
"match_count": 1
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### yara_compile_rules
|
|
208
|
+
|
|
209
|
+
Compile and validate YARA rules without executing a scan.
|
|
210
|
+
|
|
211
|
+
**Parameters:**
|
|
212
|
+
- `rule_content` (required): YARA rule content to validate (max 500KB)
|
|
213
|
+
|
|
214
|
+
**Example:**
|
|
215
|
+
```typescript
|
|
216
|
+
{
|
|
217
|
+
"rule_content": "rule test { strings: $a = \"test\" condition: $a }"
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Returns:**
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"valid": true,
|
|
225
|
+
"errors": [],
|
|
226
|
+
"warnings": []
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### yara_rule_info
|
|
231
|
+
|
|
232
|
+
Extract metadata and information from a YARA rule file.
|
|
233
|
+
|
|
234
|
+
**Parameters:**
|
|
235
|
+
- `rule_path` (required): Path to YARA rule file
|
|
236
|
+
|
|
237
|
+
**Example:**
|
|
238
|
+
```typescript
|
|
239
|
+
{
|
|
240
|
+
"rule_path": "/opt/yara-rules/malware.yar"
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Returns:**
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"rules": [
|
|
248
|
+
{
|
|
249
|
+
"name": "Win32_Trojan_Generic",
|
|
250
|
+
"tags": ["trojan", "win32"],
|
|
251
|
+
"meta": {
|
|
252
|
+
"author": "Security Researcher",
|
|
253
|
+
"description": "Generic trojan detection",
|
|
254
|
+
"date": "2024-01-01"
|
|
255
|
+
},
|
|
256
|
+
"strings_count": 5,
|
|
257
|
+
"condition": "3 of them"
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
"total_rules": 1
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### yara_generate_rule
|
|
265
|
+
|
|
266
|
+
Generate a YARA rule from components and validate by compiling.
|
|
267
|
+
|
|
268
|
+
**Parameters:**
|
|
269
|
+
- `name` (required): Rule name
|
|
270
|
+
- `strings` (required): Array of string definitions
|
|
271
|
+
- `identifier`: String identifier (e.g., "$s1")
|
|
272
|
+
- `value`: String value or hex pattern
|
|
273
|
+
- `type`: "text", "hex", or "regex" (default: "text")
|
|
274
|
+
- `condition` (optional): YARA condition expression (default: "any of them")
|
|
275
|
+
- `tags` (optional): Array of rule tags
|
|
276
|
+
- `meta` (optional): Metadata key-value pairs
|
|
277
|
+
|
|
278
|
+
**Example:**
|
|
279
|
+
```typescript
|
|
280
|
+
{
|
|
281
|
+
"name": "Custom_Malware_Detector",
|
|
282
|
+
"tags": ["malware", "custom"],
|
|
283
|
+
"meta": {
|
|
284
|
+
"author": "Security Team",
|
|
285
|
+
"description": "Detects custom malware variant"
|
|
286
|
+
},
|
|
287
|
+
"strings": [
|
|
288
|
+
{
|
|
289
|
+
"identifier": "$s1",
|
|
290
|
+
"value": "malicious string",
|
|
291
|
+
"type": "text"
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"identifier": "$hex1",
|
|
295
|
+
"value": "6D 61 6C 77 61 72 65",
|
|
296
|
+
"type": "hex"
|
|
297
|
+
}
|
|
298
|
+
],
|
|
299
|
+
"condition": "all of them"
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Returns:**
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"rule_content": "rule Custom_Malware_Detector : malware custom\n{\n meta:\n author = \"Security Team\"\n description = \"Detects custom malware variant\"\n strings:\n $s1 = \"malicious string\"\n $hex1 = { 6D 61 6C 77 61 72 65 }\n condition:\n all of them\n}",
|
|
307
|
+
"valid": true,
|
|
308
|
+
"compilation_errors": []
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### yara_scan_with_builtin
|
|
313
|
+
|
|
314
|
+
Scan a file using curated built-in YARA rulesets.
|
|
315
|
+
|
|
316
|
+
**Parameters:**
|
|
317
|
+
- `file_path` (required): Absolute path to file to scan
|
|
318
|
+
- `ruleset` (required): Built-in ruleset category
|
|
319
|
+
- `malware`: General malware detection
|
|
320
|
+
- `suspicious`: Suspicious patterns and behaviors
|
|
321
|
+
- `crypto`: Cryptographic algorithms and ransomware
|
|
322
|
+
- `webshell`: Web shell detection
|
|
323
|
+
- `exploit`: Exploit code patterns
|
|
324
|
+
- `packer`: Executable packers
|
|
325
|
+
- `ransomware`: Ransomware-specific signatures
|
|
326
|
+
- `timeout` (optional): Maximum scan duration in seconds (default: 60)
|
|
327
|
+
|
|
328
|
+
**Example:**
|
|
329
|
+
```typescript
|
|
330
|
+
{
|
|
331
|
+
"file_path": "/home/user/suspicious.exe",
|
|
332
|
+
"ruleset": "malware",
|
|
333
|
+
"timeout": 120
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Returns:**
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"file": "/home/user/suspicious.exe",
|
|
341
|
+
"ruleset": "malware",
|
|
342
|
+
"matches": [
|
|
343
|
+
{
|
|
344
|
+
"rule": "Generic_Malware",
|
|
345
|
+
"tags": ["malware"],
|
|
346
|
+
"strings": [...]
|
|
347
|
+
}
|
|
348
|
+
],
|
|
349
|
+
"match_count": 1
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Security Features
|
|
354
|
+
|
|
355
|
+
### Path Validation
|
|
356
|
+
- All paths must be absolute
|
|
357
|
+
- No path traversal (`..`) allowed
|
|
358
|
+
- No null bytes in paths
|
|
359
|
+
- Access to `/proc`, `/sys`, `/dev` is blocked
|
|
360
|
+
|
|
361
|
+
### Rule Content Validation
|
|
362
|
+
- Maximum rule size: 500KB
|
|
363
|
+
- Must contain at least one `rule` definition
|
|
364
|
+
- Only safe YARA modules allowed:
|
|
365
|
+
- Allowed: `pe`, `elf`, `math`, `hash`, `console`, `time`, `string`
|
|
366
|
+
- Blocked: `cuckoo`, `dotnet`, and other potentially dangerous modules
|
|
367
|
+
|
|
368
|
+
### Process Scanning
|
|
369
|
+
- Requires root privileges (UID 0)
|
|
370
|
+
- Process ID must be positive integer
|
|
371
|
+
- Validates process exists before scanning
|
|
372
|
+
|
|
373
|
+
### Execution Safety
|
|
374
|
+
- Command timeout enforcement (10-300 seconds)
|
|
375
|
+
- SIGKILL safety timer (timeout + 5 seconds)
|
|
376
|
+
- Maximum output buffer: 10MB
|
|
377
|
+
- Temporary files cleaned up automatically
|
|
378
|
+
|
|
379
|
+
## Example YARA Rules
|
|
380
|
+
|
|
381
|
+
### Simple Text Match
|
|
382
|
+
```yara
|
|
383
|
+
rule Simple_Text_Match {
|
|
384
|
+
strings:
|
|
385
|
+
$text = "malicious"
|
|
386
|
+
condition:
|
|
387
|
+
$text
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Hex Pattern Match
|
|
392
|
+
```yara
|
|
393
|
+
rule Hex_Pattern {
|
|
394
|
+
strings:
|
|
395
|
+
$hex = { 4D 5A 90 00 } // PE header
|
|
396
|
+
condition:
|
|
397
|
+
$hex at 0
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Complex Rule with Metadata
|
|
402
|
+
```yara
|
|
403
|
+
rule Advanced_Detection {
|
|
404
|
+
meta:
|
|
405
|
+
author = "Security Team"
|
|
406
|
+
description = "Detects advanced threat"
|
|
407
|
+
severity = "high"
|
|
408
|
+
|
|
409
|
+
strings:
|
|
410
|
+
$s1 = "suspicious_function" ascii wide
|
|
411
|
+
$s2 = /http:\/\/[a-z]+\.evil\.com/
|
|
412
|
+
$hex1 = { E8 [4] 83 C4 ?? }
|
|
413
|
+
|
|
414
|
+
condition:
|
|
415
|
+
2 of them and filesize < 1MB
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Using PE Module
|
|
420
|
+
```yara
|
|
421
|
+
import "pe"
|
|
422
|
+
|
|
423
|
+
rule PE_Characteristics {
|
|
424
|
+
condition:
|
|
425
|
+
pe.is_pe and
|
|
426
|
+
pe.number_of_sections > 5 and
|
|
427
|
+
pe.imports("kernel32.dll", "CreateRemoteThread")
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
## Troubleshooting
|
|
432
|
+
|
|
433
|
+
### YARA not found
|
|
434
|
+
```
|
|
435
|
+
Error: spawn yara ENOENT
|
|
436
|
+
```
|
|
437
|
+
**Solution**: Install YARA CLI and ensure it's in your PATH.
|
|
438
|
+
|
|
439
|
+
### Permission denied (process scanning)
|
|
440
|
+
```
|
|
441
|
+
Error: Process scanning requires root privileges
|
|
442
|
+
```
|
|
443
|
+
**Solution**: Run with sudo or as root user.
|
|
444
|
+
|
|
445
|
+
### Built-in ruleset not found
|
|
446
|
+
```
|
|
447
|
+
Error: Failed to scan with built-in ruleset 'malware'
|
|
448
|
+
```
|
|
449
|
+
**Solution**: Set `YARA_RULES_PATH` environment variable or install rules to `/opt/yara-rules/`.
|
|
450
|
+
|
|
451
|
+
### Rule compilation errors
|
|
452
|
+
```json
|
|
453
|
+
{
|
|
454
|
+
"valid": false,
|
|
455
|
+
"errors": ["syntax error, unexpected $end"],
|
|
456
|
+
"warnings": []
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
**Solution**: Check YARA rule syntax. Use `yara_compile_rules` to debug.
|
|
460
|
+
|
|
461
|
+
### Dangerous module import blocked
|
|
462
|
+
```
|
|
463
|
+
Error: Dangerous module import detected: "cuckoo"
|
|
464
|
+
```
|
|
465
|
+
**Solution**: Remove unsafe module imports or use only allowed modules (pe, elf, math, hash, console, time, string).
|
|
466
|
+
|
|
467
|
+
## Performance Tips
|
|
468
|
+
|
|
469
|
+
1. **Use specific rules**: More specific rules = faster scanning
|
|
470
|
+
2. **Set appropriate timeouts**: Large files may need longer timeouts
|
|
471
|
+
3. **Filter by extension**: When scanning directories, use `file_extensions` filter
|
|
472
|
+
4. **Avoid deep recursion**: Deep directory trees can be slow
|
|
473
|
+
5. **Optimize rule conditions**: Simple conditions are faster than complex ones
|
|
474
|
+
|
|
475
|
+
## Best Practices
|
|
476
|
+
|
|
477
|
+
1. **Test rules first**: Use `yara_compile_rules` to validate before scanning
|
|
478
|
+
2. **Use metadata**: Add author, description, date to rules
|
|
479
|
+
3. **Tag appropriately**: Use tags for categorization (malware, trojan, ransomware, etc.)
|
|
480
|
+
4. **Start specific**: Scan individual files before scanning directories
|
|
481
|
+
5. **Monitor performance**: Use appropriate timeouts for large scans
|
|
482
|
+
6. **Keep rules updated**: Regularly update built-in rulesets
|
|
483
|
+
7. **Document custom rules**: Use metadata fields for documentation
|
|
484
|
+
|
|
485
|
+
## Use Cases
|
|
486
|
+
|
|
487
|
+
- **Malware Detection**: Scan files for known malware signatures
|
|
488
|
+
- **Incident Response**: Scan compromised systems for IOCs
|
|
489
|
+
- **Threat Hunting**: Search for suspicious patterns across filesystems
|
|
490
|
+
- **Web Security**: Detect webshells in web application directories
|
|
491
|
+
- **Memory Forensics**: Scan running processes for malicious code
|
|
492
|
+
- **File Analysis**: Analyze unknown files with custom rules
|
|
493
|
+
- **Automated Scanning**: Integrate with CI/CD for security scanning
|
|
494
|
+
|
|
495
|
+
## License
|
|
496
|
+
|
|
497
|
+
MIT
|
|
498
|
+
|
|
499
|
+
## References
|
|
500
|
+
|
|
501
|
+
- [YARA Official Documentation](https://yara.readthedocs.io/)
|
|
502
|
+
- [YARA GitHub Repository](https://github.com/VirusTotal/yara)
|
|
503
|
+
- [Awesome YARA Rules](https://github.com/InQuest/awesome-yara)
|
|
504
|
+
- [YARA Rule Writing Guide](https://yara.readthedocs.io/en/stable/writingrules.html)
|