npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
NIST CSF 2.0
Overview
Social engineering penetration testing assesses an organization's human attack surface through controlled simulation of real-world deception techniques. According to Verizon DBIR 2024, the human element is involved in approximately 68% of all breaches, with phishing remaining the dominant initial access vector. This skill covers phishing, vishing (voice phishing), smishing (SMS phishing), and physical pretexting campaigns using tools like GoPhish, the Social Engineer Toolkit (SET), and Evilginx.
When to Use
- When conducting security assessments that involve conducting social engineering penetration test
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Written authorization from senior management (CISO/CTO)
- Legal review confirming compliance with local laws (CFAA, GDPR, etc.)
- Defined scope: target employee groups, attack types, exclusions
- GoPhish server, domain for phishing infrastructure, VPS
- OSINT tools: Maltego, theHarvester, LinkedIn scraping tools
- Coordination with HR and Legal for employee notification post-test
Phase 1 — OSINT and Target Profiling
Employee Reconnaissance
# Email harvesting
theHarvester -d targetcorp.com -b all -l 500 -f harvester_results
# LinkedIn OSINT (manual + tools)
# Gather: names, roles, departments, email format
# Identify: new hires, IT admins, finance team, executives
# Email format discovery
# Check: first.last@, flast@, firstl@
# Verify with: hunter.io, phonebook.cz, email-checker.net
# Social media OSINT
# Twitter/X: employees posting about work tools/frustrations
# Facebook: corporate event photos, office layout
# GitHub: employee repos with corporate email addresses
# Domain intelligence
dig targetcorp.com MX +short
dig targetcorp.com TXT +short
# Check for SPF, DKIM, DMARC records
# Weak DMARC = easier email spoofing
# Check breach databases (authorized)
# HaveIBeenPwned API for corporate emails
# Identify employees with compromised credentialsTarget Selection Matrix
| Group | Count | Pretext | Attack Vector |
|---|---|---|---|
| Finance | 15 | Invoice approval | Phishing (credential harvest) |
| IT Help Desk | 8 | Password reset | Vishing |
| Executives | 5 | Board meeting update | Spear phishing |
| New Hires (< 90 days) | 12 | HR onboarding form | Phishing (payload) |
| All Employees | 200 | IT security update | Broad phishing |
Phase 2 — Phishing Campaign
Infrastructure Setup
# Register lookalike domain
# targetcorp.com -> targetc0rp.com, targetcorp-secure.com, targetcorp.net
# Set up GoPhish server
sudo apt install gophish
# Edit config.json for admin and phishing server ports
gophish
# Configure sending profile in GoPhish
# SMTP server: mail.attackdomain.com
# From: it-security@targetcorp-secure.com
# Headers: proper DKIM/SPF for attack domain
# Create landing page (credential harvesting)
# Clone legitimate login page (Office 365, Okta, etc.)
# GoPhish: Import Site -> https://login.microsoftonline.com
# Enable: Capture Credentials, Capture Passwords
# Redirect to real site after capture
# Set up Evilginx for MFA bypass (authorized testing only)
evilginx2
: config domain attackdomain.com
: config ipv4 <server_ip>
: phishlets hostname o365 login.targetcorp-secure.com
: phishlets enable o365
: lures create o365
: lures get-url 0GoPhish Campaign Configuration
{
"campaign": {
"name": "IT Security Update - Q1 2025",
"template": {
"name": "Mandatory Security Training",
"subject": "Action Required: Complete Security Awareness Training by Friday",
"html": "<html>...[branded email with urgency]...</html>",
"from": "IT Security Team <security@targetcorp-secure.com>"
},
"landing_page": "Office 365 Login Clone",
"sending_profile": "Phishing SMTP",
"groups": ["All Employees - Batch 1"],
"launch_date": "2025-03-10T09:00:00Z",
"send_by_date": "2025-03-10T12:00:00Z"
}
}Phishing Email Templates by Pretext
Template 1 — IT Security Update:
Subject: [Action Required] Mandatory Password Reset - Security Incident
From: IT Security <security@targetcorp-secure.com>
Dear {FirstName},
Our security team has detected unauthorized access attempts on our systems.
As a precautionary measure, all employees must reset their passwords immediately.
Please click below to reset your password within the next 24 hours:
[Reset Password Now] -> {phishing_url}
Failure to comply may result in temporary account suspension.
Thank you,
IT Security TeamTemplate 2 — Finance Invoice:
Subject: Invoice #INV-2025-4821 - Approval Required
From: Accounts Payable <ap@targetcorp-secure.com>
Hi {FirstName},
Please review and approve the attached invoice from our vendor.
Amount: $47,250.00 | Due: March 15, 2025
[View Invoice] -> {phishing_url}
Best regards,
Accounts PayablePhase 3 — Vishing Campaign
Call Script Template
Pretext: IT Help Desk calling about suspicious login
Caller: "Hi, this is [Name] from the IT Help Desk. Am I speaking with [Target Name]?"
[Wait for confirmation]
Caller: "We've detected some unusual login activity on your account from an
unrecognized location. For your protection, I need to verify your identity
before we can investigate further."
Caller: "Can you confirm your employee ID and the email address associated
with your account?"
[Record responses]
Caller: "Thank you. I'm going to send you a verification link to confirm
it's really you. Can you click on it and enter your credentials so we can
secure your account?"
[Send phishing link via email/SMS during call]
Caller: "Great, I can see you've been verified. Your account is now secured.
If you notice any further issues, please call the help desk at [real number]."Vishing Metrics to Track
| Metric | Description |
|---|---|
| Call answered | Target picked up the phone |
| Engaged | Target continued conversation past initial question |
| Information disclosed | Target provided credentials, employee ID, or PII |
| Link clicked | Target clicked the verification link |
| Credentials entered | Target entered credentials on phishing page |
| Reported | Target reported the call to security |
Phase 5 — Metrics and Analysis
Campaign Results Dashboard
Phishing Campaign Results:
├── Emails Sent: 200
├── Emails Delivered: 195 (97.5%)
├── Emails Opened: 142 (72.8%)
├── Links Clicked: 68 (34.9%)
├── Credentials Submitted: 31 (15.9%)
├── MFA Bypassed: 8 (4.1%) [Evilginx]
├── Reported to SOC: 12 (6.2%)
└── No Action: 53 (27.2%)
Vishing Campaign Results:
├── Calls Made: 23
├── Calls Answered: 18 (78.3%)
├── Engaged in Conversation: 15 (65.2%)
├── Information Disclosed: 9 (39.1%)
├── Credentials Provided: 4 (17.4%)
└── Reported to Security: 2 (8.7%)
Physical Assessment:
├── Tailgating Successful: 3/5 attempts
├── USB Drives Plugged In: 2/10 dropped
├── Restricted Areas Accessed: 2/4 attempted
└── Challenged by Employee: 1 timeRisk Scoring
| Attack Vector | Success Rate | Risk Level | Priority |
|---|---|---|---|
| Phishing (credential harvest) | 15.9% | High | P1 |
| Vishing (info disclosure) | 39.1% | Critical | P1 |
| Physical tailgating | 60% | High | P2 |
| USB drop | 20% | Medium | P3 |
| Spear phishing (exec) | 40% | Critical | P1 |
Phase 6 — Reporting and Recommendations
Remediation Priorities
| Priority | Recommendation | Timeline |
|---|---|---|
| P1 | Deploy phishing-resistant MFA (FIDO2/WebAuthn) | 30 days |
| P1 | Implement targeted security awareness training | 14 days |
| P1 | Deploy email gateway with URL rewriting | 30 days |
| P2 | Strengthen physical access controls (mantraps, visitor badges) | 60 days |
| P2 | Implement security champion program per department | 30 days |
| P3 | Deploy USB device control policy | 30 days |
| P3 | Establish phishing reporting button in email client | 14 days |
Tools Reference
| Tool | Purpose |
|---|---|
| GoPhish | Phishing campaign management platform |
| Evilginx2 | MFA bypass via reverse proxy phishing |
| Social Engineer Toolkit (SET) | Social engineering attack framework |
| Maltego | OSINT and relationship mapping |
| theHarvester | Email and domain OSINT |
| King Phisher | Phishing campaign tool |
| Modlishka | Reverse proxy for credential interception |
References
- GoPhish: https://getgophish.com/
- Evilginx2: https://github.com/kgretzky/evilginx2
- Social Engineer Toolkit: https://github.com/trustedsec/social-engineer-toolkit
- Verizon DBIR: https://www.verizon.com/business/resources/reports/dbir/
- NIST SP 800-61: Computer Security Incident Handling Guide
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.5 KB
Social Engineering Penetration Test — API Reference
Libraries
| Library | Install | Purpose |
|---|---|---|
| requests | pip install requests |
GoPhish REST API client |
| gophish | pip install gophish |
Official GoPhish Python client |
GoPhish API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/campaigns/ |
List all campaigns |
| GET | /api/campaigns/{id}/results |
Campaign results and metrics |
| POST | /api/campaigns/ |
Create new campaign |
| POST | /api/templates/ |
Create email template |
| POST | /api/groups/ |
Create target group |
| POST | /api/smtp/ |
Create sending profile |
| POST | /api/pages/ |
Create landing page |
Campaign Metrics
| Metric | Formula |
|---|---|
| Open Rate | emails_opened / emails_sent x 100 |
| Click Rate | links_clicked / emails_sent x 100 |
| Submit Rate | data_submitted / emails_sent x 100 |
| Report Rate | reported / emails_sent x 100 |
Social Engineering Vectors
| Vector | Tools |
|---|---|
| Email Phishing | GoPhish, King Phisher |
| Vishing | Pretext scripts, VoIP tools |
| Physical | Badge cloning, tailgating |
| USB Drops | Rubber Ducky, USB armory |
External References
standards.md0.9 KB
Standards — Social Engineering Penetration Testing
Frameworks
- PTES Social Engineering Section: http://www.pentest-standard.org/index.php/Social_Engineering
- NIST SP 800-50: Building an Information Technology Security Awareness and Training Program
- SANS Security Awareness Maturity Model
- MITRE ATT&CK Initial Access: https://attack.mitre.org/tactics/TA0001/
MITRE ATT&CK Techniques
| Technique | ID | Vector |
|---|---|---|
| Phishing: Spear Phishing Link | T1566.002 | Email with malicious URL |
| Phishing: Spear Phishing Attachment | T1566.001 | Email with payload |
| Phishing: Spear Phishing via Service | T1566.003 | Social media / messaging |
Legal Considerations
- Must have explicit written authorization
- Cannot target personal email or devices without consent
- GDPR compliance for EU employees
- Cannot use real malware or destructive payloads
- Results must be anonymized in reporting to protect individuals
workflows.md1.1 KB
Workflows — Social Engineering Penetration Testing
Campaign Lifecycle
Authorization & Scoping
│
├── OSINT & Target Profiling
│ ├── Email harvesting
│ ├── LinkedIn/social media reconnaissance
│ └── Target group selection
│
├── Infrastructure Setup
│ ├── Domain registration (lookalike)
│ ├── GoPhish/Evilginx deployment
│ ├── SMTP configuration (SPF/DKIM)
│ └── Landing page creation
│
├── Campaign Execution
│ ├── Phishing emails (batched sends)
│ ├── Vishing calls
│ ├── Physical pretexting
│ └── USB drops
│
├── Monitoring & Data Collection
│ ├── Email opens/clicks tracking
│ ├── Credential captures
│ ├── Call recordings/notes
│ └── Physical access logs
│
└── Reporting & Training
├── Metrics compilation
├── Risk scoring
├── Executive report
└── Targeted training recommendationsScripts 2
agent.py5.8 KB
#!/usr/bin/env python3
"""Social engineering penetration test management agent using GoPhish API."""
import json
import sys
import argparse
from datetime import datetime
try:
import requests
requests.packages.urllib3.disable_warnings()
except ImportError:
print("Install: pip install requests")
sys.exit(1)
class GoPhishClient:
"""GoPhish API client for phishing campaign management."""
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, endpoint):
resp = requests.get(f"{self.base_url}/api/{endpoint}", headers=self.headers, verify=False, timeout=30)
resp.raise_for_status()
return resp.json()
def _post(self, endpoint, data):
resp = requests.post(f"{self.base_url}/api/{endpoint}", headers=self.headers,
json=data, verify=False, timeout=30)
resp.raise_for_status()
return resp.json()
def list_campaigns(self):
return self._get("campaigns/")
def get_campaign_results(self, campaign_id):
return self._get(f"campaigns/{campaign_id}/results")
def create_sending_profile(self, name, host, from_addr, username, password):
return self._post("smtp/", {
"name": name, "host": host, "from_address": from_addr,
"username": username, "password": password, "ignore_cert_errors": True,
})
def create_template(self, name, subject, html, text=""):
return self._post("templates/", {
"name": name, "subject": subject, "html": html, "text": text,
})
def create_group(self, name, targets):
return self._post("groups/", {
"name": name,
"targets": [{"email": t["email"], "first_name": t.get("first_name", ""),
"last_name": t.get("last_name", "")} for t in targets],
})
def analyze_campaign_results(results):
"""Analyze phishing campaign results for metrics."""
stats = {"total": 0, "sent": 0, "opened": 0, "clicked": 0, "submitted": 0, "reported": 0}
for r in results:
stats["total"] += 1
status = r.get("status", "").lower()
if status == "email sent":
stats["sent"] += 1
elif status == "email opened":
stats["opened"] += 1
elif status == "clicked link":
stats["clicked"] += 1
elif status == "submitted data":
stats["submitted"] += 1
if stats["sent"] > 0:
stats["open_rate"] = round(stats["opened"] / stats["sent"] * 100, 1)
stats["click_rate"] = round(stats["clicked"] / stats["sent"] * 100, 1)
stats["submit_rate"] = round(stats["submitted"] / stats["sent"] * 100, 1)
return stats
def generate_pretext_scenarios():
"""Generate social engineering pretext scenarios for testing."""
return [
{
"scenario": "IT Password Reset",
"pretext": "IT department requires immediate password reset due to security incident",
"vector": "email",
"urgency": "high",
"success_indicator": "User clicks link and enters credentials",
},
{
"scenario": "CEO Wire Transfer",
"pretext": "CEO requests urgent wire transfer for confidential acquisition",
"vector": "email",
"urgency": "high",
"success_indicator": "User initiates transfer or reveals banking info",
},
{
"scenario": "Vendor Invoice",
"pretext": "Known vendor sends updated invoice with changed payment details",
"vector": "email",
"urgency": "medium",
"success_indicator": "User opens attachment or clicks payment link",
},
{
"scenario": "Physical Tailgating",
"pretext": "Contractor with clipboard requests building access",
"vector": "physical",
"urgency": "low",
"success_indicator": "Employee holds door without badge verification",
},
]
def run_assessment(base_url=None, api_key=None, campaign_id=None):
"""Execute social engineering assessment analysis."""
print(f"\n{'='*60}")
print(f" SOCIAL ENGINEERING PENETRATION TEST")
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
print(f"{'='*60}\n")
if base_url and api_key:
client = GoPhishClient(base_url, api_key)
campaigns = client.list_campaigns()
print(f"--- CAMPAIGNS ({len(campaigns)}) ---")
for c in campaigns[:5]:
print(f" {c['name']}: {c['status']}")
if campaign_id:
results = client.get_campaign_results(campaign_id)
stats = analyze_campaign_results(results)
print(f"\n--- CAMPAIGN METRICS ---")
for k, v in stats.items():
print(f" {k}: {v}")
scenarios = generate_pretext_scenarios()
print(f"\n--- PRETEXT SCENARIOS ({len(scenarios)}) ---")
for s in scenarios:
print(f" [{s['urgency'].upper()}] {s['scenario']}: {s['vector']}")
return {"scenarios": scenarios}
def main():
parser = argparse.ArgumentParser(description="Social Engineering Pentest Agent")
parser.add_argument("--gophish-url", help="GoPhish server URL")
parser.add_argument("--api-key", help="GoPhish API key")
parser.add_argument("--campaign-id", type=int, help="Campaign ID for results")
parser.add_argument("--output", help="Save report to JSON file")
args = parser.parse_args()
report = run_assessment(args.gophish_url, args.api_key, args.campaign_id)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"\n[+] Report saved to {args.output}")
if __name__ == "__main__":
main()
process.py7.4 KB
#!/usr/bin/env python3
"""
Social Engineering Penetration Test — Campaign Metrics Processor
Processes GoPhish campaign results and generates analysis reports.
Requires: requests library for GoPhish API interaction.
Usage:
python process.py --gophish-url https://localhost:3333 --api-key <key> --output ./results
"""
import json
import csv
import argparse
import datetime
from pathlib import Path
from typing import Optional
try:
import requests
requests.packages.urllib3.disable_warnings()
except ImportError:
print("Install requests: pip install requests")
raise
class GoPhishClient:
"""Client for GoPhish REST API."""
def __init__(self, base_url: str, api_key: str):
self.base_url = base_url.rstrip("/")
self.headers = {"Authorization": f"Bearer {api_key}"}
self.session = requests.Session()
self.session.headers.update(self.headers)
self.session.verify = False
def get_campaigns(self) -> list[dict]:
resp = self.session.get(f"{self.base_url}/api/campaigns/")
resp.raise_for_status()
return resp.json()
def get_campaign(self, campaign_id: int) -> dict:
resp = self.session.get(f"{self.base_url}/api/campaigns/{campaign_id}")
resp.raise_for_status()
return resp.json()
def get_campaign_results(self, campaign_id: int) -> dict:
resp = self.session.get(f"{self.base_url}/api/campaigns/{campaign_id}/results")
resp.raise_for_status()
return resp.json()
def analyze_campaign(campaign: dict) -> dict:
"""Analyze a single campaign's results."""
results = campaign.get("results", [])
timeline = campaign.get("timeline", [])
stats = {
"campaign_name": campaign.get("name", "Unknown"),
"total_targets": len(results),
"emails_sent": 0,
"emails_opened": 0,
"links_clicked": 0,
"credentials_submitted": 0,
"emails_reported": 0,
"errors": 0,
}
for entry in results:
status = entry.get("status", "")
if status == "Email Sent" or status in ("Email Opened", "Clicked Link",
"Submitted Data", "Email Reported"):
stats["emails_sent"] += 1
if status in ("Email Opened", "Clicked Link", "Submitted Data"):
stats["emails_opened"] += 1
if status in ("Clicked Link", "Submitted Data"):
stats["links_clicked"] += 1
if status == "Submitted Data":
stats["credentials_submitted"] += 1
if status == "Email Reported":
stats["emails_reported"] += 1
if status == "Error":
stats["errors"] += 1
# Calculate rates
total = stats["total_targets"]
if total > 0:
stats["open_rate"] = round(stats["emails_opened"] / total * 100, 1)
stats["click_rate"] = round(stats["links_clicked"] / total * 100, 1)
stats["submit_rate"] = round(stats["credentials_submitted"] / total * 100, 1)
stats["report_rate"] = round(stats["emails_reported"] / total * 100, 1)
else:
stats["open_rate"] = stats["click_rate"] = stats["submit_rate"] = stats["report_rate"] = 0
return stats
def analyze_by_department(results: list[dict]) -> dict[str, dict]:
"""Break down results by department/position."""
departments = {}
for entry in results:
dept = entry.get("position", "Unknown")
if dept not in departments:
departments[dept] = {
"total": 0, "clicked": 0, "submitted": 0, "reported": 0
}
departments[dept]["total"] += 1
status = entry.get("status", "")
if status in ("Clicked Link", "Submitted Data"):
departments[dept]["clicked"] += 1
if status == "Submitted Data":
departments[dept]["submitted"] += 1
if status == "Email Reported":
departments[dept]["reported"] += 1
return departments
def generate_report(stats: dict, dept_analysis: dict, output_dir: Path) -> str:
"""Generate campaign analysis report."""
report_file = output_dir / "se_campaign_report.md"
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
with open(report_file, "w") as f:
f.write("# Social Engineering Campaign Analysis Report\n\n")
f.write(f"**Campaign:** {stats['campaign_name']}\n")
f.write(f"**Generated:** {timestamp}\n\n---\n\n")
f.write("## Campaign Metrics\n\n")
f.write("| Metric | Count | Rate |\n")
f.write("|--------|-------|------|\n")
f.write(f"| Targets | {stats['total_targets']} | 100% |\n")
f.write(f"| Emails Sent | {stats['emails_sent']} | — |\n")
f.write(f"| Emails Opened | {stats['emails_opened']} | {stats['open_rate']}% |\n")
f.write(f"| Links Clicked | {stats['links_clicked']} | {stats['click_rate']}% |\n")
f.write(f"| Credentials Submitted | {stats['credentials_submitted']} | {stats['submit_rate']}% |\n")
f.write(f"| Reported to Security | {stats['emails_reported']} | {stats['report_rate']}% |\n\n")
f.write("## Department Breakdown\n\n")
f.write("| Department | Total | Clicked | Submitted | Reported |\n")
f.write("|-----------|-------|---------|-----------|----------|\n")
for dept, data in sorted(dept_analysis.items()):
f.write(f"| {dept} | {data['total']} | {data['clicked']} | {data['submitted']} | {data['reported']} |\n")
f.write("\n")
f.write("## Risk Assessment\n\n")
if stats["submit_rate"] > 20:
risk = "CRITICAL"
elif stats["submit_rate"] > 10:
risk = "HIGH"
elif stats["submit_rate"] > 5:
risk = "MEDIUM"
else:
risk = "LOW"
f.write(f"**Overall Risk Level: {risk}**\n\n")
f.write("## Recommendations\n\n")
f.write("1. Deploy phishing-resistant MFA (FIDO2/WebAuthn)\n")
f.write("2. Implement targeted training for high-risk departments\n")
f.write("3. Deploy email security gateway with URL sandboxing\n")
f.write("4. Establish phishing report button and reward program\n")
f.write("5. Conduct quarterly phishing simulations\n")
print(f"[+] Report: {report_file}")
return str(report_file)
def main():
parser = argparse.ArgumentParser(description="SE Campaign Analysis")
parser.add_argument("--gophish-url", default="https://localhost:3333")
parser.add_argument("--api-key", required=True)
parser.add_argument("--campaign-id", type=int, help="Specific campaign ID")
parser.add_argument("--output", default="./results")
args = parser.parse_args()
output_dir = Path(args.output)
output_dir.mkdir(parents=True, exist_ok=True)
client = GoPhishClient(args.gophish_url, args.api_key)
if args.campaign_id:
campaign = client.get_campaign(args.campaign_id)
stats = analyze_campaign(campaign)
dept_analysis = analyze_by_department(campaign.get("results", []))
generate_report(stats, dept_analysis, output_dir)
else:
campaigns = client.get_campaigns()
for campaign in campaigns:
stats = analyze_campaign(campaign)
dept_analysis = analyze_by_department(campaign.get("results", []))
generate_report(stats, dept_analysis, output_dir)
print(f"[+] Processed campaign: {campaign.get('name')}")
if __name__ == "__main__":
main()