#!/usr/bin/env python3 """Agent for performing phishing simulation campaigns with GoPhish API.""" import json import os import argparse from datetime import datetime try: import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) except ImportError: requests = None class GoPhishClient: """Client for GoPhish REST API.""" def __init__(self, base_url, api_key): self.base_url = base_url.rstrip("/") self.headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} def _get(self, path): resp = requests.get(f"{self.base_url}{path}", headers=self.headers, verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", timeout=30) # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments resp.raise_for_status() return resp.json() def _post(self, path, data): resp = requests.post(f"{self.base_url}{path}", headers=self.headers, json=data, verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", timeout=30) # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments resp.raise_for_status() return resp.json() def get_campaigns(self): return self._get("/api/campaigns/") def get_campaign(self, campaign_id): return self._get(f"/api/campaigns/{campaign_id}") def get_campaign_results(self, campaign_id): return self._get(f"/api/campaigns/{campaign_id}/results") def create_campaign(self, name, template_id, page_id, smtp_id, group_ids, url, launch_date=None): data = {"name": name, "template": {"id": template_id}, "page": {"id": page_id}, "smtp": {"id": smtp_id}, "groups": [{"id": gid} for gid in group_ids], "url": url} if launch_date: data["launch_date"] = launch_date return self._post("/api/campaigns/", data) def get_groups(self): return self._get("/api/groups/") def get_templates(self): return self._get("/api/templates/") def get_sending_profiles(self): return self._get("/api/smtp/") def list_campaigns(base_url, api_key): """List all phishing simulation campaigns.""" client = GoPhishClient(base_url, api_key) campaigns = client.get_campaigns() return { "total_campaigns": len(campaigns), "campaigns": [{"id": c["id"], "name": c["name"], "status": c["status"], "created_date": c.get("created_date"), "launch_date": c.get("launch_date")} for c in campaigns], } def get_campaign_metrics(base_url, api_key, campaign_id): """Get detailed metrics for a phishing campaign.""" client = GoPhishClient(base_url, api_key) campaign = client.get_campaign(campaign_id) results = campaign.get("results", []) stats = {"total": len(results), "sent": 0, "opened": 0, "clicked": 0, "submitted": 0, "reported": 0} for r in results: status = r.get("status", "").lower() if "sent" in status or "email sent" in status: stats["sent"] += 1 if "opened" in status or "email opened" in status: stats["opened"] += 1 if "clicked" in status: stats["clicked"] += 1 if "submitted" in status: stats["submitted"] += 1 if "reported" in status: stats["reported"] += 1 total = max(stats["sent"], 1) return { "campaign_id": campaign_id, "name": campaign.get("name"), "status": campaign.get("status"), "stats": stats, "rates": { "open_rate": round(stats["opened"] / total * 100, 1), "click_rate": round(stats["clicked"] / total * 100, 1), "submit_rate": round(stats["submitted"] / total * 100, 1), "report_rate": round(stats["reported"] / total * 100, 1), }, } def launch_campaign(base_url, api_key, name, template_id, page_id, smtp_id, group_ids, url): """Launch a new phishing simulation campaign.""" client = GoPhishClient(base_url, api_key) result = client.create_campaign(name, template_id, page_id, smtp_id, group_ids, url) return {"campaign_created": True, "campaign": result} def list_resources(base_url, api_key): """List available templates, groups, and sending profiles.""" client = GoPhishClient(base_url, api_key) return { "groups": [{"id": g["id"], "name": g["name"], "targets": len(g.get("targets", []))} for g in client.get_groups()], "templates": [{"id": t["id"], "name": t["name"]} for t in client.get_templates()], "sending_profiles": [{"id": s["id"], "name": s["name"], "host": s.get("host")} for s in client.get_sending_profiles()], } def generate_report(base_url, api_key, campaign_id): """Generate phishing simulation report with recommendations.""" metrics = get_campaign_metrics(base_url, api_key, campaign_id) recommendations = [] if metrics["rates"]["click_rate"] > 20: recommendations.append("HIGH click rate — mandatory security awareness training needed") if metrics["rates"]["submit_rate"] > 10: recommendations.append("CRITICAL — over 10% submitted credentials, implement MFA immediately") if metrics["rates"]["report_rate"] < 5: recommendations.append("Low report rate — train users on how to report phishing") return { "generated": datetime.utcnow().isoformat(), **metrics, "risk_level": "CRITICAL" if metrics["rates"]["submit_rate"] > 10 else "HIGH" if metrics["rates"]["click_rate"] > 20 else "MEDIUM", "recommendations": recommendations, } def main(): if not requests: print(json.dumps({"error": "requests not installed"})) return parser = argparse.ArgumentParser(description="GoPhish Phishing Simulation Agent") parser.add_argument("--url", required=True, help="GoPhish server URL") parser.add_argument("--api-key", required=True, help="GoPhish API key") sub = parser.add_subparsers(dest="command") sub.add_parser("campaigns", help="List campaigns") m = sub.add_parser("metrics", help="Campaign metrics") m.add_argument("--id", type=int, required=True) sub.add_parser("resources", help="List templates, groups, profiles") r = sub.add_parser("report", help="Generate campaign report") r.add_argument("--id", type=int, required=True) l = sub.add_parser("launch", help="Launch new campaign") l.add_argument("--name", required=True) l.add_argument("--template-id", type=int, required=True) l.add_argument("--page-id", type=int, required=True) l.add_argument("--smtp-id", type=int, required=True) l.add_argument("--group-ids", nargs="+", type=int, required=True) l.add_argument("--phish-url", required=True) args = parser.parse_args() if args.command == "campaigns": result = list_campaigns(args.url, args.api_key) elif args.command == "metrics": result = get_campaign_metrics(args.url, args.api_key, args.id) elif args.command == "resources": result = list_resources(args.url, args.api_key) elif args.command == "report": result = generate_report(args.url, args.api_key, args.id) elif args.command == "launch": result = launch_campaign(args.url, args.api_key, args.name, args.template_id, args.page_id, args.smtp_id, args.group_ids, args.phish_url) else: parser.print_help() return print(json.dumps(result, indent=2, default=str)) if __name__ == "__main__": main()