mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-16 04:35:18 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Rapid7 InsightVM Scan Automation and Reporting Tool
|
||||
|
||||
Automates scan operations, asset queries, and vulnerability reporting
|
||||
via the InsightVM API v3.
|
||||
|
||||
Requirements:
|
||||
pip install requests pandas tabulate
|
||||
|
||||
Usage:
|
||||
python process.py sites # List all sites
|
||||
python process.py scan --site-id 1 # Start scan for site
|
||||
python process.py status --scan-id 12345 # Check scan status
|
||||
python process.py vulns --asset-id 42 # Get asset vulnerabilities
|
||||
python process.py report --site-id 1 --output report.csv # Export report
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
import urllib3
|
||||
from datetime import datetime
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
|
||||
class InsightVMAPI:
|
||||
"""Rapid7 InsightVM API v3 client."""
|
||||
|
||||
def __init__(self, console_url, username=None, password=None, api_key=None):
|
||||
self.base_url = f"{console_url.rstrip('/')}/api/3"
|
||||
self.session = requests.Session()
|
||||
self.session.verify = False
|
||||
|
||||
if api_key:
|
||||
self.session.headers.update({
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
})
|
||||
elif username and password:
|
||||
self.session.auth = (username, password)
|
||||
self.session.headers.update({"Content-Type": "application/json"})
|
||||
else:
|
||||
raise ValueError("Provide either api_key or username/password")
|
||||
|
||||
def _get_paginated(self, endpoint, params=None):
|
||||
"""Fetch all pages from a paginated endpoint."""
|
||||
all_resources = []
|
||||
page = 0
|
||||
while True:
|
||||
p = params.copy() if params else {}
|
||||
p["page"] = page
|
||||
p["size"] = 100
|
||||
response = self.session.get(
|
||||
f"{self.base_url}/{endpoint}", params=p, timeout=60
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
resources = data.get("resources", [])
|
||||
all_resources.extend(resources)
|
||||
total_pages = data.get("page", {}).get("totalPages", 1)
|
||||
page += 1
|
||||
if page >= total_pages:
|
||||
break
|
||||
return all_resources
|
||||
|
||||
def list_sites(self):
|
||||
"""List all scan sites."""
|
||||
return self._get_paginated("sites")
|
||||
|
||||
def get_site(self, site_id):
|
||||
"""Get details for a specific site."""
|
||||
response = self.session.get(
|
||||
f"{self.base_url}/sites/{site_id}", timeout=30
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def start_scan(self, site_id, engine_id=None, template_id=None, hosts=None):
|
||||
"""Start a scan for a site."""
|
||||
payload = {}
|
||||
if engine_id:
|
||||
payload["engineId"] = engine_id
|
||||
if template_id:
|
||||
payload["templateId"] = template_id
|
||||
if hosts:
|
||||
payload["hosts"] = hosts
|
||||
|
||||
response = self.session.post(
|
||||
f"{self.base_url}/sites/{site_id}/scans",
|
||||
json=payload, timeout=30
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def get_scan_status(self, scan_id):
|
||||
"""Get the status of a scan."""
|
||||
response = self.session.get(
|
||||
f"{self.base_url}/scans/{scan_id}", timeout=30
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def wait_for_scan(self, scan_id, poll_interval=30, timeout=3600):
|
||||
"""Wait for a scan to complete."""
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
status = self.get_scan_status(scan_id)
|
||||
state = status.get("status", "unknown")
|
||||
print(f" Scan {scan_id}: {state} "
|
||||
f"({status.get('assets', 0)} assets, "
|
||||
f"{status.get('vulnerabilities', {}).get('total', 0)} vulns)")
|
||||
if state in ("finished", "stopped", "error", "aborted"):
|
||||
return status
|
||||
time.sleep(poll_interval)
|
||||
print(f" [!] Scan timeout after {timeout}s")
|
||||
return None
|
||||
|
||||
def get_site_assets(self, site_id):
|
||||
"""Get all assets for a site."""
|
||||
return self._get_paginated(f"sites/{site_id}/assets")
|
||||
|
||||
def get_asset_vulnerabilities(self, asset_id):
|
||||
"""Get vulnerabilities for a specific asset."""
|
||||
return self._get_paginated(f"assets/{asset_id}/vulnerabilities")
|
||||
|
||||
def get_vulnerability_details(self, vuln_id):
|
||||
"""Get details for a specific vulnerability."""
|
||||
response = self.session.get(
|
||||
f"{self.base_url}/vulnerabilities/{vuln_id}", timeout=30
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def list_scan_engines(self):
|
||||
"""List all scan engines."""
|
||||
return self._get_paginated("scan_engines")
|
||||
|
||||
def list_scan_templates(self):
|
||||
"""List available scan templates."""
|
||||
return self._get_paginated("scan_templates")
|
||||
|
||||
|
||||
def cmd_list_sites(api):
|
||||
"""List all configured sites."""
|
||||
sites = api.list_sites()
|
||||
if not sites:
|
||||
print("No sites configured.")
|
||||
return
|
||||
|
||||
print(f"\n{'ID':<6} {'Name':<35} {'Assets':<10} {'Last Scan':<20}")
|
||||
print("-" * 75)
|
||||
for site in sites:
|
||||
last_scan = site.get("lastScanTime", "Never")
|
||||
if last_scan != "Never":
|
||||
last_scan = last_scan[:19]
|
||||
print(f"{site['id']:<6} {site['name'][:34]:<35} "
|
||||
f"{site.get('assets', 0):<10} {last_scan:<20}")
|
||||
|
||||
|
||||
def cmd_start_scan(api, site_id, engine_id=None, template_id=None, wait=False):
|
||||
"""Start a scan for a site."""
|
||||
print(f"[*] Starting scan for site {site_id}...")
|
||||
result = api.start_scan(site_id, engine_id, template_id)
|
||||
scan_id = result.get("id")
|
||||
print(f"[+] Scan started: ID={scan_id}")
|
||||
|
||||
if wait and scan_id:
|
||||
print("[*] Waiting for scan to complete...")
|
||||
final_status = api.wait_for_scan(scan_id)
|
||||
if final_status:
|
||||
print(f"\n[+] Scan completed: {final_status.get('status')}")
|
||||
vulns = final_status.get("vulnerabilities", {})
|
||||
print(f" Total vulnerabilities: {vulns.get('total', 0)}")
|
||||
print(f" Critical: {vulns.get('critical', 0)}")
|
||||
print(f" Severe: {vulns.get('severe', 0)}")
|
||||
print(f" Moderate: {vulns.get('moderate', 0)}")
|
||||
|
||||
|
||||
def cmd_scan_status(api, scan_id):
|
||||
"""Check scan status."""
|
||||
status = api.get_scan_status(scan_id)
|
||||
print(f"\nScan ID: {status.get('id')}")
|
||||
print(f"Status: {status.get('status')}")
|
||||
print(f"Start Time: {status.get('startTime', 'N/A')}")
|
||||
print(f"End Time: {status.get('endTime', 'N/A')}")
|
||||
print(f"Assets: {status.get('assets', 0)}")
|
||||
vulns = status.get("vulnerabilities", {})
|
||||
print(f"Vulns Total: {vulns.get('total', 0)}")
|
||||
print(f" Critical: {vulns.get('critical', 0)}")
|
||||
print(f" Severe: {vulns.get('severe', 0)}")
|
||||
print(f" Moderate: {vulns.get('moderate', 0)}")
|
||||
|
||||
|
||||
def cmd_asset_vulns(api, asset_id):
|
||||
"""List vulnerabilities for an asset."""
|
||||
vulns = api.get_asset_vulnerabilities(asset_id)
|
||||
if not vulns:
|
||||
print(f"No vulnerabilities found for asset {asset_id}.")
|
||||
return
|
||||
|
||||
print(f"\nVulnerabilities for asset {asset_id}: {len(vulns)} total\n")
|
||||
print(f"{'Vuln ID':<40} {'Severity':<10} {'CVSS':<8} {'Status':<12}")
|
||||
print("-" * 72)
|
||||
for v in sorted(vulns, key=lambda x: x.get("severity", ""), reverse=True):
|
||||
print(f"{v.get('id', 'N/A')[:39]:<40} "
|
||||
f"{v.get('severity', 'N/A'):<10} "
|
||||
f"{v.get('cvssV3Score', 'N/A'):<8} "
|
||||
f"{v.get('status', 'N/A'):<12}")
|
||||
|
||||
|
||||
def cmd_export_report(api, site_id, output_file):
|
||||
"""Export vulnerability report for a site to CSV."""
|
||||
print(f"[*] Fetching assets for site {site_id}...")
|
||||
assets = api.get_site_assets(site_id)
|
||||
print(f"[+] Found {len(assets)} assets")
|
||||
|
||||
all_findings = []
|
||||
for asset in assets:
|
||||
asset_id = asset.get("id")
|
||||
hostname = asset.get("hostName", asset.get("ip", "unknown"))
|
||||
ip = asset.get("ip", "N/A")
|
||||
os_name = asset.get("os", {}).get("description", "Unknown")
|
||||
|
||||
vulns = api.get_asset_vulnerabilities(asset_id)
|
||||
for v in vulns:
|
||||
all_findings.append({
|
||||
"asset_id": asset_id,
|
||||
"hostname": hostname,
|
||||
"ip_address": ip,
|
||||
"os": os_name,
|
||||
"vulnerability_id": v.get("id", ""),
|
||||
"severity": v.get("severity", ""),
|
||||
"cvss_v3_score": v.get("cvssV3Score", ""),
|
||||
"status": v.get("status", ""),
|
||||
"first_found": v.get("since", ""),
|
||||
})
|
||||
|
||||
print(f" Processed {hostname}: {len(vulns)} vulnerabilities")
|
||||
|
||||
if all_findings:
|
||||
df = pd.DataFrame(all_findings)
|
||||
df = df.sort_values(["cvss_v3_score", "severity"], ascending=[False, False])
|
||||
df.to_csv(output_file, index=False)
|
||||
print(f"\n[+] Report exported to {output_file}")
|
||||
print(f" Total findings: {len(all_findings)}")
|
||||
print(f"\n Severity Distribution:")
|
||||
print(df["severity"].value_counts().to_string())
|
||||
else:
|
||||
print("[!] No findings to export.")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Rapid7 InsightVM Scan Automation Tool"
|
||||
)
|
||||
parser.add_argument("--console", default="https://localhost:3780",
|
||||
help="InsightVM console URL")
|
||||
parser.add_argument("--username", help="Console username")
|
||||
parser.add_argument("--password", help="Console password")
|
||||
parser.add_argument("--api-key", help="API key (alternative to user/pass)")
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command")
|
||||
|
||||
subparsers.add_parser("sites", help="List all scan sites")
|
||||
|
||||
scan_p = subparsers.add_parser("scan", help="Start a scan")
|
||||
scan_p.add_argument("--site-id", type=int, required=True)
|
||||
scan_p.add_argument("--engine-id", type=int)
|
||||
scan_p.add_argument("--template-id", type=str)
|
||||
scan_p.add_argument("--wait", action="store_true")
|
||||
|
||||
status_p = subparsers.add_parser("status", help="Check scan status")
|
||||
status_p.add_argument("--scan-id", type=int, required=True)
|
||||
|
||||
vuln_p = subparsers.add_parser("vulns", help="List asset vulnerabilities")
|
||||
vuln_p.add_argument("--asset-id", type=int, required=True)
|
||||
|
||||
report_p = subparsers.add_parser("report", help="Export vulnerability report")
|
||||
report_p.add_argument("--site-id", type=int, required=True)
|
||||
report_p.add_argument("--output", default="insightvm_report.csv")
|
||||
|
||||
subparsers.add_parser("engines", help="List scan engines")
|
||||
subparsers.add_parser("templates", help="List scan templates")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
api = InsightVMAPI(
|
||||
args.console,
|
||||
username=args.username,
|
||||
password=args.password,
|
||||
api_key=args.api_key
|
||||
)
|
||||
|
||||
if args.command == "sites":
|
||||
cmd_list_sites(api)
|
||||
elif args.command == "scan":
|
||||
cmd_start_scan(api, args.site_id, args.engine_id,
|
||||
args.template_id, args.wait)
|
||||
elif args.command == "status":
|
||||
cmd_scan_status(api, args.scan_id)
|
||||
elif args.command == "vulns":
|
||||
cmd_asset_vulns(api, args.asset_id)
|
||||
elif args.command == "report":
|
||||
cmd_export_report(api, args.site_id, args.output)
|
||||
elif args.command == "engines":
|
||||
engines = api.list_scan_engines()
|
||||
for e in engines:
|
||||
print(f" Engine {e['id']}: {e['name']} - {e.get('address', 'N/A')}")
|
||||
elif args.command == "templates":
|
||||
templates = api.list_scan_templates()
|
||||
for t in templates:
|
||||
print(f" {t['id']}: {t['name']}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user