mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-17 13:15:16 +03:00
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:
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for Linux memory forensics using LiME acquisition and Volatility 3."""
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def acquire_memory_lime(output_path, lime_format="lime"):
|
||||
"""Acquire memory using LiME kernel module."""
|
||||
kernel_version = subprocess.run(
|
||||
["uname", "-r"], capture_output=True, text=True
|
||||
).stdout.strip()
|
||||
lime_module = f"lime-{kernel_version}.ko"
|
||||
if not Path(lime_module).exists():
|
||||
lime_module = "lime.ko"
|
||||
cmd = ["insmod", lime_module, f"path={output_path}", f"format={lime_format}"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
return {
|
||||
"status": "success" if result.returncode == 0 else "failed",
|
||||
"output_path": output_path,
|
||||
"format": lime_format,
|
||||
"kernel": kernel_version,
|
||||
"stderr": result.stderr,
|
||||
}
|
||||
|
||||
|
||||
def run_vol3_plugin(image_path, plugin_name, extra_args=None):
|
||||
"""Run a Volatility 3 plugin and capture output."""
|
||||
cmd = ["vol3", "-f", image_path, plugin_name]
|
||||
if extra_args:
|
||||
cmd.extend(extra_args)
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd, capture_output=True, text=True, timeout=300,
|
||||
)
|
||||
lines = result.stdout.strip().splitlines()
|
||||
return {"plugin": plugin_name, "output": lines, "error": result.stderr.strip()}
|
||||
except subprocess.TimeoutExpired:
|
||||
return {"plugin": plugin_name, "output": [], "error": "Timeout"}
|
||||
|
||||
|
||||
def parse_pslist_output(lines):
|
||||
"""Parse Volatility linux.pslist output into structured data."""
|
||||
processes = []
|
||||
for line in lines:
|
||||
parts = line.split()
|
||||
if len(parts) >= 4 and parts[0].isdigit():
|
||||
processes.append({
|
||||
"pid": int(parts[0]),
|
||||
"ppid": int(parts[1]) if parts[1].isdigit() else 0,
|
||||
"name": parts[-1],
|
||||
})
|
||||
return processes
|
||||
|
||||
|
||||
def list_processes(image_path):
|
||||
"""List all processes from memory image."""
|
||||
result = run_vol3_plugin(image_path, "linux.pslist")
|
||||
return parse_pslist_output(result.get("output", []))
|
||||
|
||||
|
||||
def extract_bash_history(image_path):
|
||||
"""Extract bash command history from memory."""
|
||||
result = run_vol3_plugin(image_path, "linux.bash")
|
||||
commands = []
|
||||
for line in result.get("output", []):
|
||||
parts = line.split(None, 3)
|
||||
if len(parts) >= 4 and parts[0].isdigit():
|
||||
commands.append({
|
||||
"pid": int(parts[0]),
|
||||
"name": parts[1],
|
||||
"timestamp": parts[2] if len(parts) > 2 else "",
|
||||
"command": parts[3] if len(parts) > 3 else "",
|
||||
})
|
||||
return commands
|
||||
|
||||
|
||||
def list_network_connections(image_path):
|
||||
"""List network connections from memory."""
|
||||
result = run_vol3_plugin(image_path, "linux.sockstat")
|
||||
connections = []
|
||||
for line in result.get("output", []):
|
||||
if "TCP" in line or "UDP" in line:
|
||||
connections.append(line.strip())
|
||||
return connections
|
||||
|
||||
|
||||
def list_kernel_modules(image_path):
|
||||
"""List loaded kernel modules to detect rootkits."""
|
||||
result = run_vol3_plugin(image_path, "linux.lsmod")
|
||||
modules = []
|
||||
for line in result.get("output", []):
|
||||
parts = line.split()
|
||||
if parts and not parts[0].startswith("Offset"):
|
||||
modules.append({"name": parts[-1] if parts else line.strip()})
|
||||
return modules
|
||||
|
||||
|
||||
def detect_hidden_processes(image_path):
|
||||
"""Compare pslist vs psscan to find hidden processes."""
|
||||
pslist = run_vol3_plugin(image_path, "linux.pslist")
|
||||
psscan = run_vol3_plugin(image_path, "linux.psscan")
|
||||
pslist_pids = set()
|
||||
for line in pslist.get("output", []):
|
||||
parts = line.split()
|
||||
if parts and parts[0].isdigit():
|
||||
pslist_pids.add(int(parts[0]))
|
||||
hidden = []
|
||||
for line in psscan.get("output", []):
|
||||
parts = line.split()
|
||||
if parts and parts[0].isdigit():
|
||||
pid = int(parts[0])
|
||||
if pid not in pslist_pids and pid > 0:
|
||||
hidden.append({"pid": pid, "line": line.strip()})
|
||||
return hidden
|
||||
|
||||
|
||||
def detect_suspicious_commands(bash_history):
|
||||
"""Flag suspicious commands in bash history."""
|
||||
suspicious_patterns = [
|
||||
"curl.*|.*sh", "wget.*&&.*chmod", "base64.*-d",
|
||||
"nc.*-e", "python.*-c.*import.*socket",
|
||||
"nohup", "rm.*-rf.*/var/log", "history.*-c",
|
||||
"iptables.*-F", "chmod.*777", "chattr.*-i",
|
||||
]
|
||||
import re
|
||||
findings = []
|
||||
for entry in bash_history:
|
||||
cmd = entry.get("command", "")
|
||||
for pattern in suspicious_patterns:
|
||||
if re.search(pattern, cmd, re.IGNORECASE):
|
||||
findings.append({
|
||||
"pid": entry["pid"],
|
||||
"command": cmd,
|
||||
"pattern": pattern,
|
||||
"severity": "HIGH",
|
||||
})
|
||||
break
|
||||
return findings
|
||||
|
||||
|
||||
def check_malfind(image_path):
|
||||
"""Run malfind to detect injected code."""
|
||||
result = run_vol3_plugin(image_path, "linux.malfind")
|
||||
return result.get("output", [])
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiME + Volatility 3 Forensics Agent")
|
||||
parser.add_argument("--image", help="Path to memory image")
|
||||
parser.add_argument("--acquire", help="Output path for LiME acquisition")
|
||||
parser.add_argument("--output", default="memory_forensics_report.json")
|
||||
parser.add_argument("--action", choices=[
|
||||
"acquire", "pslist", "bash", "network", "modules",
|
||||
"hidden", "malfind", "full_analysis"
|
||||
], default="full_analysis")
|
||||
args = parser.parse_args()
|
||||
|
||||
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
|
||||
|
||||
if args.action == "acquire" and args.acquire:
|
||||
result = acquire_memory_lime(args.acquire)
|
||||
report["findings"]["acquisition"] = result
|
||||
print(f"[+] Memory acquisition: {result['status']}")
|
||||
return
|
||||
|
||||
if not args.image:
|
||||
print("[-] --image required for analysis actions")
|
||||
return
|
||||
|
||||
if args.action in ("pslist", "full_analysis"):
|
||||
procs = list_processes(args.image)
|
||||
report["findings"]["processes"] = procs
|
||||
print(f"[+] Processes: {len(procs)}")
|
||||
|
||||
if args.action in ("bash", "full_analysis"):
|
||||
history = extract_bash_history(args.image)
|
||||
report["findings"]["bash_history"] = history
|
||||
suspicious = detect_suspicious_commands(history)
|
||||
report["findings"]["suspicious_commands"] = suspicious
|
||||
print(f"[+] Bash commands: {len(history)}, Suspicious: {len(suspicious)}")
|
||||
|
||||
if args.action in ("network", "full_analysis"):
|
||||
conns = list_network_connections(args.image)
|
||||
report["findings"]["connections"] = conns
|
||||
print(f"[+] Network connections: {len(conns)}")
|
||||
|
||||
if args.action in ("modules", "full_analysis"):
|
||||
modules = list_kernel_modules(args.image)
|
||||
report["findings"]["kernel_modules"] = modules
|
||||
print(f"[+] Kernel modules: {len(modules)}")
|
||||
|
||||
if args.action in ("hidden", "full_analysis"):
|
||||
hidden = detect_hidden_processes(args.image)
|
||||
report["findings"]["hidden_processes"] = hidden
|
||||
print(f"[+] Hidden processes: {len(hidden)}")
|
||||
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
print(f"[+] Report saved to {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user