- name
- pentest-lyan-web-security-testing
- description
- Autonomous web penetration testing skill with threat modeling, JavaScript analysis, and multi-role verification
- triggers
- ["run pentest-lyan security test","start web penetration test with lyan","analyze web application security using pentest-lyan","perform black box testing with lyan","test web app for vulnerabilities using pentest-lyan","conduct authorized security assessment with lyan","scan web application with pentest-lyan","resume pentest-lyan security test"]
# Pentest-Lyan Web Security Testing
> Skill by [ara.so](https://ara.so) — Security Skills collection.
Pentest-Lyan is an autonomous web penetration testing framework that performs self-directed threat modeling across 12 dimensions, complete JavaScript analysis, and cross-role verification. It validates business impact (not just HTTP 200 responses), maintains state across sessions, and generates both technical Markdown and delivery-ready Word reports.
## What It Does
- **Autonomous Threat Modeling**: Identifies threats based on 12 thinking dimensions rather than fixed vulnerability checklists
- **Deep JavaScript Analysis**: Reads and understands business logic, signing mechanisms, and frontend parameters before testing APIs
- **Business Impact Validation**: Verifies database-layer changes, data access, and state transitions actually occur
- **Multi-Role Testing**: Builds permission matrices and performs cross-role privilege escalation checks
- **Stateful Testing**: Supports resume (`--resume`), multi-project isolation, and session pooling
- **Dual Report Formats**: Markdown for technical details, Word for delivery; separates critical findings from configuration issues
## Installation
### Prerequisites
1. **Python 3.8+** with the project dependencies
2. **Playwright MCP Server** (recommended for browser automation and session pooling)
### Setup Steps
```bash
# Clone the repository
git clone https://github.com/HeaSec/Pentest-Lyan.git
cd Pentest-Lyan
# Install Python dependencies (if requirements.txt exists)
pip install -r requirements.txt
# Install as a Claude Code skill
# Copy the entire pentest-lyan/ directory to your Claude Code skills path
# Default locations:
# - macOS/Linux: ~/.config/claude-code/skills/
# - Windows: %APPDATA%\claude-code\skills\
cp -r . ~/.config/claude-code/skills/pentest-lyan/
```
### Playwright MCP Setup (Optional but Recommended)
```bash
# Install Playwright MCP for browser automation
npm install -g @playwright/mcp-server
# Or add to your MCP configuration
# The skill will use curl if Playwright is unavailable
```
## Project Structure
```
pentest-lyan/
├── SKILL.md # Main orchestrator (3 phases, 9 exit conditions)
├── gates.md # HARD GATE definitions (G1-G7)
├── schema.md # Data schema index
├── references/ # Process documentation (read by agent as needed)
│ ├── discovery-guide.md
│ ├── attack-guide.md
│ ├── threat-modeling.md
│ ├── validation-guide.md
│ ├── cross-role-testing.md
│ ├── audit-guide.md
│ ├── report-template.md
│ ├── docx-template.md
│ └── post-delivery.md
├── schema/ # Field specification schemas (*.schema.json)
├── scripts/ # Utility scripts
│ └── render_docx.py
└── templates/ # Word document templates
```
## Basic Usage
### Starting a New Security Test
```bash
# Basic invocation
/pentest-lyan https://target.example.com
# Provide credentials (required for proper testing)
/pentest-lyan https://target.example.com
账号:
- admin/Admin@123 (role_level: high_privilege)
- user1/User@123 (role_level: standard)
- user2/User@123 (role_level: standard)
```
**Important**: No need to declare authorization scope/timeframe — issuing the command implies authorization.
### Multi-Project Management
```bash
# List all projects
/pentest-lyan --list
# Resume an existing project
/pentest-lyan --resume <project-id>
# Start with custom project ID
/pentest-lyan https://target.example.com --project custom-id
```
Default `project-id` is extracted from the hostname's first segment.
## Testing Phases
Pentest-Lyan executes in three sequential phases:
### Phase 1: Discovery
- Deep JavaScript analysis (business logic, signing, parameters)
- Complete API endpoint discovery
- Session pool creation
- Permission matrix generation
### Phase 2: Attack
- Feature-level testing pipeline
- Dynamic sub-module discovery
- Cross-role privilege verification
- Business impact validation
### Phase 3: Audit
- Schema validation
- Completeness auditing
- System-level checks
- Report generation (Markdown + Word)
## Account Requirements (G1 Gate)
The G1 gate checks account availability but **does not block** testing:
- **≥2 accounts**: Normal flow, full cross-role testing
- **0-1 accounts**: Degraded mode, limited privilege testing; if registration page found, report prompts user to register additional accounts
`role_level` must be explicitly declared by the user (not inferred from username):
- `high_privilege`: Admin, superuser, manager
- `standard`: Regular user
- `limited`: Guest, read-only
## Working with State Files
Pentest-Lyan maintains state in `pentest-data/<project-id>/`:
```
pentest-data/
└── <project-id>/
├── state.json # Main state (phase, coverage, findings)
├── index.json # Project metadata
├── pages/ # Discovered pages/APIs
├── sessions/ # Session data (contains credentials)
├── modules/ # Feature module state
└── coverage/ # Coverage tracking
```
### State File Example
```json
{
"project_id": "example-com",
"phase": "discovery",
"target": "https://example.com",
"accounts": [
{
"username": "admin",
"password": "REDACTED",
"role_level": "high_privilege"
}
],
"discovered_endpoints": [],
"findings": [],
"coverage": {}
}
```
**Security Warning**: `pentest-data/` contains plaintext credentials. Add to `.gitignore`:
```bash
# Add to .gitignore
echo "pentest-data/" >> .gitignore
echo "pentest-report/" >> .gitignore
```
## Threat Modeling Dimensions
Pentest-Lyan uses 12 autonomous threat dimensions:
1. **Authentication**: Session, token, multi-factor bypasses
2. **Authorization**: Horizontal/vertical privilege escalation, IDOR
3. **Input Validation**: Injection, XSS, path traversal
4. **Business Logic**: Workflow bypasses, race conditions
5. **Data Exposure**: Sensitive data leaks, information disclosure
6. **Session Management**: Fixation, hijacking, timeout issues
7. **Cryptography**: Weak algorithms, improper key management
8. **Configuration**: Default credentials, unnecessary services
9. **API Security**: Rate limiting, parameter tampering
10. **File Handling**: Upload bypasses, arbitrary file operations
11. **Error Handling**: Stack traces, verbose errors
12. **Third-Party**: Dependency vulnerabilities, external service abuse
## Code Examples
### Extending Validation Logic (Python)
```python
# Example: Custom validator for business impact
# File: custom_validators.py
import requests
import json
def validate_discount_manipulation(session, endpoint, payload):
"""
Verify that discount manipulation actually affects the database.
Returns True if vulnerability is confirmed.
"""
# Apply discount
resp = session.post(
endpoint,
json=payload,
headers={"Content-Type": "application/json"}
)
if resp.status_code != 200:
return False
# Retrieve order to confirm database change
order_id = resp.json().get("order_id")
verify_resp = session.get(f"/api/orders/{order_id}")
if verify_resp.status_code == 200:
order_data = verify_resp.json()
expected_price = payload.get("discounted_price")
actual_price = order_data.get("total_price")
# Confirm business impact
return actual_price == expected_price
return False
# Use in validation-guide.md workflow
```
### Reading JavaScript for Signing Logic
```python
# Example: Extracting signing mechanism from JS
# The agent performs this during discovery phase
import re
import requests
def extract_signing_function(js_url):
"""
Download and parse JavaScript to find signing functions.
"""
resp = requests.get(js_url)
js_content = resp.text
# Look for common signing patterns
signing_patterns = [
r'function\s+sign\([^)]*\)\s*{([^}]+)}',
r'const\s+sign\s*=\s*\([^)]*\)\s*=>\s*{([^}]+)}',
r'\.sign\s*=\s*function\([^)]*\)\s*{([^}]+)}'
]
for pattern in signing_patterns:
matches = re.findall(pattern, js_content)
if matches:
return {
"signing_function": matches[0],
"algorithm": detect_algorithm(matches[0])
}
return None
def detect_algorithm(func_body):
"""Detect crypto algorithm from function body."""
if 'md5' in func_body.lower():
return 'md5'
elif 'sha256' in func_body.lower():
return 'sha256'
elif 'hmac' in func_body.lower():
return 'hmac'
return 'unknown'
```
### Permission Matrix Generation
```python
# Example: Building permission matrix for cross-role testing
# File: permission_matrix.py
def build_permission_matrix(endpoints, sessions):
"""
Test each endpoint with each role to build permission matrix.
Returns matrix of {endpoint: {role: accessible}}.
"""
matrix = {}
for endpoint in endpoints:
matrix[endpoint["path"]] = {}
for session_info in sessions:
role = session_info["role_level"]
session = session_info["session"]
# Test access
resp = session.get(
endpoint["url"],
allow_redirects=False
)
# Determine if accessible
accessible = resp.status_code in [200, 201, 204]
matrix[endpoint["path"]][role] = {
"accessible": accessible,
"status_code": resp.status_code
}
return matrix
# Example matrix output:
# {
# "/api/admin/users": {
# "high_privilege": {"accessible": True, "status_code": 200},
# "standard": {"accessible": False, "status_code": 403}
# },
# "/api/profile": {
# "high_privilege": {"accessible": True, "status_code": 200},
# "standard": {"accessible": True, "status_code": 200}
# }
# }
```
### Cross-Role Privilege Testing
```python
# Example: Test privilege escalation using permission matrix
# File: cross_role_test.py
def test_privilege_escalation(matrix, sessions):
"""
Use permission matrix to find privilege escalation vulnerabilities.
"""
findings = []
for endpoint, roles in matrix.items():
# Find endpoints accessible to high_privilege but not standard
if (roles.get("high_privilege", {}).get("accessible") and
not roles.get("standard", {}).get("accessible")):
# Test with standard user using high_privilege user's ID
standard_session = get_session_by_role(sessions, "standard")
high_priv_user_id = get_user_id_by_role(sessions, "high_privilege")
# Attempt access with victim ID (not hardcoded)
test_url = endpoint.replace("{user_id}", str(high_priv_user_id))
resp = standard_session.get(test_url)
if resp.status_code in [200, 201]:
findings.append({
"type": "privilege_escalation",
"endpoint": endpoint,
"description": f"Standard user can access high_privilege endpoint",
"evidence": {
"url": test_url,
"status": resp.status_code,
"attacker_role": "standard",
"victim_role": "high_privilege"
}
})
return findings
```
## Report Generation
### Markdown Report
Generated automatically at end of audit phase:
```bash
# Reports are written to:
pentest-report/<project-id>_<timestamp>.md
```
Structure:
- Executive Summary
- Findings (Critical → High → Medium → Low)
- Coverage Analysis (answers: input surface, behavior surface, depth)
- Appendix (configuration issues, not_vulnerable with unruled_out)
### Word Report
```python
# scripts/render_docx.py
import sys
from docx import Document
from docx.shared import Inches, Pt, RGBColor
def render_docx(markdown_path, output_path, template_path=None):
"""
Convert Markdown report to Word document.
Args:
markdown_path: Path to .md report
output_path: Path for output .docx
template_path: Optional custom template
"""
doc = Document(template_path) if template_path else Document()
with open(markdown_path, 'r', encoding='utf-8') as f:
content = f.read()
# Parse markdown and apply styles
sections = parse_markdown(content)
for section in sections:
if section['type'] == 'heading1':
doc.add_heading(section['text'], level=1)
elif section['type'] == 'finding':
add_finding_block(doc, section['data'])
elif section['type'] == 'code':
add_code_block(doc, section['text'])
doc.save(output_path)
# Usage:
# python scripts/render_docx.py pentest-report/example-com_2026.md output.docx
```
## Configuration
### Environment Variables
```bash
# Optional: Custom data directory
GitHubで見る