mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-16 07:53:18 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Agentless Vulnerability Scanning Orchestrator
|
||||
|
||||
Performs SSH-based agentless vulnerability scanning on Linux hosts
|
||||
by enumerating packages and checking against known vulnerabilities.
|
||||
|
||||
Requirements:
|
||||
pip install paramiko requests pandas
|
||||
|
||||
Usage:
|
||||
python process.py scan --hosts hosts.txt --key /path/to/ssh_key
|
||||
python process.py check --host 192.168.1.10 --user scanner --key /path/to/ssh_key
|
||||
python process.py report --input scan_results.json --output report.csv
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
import pandas as pd
|
||||
import paramiko
|
||||
import requests
|
||||
|
||||
|
||||
NVD_API = "https://services.nvd.nist.gov/rest/json/cves/2.0"
|
||||
|
||||
|
||||
class AgentlessScanner:
|
||||
"""SSH-based agentless vulnerability scanner."""
|
||||
|
||||
def __init__(self, key_path, username="scanner"):
|
||||
self.key_path = key_path
|
||||
self.username = username
|
||||
|
||||
def _connect(self, hostname, port=22):
|
||||
"""Establish SSH connection."""
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
key = paramiko.Ed25519Key.from_private_key_file(self.key_path)
|
||||
except paramiko.ssh_exception.SSHException:
|
||||
key = paramiko.RSAKey.from_private_key_file(self.key_path)
|
||||
client.connect(hostname, port=port, username=self.username,
|
||||
pkey=key, timeout=30)
|
||||
return client
|
||||
|
||||
def _exec(self, client, command, timeout=30):
|
||||
"""Execute command and return output."""
|
||||
_, stdout, stderr = client.exec_command(command, timeout=timeout)
|
||||
return stdout.read().decode().strip(), stderr.read().decode().strip()
|
||||
|
||||
def get_os_info(self, client):
|
||||
"""Detect OS distribution and version."""
|
||||
out, _ = self._exec(client, "cat /etc/os-release")
|
||||
info = {}
|
||||
for line in out.split("\n"):
|
||||
if "=" in line:
|
||||
k, v = line.split("=", 1)
|
||||
info[k] = v.strip('"')
|
||||
return info
|
||||
|
||||
def get_packages_dpkg(self, client):
|
||||
"""Get packages via dpkg (Debian/Ubuntu)."""
|
||||
out, _ = self._exec(
|
||||
client,
|
||||
"dpkg-query -W -f='${Package}|${Version}|${Architecture}\\n'"
|
||||
)
|
||||
packages = []
|
||||
for line in out.split("\n"):
|
||||
parts = line.split("|")
|
||||
if len(parts) >= 2:
|
||||
packages.append({
|
||||
"name": parts[0],
|
||||
"version": parts[1],
|
||||
"arch": parts[2] if len(parts) > 2 else "",
|
||||
})
|
||||
return packages
|
||||
|
||||
def get_packages_rpm(self, client):
|
||||
"""Get packages via rpm (RHEL/CentOS/Fedora)."""
|
||||
out, _ = self._exec(
|
||||
client,
|
||||
"rpm -qa --queryformat '%{NAME}|%{VERSION}-%{RELEASE}|%{ARCH}\\n'"
|
||||
)
|
||||
packages = []
|
||||
for line in out.split("\n"):
|
||||
parts = line.split("|")
|
||||
if len(parts) >= 2:
|
||||
packages.append({
|
||||
"name": parts[0],
|
||||
"version": parts[1],
|
||||
"arch": parts[2] if len(parts) > 2 else "",
|
||||
})
|
||||
return packages
|
||||
|
||||
def get_kernel(self, client):
|
||||
"""Get running kernel version."""
|
||||
out, _ = self._exec(client, "uname -r")
|
||||
return out
|
||||
|
||||
def get_listening_services(self, client):
|
||||
"""Get listening network services."""
|
||||
out, _ = self._exec(client, "ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null")
|
||||
return out
|
||||
|
||||
def scan_host(self, hostname, port=22):
|
||||
"""Perform full agentless scan."""
|
||||
result = {
|
||||
"hostname": hostname,
|
||||
"scan_time": datetime.utcnow().isoformat(),
|
||||
"status": "success",
|
||||
"os_info": {},
|
||||
"kernel": "",
|
||||
"packages": [],
|
||||
"listening_services": "",
|
||||
}
|
||||
|
||||
try:
|
||||
client = self._connect(hostname, port)
|
||||
result["os_info"] = self.get_os_info(client)
|
||||
result["kernel"] = self.get_kernel(client)
|
||||
|
||||
os_id = result["os_info"].get("ID", "").lower()
|
||||
if os_id in ("ubuntu", "debian", "kali"):
|
||||
result["packages"] = self.get_packages_dpkg(client)
|
||||
else:
|
||||
result["packages"] = self.get_packages_rpm(client)
|
||||
|
||||
result["listening_services"] = self.get_listening_services(client)
|
||||
client.close()
|
||||
|
||||
print(f" [+] {hostname}: {result['os_info'].get('PRETTY_NAME', 'Unknown')} | "
|
||||
f"{len(result['packages'])} packages | kernel {result['kernel']}")
|
||||
|
||||
except Exception as e:
|
||||
result["status"] = "error"
|
||||
result["error"] = str(e)
|
||||
print(f" [!] {hostname}: {e}")
|
||||
|
||||
return result
|
||||
|
||||
def scan_hosts(self, hosts, port=22):
|
||||
"""Scan multiple hosts."""
|
||||
results = []
|
||||
for host in hosts:
|
||||
host = host.strip()
|
||||
if not host or host.startswith("#"):
|
||||
continue
|
||||
print(f"[*] Scanning {host}...")
|
||||
results.append(self.scan_host(host, port))
|
||||
return results
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Agentless Vulnerability Scanning Orchestrator"
|
||||
)
|
||||
subparsers = parser.add_subparsers(dest="command")
|
||||
|
||||
scan_p = subparsers.add_parser("scan", help="Scan hosts from file")
|
||||
scan_p.add_argument("--hosts", required=True, help="File with hostnames/IPs")
|
||||
scan_p.add_argument("--key", required=True, help="SSH private key path")
|
||||
scan_p.add_argument("--user", default="scanner", help="SSH username")
|
||||
scan_p.add_argument("--port", type=int, default=22, help="SSH port")
|
||||
scan_p.add_argument("--output", default="scan_results.json")
|
||||
|
||||
check_p = subparsers.add_parser("check", help="Scan a single host")
|
||||
check_p.add_argument("--host", required=True)
|
||||
check_p.add_argument("--key", required=True)
|
||||
check_p.add_argument("--user", default="scanner")
|
||||
check_p.add_argument("--port", type=int, default=22)
|
||||
|
||||
report_p = subparsers.add_parser("report", help="Generate CSV report")
|
||||
report_p.add_argument("--input", required=True, help="Scan results JSON")
|
||||
report_p.add_argument("--output", default="scan_report.csv")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "scan":
|
||||
scanner = AgentlessScanner(args.key, args.user)
|
||||
with open(args.hosts) as f:
|
||||
hosts = f.readlines()
|
||||
results = scanner.scan_hosts(hosts, args.port)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(results, f, indent=2)
|
||||
print(f"\n[+] Results saved to {args.output}")
|
||||
successful = sum(1 for r in results if r["status"] == "success")
|
||||
print(f" Scanned: {len(results)} | Success: {successful}")
|
||||
|
||||
elif args.command == "check":
|
||||
scanner = AgentlessScanner(args.key, args.user)
|
||||
result = scanner.scan_host(args.host, args.port)
|
||||
print(json.dumps(result, indent=2, default=str))
|
||||
|
||||
elif args.command == "report":
|
||||
with open(args.input) as f:
|
||||
results = json.load(f)
|
||||
rows = []
|
||||
for r in results:
|
||||
for pkg in r.get("packages", []):
|
||||
rows.append({
|
||||
"hostname": r["hostname"],
|
||||
"os": r.get("os_info", {}).get("PRETTY_NAME", ""),
|
||||
"kernel": r.get("kernel", ""),
|
||||
"package": pkg["name"],
|
||||
"version": pkg["version"],
|
||||
})
|
||||
df = pd.DataFrame(rows)
|
||||
df.to_csv(args.output, index=False)
|
||||
print(f"[+] Report with {len(rows)} package entries saved to {args.output}")
|
||||
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user