
metatron-pentest-assistant
AI-powered penetration testing assistant using local LLM (metatron-qwen via Ollama) on Parrot OS Linux
- Installs
- 645
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/reason-machines/trending-skills --skill metatron-pentest-assistant- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads metatron-pentest-assistant automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
METATRON Penetration Testing Assistant
Skill by ara.so — Daily 2026 Skills collection.
METATRON is a CLI-based AI penetration testing assistant that runs entirely locally — no cloud, no API keys. It orchestrates recon tools (nmap, whois, whatweb, curl, dig, nikto), feeds results to a locally running fine-tuned LLM (metatron-qwen via Ollama), and stores all findings in MariaDB with full scan history, vulnerability tracking, and PDF/HTML export.
Architecture Overview
metatron.py ← CLI entry point, main menu, scan orchestration
db.py ← MariaDB CRUD (history, vulns, fixes, exploits, summary)
tools.py ← Recon tool runners (nmap, whois, whatweb, curl, dig, nikto)
llm.py ← Ollama interface, agentic loop, AI tool dispatch
search.py ← DuckDuckGo search + CVE lookup (no API key)
Modelfile ← Custom metatron-qwen model config
Database spine: every scan creates a sl_no in history; all other tables link via sl_no.
Installation
1. Clone and set up Python environment
git clone https://github.com/sooryathejas/METATRON.git
cd METATRON
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
2. Install system recon tools
sudo apt install nmap whois whatweb curl dnsutils nikto
3. Install Ollama and pull base model
curl -fsSL https://ollama.com/install.sh | sh
# 8GB+ RAM:
ollama pull huihui_ai/qwen3.5-abliterated:9b
# <8GB RAM — use 4b and edit Modelfile FROM line accordingly:
ollama pull huihui_ai/qwen3.5-abliterated:4b
4. Build the custom metatron-qwen model
ollama create metatron-qwen -f Modelfile
ollama list # verify metatron-qwen appears
Modelfile (the repo ships this — key parameters):
FROM huihui_ai/qwen3.5-abliterated:9b
PARAMETER num_ctx 16384
PARAMETER temperature 0.7
PARAMETER top_k 10
PARAMETER top_p 0.9
To use 4b instead, edit Modelfile:
FROM huihui_ai/qwen3.5-abliterated:4b
Then rebuild: ollama create metatron-qwen -f Modelfile
5. Set up MariaDB
sudo systemctl start mariadb
sudo systemctl enable mariadb
mysql -u root
CREATE DATABASE metatron;
CREATE USER 'metatron'@'localhost' IDENTIFIED BY '123';
GRANT ALL PRIVILEGES ON metatron.* TO 'metatron'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Create all tables:
mysql -u metatron -p123 metatron < schema.sql
Or manually (paste from README schema block). The 5 tables:
history— one row per scan session (spine)vulnerabilities— findings per sessionfixes— remediation per vulnerabilityexploits_attempted— exploit attempts per sessionsummary— raw scan + full AI analysis dump
Running METATRON
METATRON requires two terminals:
Terminal 1 — Load model into memory:
ollama run metatron-qwen
# Wait for >>> prompt before proceeding
Terminal 2 — Launch the assistant:
cd ~/METATRON
source venv/bin/activate
python metatron.py
Main Menu Flow
[1] New Scan → enter target IP/domain → select tools → AI analyzes → saved to DB
[2] View History → browse past scans → view/edit/delete/export
[3] Exit
New Scan — Tool Selection
[1] nmap
[2] whois
[3] whatweb
[4] curl headers
[5] dig DNS
[6] nikto
[a] Run all (except nikto)
[n] Run all + nikto (slow, thorough)
Exporting Reports
From View History → select scan → export:
PDF— professional vulnerability reportHTML— browser-viewable report
Code Examples
Programmatically run a scan and save to DB (db.py patterns)
import mysql.connector
def get_db_connection():
return mysql.connector.connect(
host="localhost",
user="metatron",
password="123",
database="metatron"
)
def create_scan_session(target: str) -> int:
"""Create a new history entry, return sl_no."""
from datetime import datetime
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(
"INSERT INTO history (target, scan_date, status) VALUES (%s, %s, %s)",
(target, datetime.now(), "active")
)
conn.commit()
sl_no = cursor.lastrowid
cursor.close()
conn.close()
return sl_no
def save_vulnerability(sl_no: int, vuln_name: str, severity: str,
port: str, service: str, description: str) -> int:
"""Save a vulnerability finding, return vuln id."""
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(
"""INSERT INTO vulnerabilities
(sl_no, vuln_name, severity, port, service, description)
VALUES (%s, %s, %s, %s, %s, %s)""",
(sl_no, vuln_name, severity, port, service, description)
)
conn.commit()
vuln_id = cursor.lastrowid
cursor.close()
conn.close()
return vuln_id
def save_fix(sl_no: int, vuln_id: int, fix_text: str, source: str = "AI"):
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(
"INSERT INTO fixes (sl_no, vuln_id, fix_text, source) VALUES (%s, %s, %s, %s)",
(sl_no, vuln_id, fix_text, source)
)
conn.commit()
cursor.close()
conn.close()
def save_summary(sl_no: int, raw_scan: str, ai_analysis: str, risk_level: str):
from datetime import datetime
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(
"""INSERT INTO summary (sl_no, raw_scan, ai_analysis, risk_level, generated_at)
VALUES (%s, %s, %s, %s, %s)""",
(sl_no, raw_scan, ai_analysis, risk_level, datetime.now())
)
conn.commit()
cursor.close()
conn.close()
def get_scan_history():
"""Retrieve all scan sessions."""
conn = get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT * FROM history ORDER BY scan_date DESC")
rows = cursor.fetchall()
cursor.close()
conn.close()
return rows
def get_vulnerabilities_for_scan(sl_no: int):
conn = get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute(
"SELECT * FROM vulnerabilities WHERE sl_no = %s", (sl_no,)
)
rows = cursor.fetchall()
cursor.close()
conn.close()
return rows
Running recon tools (tools.py patterns)
import subprocess
def run_nmap(target: str) -> str:
"""Run nmap service/version scan."""
result = subprocess.run(
["nmap", "-sV", "-sC", "-T4", target],
capture_output=True, text=True, timeout=120
)
return result.stdout + result.stderr
def run_whois(target: str) -> str:
result = subprocess.run(
["whois", target],
capture_output=True, text=True, timeout=30
)
return result.stdout
def run_whatweb(target: str) -> str:
result = subprocess.run(
["whatweb", "-a", "3", target],
capture_output=True, text=True, timeout=60
)
return result.stdout
def run_curl_headers(target: str) -> str:
result = subprocess.run(
["curl", "-I", "-L", "--max-time", "15", target],
capture_output=True, text=True, timeout=20
)
return result.stdout
def run_dig(target: str) -> str:
result = subprocess.run(
["dig", target, "ANY"],
capture_output=True, text=True, timeout=15
)
return result.stdout
def run_nikto(target: str) -> str:
"""Slow but thorough web scanner."""
result = subprocess.run(
["nikto", "-h", target],
capture_output=True, text=True, timeout=300
)
return result.stdout
def run_selected_tools(target: str, selections: list) -> dict:
"""
selections: list of tool names, e.g. ['nmap', 'whois', 'dig']
Returns dict of {tool_name: output}
"""
tool_map = {
'nmap': run_nmap,
'whois': run_whois,
'whatweb': run_whatweb,
'curl': run_curl_headers,
'dig': run_dig,
'nikto': run_nikto,
}
results = {}
for tool in selections:
if tool in tool_map:
print(f"[*] Running {tool} on {target}...")
try:
results[tool] = tool_map[tool](target)
except subprocess.TimeoutExpired:
results[tool] = f"[TIMEOUT] {tool} timed out"
except Exception as e:
results[tool] = f"[ERROR] {tool}: {e}"
return results
Querying Ollama LLM (llm.py patterns)
import requests
import json
OLLAMA_URL = "http://localhost:11434/api/generate"
MODEL_NAME = "metatron-qwen"
def query_llm(prompt: str, stream: bool = True) -> str:
"""Send prompt to metatron-qwen, return full response."""
payload = {
"model": MODEL_NAME,
"prompt": prompt,
"stream": stream
}
response = requests.post(OLLAMA_URL, json=payload, stream=stream)
if not stream:
return response.json().get("response", "")
full_response = ""
for line in response.iter_lines():
if line:
chunk = json.loads(line)
token = chunk.get("response", "")
print(token, end="", flush=True)
full_response += token
if chunk.get("done"):
break
print()
return full_response
def build_pentest_prompt(target: str, scan_results: dict) -> str:
"""Build the analysis prompt from scan results."""
combined = "\n\n".join(
f"=== {tool.upper()} ===\n{output}"
for tool, output in scan_results.items()
)
return f"""You are an expert penetration tester analyzing scan results for: {target}
SCAN RESULTS:
{combined}
Provide a structured analysis covering:
1. VULNERABILITIES FOUND — name, severity (Critical/High/Medium/Low), port, service, description
2. EXPLOIT SUGGESTIONS — specific tools or techniques for each vulnerability
3. RECOMMENDED FIXES — actionable remediation steps
4. OVERALL RISK LEVEL — Critical / High / Medium / Low
Format vulnerabilities as:
VULN: <name> | SEVERITY: <level> | PORT: <port> | SERVICE: <service>
DESC: <description>
FIX: <remediation>
"""
def analyze_target(target: str, scan_results: dict) -> str:
prompt = build_pentest_prompt(target, scan_results)
print("\n[🤖] metatron-qwen analyzing...\n")
return query_llm(prompt)
DuckDuckGo search and CVE lookup (search.py patterns)
from duckduckgo_search import DDGS
def search_exploits(query: str, max_results: int = 5) -> list:
"""Search DuckDuckGo for exploit info — no API key needed."""
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=max_results))
return results
def lookup_cve(cve_id: str) -> list:
"""Look up a CVE identifier."""
query = f"{cve_id} vulnerability exploit details"
return search_exploits(query)
def search_service_vulns(service: str, version: str) -> list:
query = f"{service} {version} known vulnerabilities CVE exploit"
return search_exploits(query)
# Usage example:
# results = lookup_cve("CVE-2021-44228")
# results = search_service_vulns("Apache", "2.4.49")
Full scan pipeline (end-to-end)
from tools import run_selected_tools
from llm import analyze_target
from db import (create_scan_session, save_vulnerability,
save_fix, save_summary)
def run_full_scan(target: str, tools: list = None):
if tools is None:
tools = ['nmap', 'whois', 'whatweb', 'curl', 'dig']
# 1. Create DB session
sl_no = create_scan_session(target)
print(f"[+] Scan session #{sl_no} created for {target}")
# 2. Run recon
scan_results = run_selected_tools(target, tools)
raw_scan = "\n\n".join(f"{k}:\n{v}" for k, v in scan_results.items())
# 3. AI analysis
ai_output = analyze_target(target, scan_results)
# 4. Parse and save (simplified — real parser in llm.py)
# Save summary
save_summary(sl_no, raw_scan, ai_output, risk_level="High")
print(f"\n[✓] Results saved to database (sl_no={sl_no})")
return sl_no, ai_output
# Run it:
# sl_no, analysis = run_full_scan("192.168.1.1", ['nmap', 'whois'])
Common Patterns
Check if Ollama model is running before scan
import requests
def check_ollama_ready(model: str = "metatron-qwen") -> bool:
try:
resp = requests.get("http://localhost:11434/api/tags", timeout=5)
models = [m["name"] for m in resp.json().get("models", [])]
return any(model in m for m in models)
except Exception:
return False
if not check_ollama_ready():
print("[!] metatron-qwen not found. Run: ollama run metatron-qwen")
exit(1)
Query scan history
from db import get_db_connection
def get_full_scan_report(sl_no: int) -> dict:
conn = get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT * FROM history WHERE sl_no = %s", (sl_no,))
history = cursor.fetchone()
cursor.execute("SELECT * FROM vulnerabilities WHERE sl_no = %s", (sl_no,))
vulns = cursor.fetchall()
cursor.execute("SELECT * FROM summary WHERE sl_no = %s", (sl_no,))
summary = cursor.fetchone()
cursor.close()
conn.close()
return {"history": history, "vulnerabilities": vulns, "summary": summary}
Add a custom recon tool
# In tools.py — add your tool function:
def run_gobuster(target: str, wordlist: str = "/usr/share/wordlists/dirb/common.txt") -> str:
result = subprocess.run(
["gobuster", "dir", "-u", f"http://{target}", "-w", wordlist],
capture_output=True, text=True, timeout=180
)
return result.stdout
# Register it in the tool_map in run_selected_tools():
tool_map['gobuster'] = run_gobuster
Troubleshooting
metatron-qwen not found / connection refused
# Terminal 1: ensure model is loaded
ollama run metatron-qwen
# Should show >>> prompt
# Verify Ollama API is reachable
curl http://localhost:11434/api/tags
Out of memory when running 9b model
# Switch to 4b: edit Modelfile first line:
# FROM huihui_ai/qwen3.5-abliterated:4b
ollama create metatron-qwen -f Modelfile
MariaDB connection error
sudo systemctl status mariadb
sudo systemctl start mariadb
# Verify credentials work:
mysql -u metatron -p123 metatron -e "SHOW TABLES;"
mysql.connector not found
source venv/bin/activate
pip install mysql-connector-python
nmap requires root for SYN scan
sudo nmap -sV -sC -T4 <target>
# Or use TCP connect scan (no root needed):
nmap -sT -sV <target>
Nikto timeout
Nikto is slow by design. Either use [a] (all without nikto) or increase the subprocess timeout in tools.py:
result = subprocess.run(["nikto", "-h", target],
capture_output=True, text=True,
timeout=600) # 10 minutes
Slow AI responses
The 9b model needs time to load. If response is slow after the first query, it's still loading. Subsequent queries will be faster. Ensure no other GPU/memory-heavy processes are running.
Configuration Reference
| Setting | Location | Default | Notes |
|---|---|---|---|
| DB host | db.py | localhost | Change for remote DB |
| DB user | db.py | metatron | Match SQL user created |
| DB password | db.py | 123 | Change in production |
| DB name | db.py | metatron | |
| Ollama URL | llm.py | http://localhost:11434 | |
| Model name | llm.py | metatron-qwen | Must match ollama list |
| Context window | Modelfile | 16384 | Increase for large scans |
| Temperature | Modelfile | 0.7 | Lower = more deterministic |
Security note: For production use, replace the hardcoded DB password with an environment variable:
os.environ.get("METATRON_DB_PASSWORD", "123")
Legal Disclaimer
METATRON is for educational purposes and authorized penetration testing only. Only scan systems you own or have explicit written permission to test. Unauthorized scanning is illegal.
FAQ
What does the metatron-pentest-assistant skill do?
AI-powered penetration testing assistant using local LLM (metatron-qwen via Ollama) on Parrot OS Linux
How do I install metatron-pentest-assistant?
Run npx skills add https://github.com/reason-machines/trending-skills --skill metatron-pentest-assistant in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/metatron-pentest-assistant/ (personal) or .claude/skills/metatron-pentest-assistant/ (project).
Which AI agents can use metatron-pentest-assistant?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is metatron-pentest-assistant safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains metatron-pentest-assistant?
It is published by reason-machines in reason-machines/trending-skills. It has 645 recorded installs.
More from reason-machines/trending-skills
openclaw-control-center
reason-machines/trending-skills
Local-first, security-first control center for OpenClaw agents — visibility dashboard with readonly defaults, token attribution, collaboration tracing, and safe write operations.
inkos-multi-agent-novel-writing
reason-machines/trending-skills
Multi-agent CLI system for autonomous novel writing, auditing, and revision with human review gates
claude-hud-statusline
reason-machines/trending-skills
A Claude Code plugin that displays a real-time HUD showing context usage, active tools, running agents, and todo progress in your terminal statusline.
understand-anything-knowledge-graph
reason-machines/trending-skills
Turn any codebase into an interactive knowledge graph using Claude Code skills — explore, search, and ask questions about any project visually.
agency-agents-ai-specialists
reason-machines/trending-skills
A collection of specialized AI agent personalities for Claude Code, Cursor, Aider, Windsurf, and other AI coding tools — covering engineering, design, marketing, sales, and more.
agent-browser-automation
reason-machines/trending-skills
Headless browser automation CLI for AI agents using native Rust binary with Chrome DevTools Protocol
Popular security skills
azure-compliance
microsoft/azure-skills
Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.
minimal-run-and-audit
lllllllama/rigorpilot-skills
Rigor Run skill for README-first deep learning repo reproduction. Use when the task is specifically to capture or normalize evidence from the selected smoke test or documented inference or evaluation command and write standardized reprooutputs/ files, including patch notes when repository files changed. Do not use for training execution, initial repo intake, generic environment setup, paper lookup, target selection, hidden scientific-meaning changes, or end-to-end orchestration by itself.
seo-audit
coreyhaines31/marketingskills
When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," "SEO health check," "my traffic dropped," "lost rankings," "not showing up in Google," "site isn't ranking," "Google update hit me," "page speed," "core web vitals," "crawl errors," "indexing issues," "stuck on page 2," "striking distance keywords," "title tag rewrite," "low CTR," "local SEO," "Google Business Profile," or "map pack." Use this even if the user just says something vague like "my SEO is bad" or "help with SEO" — start with an audit. For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema. For AI search optimization, see ai-seo.
firebase-security-rules-auditor
firebase/agent-skills
Audits Firebase (Firestore, Cloud Storage) security rules for vulnerabilities, privilege escalation, role bypasses, create vs update inconsistencies, resource exhaustion, type safety, size limits, and hasOnly ownership checks. Use when auditing/reviewing rules, running red-team rule assessments, or scoring against auditor checklists. Don't use for Firebase CLI (login, deploy), Auth, Crashlytics, Remote Config, or database queries.
audit
pbakaus/impeccable
Run technical quality checks across accessibility, performance, theming, responsive design, and anti-patterns. Generates a scored report with P0-P3 severity ratings and actionable plan. Use when the user wants an accessibility check, performance audit, or technical quality review.
competitors
coreyhaines31/marketingskills
When the user wants to create competitor comparison or alternative pages for SEO and buyer-facing use. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' 'competitive landing pages,' 'how do we compare to X,' 'competitor teardown,' 'audit our competitor pages,' 'are our comparison pages out of date,' or 'competitive asset audit.' Use this for any content that positions your product against competitors. Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. For auditing existing claims (not researching competitors from scratch, which is competitor-profiling; not technical SEO on these pages, which is seo-audit), use the asset audit here. For internal battle cards and sales-specific competitor docs, see sales-enablement.