Files
Anthropic-Cybersecurity-Skills/skills/building-threat-intelligence-platform/scripts/agent.py
T
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
2026-03-19 13:26:49 +01:00

164 lines
5.7 KiB
Python

#!/usr/bin/env python3
"""Threat intelligence platform builder.
Core TIP components: STIX/TAXII ingestion, indicator lifecycle management,
confidence scoring, sharing groups, and intelligence dissemination.
"""
import json
import datetime
import re
import uuid
STIX_INDICATOR_TYPES = {
"ipv4-addr": "[ipv4-addr:value = '{}']",
"domain-name": "[domain-name:value = '{}']",
"url": "[url:value = '{}']",
"file-sha256": "[file:hashes.'SHA-256' = '{}']",
"file-md5": "[file:hashes.MD5 = '{}']",
"email-addr": "[email-addr:value = '{}']",
}
TLP_DEFINITIONS = {
"TLP:CLEAR": {"color": "white", "sharing": "Unlimited", "code": 0},
"TLP:GREEN": {"color": "green", "sharing": "Community", "code": 1},
"TLP:AMBER": {"color": "amber", "sharing": "Organization", "code": 2},
"TLP:AMBER+STRICT": {"color": "amber", "sharing": "Need-to-know only", "code": 3},
"TLP:RED": {"color": "red", "sharing": "Named recipients only", "code": 4},
}
def classify_indicator(value):
"""Classify indicator type from raw value."""
if re.match(r"^[0-9]{1,3}(\\.[0-9]{1,3}){3}$", value):
return "ipv4-addr"
if re.match(r"^[a-fA-F0-9]{64}$", value):
return "file-sha256"
if re.match(r"^[a-fA-F0-9]{32}$", value):
return "file-md5"
if re.match(r"^[a-zA-Z0-9][a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", value):
return "domain-name"
if value.startswith("http://") or value.startswith("https://"):
return "url"
if "@" in value:
return "email-addr"
return "unknown"
def create_stix_indicator(value, indicator_type=None, confidence=50, tlp="TLP:AMBER"):
"""Create a STIX 2.1 Indicator object."""
if not indicator_type:
indicator_type = classify_indicator(value)
pattern_template = STIX_INDICATOR_TYPES.get(indicator_type)
if not pattern_template:
return {"error": "Unsupported indicator type: " + indicator_type}
now = datetime.datetime.utcnow().isoformat(timespec="milliseconds") + "Z"
indicator_id = "indicator--" + str(uuid.uuid5(uuid.NAMESPACE_URL, value))
indicator = {
"type": "indicator",
"spec_version": "2.1",
"id": indicator_id,
"created": now,
"modified": now,
"name": "{}: {}".format(indicator_type, value),
"pattern": pattern_template.format(value),
"pattern_type": "stix",
"valid_from": now,
"confidence": confidence,
"labels": ["malicious-activity"],
"object_marking_refs": [tlp_to_marking_ref(tlp)],
}
return indicator
def tlp_to_marking_ref(tlp):
"""Convert TLP label to STIX marking definition ID."""
tlp_refs = {
"TLP:CLEAR": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
"TLP:GREEN": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",
"TLP:AMBER": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",
"TLP:AMBER+STRICT": "marking-definition--826578e1-40a3-4b46-a8d8-b9931fdd750e",
"TLP:RED": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed",
}
return tlp_refs.get(tlp, tlp_refs["TLP:AMBER"])
def calculate_indicator_score(sources_count, age_days, confirmed_sightings, false_positives):
"""Calculate indicator confidence score (0-100)."""
source_score = min(sources_count * 15, 40)
age_penalty = min(age_days * 0.5, 30)
sighting_score = min(confirmed_sightings * 10, 30)
fp_penalty = min(false_positives * 15, 30)
score = source_score - age_penalty + sighting_score - fp_penalty
return max(0, min(100, round(score)))
def build_stix_bundle(indicators):
"""Build STIX 2.1 Bundle from list of indicators."""
bundle = {
"type": "bundle",
"id": "bundle--" + str(uuid.uuid4()),
"objects": indicators,
}
return bundle
def generate_tip_report(indicators, platform_name="Internal TIP"):
"""Generate TIP status report."""
type_counts = {}
for ind in indicators:
itype = ind.get("name", "").split(":")[0] if ":" in ind.get("name", "") else "unknown"
type_counts[itype] = type_counts.get(itype, 0) + 1
return {
"platform": platform_name,
"generated_at": datetime.datetime.utcnow().isoformat() + "Z",
"total_indicators": len(indicators),
"type_breakdown": type_counts,
"avg_confidence": round(
sum(i.get("confidence", 0) for i in indicators) / max(len(indicators), 1), 1
),
}
if __name__ == "__main__":
print("=" * 60)
print("Threat Intelligence Platform Builder")
print("STIX 2.1 indicators, scoring, TLP marking, bundle export")
print("=" * 60)
demo_values = [
"198.51.100.42",
"evil-domain.example.com",
"a" * 64,
"https://evil.example.com/payload.exe",
"attacker@evil.example.com",
]
indicators = []
for val in demo_values:
ind = create_stix_indicator(val, confidence=75, tlp="TLP:AMBER")
if "error" not in ind:
indicators.append(ind)
print("\n--- Indicators Created ---")
for ind in indicators:
print(" {} [confidence={}]".format(ind["name"], ind["confidence"]))
print(" Pattern: {}".format(ind["pattern"]))
bundle = build_stix_bundle(indicators)
print("\nSTIX Bundle: {} ({} objects)".format(bundle["id"], len(bundle["objects"])))
score = calculate_indicator_score(sources_count=3, age_days=5, confirmed_sightings=2, false_positives=0)
print("\nSample score calculation: {}".format(score))
report = generate_tip_report(indicators)
print("\n--- Platform Report ---")
for k, v in report.items():
print(" {}: {}".format(k, v))
print("\n" + json.dumps({"indicators_created": len(indicators)}, indent=2))