
Un sistema RAG personal para conocimiento de seguridad ofensiva.
Un sistema RAG offline personal para conocimiento de seguridad ofensiva. Ingiere tus writeups, soluciones de laboratorio, informes de bug bounty y blogs de seguridad, luego consúltalos en lenguaje natural durante los compromisos. Sin nube, sin SaaS, tu conocimiento permanece tuyo.
ZETSU convierte tu conocimiento acumulado en un asistente consultable. En lugar de buscar con grep en archivos markdown o recordar qué writeup tenía ese comando de certipy, preguntas de forma natural:
how do i escalate with SeImpersonatePrivilege
what did i do after getting ADFS access
sliver socks5 pivot setup
explain ESC8 vs ESC4
Primero recupera de tus notas reales, luego genera una respuesta basada en lo que has documentado, no en conocimiento genérico de Internet.


Extracción FARR: en el momento de la ingesta, un LLM lee cada sección de tus writeups y extrae pasos de ataque estructurados (Finding, Action, Reasoning, Result). Lo que recuperas es una unidad semántica, no una ventana aleatoria de 800 tokens.
Recuperación híbrida: BM25 para coincidencia exacta de tokens (nombres de herramientas, números CVE, flags de CLI) + búsqueda vectorial para similitud semántica. La fusión RRF combina ambos.
Reordenador cross-encoder: reordena los fragmentos recuperados por relevancia real antes de enviarlos al LLM.
Dos estilos de respuesta: el modo Operador prioriza comandos exactos, el modo Concepto prioriza el razonamiento. Misma recuperación, presentación diferente. Cambia con Ctrl+M en la TUI.
Múltiples backends LLM: Anthropic, compatible con OpenAI (DeepSeek, etc.), u Ollama local. Backends separados para ingesta y consulta.
Múltiples tipos de fuente: archivos markdown locales, URLs individuales, wikis de GitHub, feeds Atom/RSS.
Historial de chat persistente: guardado en ~/.zetsu/history/YYYY-MM-DD.json, navegable con /history.
TUI + Web UI + CLI: usa lo que se ajuste al contexto. TUI durante compromisos, Web UI para estudiar, CLI para scripting.
git clone https://github.com/chaelsoo/zetsu
cd zetsu
pip install -r requirements.txt
Configura tu clave de API:
cp .env.example .env
# edit .env and add your key
1. Añade tus writeups
Coloca archivos .md en docs/. Exportaciones de Notion, notas de Obsidian, exportaciones de blog, cualquier cosa markdown funciona.
2. Configura las fuentes en config.toml
[llm]
backend = "openai"
openai_model = "deepseek-chat"
base_url = "https://api.deepseek.com/v1"
[[sources]]
type = "markdown_dir"
path = "./docs"
name = "my_writeups"
extract = "farr"
enabled = true
3. Ingesta
python zetsu.py ingest
4. Úsalo
python zetsu.py tui # terminal UI
python zetsu.py web # browser at localhost:8000
python zetsu.py ask "how do i abuse SeImpersonatePrivilege"
python zetsu.py ingest # ingest enabled sources
python zetsu.py ingest --force # wipe and rebuild everything
python zetsu.py ingest --dry-run # estimate without making LLM calls
python zetsu.py ingest --all-sources # enable all sources regardless of enabled flag
python zetsu.py tui # terminal UI
python zetsu.py web # web UI
python zetsu.py ask "query" # one-shot CLI
python zetsu.py ask "query" --style concept
python zetsu.py stats # vector store stats
farr: El LLM extrae pasos de ataque discretos como JSON estructurado (Finding, Action, Reasoning, Result). Mejor para writeups con cadenas de ataque claras.farr+narrative: igual que farr, más un resumen en prosa que captura el razonamiento del autor. Mejor para blogs donde el proceso de pensamiento importa.headers: sin LLM, solo divide por encabezados y mantén textual. Mejor para referencias de comandos y documentación de herramientas.Configura en config.toml. Backends separados para ingesta (extracción masiva) y consultas (generación):
[llm] # query time
backend = "openai"
openai_model = "deepseek-chat"
base_url = "https://api.deepseek.com/v1"
[ingest] # ingest time
backend = "openai"
openai_model = "deepseek-chat"
base_url = "https://api.deepseek.com/v1"
workers = 8 # parallel files during FARR extraction
Backends soportados: anthropic, openai (cualquier API compatible con OpenAI), ollama.
[!IMPORTANT] ChromaDB se ejecuta localmente por defecto, lo que carga el índice vectorial completo en RAM. Para corpus grandes (más de 10k fragmentos) o máquinas con memoria limitada, se recomienda encarecidamente ejecutar ChromaDB como servidor remoto en su lugar. Consulta documentación del servidor ChromaDB para la configuración. El soporte remoto en ZETSU está planificado.
Evaluado a través de 910 preguntas que cubren 12 categorías de seguridad ofensiva (ADCS, Kerberos, enumeración de AD, MSSQL, Sliver C2, escalada de privilegios, ataques web, credenciales, movimiento lateral, nube/Entra ID, OPSEC, herramientas).
| Métrica | Resultado |
|---|---|
| Preguntas respondidas | 910 / 910 (100%) |
| Respuestas con código/comandos | 842 / 910 (93%) |
Fuentes principales que contribuyen a las respuestas: writeups personales de HTB, blog de dirkjanm, investigación de shenaniganslabs, HackTricks ADCS, wiki de Sliver, cheatsheet de netexec.
En palabras simples, debes asegurarte de añadir recursos buenos y estructurados que quieras que el RAG ingiera; este proyecto se enfoca 100% en usar una base de conocimiento, no en confiar en la memoria del LLM o en conocimiento preentrenado.
Conjunto de datos de evaluación completo y resultados en eval/.
Documentaré en un blog el uso y su efectividad muy pronto, mantente atento.
| Tecla | Acción |
|---|
Enter | Enviar consulta |
Ctrl+M | Cambiar modo Operador/Concepto |
Ctrl+Y | Copiar última respuesta al portapapeles |
Ctrl+L | Limpiar sesión |
Ctrl+C | Salir |
/help | Mostrar comandos |
/stats | Estadísticas de almacén vectorial + historial |
/history | Consultas pasadas de hoy |
/clear | Limpiar sesión |
| Tipo | Usar para | Modo de extracción |
|---|
markdown_dir | Tus writeups, notas | farr |
markdown_file | Archivo markdown individual | farr |
url | Wikis de herramientas, páginas de referencia | headers |
atom | Blogs de seguridad con feeds | farr+narrative |
| Brechas de contexto (el modelo admitió falta de información) | 66 / 910 (7.3%) |
| Tiempo promedio de recuperación | 68ms |
| Tiempo promedio total de respuesta | 3.8s |