mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-17 13:15:16 +03:00
c21af3347e
- Add scripts/agent.py and references/api-reference.md to all remaining skills - Update all 648 LICENSE files: copyright now reads 'Mahipal' - Add implementing-security-monitoring-with-datadog (new skill with full anatomy) - All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
173 lines
6.9 KiB
Python
173 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
|
"""IOC Defanging and Sharing Pipeline Agent - Defangs, enriches, and shares IOCs in STIX format."""
|
|
|
|
import json
|
|
import logging
|
|
import argparse
|
|
import os
|
|
import re
|
|
from datetime import datetime
|
|
|
|
import requests
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
IOC_PATTERNS = {
|
|
"ipv4": re.compile(r"\b(?:\d{1,3}\.){3}\d{1,3}\b"),
|
|
"domain": re.compile(r"\b(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}\b"),
|
|
"url": re.compile(r"https?://[^\s\"'<>]+"),
|
|
"md5": re.compile(r"\b[a-fA-F0-9]{32}\b"),
|
|
"sha256": re.compile(r"\b[a-fA-F0-9]{64}\b"),
|
|
"email": re.compile(r"\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b"),
|
|
}
|
|
|
|
EXCLUSION_DOMAINS = {"example.com", "example.org", "example.net", "localhost", "schema.org",
|
|
"w3.org", "microsoft.com", "google.com", "github.com"}
|
|
|
|
|
|
def extract_iocs(text):
|
|
"""Extract IOCs from raw text."""
|
|
results = {}
|
|
for ioc_type, pattern in IOC_PATTERNS.items():
|
|
matches = set(pattern.findall(text))
|
|
if ioc_type == "domain":
|
|
matches = {m for m in matches if m.split(".")[-1] not in {"py", "js", "json", "xml", "yml"}
|
|
and m not in EXCLUSION_DOMAINS and not any(excl in m for excl in EXCLUSION_DOMAINS)}
|
|
results[ioc_type] = list(matches)
|
|
logger.info("Extracted IOCs: %s", {k: len(v) for k, v in results.items()})
|
|
return results
|
|
|
|
|
|
def defang_ioc(value, ioc_type):
|
|
"""Defang an IOC for safe sharing."""
|
|
if ioc_type == "ipv4":
|
|
return value.replace(".", "[.]")
|
|
elif ioc_type in ("domain", "email"):
|
|
return value.replace(".", "[.]")
|
|
elif ioc_type == "url":
|
|
return value.replace("http://", "hxxp://").replace("https://", "hxxps://").replace(".", "[.]")
|
|
return value
|
|
|
|
|
|
def refang_ioc(value, ioc_type):
|
|
"""Refang a defanged IOC back to original form."""
|
|
if ioc_type in ("ipv4", "domain", "email"):
|
|
return value.replace("[.]", ".")
|
|
elif ioc_type == "url":
|
|
return value.replace("hxxp://", "http://").replace("hxxps://", "https://").replace("[.]", ".")
|
|
return value
|
|
|
|
|
|
def enrich_ioc(value, ioc_type, vt_key=None, abuseipdb_key=None):
|
|
"""Enrich IOC with threat intelligence from VirusTotal and AbuseIPDB."""
|
|
vt_key = vt_key or os.environ.get("VT_API_KEY", "")
|
|
abuseipdb_key = abuseipdb_key or os.environ.get("ABUSEIPDB_KEY", "")
|
|
enrichment = {"value": value, "type": ioc_type, "sources": []}
|
|
if ioc_type in ("md5", "sha256") and vt_key:
|
|
try:
|
|
resp = requests.get(f"https://www.virustotal.com/api/v3/files/{value}",
|
|
headers={"x-apikey": vt_key}, timeout=10)
|
|
if resp.status_code == 200:
|
|
data = resp.json().get("data", {}).get("attributes", {}).get("last_analysis_stats", {})
|
|
enrichment["vt_malicious"] = data.get("malicious", 0)
|
|
enrichment["sources"].append("virustotal")
|
|
except requests.RequestException:
|
|
pass
|
|
elif ioc_type == "ipv4" and abuseipdb_key:
|
|
try:
|
|
resp = requests.get("https://api.abuseipdb.com/api/v2/check",
|
|
params={"ipAddress": value, "maxAgeInDays": 90},
|
|
headers={"Key": abuseipdb_key, "Accept": "application/json"}, timeout=10)
|
|
if resp.status_code == 200:
|
|
data = resp.json().get("data", {})
|
|
enrichment["abuse_score"] = data.get("abuseConfidenceScore", 0)
|
|
enrichment["sources"].append("abuseipdb")
|
|
except requests.RequestException:
|
|
pass
|
|
return enrichment
|
|
|
|
|
|
def to_stix_bundle(iocs):
|
|
"""Convert IOCs to STIX 2.1 bundle for sharing."""
|
|
objects = []
|
|
stix_type_map = {"ipv4": "ipv4-addr", "domain": "domain-name", "url": "url",
|
|
"md5": "file", "sha256": "file", "email": "email-addr"}
|
|
for ioc_type, values in iocs.items():
|
|
for value in values:
|
|
stype = stix_type_map.get(ioc_type)
|
|
if not stype:
|
|
continue
|
|
indicator = {
|
|
"type": "indicator",
|
|
"spec_version": "2.1",
|
|
"id": f"indicator--{hash(value) % (10**12):012d}",
|
|
"created": datetime.utcnow().isoformat() + "Z",
|
|
"pattern_type": "stix",
|
|
"pattern": f"[{stype}:value = '{value}']" if stype != "file"
|
|
else f"[file:hashes.'{ioc_type.upper()}' = '{value}']",
|
|
"valid_from": datetime.utcnow().isoformat() + "Z",
|
|
"labels": ["malicious-activity"],
|
|
}
|
|
objects.append(indicator)
|
|
bundle = {"type": "bundle", "id": f"bundle--{hash(str(iocs)) % (10**12):012d}",
|
|
"objects": objects}
|
|
logger.info("Created STIX bundle with %d indicators", len(objects))
|
|
return bundle
|
|
|
|
|
|
def defang_all(iocs):
|
|
"""Defang all extracted IOCs."""
|
|
defanged = {}
|
|
for ioc_type, values in iocs.items():
|
|
defanged[ioc_type] = [{"original": v, "defanged": defang_ioc(v, ioc_type)} for v in values]
|
|
return defanged
|
|
|
|
|
|
def generate_report(iocs, defanged, stix_bundle):
|
|
"""Generate IOC sharing pipeline report."""
|
|
total = sum(len(v) for v in iocs.values())
|
|
report = {
|
|
"timestamp": datetime.utcnow().isoformat(),
|
|
"total_iocs": total,
|
|
"by_type": {k: len(v) for k, v in iocs.items()},
|
|
"defanged_iocs": defanged,
|
|
"stix_indicator_count": len(stix_bundle.get("objects", [])),
|
|
"stix_bundle": stix_bundle,
|
|
}
|
|
print(f"IOC PIPELINE REPORT: {total} IOCs extracted, {len(stix_bundle.get('objects', []))} STIX indicators")
|
|
return report
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="IOC Defanging and Sharing Pipeline")
|
|
parser.add_argument("--input-file", required=True, help="Text file containing IOCs")
|
|
parser.add_argument("--enrich", action="store_true", help="Enrich IOCs with threat intel")
|
|
parser.add_argument("--vt-key", default=os.environ.get("VT_API_KEY", ""), help="VirusTotal API key")
|
|
parser.add_argument("--abuseipdb-key", default=os.environ.get("ABUSEIPDB_KEY", ""), help="AbuseIPDB API key")
|
|
parser.add_argument("--output", default="ioc_pipeline_report.json")
|
|
args = parser.parse_args()
|
|
|
|
with open(args.input_file) as f:
|
|
text = f.read()
|
|
|
|
iocs = extract_iocs(text)
|
|
defanged = defang_all(iocs)
|
|
stix_bundle = to_stix_bundle(iocs)
|
|
|
|
if args.enrich:
|
|
enrichments = []
|
|
for ioc_type, values in iocs.items():
|
|
for value in values[:10]:
|
|
enrichments.append(enrich_ioc(value, ioc_type, args.vt_key, args.abuseipdb_key))
|
|
logger.info("Enriched %d IOCs", len(enrichments))
|
|
|
|
report = generate_report(iocs, defanged, stix_bundle)
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2)
|
|
logger.info("Report saved to %s", args.output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|