Imported from reason-machines/security-skills (
skills/pentestcode-ai-pentest-agent/SKILL.md). Install upstream withnpx skills add reason-machines/security-skills --skill pentestcode-ai-pentest-agent. Copyright stays with the author.
PentestCode AI Pentest Agent
Skill by ara.so — Security Skills collection.
PentestCode is an AI penetration testing agent that runs in your terminal with a multi-agent architecture. It maintains persistent engagement state, coordinates 13 specialized security agents, and automates reconnaissance through post-exploitation workflows. Built on TypeScript with Effect library.
Installation
# Quick install (self-contained binary)
curl -fsSL https://raw.githubusercontent.com/s0ld13rr/pentestcode/main/install.sh | bash
# Pin specific version
PENTESTCODE_VERSION=0.1.7 curl -fsSL https://raw.githubusercontent.com/s0ld13rr/pentestcode/main/install.sh | bash
# Custom install directory
PENTESTCODE_INSTALL=/usr/local/bin curl -fsSL https://raw.githubusercontent.com/s0ld13rr/pentestcode/main/install.sh | bash
# From source (requires Bun)
bun install
bun run build --single --skip-embed-web-ui
# Binary at packages/opencode/dist/pentestcode-<os>-<arch>/bin/pentestcode
Authentication & Configuration
# Configure LLM provider (required first step)
pentestcode auth login
# Configuration file: .pentestcode/pentestcode.jsonc
Example configuration:
{
"provider": {
"anthropic": {
"model": "claude-sonnet-4-20250514",
"apiKey": "${ANTHROPIC_API_KEY}"
}
},
"mode": "auto", // auto, free, or guided
"pauseOnFindings": "checkpoint", // never, always, checkpoint
"scope": {
"targets": ["10.10.10.0/24"],
"exclude": ["10.10.10.1"]
}
}
Supported providers: Anthropic, OpenAI, Google, Azure, AWS Bedrock, Ollama, Together, Groq, Fireworks, DeepSeek, Mistral.
Core Usage Patterns
Interactive Session
# Launch interactive mode
pentestcode
# Inside session
you: "pentest 10.10.10.5, goal is domain admin"
you: "scan 192.168.1.0/24 and enumerate all services"
you: "spray credentials across SMB and WinRM"
One-Shot Execution
# Execute single command and exit
pentestcode --prompt "scan 10.10.10.0/24 and enumerate all services"
# With custom config
pentestcode --config custom.jsonc --prompt "pentest 10.10.11.23"
CTF Mode
pentestcode --prompt "HTB box 10.10.11.45, find user.txt and root.txt"
Slash Commands
# Engagement dashboard
/status
# View discovered hosts and services
/targets
# Show vulnerabilities by severity
/vulns
# List discovered credentials
/creds
# View/edit target scope
/scope add 10.10.10.0/24
/scope exclude 10.10.10.1
/scope list
# Phase management
/phase # Show current phase
/phase recon # Jump to phase
# Switch operational modes
/mode auto # Autonomous execution
/mode free # No phase structure
/mode guided # Step-by-step approval
# Pause behavior
/pause never # Run continuously
/pause always # Stop at every finding
/pause checkpoint # Stop at phase boundaries
# Generate report
/report
Multi-Agent Architecture
PentestCode uses 13 specialized agents coordinated by a strategist:
// Agent types and their roles:
// - pentest: Lead strategist/coordinator
// - recon: Passive information gathering
// - scanner: Active service discovery
// - enumerator: Service enumeration
// - exploiter: Vulnerability exploitation
// - identity: AD/Kerberos attacks
// - infrastructure: SNMP/IPMI/databases
// - webapp: OWASP Top 10 testing
// - post-exploit: Post-exploitation tasks
// - exploit-dev: Exploit development
// - critic: False positive checking
// - reporter: Report generation
// - (hidden): context compression, session management
Agents spawn in parallel and share engagement state:
# Scanner finds open ports → state updated
# Enumerator sees new services immediately → spawns parallel enumeration
# Exploiter receives vuln data → begins exploitation
Built-in Tools
Parser Tools (Mandatory Usage)
# nmap_parse - Parse nmap XML into engagement state
nmap -sS -sV -p- 10.10.10.5 -oX scan.xml
# Agent must use: nmap_parse scan.xml
# nuclei_parse - Parse Nuclei JSON findings
nuclei -u https://target.com -json -o nuclei.json
# Agent must use: nuclei_parse nuclei.json
# cme_parse - Parse NetExec/CrackMapExec output
netexec smb 10.10.10.0/24 -u users.txt -p passwords.txt > cme.log
# Agent must use: cme_parse cme.log
# gobuster_parse - Parse directory brute output
gobuster dir -u https://target.com -w wordlist.txt -o gobuster.txt
# Agent must use: gobuster_parse gobuster.txt
# bloodhound_parse - Parse SharpHound JSON
# Agent must use: bloodhound_parse bloodhound.json
# sqlmap_parse - Parse sqlmap output
# Agent must use: sqlmap_parse sqlmap.log
Analysis Tools
# xss_detect - Analyze HTTP responses for XSS
# Input: response body, reflected parameters
# Output: XSS vulnerability classification
# jwt_analyze - JWT security analysis
# Checks: alg:none, weak HMAC, expiry, claims
# scope_check - Validate targets against scope
# Returns: in_scope boolean, CIDR/wildcard matching
Tactical Tools
# cred_spray - Plan credential spray
# Inputs: credentials list, discovered services
# Output: spray plan across SMB/WinRM/RDP/LDAP/SSH
# attack_path_suggest - Graph-based attack path finding
# Algorithm: Dijkstra + Yen's K-shortest paths
# Output: Ranked paths to objective
# tunnel_manage - Manage pivot tunnels
# Supports: SSH, chisel, ligolo
# Tracks: Live sessions, tunnel topology
State Management Tools
// state_update - Record findings (30+ mutation types)
// Usage patterns:
// Add host
state_update({
type: "add_host",
ip: "10.10.10.5",
hostname: "dc01.corp.local",
os: "Windows Server 2019"
})
// Add service
state_update({
type: "add_service",
host: "10.10.10.5",
port: 445,
protocol: "tcp",
service: "microsoft-ds",
version: "Windows Server 2019"
})
// Add vulnerability
state_update({
type: "add_vuln",
host: "10.10.10.5",
title: "SMB Signing Not Required",
severity: "medium",
confidence: 0.9,
evidence: "nmap output shows signing disabled"
})
// Add credential
state_update({
type: "add_cred",
username: "administrator",
password: "P@ssw0rd",
type: "plaintext",
domain: "CORP",
valid_for: ["smb://10.10.10.5", "winrm://10.10.10.5"]
})
// Batch updates
state_update([
{ type: "add_host", ip: "10.10.10.6" },
{ type: "add_service", host: "10.10.10.6", port: 80 }
])
// state_query - Query engagement state (20+ query types)
// Get all hosts
state_query({ type: "hosts" })
// Get services on specific host
state_query({ type: "services", host: "10.10.10.5" })
// Get vulnerabilities by severity
state_query({ type: "vulns", severity: "critical" })
// Get all credentials
state_query({ type: "creds" })
// Get access paths
state_query({ type: "access", host: "10.10.10.5" })
// Get AD domain model
state_query({ type: "ad_domain" })
// Check attack paths to objective
state_query({
type: "attack_paths",
source: "10.10.10.5",
target: "domain_admin"
})
Engagement State Structure
The engagement state persists at .pentestcode/state.json:
interface EngagementState {
// Hosts & services
hosts: Array<{
ip: string;
hostname?: string;
os?: string;
ports: Array<{
port: number;
protocol: "tcp" | "udp";
state: "open" | "closed" | "filtered";
service?: string;
version?: string;
banner?: string;
}>;
}>;
// Vulnerabilities
vulns: Array<{
id: string;
host: string;
title: string;
severity: "critical" | "high" | "medium" | "low" | "info";
status: "suspected" | "confirmed" | "exploited";
confidence: number; // 0.0-1.0
evidence: string[];
cve?: string;
}>;
// Credentials
creds: Array<{
username: string;
password?: string;
hash?: string;
type: "plaintext" | "ntlm" | "aes256" | "rc4" | "ssh_key";
domain?: string;
valid_for: string[]; // URLs where cred works
}>;
// Access gained
access: Array<{
host: string;
type: "shell" | "rdp" | "winrm" | "ssh" | "db" | "smb";
username: string;
privilege: "user" | "admin" | "system";
}>;
// Relationships (entity graph)
relationships: Array<{
from: string;
to: string;
type: "EXPLOITED_VIA" | "CREDENTIAL_FROM" | "ADMIN_OF" | "PIVOT_TO";
cost: number; // For path finding
}>;
// Active Directory model
ad_domain?: {
name: string;
domain_controllers: string[];
domain_admins: string[];
password_policy: object;
trusts: Array<{ domain: string; type: string }>;
};
// Current phase
phase: "recon" | "scan" | "enumerate" | "exploit" | "post-exploit" | "report";
// Objectives (for CTF/goal-oriented tests)
objectives: Array<{
id: string;
description: string;
status: "pending" | "complete";
flag?: string;
}>;
}
Real Workflow Example
# 1. Start engagement
pentestcode
you: "pentest 10.10.10.5, goal is domain admin"
# Agent flow:
# - Spawns scanner agent → runs nmap
# - Parses XML with nmap_parse → populates hosts/services in state
# - Recognizes ports 88 (Kerberos) + 389 (LDAP) → identifies DC
# - Spawns 3 parallel enumerators: SMB, LDAP, HTTP
# - SMB enumerator finds null session → writable share
# - LDAP enumerator extracts user list → updates state
# - HTTP enumerator runs gobuster → finds admin portal
# - Identity agent runs AS-REP roast → gets hash
# - Exploiter runs hashcat → cracks password
# - Post-exploit agent sprays cred across all services
# - WinRM access gained → spawns shell
# - Dumps SAM/LSA → extracts domain admin hash
# - Updates state with EXPLOITED_VIA relationships
# - Generates findings.md with evidence chain
# 2. Check progress
/status
# Shows: 1 DC, 7 services, 12 vulns, 3 creds, WinRM access
# 3. View findings
/vulns
# Lists vulnerabilities by severity with evidence
# 4. Review credentials
/creds
# Shows cracked passwords and where they work
# 5. Generate report
/report
# Creates markdown pentest report with timeline
Skills System
PentestCode loads knowledge packs on demand:
# Skills directory: .pentestcode/skills/
# Phase checklists (6 files)
PHASE_RECON.md
PHASE_SCAN.md
PHASE_ENUMERATE.md
PHASE_EXPLOIT.md
PHASE_POST_EXPLOIT.md
PHASE_REPORT.md
# Service knowledge (9 files)
SERVICE_SMB.md
SERVICE_SSH.md
SERVICE_HTTP.md
SERVICE_DNS.md
SERVICE_DATABASES.md
# ... etc
# Playbooks (4 files)
PLAYBOOK_INFRASTRUCTURE.md
PLAYBOOK_ACTIVE_DIRECTORY.md
PLAYBOOK_WEB_APPLICATION.md
PLAYBOOK_CLOUD.md
Add custom skills by creating SKILL_NAME.md:
# Custom Skill: Internal App Testing
## Tools
- Custom scanner at /opt/internal-scanner
- Credential wordlist at /wordlists/internal.txt
## Workflow
1. Run internal-scanner against target
2. Parse output with custom parser
3. ...
Skills are plain markdown — no code changes needed.
Mode-Specific Patterns
Auto Mode (Autonomous)
pentestcode --prompt "pentest 10.10.10.0/24"
# Agent:
# - Plans full engagement
# - Spawns subagents as needed
# - Progresses through phases automatically
# - Stops at checkpoints for review (if pause=checkpoint)
Free Mode (Unrestricted)
pentestcode
/mode free
you: "scan this random IP I found: 8.8.8.8"
# Agent:
# - Bypasses scope checks
# - No phase structure
# - Responds to direct requests
# - Useful for ad-hoc testing
Guided Mode (Step-by-Step)
pentestcode
/mode guided
you: "pentest 10.10.10.5"
# Agent proposes: "Run nmap -sS -sV -p- 10.10.10.5?"
you: "yes"
# Agent runs scan, then asks: "Enumerate SMB on port 445?"
you: "yes"
# ... continues with approval at each step
Troubleshooting
High Token Usage
# Use cheaper model for recon phases
{
"provider": {
"anthropic": {
"model": "claude-haiku-3-5-20250305" # Cheaper for bulk work
}
}
}
# Limit verbosity
you: "scan target, only report critical findings"
Agent Loops / Repeats Work
# Check state before running tools
/status
/targets # See what's already discovered
# Be explicit
you: "enumerate HTTP on port 80 at 10.10.10.5, do not rescan"
# Use guided mode to prevent redundant actions
/mode guided
Parser Failures
# Parsers expect specific formats
# If tool output is non-standard, parse manually:
you: "the nmap XML is at scan.xml but format is unusual"
# Agent should read file, extract data, manually call state_update
# Check findings.md for parse errors
tail -f .pentestcode/findings.md
Missing Dependencies
# PentestCode doesn't bundle pentest tools
# Install separately:
# Kali/Debian
sudo apt install nmap nuclei gobuster netexec bloodhound crackmapexec
# Arch
sudo pacman -S nmap
# macOS
brew install nmap nuclei gobuster
Scope Violations
# Agent stops: "Target out of scope"
/scope add 10.10.11.0/24
# Bypass scope checks temporarily
/mode free
you: "scan 1.2.3.4"
/mode auto # Return to normal
Environment Variables
# LLM Provider Keys
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
export GOOGLE_API_KEY="..."
# Custom config location
export PENTESTCODE_CONFIG="/path/to/config.jsonc"
# Install directory
export PENTESTCODE_INSTALL="/usr/local/bin"
# Version pinning (for install script)
export PENTESTCODE_VERSION="0.1.7"
Integration Patterns
With Existing Tools
# Run external tools, feed to PentestCode
nmap -sS -sV -p- 10.10.10.5 -oX scan.xml
pentestcode --prompt "parse scan.xml and continue pentest"
# Chain with CTF tools
python exploit.py > output.txt
pentestcode --prompt "analyze output.txt and suggest next steps"
With CI/CD
#!/bin/bash
# Automated security testing pipeline
pentestcode --prompt "scan staging environment at 10.0.1.0/24" \
--config ci.jsonc \
--report report.md
# Check for critical findings
if grep -q "severity: critical" report.md; then
exit 1
fi
Programmatic State Access
// Read engagement state from another tool
import fs from 'fs';
interface State {
hosts: Array<{ ip: string; ports: any[] }>;
vulns: Array<{ severity: string; title: string }>;
creds: Array<{ username: string; password: string }>;
}
const state: State = JSON.parse(
fs.readFileSync('.pentestcode/state.json', 'utf-8')
);
// Extract critical vulns
const critical = state.vulns.filter(v => v.severity === 'critical');
// Get valid credentials
const valid_creds = state.creds.filter(c => c.valid_for.length > 0);
Performance Optimization
# Limit parallel agent spawning
{
"maxParallelAgents": 3 # Default is unlimited
}
# Use local models for expensive operations
{
"provider": {
"ollama": {
"model": "llama3.1:8b",
"baseURL": "http://localhost:11434"
}
}
}
# Checkpoint-based pausing reduces redundant work
/pause checkpoint # Review at phase boundaries only
License
MIT License - See project LICENSE file for details.