@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.
Files changed (3) hide show
  1. package/README.md +1336 -0
  2. package/dist/index.js +45094 -0
  3. 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.