Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills

Complete skill folder anatomy across all cybersecurity skills:
- scripts/agent.py: 80-150 line Python agents using real libraries (impacket,
  boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.)
- references/api-reference.md: real API documentation with method signatures
- LICENSE: MIT license for all skill folders
This commit is contained in:
mukul975
2026-03-10 21:02:12 +01:00
parent c74d52fa30
commit 27c6414ca5
1390 changed files with 106806 additions and 0 deletions
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Anthropic Agent Skills Contributors
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,62 @@
# API Reference: Performing Disk Forensics Investigation
## pytsk3 Library (The Sleuth Kit Python Bindings)
| Class/Method | Description |
|--------------|-------------|
| `pytsk3.Img_Info(path)` | Open disk image (raw, E01, AFF) |
| `pytsk3.FS_Info(img_info)` | Parse file system from image |
| `fs.open_dir(path)` | Open directory for listing |
| `fs.open_file(path)` | Open file for reading content |
| `entry.info.meta` | Access file metadata (timestamps, size, flags) |
| `TSK_FS_META_FLAG_UNALLOC` | Flag indicating deleted/unallocated file |
## File Metadata Fields
| Field | Description |
|-------|-------------|
| `meta.crtime` | File creation time (NTFS) |
| `meta.mtime` | Last modification time |
| `meta.atime` | Last access time |
| `meta.ctime` | Metadata change time |
| `meta.size` | File size in bytes |
| `meta.addr` | Inode/MFT entry number |
| `meta.flags` | Allocation flags |
## NTFS MFT Structure
| Offset | Size | Description |
|--------|------|-------------|
| 0x00 | 4 bytes | Signature ("FILE") |
| 0x16 | 2 bytes | Flags (in-use, directory) |
| 0x1C | 4 bytes | Real size of MFT entry |
## Key Libraries
- **pytsk3** (`pip install pytsk3`): Python bindings for The Sleuth Kit
- **dfvfs** (`pip install dfvfs`): Digital Forensics Virtual File System
- **hashlib** (stdlib): Image integrity verification (MD5, SHA-256)
- **struct** (stdlib): Parse binary MFT entry headers
## CLI Tools (Reference)
| Tool | Description |
|------|-------------|
| `fls -r image.dd` | Recursively list files (TSK) |
| `icat image.dd inode` | Extract file by inode number |
| `mmls image.dd` | List disk partitions |
| `fsstat image.dd` | File system statistics |
## Configuration
| Variable | Description |
|----------|-------------|
| Image path | Path to forensic disk image (dd, E01, AFF) |
| MFT export | Exported $MFT file for NTFS-specific analysis |
## References
- [The Sleuth Kit](https://www.sleuthkit.org/)
- [pytsk3 Documentation](https://github.com/py4n6/pytsk)
- [Autopsy Digital Forensics](https://www.autopsy.com/)
- [SANS Forensics Poster](https://www.sans.org/posters/windows-forensic-analysis/)
@@ -0,0 +1,272 @@
#!/usr/bin/env python3
"""
Disk Forensics Investigation Agent
Performs disk forensics analysis including image verification, file system
parsing, deleted file recovery, and timeline generation using pytsk3 and
hashlib for evidence integrity.
"""
import csv
import hashlib
import json
import os
import struct
import sys
from datetime import datetime, timezone
from pathlib import Path
try:
import pytsk3
HAS_PYTSK3 = True
except ImportError:
HAS_PYTSK3 = False
def verify_image_integrity(image_path: str) -> dict:
"""Calculate and verify hash of forensic disk image."""
if not os.path.exists(image_path):
return {"error": f"Image not found: {image_path}"}
md5 = hashlib.md5()
sha256 = hashlib.sha256()
size = 0
with open(image_path, "rb") as f:
while True:
chunk = f.read(65536)
if not chunk:
break
md5.update(chunk)
sha256.update(chunk)
size += len(chunk)
return {
"image_path": image_path,
"size_bytes": size,
"size_gb": round(size / (1024**3), 2),
"md5": md5.hexdigest(),
"sha256": sha256.hexdigest(),
"verified_at": datetime.now(timezone.utc).isoformat(),
}
def parse_filesystem_pytsk3(image_path: str) -> dict:
"""Parse file system from disk image using pytsk3."""
if not HAS_PYTSK3:
return {"error": "pytsk3 not installed. Install with: pip install pytsk3"}
try:
img = pytsk3.Img_Info(image_path)
fs = pytsk3.FS_Info(img)
except Exception as e:
return {"error": f"Failed to open image: {e}"}
fs_info = {
"fs_type": str(fs.info.ftype),
"block_size": fs.info.block_size,
"block_count": fs.info.block_count,
"total_size_gb": round(fs.info.block_size * fs.info.block_count / (1024**3), 2),
}
return fs_info
def list_files_pytsk3(image_path: str, directory: str = "/") -> list[dict]:
"""List files in a directory within the disk image."""
if not HAS_PYTSK3:
return [{"error": "pytsk3 not installed"}]
try:
img = pytsk3.Img_Info(image_path)
fs = pytsk3.FS_Info(img)
dir_obj = fs.open_dir(directory)
except Exception as e:
return [{"error": str(e)}]
files = []
for entry in dir_obj:
name = entry.info.name.name.decode("utf-8", errors="ignore")
if name in (".", ".."):
continue
meta = entry.info.meta
if meta:
files.append({
"name": name,
"type": "directory" if meta.type == pytsk3.TSK_FS_META_TYPE_DIR else "file",
"size": meta.size,
"created": datetime.fromtimestamp(meta.crtime, tz=timezone.utc).isoformat() if meta.crtime else "",
"modified": datetime.fromtimestamp(meta.mtime, tz=timezone.utc).isoformat() if meta.mtime else "",
"accessed": datetime.fromtimestamp(meta.atime, tz=timezone.utc).isoformat() if meta.atime else "",
"inode": meta.addr,
"flags": str(meta.flags),
})
return files
def find_deleted_files(image_path: str) -> list[dict]:
"""Search for deleted files in the disk image."""
if not HAS_PYTSK3:
return [{"error": "pytsk3 not installed"}]
try:
img = pytsk3.Img_Info(image_path)
fs = pytsk3.FS_Info(img)
except Exception as e:
return [{"error": str(e)}]
deleted = []
def walk_directory(dir_obj, path="/"):
for entry in dir_obj:
name = entry.info.name.name.decode("utf-8", errors="ignore")
if name in (".", ".."):
continue
meta = entry.info.meta
if meta and meta.flags & pytsk3.TSK_FS_META_FLAG_UNALLOC:
deleted.append({
"name": name,
"path": f"{path}{name}",
"size": meta.size,
"deleted_approx": datetime.fromtimestamp(
meta.mtime, tz=timezone.utc
).isoformat() if meta.mtime else "",
"inode": meta.addr,
"recoverable": meta.size > 0,
})
if meta and meta.type == pytsk3.TSK_FS_META_TYPE_DIR:
try:
sub_dir = fs.open_dir(inode=meta.addr)
walk_directory(sub_dir, f"{path}{name}/")
except Exception:
pass
try:
root = fs.open_dir("/")
walk_directory(root)
except Exception as e:
deleted.append({"error": str(e)})
return deleted
def parse_mft_entries(mft_path: str) -> list[dict]:
"""Parse MFT entries from an exported $MFT file for NTFS analysis."""
entries = []
if not os.path.exists(mft_path):
return [{"error": f"MFT file not found: {mft_path}"}]
with open(mft_path, "rb") as f:
entry_size = 1024
entry_num = 0
while True:
data = f.read(entry_size)
if len(data) < entry_size:
break
if data[:4] == b"FILE":
flags = struct.unpack_from("<H", data, 22)[0]
is_deleted = not (flags & 0x01)
is_directory = bool(flags & 0x02)
entries.append({
"entry_number": entry_num,
"is_deleted": is_deleted,
"is_directory": is_directory,
"flags": flags,
})
entry_num += 1
if entry_num >= 10000:
break
total = len(entries)
deleted = sum(1 for e in entries if e["is_deleted"])
return entries[:100] if len(entries) > 100 else entries
def build_timeline(files: list[dict]) -> list[dict]:
"""Build a timeline of file system activity from file metadata."""
events = []
for f in files:
if isinstance(f, dict) and "error" not in f:
if f.get("created"):
events.append({"timestamp": f["created"], "event": "created", "path": f.get("name", "")})
if f.get("modified"):
events.append({"timestamp": f["modified"], "event": "modified", "path": f.get("name", "")})
if f.get("accessed"):
events.append({"timestamp": f["accessed"], "event": "accessed", "path": f.get("name", "")})
events.sort(key=lambda x: x.get("timestamp", ""))
return events
def generate_report(
integrity: dict, fs_info: dict, files: list, deleted: list, timeline: list
) -> str:
"""Generate disk forensics investigation report."""
lines = [
"DISK FORENSICS INVESTIGATION REPORT",
"=" * 50,
f"Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
"",
"IMAGE INTEGRITY:",
f" Image: {integrity.get('image_path', 'N/A')}",
f" Size: {integrity.get('size_gb', 'N/A')} GB",
f" MD5: {integrity.get('md5', 'N/A')}",
f" SHA-256: {integrity.get('sha256', 'N/A')}",
"",
"FILE SYSTEM:",
f" Type: {fs_info.get('fs_type', 'N/A')}",
f" Total Size: {fs_info.get('total_size_gb', 'N/A')} GB",
"",
f"FILES FOUND: {len(files)}",
f"DELETED FILES: {len([d for d in deleted if d.get('recoverable')])} recoverable",
f"TIMELINE EVENTS: {len(timeline)}",
]
if deleted:
lines.extend(["", "DELETED FILES (SAMPLE):"])
for d in deleted[:10]:
if "error" not in d:
lines.append(f" {d.get('path', 'N/A')} ({d.get('size', 0)} bytes)")
return "\n".join(lines)
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <disk_image_path> [mft_path]")
sys.exit(1)
image_path = sys.argv[1]
mft_path = sys.argv[2] if len(sys.argv) > 2 else None
print(f"[*] Verifying image integrity: {image_path}")
integrity = verify_image_integrity(image_path)
print(f"[*] SHA-256: {integrity.get('sha256', 'error')}")
print("[*] Parsing file system...")
fs_info = parse_filesystem_pytsk3(image_path)
print("[*] Listing files...")
files = list_files_pytsk3(image_path)
print("[*] Searching for deleted files...")
deleted = find_deleted_files(image_path)
timeline = build_timeline(files)
report = generate_report(integrity, fs_info, files, deleted, timeline)
print(report)
output = f"disk_forensics_{datetime.now(timezone.utc).strftime('%Y%m%d')}.json"
with open(output, "w") as f:
json.dump({"integrity": integrity, "fs_info": fs_info, "deleted_files": deleted,
"timeline": timeline[:100]}, f, indent=2)
print(f"\n[*] Results saved to {output}")