Penetration Testing Toolkit
A structured penetration testing framework built for security professionals. This toolkit includes automated reconnaissance scripts, vulnerability scanning modules, exploitation helpers, evidence collection utilities, and report templates — organized around PTES methodology for consistent, defensible assessments.
Key Features
- Reconnaissance Automation — Python scripts for passive OSINT: subdomain enumeration, DNS analysis, WHOIS lookups, and technology fingerprinting.
- Vulnerability Scanner Engine — Modular scanner for SQLi, XSS, SSRF, directory traversal, and header misconfigurations with JSON output.
- Exploitation Helpers — Payload generators, reverse shell templates, and privilege escalation scripts.
- Evidence Collection — Automated screenshot capture and response logging with chain-of-evidence timestamps.
- Report Generator — Professional pentest report templates with executive summary, CVSS-scored findings, and remediation guidance.
- Methodology Checklists — PTES-aligned checklists for scoping, recon, scanning, exploitation, and reporting.
- Scope Management — Target scope validator preventing out-of-scope testing with IP/domain boundary checks.
Quick Start
# Extract the toolkit
unzip penetration-testing-toolkit.zip
cd penetration-testing-toolkit/
# Define your engagement scope
cp configs/scope.example.yaml configs/scope.yaml
# Edit scope.yaml with authorized targets
# Run passive reconnaissance
python3 scripts/recon.py --scope configs/scope.yaml --output recon_results.json
# Run vulnerability scan against in-scope targets
python3 scripts/vuln_scanner.py --target https://app.example.com --output scan_report.json
# Generate the final report
python3 scripts/report_generator.py --findings findings/ --template templates/report.md --output report.md
Scope Validator
import ipaddress
import logging
from urllib.parse import urlparse
from typing import Any
logger = logging.getLogger(__name__)
class ScopeValidator:
"""Prevent accidental out-of-scope testing."""
def __init__(self, scope_config: dict[str, Any]):
self.allowed_domains: set[str] = set(scope_config.get("domains", []))
self.allowed_networks: list[ipaddress.IPv4Network] = [
ipaddress.IPv4Network(net) for net in scope_config.get("networks", [])
]
self.excluded_ips: set[str] = set(scope_config.get("excluded_ips", []))
def is_in_scope(self, target: str) -> bool:
"""Check if a target URL or IP is within the authorized scope."""
parsed = urlparse(target) if "://" in target else None
hostname = parsed.hostname if parsed else target
# Check domain allowlist (including parent domains)
parts = hostname.split(".") if hostname else []
for i in range(len(parts)):
if ".".join(parts[i:]) in self.allowed_domains:
return True
# Check IP range
try:
ip = ipaddress.IPv4Address(hostname)
if str(ip) in self.excluded_ips:
return False
return any(ip in net for net in self.allowed_networks)
except (ipaddress.AddressValueError, ValueError):
pass
logger.warning("Target %s is OUT OF SCOPE", target)
return False
Architecture / How It Works
Scoping ──► Recon ──► Scanning ──► Exploitation ──► Post-Exploit ──► Reporting
│ │ │ │ │ │
scope.yaml OSINT Vuln Scan Payloads Evidence Executive PDF
Subdomains Ports/Svcs PrivEsc Screenshots Tech Findings
Usage Examples
Subdomain Enumerator
import json
import ssl
import socket
from urllib.request import urlopen
class SubdomainEnumerator:
"""Passive subdomain discovery via Certificate Transparency logs."""
def __init__(self, domain: str):
self.domain = domain
self.subdomains: set[str] = set()
def enumerate_ct_logs(self) -> set[str]:
url = f"https://crt.sh/?q=%25.{self.domain}&output=json"
try:
with urlopen(url, context=ssl.create_default_context(), timeout=30) as resp:
for entry in json.loads(resp.read()):
for sub in entry.get("name_value", "").split("\n"):
sub = sub.strip().lower()
if sub.endswith(self.domain) and "*" not in sub:
self.subdomains.add(sub)
except Exception:
pass
return self.subdomains
def resolve_subdomains(self) -> dict[str, str | None]:
resolved: dict[str, str | None] = {}
for sub in self.subdomains:
try:
resolved[sub] = socket.gethostbyname(sub)
except socket.gaierror:
resolved[sub] = None
return resolved
Vulnerability Finding Template
finding:
id: "FIND-001"
title: "SQL Injection in User Search Endpoint"
severity: "Critical"
cvss_score: 9.8
cvss_vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
endpoint: "GET /api/v1/users?search="
description: "User search concatenates input into SQL without parameterization."
evidence:
request: "GET /api/v1/users?search=' OR '1'='1 HTTP/1.1"
response: "200 OK — returned all 14,302 user records"
remediation: "Use parameterized queries with prepared statements."
Configuration
| Parameter | Default | Description |
|---|---|---|
scope.enforce_boundaries |
true |
Block requests to out-of-scope targets |
recon.ct_log_timeout |
30 |
Timeout for CT log queries (seconds) |
recon.dns_resolver |
8.8.8.8 |
DNS resolver for subdomain resolution |
scanner.max_threads |
10 |
Concurrent scanning threads |
scanner.request_delay |
0.5 |
Delay between requests (seconds) |
report.include_evidence |
true |
Embed evidence screenshots in report |
report.cvss_version |
3.1 |
CVSS version for risk scoring |
Best Practices
-
Always validate scope first — Run every target through
ScopeValidator. Out-of-scope testing is unauthorized access. - Start passive, go active — Exhaust CT logs, WHOIS, DNS before sending packets.
- Document everything in real time — Record timestamps, commands, and responses as you go.
- Rate-limit your scans — Aggressive scanning triggers alerts and can cause DoS.
- Clean up after yourself — Remove test accounts, uploaded files, and shells. ## Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Scanner blocked by WAF | Rate too aggressive or known scanner fingerprint | Reduce scanner.request_delay to 2s; rotate User-Agent headers |
| CT log query returns empty | Domain uses private CA or wildcard only | Fall back to DNS brute-forcing with --wordlist option |
| Scope validator rejects valid target | Target resolves to CDN IP outside defined range | Add CDN IP ranges to scope.networks or use domain-based scoping |
| Report generator crashes on large engagements | Too many findings loaded into memory | Use --batch-size 50 to process findings in chunks |
This is 1 of 9 resources in the Security Engineer Pro toolkit. Get the complete [Penetration Testing Toolkit] with all files, templates, and documentation for $49.
Or grab the entire Security Engineer Pro bundle (9 products) for $119 — save 30%.
Top comments (0)