@modular-intelligence/forensic-analysis 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 +1336 -0
- package/dist/index.js +45094 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,1336 @@
|
|
|
1
|
+
# Forensic Analysis MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server for file forensics and static analysis. Perform deep inspection of files including hashing, binary string extraction, entropy analysis, PE/ELF header parsing, metadata extraction, and comprehensive forensic investigation capabilities.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This MCP server provides ten specialized tools for analyzing files without executing them. Whether you're investigating suspicious binaries, analyzing malware samples, performing general file forensics, or building forensic investigation reports, this server enables Claude to perform comprehensive static analysis using industry-standard techniques.
|
|
8
|
+
|
|
9
|
+
**Key capabilities:**
|
|
10
|
+
- Calculate cryptographic hashes (MD5, SHA1, SHA256) on individual files and entire directories
|
|
11
|
+
- Extract printable strings with pattern recognition (URLs, IPs, suspicious APIs)
|
|
12
|
+
- Identify file types via magic bytes
|
|
13
|
+
- Calculate Shannon entropy to detect packing/encryption
|
|
14
|
+
- Parse Windows PE (Portable Executable) headers with section analysis
|
|
15
|
+
- Parse Linux ELF headers with readelf
|
|
16
|
+
- Extract metadata from images, documents, and media files
|
|
17
|
+
- Recursively hash directories and detect duplicate files
|
|
18
|
+
- Correlate file timestamps with log entries for timeline analysis
|
|
19
|
+
- Generate structured forensic investigation reports with findings and indicators
|
|
20
|
+
|
|
21
|
+
## Tools
|
|
22
|
+
|
|
23
|
+
### Tool Reference
|
|
24
|
+
|
|
25
|
+
| Tool | Purpose | Input | Output |
|
|
26
|
+
|------|---------|-------|--------|
|
|
27
|
+
| `file_hash` | Calculate MD5, SHA1, SHA256 hashes | File path | Three hash values + file size |
|
|
28
|
+
| `file_strings` | Extract strings with pattern highlighting | File path, min length, encoding | Strings + categorized interesting patterns |
|
|
29
|
+
| `file_identify` | Identify file type via magic bytes | File path | Type, MIME type, hex magic bytes |
|
|
30
|
+
| `file_entropy` | Calculate Shannon entropy | File path | Entropy value + rating (very_low to extremely_high) |
|
|
31
|
+
| `pe_header` | Parse Windows PE headers | File path | Machine type, sections, imports, packing detection |
|
|
32
|
+
| `elf_header` | Parse Linux ELF headers | File path | Architecture, sections, entry point |
|
|
33
|
+
| `exif_metadata` | Extract file metadata | File path | Key-value metadata dictionary |
|
|
34
|
+
| `hash_directory` | Recursively hash files in directory | Directory path, algorithm, pattern | File hashes + duplicate detection |
|
|
35
|
+
| `file_correlate` | Correlate file timestamps with log entries | Directory path, log file, time window | Timeline correlations between files and logs |
|
|
36
|
+
| `forensic_report` | Generate structured forensic report | Case ID, title, findings, evidence | Professional report with aggregated findings |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Tool Details
|
|
41
|
+
|
|
42
|
+
### file_hash
|
|
43
|
+
|
|
44
|
+
Calculate cryptographic hashes for file integrity verification and malware database lookups.
|
|
45
|
+
|
|
46
|
+
**Input Schema:**
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"file": "/path/to/file"
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Example Output:**
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"file": "/Users/ehenry/Documents/sample.exe",
|
|
57
|
+
"size": 45056,
|
|
58
|
+
"md5": "d41d8cd98f00b204e9800998ecf8427e",
|
|
59
|
+
"sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
|
60
|
+
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Use cases:**
|
|
65
|
+
- Check files against VirusTotal or other malware databases
|
|
66
|
+
- Verify file integrity across different systems
|
|
67
|
+
- Create hash-based file inventories
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### file_strings
|
|
72
|
+
|
|
73
|
+
Extract ASCII and wide-character strings from binaries with automatic pattern recognition for suspicious indicators.
|
|
74
|
+
|
|
75
|
+
**Input Schema:**
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"file": "/path/to/file",
|
|
79
|
+
"min_length": 6,
|
|
80
|
+
"encoding": "both",
|
|
81
|
+
"max_results": 500
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Parameters:**
|
|
86
|
+
- `min_length`: Minimum string length (3-100, default: 6)
|
|
87
|
+
- `encoding`: "ascii", "wide" (Unicode), or "both" (default: "both")
|
|
88
|
+
- `max_results`: Maximum strings to return (default: 500)
|
|
89
|
+
|
|
90
|
+
**Interesting Pattern Categories:**
|
|
91
|
+
- `url` — HTTP/HTTPS URLs
|
|
92
|
+
- `ip_address` — IPv4 addresses
|
|
93
|
+
- `email` — Email addresses
|
|
94
|
+
- `unc_path` — UNC network paths (\\server\share)
|
|
95
|
+
- `windows_path` — Windows file paths (C:\...)
|
|
96
|
+
- `registry_key` — Windows registry keys (HKEY_...)
|
|
97
|
+
- `sensitive_keyword` — "password", "secret", "apikey", etc.
|
|
98
|
+
- `shell_reference` — Shell commands (cmd.exe, powershell, bash)
|
|
99
|
+
- `suspicious_api` — Win32 APIs (CreateProcess, VirtualAlloc, LoadLibrary, etc.)
|
|
100
|
+
- `crypto_reference` — Cryptography keywords (encrypt, decrypt, cipher)
|
|
101
|
+
|
|
102
|
+
**Example Output:**
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"file": "/Users/ehenry/Documents/sample.exe",
|
|
106
|
+
"total_strings": 1247,
|
|
107
|
+
"strings": [
|
|
108
|
+
"This program cannot be run in DOS mode",
|
|
109
|
+
"kernel32.dll",
|
|
110
|
+
"advapi32.dll",
|
|
111
|
+
"user32.dll",
|
|
112
|
+
"LoadLibraryA",
|
|
113
|
+
"GetProcAddress"
|
|
114
|
+
],
|
|
115
|
+
"interesting": [
|
|
116
|
+
{
|
|
117
|
+
"value": "http://malware.example.com/beacon",
|
|
118
|
+
"category": "url"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"value": "CreateProcessA",
|
|
122
|
+
"category": "suspicious_api"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"value": "192.168.1.100",
|
|
126
|
+
"category": "ip_address"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"value": "VirtualAlloc WriteProcessMemory CreateRemoteThread",
|
|
130
|
+
"category": "suspicious_api"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"value": "password=",
|
|
134
|
+
"category": "sensitive_keyword"
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Use cases:**
|
|
141
|
+
- Quickly identify command & control domains
|
|
142
|
+
- Detect suspicious API usage patterns
|
|
143
|
+
- Find hardcoded credentials or configuration
|
|
144
|
+
- Analyze code reuse and similarities
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### file_identify
|
|
149
|
+
|
|
150
|
+
Identify file type using magic bytes (file command) for verification of claimed file types.
|
|
151
|
+
|
|
152
|
+
**Input Schema:**
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"file": "/path/to/file"
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Example Output:**
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"file": "/Users/ehenry/Documents/sample.exe",
|
|
163
|
+
"type": "PE32 executable (console) Intel 80386, for MS Windows",
|
|
164
|
+
"mime_type": "application/x-msdownload",
|
|
165
|
+
"magic_bytes": "4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00"
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Magic Bytes Reference:**
|
|
170
|
+
- `4d 5a` — PE/DOS executable (MZ header)
|
|
171
|
+
- `7f 45 4c 46` — ELF (Linux/Unix binary)
|
|
172
|
+
- `89 50 4e 47` — PNG image
|
|
173
|
+
- `ff d8 ff` — JPEG image
|
|
174
|
+
- `50 4b 03 04` — ZIP archive
|
|
175
|
+
|
|
176
|
+
**Use cases:**
|
|
177
|
+
- Verify file type hasn't been disguised with wrong extension
|
|
178
|
+
- Detect polyglot files that are multiple formats simultaneously
|
|
179
|
+
- Identify obfuscated or renamed files
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### file_entropy
|
|
184
|
+
|
|
185
|
+
Calculate Shannon entropy to detect compression, encryption, or packing.
|
|
186
|
+
|
|
187
|
+
**Input Schema:**
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"file": "/path/to/file"
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Example Output:**
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"file": "/Users/ehenry/Documents/sample.exe",
|
|
198
|
+
"overall_entropy": 6.847,
|
|
199
|
+
"entropy_rating": "very_high (likely compressed/encrypted)",
|
|
200
|
+
"size": 45056,
|
|
201
|
+
"max_possible_entropy": 8,
|
|
202
|
+
"entropy_percentage": 85.59
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Entropy Rating Scale:**
|
|
207
|
+
|
|
208
|
+
| Entropy Range | Rating | Meaning |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| < 1.0 | very_low | Empty or uniform data (suspicious padding) |
|
|
211
|
+
| 1.0 - 3.0 | low | Structured data, plain text, source code |
|
|
212
|
+
| 3.0 - 5.0 | medium | Mixed content, normal executables |
|
|
213
|
+
| 5.0 - 7.0 | high | Compressed or encoded sections |
|
|
214
|
+
| 7.0 - 7.5 | very_high | Likely compressed/encrypted |
|
|
215
|
+
| > 7.5 | extremely_high | Almost certainly encrypted or random data |
|
|
216
|
+
|
|
217
|
+
**Interpretation:**
|
|
218
|
+
- **Legitimate binaries:** Typically 4.0 - 6.5 (mix of code, strings, data)
|
|
219
|
+
- **Packed malware:** Often 7.0+ (entire payload compressed/encrypted)
|
|
220
|
+
- **Encrypted data:** Approaches 8.0 (maximum randomness)
|
|
221
|
+
|
|
222
|
+
**Use cases:**
|
|
223
|
+
- Detect code packing/obfuscation
|
|
224
|
+
- Identify encryption without cryptanalysis
|
|
225
|
+
- Spot unusual data patterns
|
|
226
|
+
- Compare sections of a binary (high entropy .text section = suspicious)
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### pe_header
|
|
231
|
+
|
|
232
|
+
Parse Windows PE (Portable Executable) headers for comprehensive binary analysis. Pure TypeScript parsing, no external tools required.
|
|
233
|
+
|
|
234
|
+
**Input Schema:**
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"file": "/path/to/file"
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Example Output:**
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"file": "/Users/ehenry/Documents/malware.exe",
|
|
245
|
+
"is_64bit": true,
|
|
246
|
+
"machine": "AMD64",
|
|
247
|
+
"timestamp": "2023-06-15T10:23:45.000Z",
|
|
248
|
+
"characteristics": [
|
|
249
|
+
"EXECUTABLE_IMAGE",
|
|
250
|
+
"LARGE_ADDRESS_AWARE"
|
|
251
|
+
],
|
|
252
|
+
"sections": [
|
|
253
|
+
{
|
|
254
|
+
"name": ".text",
|
|
255
|
+
"virtual_size": 204800,
|
|
256
|
+
"raw_size": 205312,
|
|
257
|
+
"entropy": 6.234,
|
|
258
|
+
"characteristics": [
|
|
259
|
+
"CODE",
|
|
260
|
+
"EXECUTE",
|
|
261
|
+
"READ"
|
|
262
|
+
]
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"name": ".data",
|
|
266
|
+
"virtual_size": 4096,
|
|
267
|
+
"raw_size": 4096,
|
|
268
|
+
"entropy": 3.456,
|
|
269
|
+
"characteristics": [
|
|
270
|
+
"INITIALIZED_DATA",
|
|
271
|
+
"READ",
|
|
272
|
+
"WRITE"
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": ".rsrc",
|
|
277
|
+
"virtual_size": 8192,
|
|
278
|
+
"raw_size": 8192,
|
|
279
|
+
"entropy": 2.123,
|
|
280
|
+
"characteristics": [
|
|
281
|
+
"INITIALIZED_DATA",
|
|
282
|
+
"READ"
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
],
|
|
286
|
+
"imports": [
|
|
287
|
+
{
|
|
288
|
+
"dll": "kernel32.dll",
|
|
289
|
+
"functions": []
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"dll": "user32.dll",
|
|
293
|
+
"functions": []
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"dll": "advapi32.dll",
|
|
297
|
+
"functions": []
|
|
298
|
+
}
|
|
299
|
+
],
|
|
300
|
+
"is_packed": true,
|
|
301
|
+
"packing_indicators": "High entropy sections: .text, .reloc; RWX sections: .overlay"
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Key Fields:**
|
|
306
|
+
|
|
307
|
+
- **machine:** i386, AMD64, ARM, ARM64
|
|
308
|
+
- **timestamp:** Compilation date (UTC)
|
|
309
|
+
- **characteristics:** EXECUTABLE_IMAGE, DLL, 32BIT_MACHINE, LARGE_ADDRESS_AWARE
|
|
310
|
+
- **sections:** Code, data, resources, debug info
|
|
311
|
+
- **entropy:** Section-level entropy (high entropy = packed)
|
|
312
|
+
- **characteristics:** CODE, INITIALIZED_DATA, EXECUTE, READ, WRITE
|
|
313
|
+
- **is_packed:** Detected based on high entropy sections or RWX permissions
|
|
314
|
+
- **packing_indicators:** Specific detection reasons
|
|
315
|
+
|
|
316
|
+
**Packing Detection Heuristics:**
|
|
317
|
+
- Section entropy > 7.0 (indicates compression/encryption)
|
|
318
|
+
- Read+Write+Execute permissions on same section (unusual for legitimate code)
|
|
319
|
+
- Size mismatches between virtual and raw sizes
|
|
320
|
+
|
|
321
|
+
**Common Packed Binary Indicators:**
|
|
322
|
+
```
|
|
323
|
+
.text entropy: 7.2+ (should be 4.5-6.5)
|
|
324
|
+
.reloc entropy: 7.5+ (normally 3.0-5.0)
|
|
325
|
+
RWX section present (normal code is RX only)
|
|
326
|
+
Timestamp: 1970-01-01 (modified to hide compilation time)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Use cases:**
|
|
330
|
+
- Detect code packing and obfuscation
|
|
331
|
+
- Identify imported APIs (often reveals malware family)
|
|
332
|
+
- Analyze binary compilation metadata
|
|
333
|
+
- Check for suspicious section permissions
|
|
334
|
+
- Verify DLL dependencies
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
### elf_header
|
|
339
|
+
|
|
340
|
+
Parse Linux/Unix ELF (Executable and Linkable Format) headers using readelf.
|
|
341
|
+
|
|
342
|
+
**Input Schema:**
|
|
343
|
+
```json
|
|
344
|
+
{
|
|
345
|
+
"file": "/path/to/file"
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Example Output:**
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"file": "/usr/bin/ls",
|
|
353
|
+
"class": "ELF64",
|
|
354
|
+
"data": "2's complement, little endian",
|
|
355
|
+
"type": "EXEC (Executable file)",
|
|
356
|
+
"machine": "Advanced Micro Devices X86-64",
|
|
357
|
+
"entry_point": "0x401000",
|
|
358
|
+
"section_count": 27,
|
|
359
|
+
"sections": [
|
|
360
|
+
{
|
|
361
|
+
"name": ".text",
|
|
362
|
+
"type": "PROGBITS",
|
|
363
|
+
"size": 184652,
|
|
364
|
+
"flags": "AX"
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"name": ".rodata",
|
|
368
|
+
"type": "PROGBITS",
|
|
369
|
+
"size": 98304,
|
|
370
|
+
"flags": "A"
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"name": ".data",
|
|
374
|
+
"type": "PROGBITS",
|
|
375
|
+
"size": 8192,
|
|
376
|
+
"flags": "WA"
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"name": ".bss",
|
|
380
|
+
"type": "NOBITS",
|
|
381
|
+
"size": 4096,
|
|
382
|
+
"flags": "WA"
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Key Fields:**
|
|
389
|
+
|
|
390
|
+
- **class:** ELF32, ELF64
|
|
391
|
+
- **data:** Endianness (little/big endian)
|
|
392
|
+
- **type:** EXEC (executable), DYN (shared object), REL (relocatable)
|
|
393
|
+
- **machine:** x86, x86-64, ARM, ARM64, MIPS, PPC, etc.
|
|
394
|
+
- **entry_point:** Memory address where execution begins
|
|
395
|
+
- **sections:** Program sections (.text, .data, .bss, .rodata, etc.)
|
|
396
|
+
- **flags:** A (allocate), W (write), X (execute)
|
|
397
|
+
|
|
398
|
+
**Section Types:**
|
|
399
|
+
- `PROGBITS` — Program data in file
|
|
400
|
+
- `NOBITS` — Space but no file data (like .bss)
|
|
401
|
+
- `SYMTAB` — Symbol table
|
|
402
|
+
- `STRTAB` — String table
|
|
403
|
+
- `RELA` — Relocation entries
|
|
404
|
+
- `DYNAMIC` — Dynamic linking info
|
|
405
|
+
|
|
406
|
+
**Use cases:**
|
|
407
|
+
- Analyze Linux/Unix binaries
|
|
408
|
+
- Check architecture and entry points
|
|
409
|
+
- Identify stripped vs. unstripped binaries
|
|
410
|
+
- Verify PIE (Position Independent Executable) support
|
|
411
|
+
- Detect hardening features
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
### exif_metadata
|
|
416
|
+
|
|
417
|
+
Extract metadata from image files, documents, and media using exiftool.
|
|
418
|
+
|
|
419
|
+
**Input Schema:**
|
|
420
|
+
```json
|
|
421
|
+
{
|
|
422
|
+
"file": "/path/to/image.jpg"
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**Example Output:**
|
|
427
|
+
```json
|
|
428
|
+
{
|
|
429
|
+
"file": "/Users/ehenry/Documents/photo.jpg",
|
|
430
|
+
"field_count": 34,
|
|
431
|
+
"metadata": {
|
|
432
|
+
"FileName": "photo.jpg",
|
|
433
|
+
"FileSize": "2048 kB",
|
|
434
|
+
"FileType": "JPEG",
|
|
435
|
+
"MIMEType": "image/jpeg",
|
|
436
|
+
"ExifImageWidth": "4032",
|
|
437
|
+
"ExifImageHeight": "3024",
|
|
438
|
+
"Make": "Apple",
|
|
439
|
+
"Model": "iPhone 14 Pro",
|
|
440
|
+
"DateTime": "2023:06:15 14:23:45",
|
|
441
|
+
"LensModel": "iPhone 14 Pro main camera 6.86mm f/1.78",
|
|
442
|
+
"GPSLatitude": "37 deg 46' 54.32\" N",
|
|
443
|
+
"GPSLongitude": "122 deg 24' 13.70\" W",
|
|
444
|
+
"GPSAltitude": "12.3 m Above Sea Level",
|
|
445
|
+
"Copyright": "2023 John Doe",
|
|
446
|
+
"ImageDescription": "Vacation photo"
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**Common Metadata Fields:**
|
|
452
|
+
- **Image:** Width, height, bit depth, color space
|
|
453
|
+
- **Camera:** Make, model, lens, aperture, shutter speed, ISO
|
|
454
|
+
- **Location:** GPS coordinates, altitude
|
|
455
|
+
- **Timestamps:** Original, modified, digitized
|
|
456
|
+
- **Copyright:** Creator, copyright notice, usage rights
|
|
457
|
+
- **Software:** Creator application, version
|
|
458
|
+
|
|
459
|
+
**Privacy Note:** EXIF data can reveal:
|
|
460
|
+
- Camera location (GPS coordinates)
|
|
461
|
+
- Device used (phone model)
|
|
462
|
+
- Creation timestamp
|
|
463
|
+
- Copyright/author information
|
|
464
|
+
- Camera settings and behavior patterns
|
|
465
|
+
|
|
466
|
+
**Use cases:**
|
|
467
|
+
- Extract geolocation data from images
|
|
468
|
+
- Identify device/software used
|
|
469
|
+
- Discover copyright and authorship info
|
|
470
|
+
- Detect privacy leaks in shared images
|
|
471
|
+
- Verify timestamp authenticity
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
### hash_directory
|
|
476
|
+
|
|
477
|
+
Recursively hash all files in a directory with duplicate file detection.
|
|
478
|
+
|
|
479
|
+
**Input Schema:**
|
|
480
|
+
```typescript
|
|
481
|
+
{
|
|
482
|
+
directory_path: string // Path to directory to hash
|
|
483
|
+
algorithm: "md5" | "sha1" | "sha256" // Hash algorithm (default: sha256)
|
|
484
|
+
recursive: boolean // Hash subdirectories (default: true)
|
|
485
|
+
max_files: number // Maximum files to process (default: 1000)
|
|
486
|
+
include_pattern?: string // Only include files matching pattern (e.g., '*.exe')
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Example Request:**
|
|
491
|
+
```json
|
|
492
|
+
{
|
|
493
|
+
"directory_path": "/Users/ehenry/Downloads",
|
|
494
|
+
"algorithm": "sha256",
|
|
495
|
+
"recursive": true,
|
|
496
|
+
"max_files": 1000,
|
|
497
|
+
"include_pattern": "*.exe"
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Example Output:**
|
|
502
|
+
```json
|
|
503
|
+
{
|
|
504
|
+
"directory": "/Users/ehenry/Downloads",
|
|
505
|
+
"algorithm": "sha256",
|
|
506
|
+
"total_files": 42,
|
|
507
|
+
"total_errors": 2,
|
|
508
|
+
"duplicates_found": 3,
|
|
509
|
+
"files": [
|
|
510
|
+
{
|
|
511
|
+
"path": "/Users/ehenry/Downloads/installer.exe",
|
|
512
|
+
"hash": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f",
|
|
513
|
+
"size": 524288,
|
|
514
|
+
"modified": "2024-01-15T10:23:45.000Z"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
"path": "/Users/ehenry/Downloads/setup.exe",
|
|
518
|
+
"hash": "b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2g",
|
|
519
|
+
"size": 1048576,
|
|
520
|
+
"modified": "2024-01-14T15:30:20.000Z"
|
|
521
|
+
}
|
|
522
|
+
],
|
|
523
|
+
"duplicates": [
|
|
524
|
+
{
|
|
525
|
+
"hash": "c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2g3h",
|
|
526
|
+
"files": [
|
|
527
|
+
"/Users/ehenry/Downloads/report_v1.pdf",
|
|
528
|
+
"/Users/ehenry/Downloads/report_v1_copy.pdf",
|
|
529
|
+
"/Users/ehenry/Downloads/Archive/report_old.pdf"
|
|
530
|
+
]
|
|
531
|
+
}
|
|
532
|
+
],
|
|
533
|
+
"errors": [
|
|
534
|
+
{
|
|
535
|
+
"path": "/Users/ehenry/Downloads/large_file.iso",
|
|
536
|
+
"error": "File too large (>100MB), skipped"
|
|
537
|
+
}
|
|
538
|
+
]
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
**Use cases:**
|
|
543
|
+
- Find duplicate files in a directory tree
|
|
544
|
+
- Verify integrity of archived files
|
|
545
|
+
- Detect suspicious files disguised with different names
|
|
546
|
+
- Create forensic inventories of file systems
|
|
547
|
+
- Identify potential data exfiltration artifacts
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
### file_correlate
|
|
552
|
+
|
|
553
|
+
Correlate file modification timestamps with log entries within a specified time window for timeline analysis.
|
|
554
|
+
|
|
555
|
+
**Input Schema:**
|
|
556
|
+
```typescript
|
|
557
|
+
{
|
|
558
|
+
directory_path: string // Path to directory containing files
|
|
559
|
+
log_file: string // Path to log file to correlate
|
|
560
|
+
time_window_minutes: number // Time window in minutes (default: 60)
|
|
561
|
+
max_files: number // Maximum files to analyze (default: 500)
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Example Request:**
|
|
566
|
+
```json
|
|
567
|
+
{
|
|
568
|
+
"directory_path": "/var/log/suspicious_dir",
|
|
569
|
+
"log_file": "/var/log/syslog",
|
|
570
|
+
"time_window_minutes": 30,
|
|
571
|
+
"max_files": 500
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**Example Output:**
|
|
576
|
+
```json
|
|
577
|
+
{
|
|
578
|
+
"directory": "/var/log/suspicious_dir",
|
|
579
|
+
"log_file": "/var/log/syslog",
|
|
580
|
+
"time_window_minutes": 30,
|
|
581
|
+
"total_files_analyzed": 15,
|
|
582
|
+
"total_log_entries": 2847,
|
|
583
|
+
"correlations_found": 8,
|
|
584
|
+
"correlations": [
|
|
585
|
+
{
|
|
586
|
+
"file": "/var/log/suspicious_dir/malware.exe",
|
|
587
|
+
"file_modified": "2024-01-15T14:23:45.000Z",
|
|
588
|
+
"related_log_entries": [
|
|
589
|
+
{
|
|
590
|
+
"line_number": 1245,
|
|
591
|
+
"timestamp": "2024-01-15T14:20:30.000Z",
|
|
592
|
+
"content": "Process execution detected: C:\\System32\\cmd.exe /c download malware.exe"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
"line_number": 1246,
|
|
596
|
+
"timestamp": "2024-01-15T14:22:15.000Z",
|
|
597
|
+
"content": "File created: /var/log/suspicious_dir/malware.exe"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"line_number": 1247,
|
|
601
|
+
"timestamp": "2024-01-15T14:23:45.000Z",
|
|
602
|
+
"content": "Suspicious API call: CreateProcessA from unknown process"
|
|
603
|
+
}
|
|
604
|
+
]
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
"file": "/var/log/suspicious_dir/config.ini",
|
|
608
|
+
"file_modified": "2024-01-15T14:45:20.000Z",
|
|
609
|
+
"related_log_entries": [
|
|
610
|
+
{
|
|
611
|
+
"line_number": 1312,
|
|
612
|
+
"timestamp": "2024-01-15T14:43:00.000Z",
|
|
613
|
+
"content": "Registry key modified: HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\Run"
|
|
614
|
+
}
|
|
615
|
+
]
|
|
616
|
+
}
|
|
617
|
+
]
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
**Supported Timestamp Formats:**
|
|
622
|
+
- ISO 8601: `2024-01-15T14:23:45Z` or `2024-01-15 14:23:45`
|
|
623
|
+
- Syslog: `Jan 15 14:23:45`
|
|
624
|
+
|
|
625
|
+
**Use cases:**
|
|
626
|
+
- Timeline analysis during incident response
|
|
627
|
+
- Correlate file modifications with system events
|
|
628
|
+
- Identify suspicious activity sequences
|
|
629
|
+
- Establish causality between files and log entries
|
|
630
|
+
- Support forensic investigation timelines
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
### forensic_report
|
|
635
|
+
|
|
636
|
+
Generate a structured forensic investigation report with findings, evidence, indicators of compromise, and recommendations.
|
|
637
|
+
|
|
638
|
+
**Input Schema:**
|
|
639
|
+
```typescript
|
|
640
|
+
{
|
|
641
|
+
case_id: string // Unique case or incident identifier
|
|
642
|
+
title: string // Report title
|
|
643
|
+
findings: Array<{
|
|
644
|
+
category: string // Category (e.g., 'malware', 'network', 'filesystem')
|
|
645
|
+
severity: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"
|
|
646
|
+
description: string // Detailed finding description
|
|
647
|
+
evidence?: string[] // Evidence items (files, hashes, etc.)
|
|
648
|
+
tools_used?: string[] // Tools used to discover finding
|
|
649
|
+
}>
|
|
650
|
+
timeline?: Array<{
|
|
651
|
+
timestamp: string // ISO 8601 timestamp
|
|
652
|
+
event: string // Event description
|
|
653
|
+
source?: string // Source of the event
|
|
654
|
+
}>
|
|
655
|
+
affected_systems?: string[] // List of affected systems/hosts
|
|
656
|
+
iocs?: Array<{
|
|
657
|
+
type: string // IOC type (ip, domain, hash, url, email)
|
|
658
|
+
value: string // IOC value
|
|
659
|
+
context?: string // Context/source of IOC
|
|
660
|
+
}>
|
|
661
|
+
recommendations?: string[] // Recommended actions
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**Example Request:**
|
|
666
|
+
```json
|
|
667
|
+
{
|
|
668
|
+
"case_id": "INC-2024-0215",
|
|
669
|
+
"title": "Ransomware Incident Investigation Report",
|
|
670
|
+
"findings": [
|
|
671
|
+
{
|
|
672
|
+
"category": "malware",
|
|
673
|
+
"severity": "CRITICAL",
|
|
674
|
+
"description": "Detected known ransomware executable with high entropy and suspicious API calls",
|
|
675
|
+
"evidence": [
|
|
676
|
+
"/Users/shared/payload.exe",
|
|
677
|
+
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f"
|
|
678
|
+
],
|
|
679
|
+
"tools_used": ["file_identify", "pe_header", "file_strings"]
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
"category": "network",
|
|
683
|
+
"severity": "HIGH",
|
|
684
|
+
"description": "Suspicious outbound connections to known command and control server",
|
|
685
|
+
"evidence": [
|
|
686
|
+
"192.168.1.100",
|
|
687
|
+
"malware-c2.example.com"
|
|
688
|
+
],
|
|
689
|
+
"tools_used": ["file_strings", "network_analysis"]
|
|
690
|
+
}
|
|
691
|
+
],
|
|
692
|
+
"timeline": [
|
|
693
|
+
{
|
|
694
|
+
"timestamp": "2024-01-15T08:00:00Z",
|
|
695
|
+
"event": "Initial infection vector: phishing email with malicious attachment"
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
"timestamp": "2024-01-15T12:30:00Z",
|
|
699
|
+
"event": "Ransomware deployment and encryption process initiated"
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
"timestamp": "2024-01-15T14:00:00Z",
|
|
703
|
+
"event": "Ransom note displayed to user"
|
|
704
|
+
}
|
|
705
|
+
],
|
|
706
|
+
"affected_systems": ["WORKSTATION-01", "FILESERVER-02", "LAPTOP-15"],
|
|
707
|
+
"iocs": [
|
|
708
|
+
{
|
|
709
|
+
"type": "hash",
|
|
710
|
+
"value": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f",
|
|
711
|
+
"context": "SHA256 of ransomware executable"
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"type": "domain",
|
|
715
|
+
"value": "malware-c2.example.com",
|
|
716
|
+
"context": "Command and control domain"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"type": "ip",
|
|
720
|
+
"value": "192.0.2.100",
|
|
721
|
+
"context": "C2 server IP address"
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"type": "email",
|
|
725
|
+
"value": "attacker@example.com",
|
|
726
|
+
"context": "Ransom contact email"
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
"recommendations": [
|
|
730
|
+
"Isolate all affected systems from the network",
|
|
731
|
+
"Preserve forensic evidence before remediation",
|
|
732
|
+
"Reset credentials for all affected accounts",
|
|
733
|
+
"Update security monitoring and detection rules"
|
|
734
|
+
]
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
**Example Output:**
|
|
739
|
+
```json
|
|
740
|
+
{
|
|
741
|
+
"report_metadata": {
|
|
742
|
+
"case_id": "INC-2024-0215",
|
|
743
|
+
"title": "Ransomware Incident Investigation Report",
|
|
744
|
+
"generated_at": "2024-01-16T09:30:00.000Z",
|
|
745
|
+
"overall_risk_level": "CRITICAL"
|
|
746
|
+
},
|
|
747
|
+
"executive_summary": {
|
|
748
|
+
"total_findings": 2,
|
|
749
|
+
"severity_breakdown": {
|
|
750
|
+
"CRITICAL": 1,
|
|
751
|
+
"HIGH": 1,
|
|
752
|
+
"MEDIUM": 0,
|
|
753
|
+
"LOW": 0
|
|
754
|
+
},
|
|
755
|
+
"affected_systems_count": 3,
|
|
756
|
+
"ioc_count": 4
|
|
757
|
+
},
|
|
758
|
+
"findings": [
|
|
759
|
+
{
|
|
760
|
+
"id": "F-001",
|
|
761
|
+
"category": "malware",
|
|
762
|
+
"severity": "CRITICAL",
|
|
763
|
+
"description": "Detected known ransomware executable with high entropy and suspicious API calls",
|
|
764
|
+
"evidence": [
|
|
765
|
+
"/Users/shared/payload.exe",
|
|
766
|
+
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f"
|
|
767
|
+
],
|
|
768
|
+
"tools_used": ["file_identify", "pe_header", "file_strings"]
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
"id": "F-002",
|
|
772
|
+
"category": "network",
|
|
773
|
+
"severity": "HIGH",
|
|
774
|
+
"description": "Suspicious outbound connections to known command and control server",
|
|
775
|
+
"evidence": [
|
|
776
|
+
"192.168.1.100",
|
|
777
|
+
"malware-c2.example.com"
|
|
778
|
+
],
|
|
779
|
+
"tools_used": ["file_strings", "network_analysis"]
|
|
780
|
+
}
|
|
781
|
+
],
|
|
782
|
+
"timeline": [
|
|
783
|
+
{
|
|
784
|
+
"timestamp": "2024-01-15T08:00:00Z",
|
|
785
|
+
"event": "Initial infection vector: phishing email with malicious attachment"
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
"timestamp": "2024-01-15T12:30:00Z",
|
|
789
|
+
"event": "Ransomware deployment and encryption process initiated"
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
"timestamp": "2024-01-15T14:00:00Z",
|
|
793
|
+
"event": "Ransom note displayed to user"
|
|
794
|
+
}
|
|
795
|
+
],
|
|
796
|
+
"affected_systems": ["WORKSTATION-01", "FILESERVER-02", "LAPTOP-15"],
|
|
797
|
+
"indicators_of_compromise": [
|
|
798
|
+
{
|
|
799
|
+
"type": "hash",
|
|
800
|
+
"value": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f",
|
|
801
|
+
"context": "SHA256 of ransomware executable"
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
"type": "domain",
|
|
805
|
+
"value": "malware-c2.example.com",
|
|
806
|
+
"context": "Command and control domain"
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
"type": "ip",
|
|
810
|
+
"value": "192.0.2.100",
|
|
811
|
+
"context": "C2 server IP address"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"type": "email",
|
|
815
|
+
"value": "attacker@example.com",
|
|
816
|
+
"context": "Ransom contact email"
|
|
817
|
+
}
|
|
818
|
+
],
|
|
819
|
+
"recommendations": [
|
|
820
|
+
"Isolate affected systems from the network",
|
|
821
|
+
"Preserve forensic evidence before remediation",
|
|
822
|
+
"Reset credentials for compromised accounts",
|
|
823
|
+
"Apply patches for exploited vulnerabilities",
|
|
824
|
+
"Review and update security monitoring rules"
|
|
825
|
+
]
|
|
826
|
+
}
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
**Use cases:**
|
|
830
|
+
- Generate professional incident response reports
|
|
831
|
+
- Aggregate findings from multiple forensic tools
|
|
832
|
+
- Document investigation timeline and evidence
|
|
833
|
+
- Track indicators of compromise
|
|
834
|
+
- Provide actionable recommendations to stakeholders
|
|
835
|
+
- Support incident response procedures and compliance documentation
|
|
836
|
+
|
|
837
|
+
---
|
|
838
|
+
|
|
839
|
+
## Prerequisites
|
|
840
|
+
|
|
841
|
+
### Required Tools
|
|
842
|
+
|
|
843
|
+
The server uses standard Unix/Linux utilities that come pre-installed on most systems:
|
|
844
|
+
|
|
845
|
+
- **strings** — Extract printable strings from binaries
|
|
846
|
+
- Built into all POSIX systems
|
|
847
|
+
- Already available on macOS, Linux, BSD
|
|
848
|
+
|
|
849
|
+
- **file** — Identify file types via magic bytes
|
|
850
|
+
- Standard command on all Unix-like systems
|
|
851
|
+
- Installed by default on macOS and Linux
|
|
852
|
+
|
|
853
|
+
- **readelf** — Parse ELF binary headers
|
|
854
|
+
- Standard on Linux systems
|
|
855
|
+
- On macOS: `brew install binutils` (provides readelf)
|
|
856
|
+
- On BSD: `pkg install binutils` or equivalent
|
|
857
|
+
|
|
858
|
+
### Optional Tools
|
|
859
|
+
|
|
860
|
+
- **exiftool** — Extract metadata from images/documents
|
|
861
|
+
- macOS: `brew install exiftool`
|
|
862
|
+
- Linux: `apt-get install libimage-exiftool-perl` or `yum install perl-Image-ExifTool`
|
|
863
|
+
- Download: https://exiftool.org/
|
|
864
|
+
|
|
865
|
+
### PE Header Parsing
|
|
866
|
+
|
|
867
|
+
PE header parsing is implemented in pure TypeScript with no external dependencies. The server automatically parses Windows executables without requiring any additional tools.
|
|
868
|
+
|
|
869
|
+
### Verify Installation
|
|
870
|
+
|
|
871
|
+
```bash
|
|
872
|
+
# Check required tools
|
|
873
|
+
which strings
|
|
874
|
+
which file
|
|
875
|
+
which readelf # or brew install binutils
|
|
876
|
+
|
|
877
|
+
# Optional: Check exiftool
|
|
878
|
+
which exiftool # or brew install exiftool
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
---
|
|
882
|
+
|
|
883
|
+
## Installation
|
|
884
|
+
|
|
885
|
+
### Prerequisites
|
|
886
|
+
- Node.js 18+ or Bun 1.0+
|
|
887
|
+
- Bun runtime (recommended for better performance)
|
|
888
|
+
|
|
889
|
+
### Steps
|
|
890
|
+
|
|
891
|
+
1. **Install Bun** (if not already installed):
|
|
892
|
+
```bash
|
|
893
|
+
curl -fsSL https://bun.sh/install | bash
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
2. **Clone or download this repository:**
|
|
897
|
+
```bash
|
|
898
|
+
cd /path/to/forensic-analysis
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
3. **Install dependencies:**
|
|
902
|
+
```bash
|
|
903
|
+
bun install
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
4. **Build the server:**
|
|
907
|
+
```bash
|
|
908
|
+
bun run build
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
This creates the compiled output in `dist/index.js`.
|
|
912
|
+
|
|
913
|
+
### File Structure
|
|
914
|
+
|
|
915
|
+
```
|
|
916
|
+
forensic-analysis/
|
|
917
|
+
├── src/
|
|
918
|
+
│ ├── index.ts # Server entry point
|
|
919
|
+
│ ├── schemas.ts # Input validation schemas
|
|
920
|
+
│ ├── security.ts # File path validation
|
|
921
|
+
│ ├── types.ts # TypeScript interfaces
|
|
922
|
+
│ ├── cli-executor.ts # External command execution
|
|
923
|
+
│ └── tools/
|
|
924
|
+
│ ├── file-hash.ts
|
|
925
|
+
│ ├── file-strings.ts
|
|
926
|
+
│ ├── file-identify.ts
|
|
927
|
+
│ ├── file-entropy.ts
|
|
928
|
+
│ ├── pe-header.ts
|
|
929
|
+
│ ├── elf-header.ts
|
|
930
|
+
│ ├── exif-metadata.ts
|
|
931
|
+
│ ├── hash-directory.ts
|
|
932
|
+
│ ├── file-correlate.ts
|
|
933
|
+
│ └── forensic-report.ts
|
|
934
|
+
├── dist/ # Compiled output (generated)
|
|
935
|
+
├── package.json
|
|
936
|
+
└── README.md
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
---
|
|
940
|
+
|
|
941
|
+
## Usage
|
|
942
|
+
|
|
943
|
+
### Starting the Server
|
|
944
|
+
|
|
945
|
+
The server communicates via stdio (standard input/output), making it compatible with Claude Desktop and other MCP clients.
|
|
946
|
+
|
|
947
|
+
**Direct execution:**
|
|
948
|
+
```bash
|
|
949
|
+
bun run src/index.ts
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
**Via compiled build:**
|
|
953
|
+
```bash
|
|
954
|
+
bun dist/index.js
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
### Claude Desktop Integration
|
|
958
|
+
|
|
959
|
+
Add the server to Claude Desktop's configuration:
|
|
960
|
+
|
|
961
|
+
**File:** `~/.claude/claude.json` (or `%APPDATA%\Claude\claude.json` on Windows)
|
|
962
|
+
|
|
963
|
+
```json
|
|
964
|
+
{
|
|
965
|
+
"mcpServers": {
|
|
966
|
+
"forensic-analysis": {
|
|
967
|
+
"command": "bun",
|
|
968
|
+
"args": [
|
|
969
|
+
"run",
|
|
970
|
+
"/Users/ehenry/Documents/code/mcp-servers/forensic-analysis/src/index.ts"
|
|
971
|
+
]
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
Or with built version:
|
|
978
|
+
```json
|
|
979
|
+
{
|
|
980
|
+
"mcpServers": {
|
|
981
|
+
"forensic-analysis": {
|
|
982
|
+
"command": "bun",
|
|
983
|
+
"args": [
|
|
984
|
+
"/Users/ehenry/Documents/code/mcp-servers/forensic-analysis/dist/index.js"
|
|
985
|
+
]
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
### Claude Code (Cline) Integration
|
|
992
|
+
|
|
993
|
+
Add to Claude Code settings JSON:
|
|
994
|
+
|
|
995
|
+
```json
|
|
996
|
+
{
|
|
997
|
+
"mcpServers": {
|
|
998
|
+
"forensic-analysis": {
|
|
999
|
+
"command": "bun",
|
|
1000
|
+
"args": [
|
|
1001
|
+
"run",
|
|
1002
|
+
"/Users/ehenry/Documents/code/mcp-servers/forensic-analysis/src/index.ts"
|
|
1003
|
+
]
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
### Programmatic Usage
|
|
1010
|
+
|
|
1011
|
+
When connected to the MCP server, Claude can invoke tools like:
|
|
1012
|
+
|
|
1013
|
+
```
|
|
1014
|
+
Analyze /path/to/binary.exe for packing indicators
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
This would trigger:
|
|
1018
|
+
1. `file_identify` to verify it's a PE file
|
|
1019
|
+
2. `file_entropy` to check for high entropy
|
|
1020
|
+
3. `pe_header` to analyze sections and detect packing
|
|
1021
|
+
|
|
1022
|
+
---
|
|
1023
|
+
|
|
1024
|
+
## Security
|
|
1025
|
+
|
|
1026
|
+
### File Path Validation
|
|
1027
|
+
|
|
1028
|
+
All file paths are validated before access:
|
|
1029
|
+
|
|
1030
|
+
1. **Path normalization:** Resolves relative paths and symlinks
|
|
1031
|
+
2. **Absolute path requirement:** Converted to absolute paths
|
|
1032
|
+
3. **Blocked paths:** Access to sensitive system paths is denied:
|
|
1033
|
+
- `/etc/shadow` — Password hashes
|
|
1034
|
+
- `/proc` — Process information
|
|
1035
|
+
- `/sys` — Kernel information
|
|
1036
|
+
- `/dev` — Device files
|
|
1037
|
+
4. **Existence check:** File must exist
|
|
1038
|
+
5. **File type check:** Must be a regular file (not directory)
|
|
1039
|
+
6. **Size limit:** Files must be under 100 MB
|
|
1040
|
+
|
|
1041
|
+
### Security Module
|
|
1042
|
+
|
|
1043
|
+
```typescript
|
|
1044
|
+
// src/security.ts
|
|
1045
|
+
const BLOCKED_PATHS = ["/etc/shadow", "/proc", "/sys", "/dev"];
|
|
1046
|
+
const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
|
|
1047
|
+
|
|
1048
|
+
function validateFilePath(path: string): string {
|
|
1049
|
+
// 1. Normalize and resolve to absolute path
|
|
1050
|
+
const resolved = resolve(normalize(path));
|
|
1051
|
+
|
|
1052
|
+
// 2. Check against blocked paths
|
|
1053
|
+
for (const blocked of BLOCKED_PATHS) {
|
|
1054
|
+
if (resolved.startsWith(blocked)) {
|
|
1055
|
+
throw new Error(`Access to ${blocked} is not allowed`);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// 3. Verify file exists
|
|
1060
|
+
if (!existsSync(resolved)) {
|
|
1061
|
+
throw new Error(`File does not exist: ${resolved}`);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// 4. Verify it's a regular file
|
|
1065
|
+
const stat = statSync(resolved);
|
|
1066
|
+
if (!stat.isFile()) {
|
|
1067
|
+
throw new Error(`Path is not a file: ${resolved}`);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// 5. Check file size
|
|
1071
|
+
if (stat.size > MAX_FILE_SIZE) {
|
|
1072
|
+
throw new Error(`File too large (${(stat.size / 1024 / 1024).toFixed(1)}MB). Maximum: 100MB`);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
return resolved;
|
|
1076
|
+
}
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
### External Command Execution
|
|
1080
|
+
|
|
1081
|
+
External commands (strings, file, readelf, exiftool) are executed with:
|
|
1082
|
+
- **Timeout:** 30 seconds per command
|
|
1083
|
+
- **Buffer limit:** 10 MB max output
|
|
1084
|
+
- **No shell:** Commands executed directly without shell interpretation
|
|
1085
|
+
- **Argument validation:** Zod schemas validate all inputs
|
|
1086
|
+
|
|
1087
|
+
### Best Practices
|
|
1088
|
+
|
|
1089
|
+
- **Only analyze trusted files** — Never analyze files from untrusted sources without verification
|
|
1090
|
+
- **Use in isolated environment** — Consider running in a container or VM for suspicious files
|
|
1091
|
+
- **Monitor resource usage** — Large files (approaching 100 MB) may be slow to analyze
|
|
1092
|
+
- **Verify external tools** — Ensure strings, file, readelf are from official sources
|
|
1093
|
+
|
|
1094
|
+
---
|
|
1095
|
+
|
|
1096
|
+
## Examples
|
|
1097
|
+
|
|
1098
|
+
### Analyze a Suspicious Binary
|
|
1099
|
+
|
|
1100
|
+
```
|
|
1101
|
+
I found a suspicious executable at /Users/shared/unknown.exe.
|
|
1102
|
+
Can you analyze it for signs of malware?
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
Claude would:
|
|
1106
|
+
1. Run `file_identify` to confirm it's a PE executable
|
|
1107
|
+
2. Run `file_hash` to get hashes for VirusTotal lookup
|
|
1108
|
+
3. Run `file_entropy` to check for packing
|
|
1109
|
+
4. Run `pe_header` to analyze imports and detect packing
|
|
1110
|
+
5. Run `file_strings` to find URLs, APIs, and indicators
|
|
1111
|
+
|
|
1112
|
+
---
|
|
1113
|
+
|
|
1114
|
+
### Extract Metadata from Photo
|
|
1115
|
+
|
|
1116
|
+
```
|
|
1117
|
+
I have a photo at /Users/ehenry/Documents/vacation.jpg
|
|
1118
|
+
that I want to share publicly. What metadata does it contain?
|
|
1119
|
+
```
|
|
1120
|
+
|
|
1121
|
+
Claude would:
|
|
1122
|
+
1. Run `exif_metadata` to extract all metadata
|
|
1123
|
+
2. Report GPS coordinates, camera info, timestamps
|
|
1124
|
+
3. Recommend removing sensitive fields before sharing
|
|
1125
|
+
|
|
1126
|
+
---
|
|
1127
|
+
|
|
1128
|
+
### Compare Two Files
|
|
1129
|
+
|
|
1130
|
+
```
|
|
1131
|
+
Are these two binaries the same?
|
|
1132
|
+
File A: /tmp/program_v1.exe
|
|
1133
|
+
File B: /tmp/program_v2.exe
|
|
1134
|
+
```
|
|
1135
|
+
|
|
1136
|
+
Claude would:
|
|
1137
|
+
1. Run `file_hash` on both files
|
|
1138
|
+
2. Compare the SHA256 hashes
|
|
1139
|
+
3. If different, run `file_entropy` and `pe_header` on both
|
|
1140
|
+
4. Report differences in compilation time, sections, imports
|
|
1141
|
+
|
|
1142
|
+
---
|
|
1143
|
+
|
|
1144
|
+
### Detect Packing
|
|
1145
|
+
|
|
1146
|
+
```
|
|
1147
|
+
This binary seems obfuscated. How can I tell if it's packed?
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
Claude would:
|
|
1151
|
+
1. Run `file_entropy` to check overall entropy
|
|
1152
|
+
2. Run `pe_header` to analyze section entropy
|
|
1153
|
+
3. Check for high-entropy sections (.text, .reloc)
|
|
1154
|
+
4. Check for RWX (read-write-execute) sections
|
|
1155
|
+
5. Report packing indicators with confidence
|
|
1156
|
+
|
|
1157
|
+
---
|
|
1158
|
+
|
|
1159
|
+
### Find Duplicate Files
|
|
1160
|
+
|
|
1161
|
+
```
|
|
1162
|
+
Find all duplicate files in my Downloads directory
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
Claude would:
|
|
1166
|
+
1. Run `hash_directory` on `/Users/ehenry/Downloads`
|
|
1167
|
+
2. Report files with matching hashes
|
|
1168
|
+
3. Identify duplicate copies and suggest deletion candidates
|
|
1169
|
+
|
|
1170
|
+
---
|
|
1171
|
+
|
|
1172
|
+
### Timeline Analysis During Incident Response
|
|
1173
|
+
|
|
1174
|
+
```
|
|
1175
|
+
Correlate files in /var/suspect_files with system logs to build a timeline
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
Claude would:
|
|
1179
|
+
1. Run `file_correlate` with the suspect directory and system log file
|
|
1180
|
+
2. Show which log entries correspond to file modifications
|
|
1181
|
+
3. Help establish sequence of events during the incident
|
|
1182
|
+
|
|
1183
|
+
---
|
|
1184
|
+
|
|
1185
|
+
### Generate Forensic Investigation Report
|
|
1186
|
+
|
|
1187
|
+
```
|
|
1188
|
+
Create a comprehensive report for incident INC-2024-0215 with these findings:
|
|
1189
|
+
- Detected ransomware executable
|
|
1190
|
+
- Found C2 communications
|
|
1191
|
+
- Affected systems: WORKSTATION-01, FILESERVER-02
|
|
1192
|
+
```
|
|
1193
|
+
|
|
1194
|
+
Claude would:
|
|
1195
|
+
1. Run `forensic_report` to aggregate findings
|
|
1196
|
+
2. Generate professional report with timeline and IOCs
|
|
1197
|
+
3. Include severity levels and recommendations
|
|
1198
|
+
|
|
1199
|
+
---
|
|
1200
|
+
|
|
1201
|
+
## Architecture
|
|
1202
|
+
|
|
1203
|
+
### Design Philosophy
|
|
1204
|
+
|
|
1205
|
+
- **Stateless:** Each analysis is independent
|
|
1206
|
+
- **Sandboxed:** File path validation prevents access to protected areas
|
|
1207
|
+
- **Non-invasive:** No file modification or execution
|
|
1208
|
+
- **Transparent:** All results include file paths and metadata
|
|
1209
|
+
- **Performance:** Streaming analysis for large files where possible
|
|
1210
|
+
|
|
1211
|
+
### Tool Organization
|
|
1212
|
+
|
|
1213
|
+
Each tool in `src/tools/` exports:
|
|
1214
|
+
1. **Schema:** Zod validation for inputs (exported as `{toolName}Schema`)
|
|
1215
|
+
2. **Function:** Async handler that performs analysis (exported as `{toolName}`)
|
|
1216
|
+
3. **Result types:** Defined in `src/types.ts`
|
|
1217
|
+
|
|
1218
|
+
### MCP Server Structure
|
|
1219
|
+
|
|
1220
|
+
```typescript
|
|
1221
|
+
// src/index.ts
|
|
1222
|
+
const server = new McpServer({
|
|
1223
|
+
name: "forensic-analysis",
|
|
1224
|
+
version: "1.0.0",
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1227
|
+
// Each tool registered with schema and handler
|
|
1228
|
+
server.tool("file_hash", "Calculate hashes", fileHashSchema.shape, toolHandler(fileHash));
|
|
1229
|
+
server.tool("file_strings", "Extract strings", fileStringsSchema.shape, toolHandler(fileStrings));
|
|
1230
|
+
// ... etc
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
The `toolHandler` wrapper:
|
|
1234
|
+
- Catches errors and returns them as MCP error responses
|
|
1235
|
+
- Serializes results to JSON
|
|
1236
|
+
- Maintains consistent response format
|
|
1237
|
+
|
|
1238
|
+
---
|
|
1239
|
+
|
|
1240
|
+
## Troubleshooting
|
|
1241
|
+
|
|
1242
|
+
### "Command not found: strings"
|
|
1243
|
+
Ensure the `strings` utility is installed:
|
|
1244
|
+
```bash
|
|
1245
|
+
# macOS
|
|
1246
|
+
which strings # Should be /usr/bin/strings
|
|
1247
|
+
|
|
1248
|
+
# Linux
|
|
1249
|
+
sudo apt-get install binutils # or yum install binutils
|
|
1250
|
+
|
|
1251
|
+
# BSD
|
|
1252
|
+
pkg install binutils
|
|
1253
|
+
```
|
|
1254
|
+
|
|
1255
|
+
### "Command not found: readelf"
|
|
1256
|
+
Install binutils:
|
|
1257
|
+
```bash
|
|
1258
|
+
# macOS
|
|
1259
|
+
brew install binutils
|
|
1260
|
+
|
|
1261
|
+
# Linux
|
|
1262
|
+
sudo apt-get install binutils # or yum install binutils
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
### "exiftool not found"
|
|
1266
|
+
Install exiftool:
|
|
1267
|
+
```bash
|
|
1268
|
+
# macOS
|
|
1269
|
+
brew install exiftool
|
|
1270
|
+
|
|
1271
|
+
# Linux
|
|
1272
|
+
sudo apt-get install libimage-exiftool-perl
|
|
1273
|
+
# or
|
|
1274
|
+
sudo yum install perl-Image-ExifTool
|
|
1275
|
+
|
|
1276
|
+
# From source
|
|
1277
|
+
visit https://exiftool.org/
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
### "File too large"
|
|
1281
|
+
The 100 MB limit exists to prevent memory issues. For larger files:
|
|
1282
|
+
- Analyze portions separately using other tools
|
|
1283
|
+
- Use external forensics tools (Volatility, Ghidra, IDA)
|
|
1284
|
+
- Consider file compression/splitting
|
|
1285
|
+
|
|
1286
|
+
### "Command timed out"
|
|
1287
|
+
External commands have a 30-second timeout. For slow operations:
|
|
1288
|
+
- Try a smaller file
|
|
1289
|
+
- Verify the file isn't corrupted
|
|
1290
|
+
- Check system load
|
|
1291
|
+
|
|
1292
|
+
### "Invalid PE file (missing MZ signature)"
|
|
1293
|
+
The file is not a Windows executable:
|
|
1294
|
+
- Use `file_identify` to confirm actual type
|
|
1295
|
+
- PE header parsing only works on PE files
|
|
1296
|
+
- Try `elf_header` for Linux binaries
|
|
1297
|
+
|
|
1298
|
+
---
|
|
1299
|
+
|
|
1300
|
+
## Performance Notes
|
|
1301
|
+
|
|
1302
|
+
### Analysis Speed
|
|
1303
|
+
|
|
1304
|
+
Tool performance depends on file size and complexity:
|
|
1305
|
+
|
|
1306
|
+
- **file_hash:** ~10-50 MB/sec (limited by disk I/O)
|
|
1307
|
+
- **file_identify:** ~1-5 MB/sec (reads magic bytes only)
|
|
1308
|
+
- **file_entropy:** ~50-100 MB/sec (reads entire file)
|
|
1309
|
+
- **file_strings:** ~5-20 MB/sec (pattern matching overhead)
|
|
1310
|
+
- **pe_header:** ~10-50 MB/sec (inline parsing, no external tools)
|
|
1311
|
+
- **elf_header:** ~5-10 MB/sec (depends on readelf performance)
|
|
1312
|
+
- **exif_metadata:** ~1-5 MB/sec (depends on file type and exiftool)
|
|
1313
|
+
- **hash_directory:** ~5-30 MB/sec aggregate (depends on file count and sizes)
|
|
1314
|
+
- **file_correlate:** ~1-10 MB/sec (depends on log file size)
|
|
1315
|
+
- **forensic_report:** Instant (data aggregation only)
|
|
1316
|
+
|
|
1317
|
+
### Memory Usage
|
|
1318
|
+
|
|
1319
|
+
- Small files (< 10 MB): < 50 MB RAM
|
|
1320
|
+
- Medium files (10-50 MB): 100-300 MB RAM
|
|
1321
|
+
- Large files (50-100 MB): 300-600 MB RAM
|
|
1322
|
+
- Directory operations: Depends on file count (typically under 500 MB for 1000 files)
|
|
1323
|
+
|
|
1324
|
+
---
|
|
1325
|
+
|
|
1326
|
+
## License
|
|
1327
|
+
|
|
1328
|
+
MIT License
|
|
1329
|
+
|
|
1330
|
+
Copyright (c) 2024
|
|
1331
|
+
|
|
1332
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
1333
|
+
|
|
1334
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
1335
|
+
|
|
1336
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|